1. 从“功能堆叠”到“能力编排”:通用Agent到底改了什么
过去十几年,我们做软件架构的思路基本没变过:先画页面,再拆服务,然后定义接口,最后把业务逻辑一层层塞进代码里。一个电商系统有商品模块、订单模块、支付模块、售后模块,每个模块都有自己的数据库、自己的接口、自己的前端页面。用户要完成一件事,得在多个页面之间跳来跳去,系统之间的边界清晰但僵硬。
通用Agent的出现,把这个逻辑彻底翻了个面。它不再要求用户去适应软件的流程,而是让软件来理解用户的意图。你只需要说“帮我订一张明天下午去某地的票,靠窗,价格别太离谱”,Agent自己去拆解任务、调用工具、比对结果、完成下单。整个过程里,用户面对的不再是一堆按钮和表单,而是一个能听懂人话、能自己想办法的“大脑”。
这个变化的核心在于:软件的核心资产从“功能代码”变成了“技能定义”。以前我们写一个退款功能,要写接口、写校验、写状态机、写通知逻辑,几百行代码跑不掉。现在你只需要定义一个“退款技能”,告诉Agent这个技能能做什么、需要什么参数、有什么限制条件,剩下的编排逻辑交给Agent自己去推理。代码量可能只有原来的十分之一,但灵活性提升了不止一个量级。
我拿一个实际场景来说明。假设你要做一个内部报销系统。传统做法是:员工登录系统,填写报销单,上传发票,选择费用类型,提交审批,财务审核,打款。每个环节都有页面,都有校验规则,都有状态流转。通用Agent的做法是:员工直接把发票拍照发给Agent,说“帮我报销这笔打车费”。Agent识别发票信息,判断费用类型,检查是否符合报销政策,自动填写报销单,提交审批,甚至可以在审批通过后通知员工。整个过程中,员工不需要知道报销系统长什么样,只需要表达意图。
这就是标题里说的“大脑+技能+护栏”的雏形。大脑负责理解和推理,技能负责执行具体操作,护栏负责确保安全合规。三者分离之后,软件架构从“以功能为中心”转向了“以意图为中心”。这个转变的影响范围极广,从企业内部系统到面向消费者的应用,从简单的信息查询到复杂的多步骤任务,都会被重新定义。
适合谁来关注这个变化?如果你是后端开发者,你需要思考哪些逻辑应该封装成技能,哪些应该留给Agent推理。如果你是产品经理,你需要重新设计用户与系统的交互方式,从“引导用户点击”变成“理解用户意图”。如果你是架构师,你需要考虑如何在不破坏现有系统的前提下,逐步引入Agent能力。这篇文章会从架构设计、技能封装、护栏机制、实操落地四个维度,把这件事讲透。
2. 大脑、技能、护栏:三层架构的拆解与设计考量
2.1 为什么是这三层,而不是更多或更少
把通用Agent架构拆成“大脑+技能+护栏”三层,不是拍脑袋决定的,而是经过大量实践之后收敛出来的最小可行结构。少一层不行,多一层冗余。
先说为什么不能只有“大脑+技能”。大脑负责推理和编排,技能负责执行具体操作。如果没有护栏,大脑可能会调用不该调用的技能,或者用错误的方式调用技能。比如用户说“帮我删掉上个月的订单记录”,大脑理解了这个意图,直接调用“删除订单”技能,结果把财务数据也删了。护栏的作用就是在技能执行前后加一层校验,确保操作符合业务规则和安全边界。
再说为什么不需要更多层。有人会问,要不要加一个“记忆层”或者“上下文层”?我的经验是,记忆和上下文管理应该属于大脑的一部分,而不是独立的一层。大脑本身就需要维护对话历史、用户偏好、任务状态等信息,这些信息在推理过程中自然会被用到。如果单独拆出一层,反而会增加数据同步的复杂度和延迟。技能层也不需要再细分,因为技能本身就是最小的可执行单元,再拆就变成函数调用了,失去了Agent编排的意义。
三层架构的核心优势在于职责清晰。大脑只负责“想”,技能只负责“做”,护栏只负责“管”。任何一层出问题,排查范围都很明确。大脑推理错了,去看提示词和上下文;技能执行失败了,去看技能实现和参数;护栏拦截了,去看规则配置。这种清晰的分工在传统软件架构里是很难做到的,因为业务逻辑往往散落在各个模块里,出了问题得全局排查。
2.2 大脑层:提示词工程与推理策略的实战要点
大脑层是整个架构的核心,它的质量直接决定了Agent的智能程度。我见过很多团队在这一层踩坑,最常见的问题是把大脑当成一个简单的“意图分类器”,只做路由转发,不做真正的推理。这样做的结果是,Agent只能处理预定义好的几种意图,遇到稍微复杂一点的任务就歇菜了。
大脑层的设计要点有三个:提示词结构、推理策略、上下文管理。
提示词结构决定了大脑的“思维方式”。我习惯把提示词分成四个部分:角色定义、能力说明、约束条件、输出格式。角色定义告诉大脑它是谁,比如“你是一个企业内部报销助手”。能力说明列出它可以调用的技能,以及每个技能的用途和参数。约束条件明确它不能做什么,比如“不能直接修改财务数据”。输出格式规定它应该以什么形式返回结果,比如JSON或者自然语言。
推理策略决定了大脑的“思考深度”。最简单的策略是“单步推理”,用户说一句话,大脑直接决定调用哪个技能。这种策略适合简单任务,但遇到多步骤任务就不行了。更高级的策略是“链式推理”,大脑先把任务拆成多个步骤,然后逐步执行。比如“帮我订一张明天下午去某地的票,靠窗,价格别太离谱”,大脑会先拆成“查询明天下午的票”“筛选靠窗的选项”“按价格排序”“选择最合适的”“下单”五个步骤,然后依次执行。
上下文管理决定了大脑的“记忆力”。Agent需要记住对话历史、用户偏好、任务状态等信息。我的经验是,上下文不要全量保留,而是要做摘要和压缩。比如用户和Agent聊了二十轮,前面十几轮可能都是闲聊,只有最近几轮涉及具体任务。大脑只需要保留最近几轮的关键信息,以及从历史对话中提取出来的用户偏好,比如“用户喜欢靠窗座位”“用户对价格敏感”。这样既能保证推理质量,又能控制token消耗。
提示:大脑层的提示词不要写得太长。我见过一个团队的提示词写了三千多字,结果大脑推理速度极慢,而且经常忽略后面的约束条件。提示词控制在八百字以内,把最关键的信息放在前面,效果反而更好。
2.3 技能层:从“写代码”到“定义能力”的转变
技能层是通用Agent架构里最容易被低估的一层。很多人觉得技能就是API调用,把现有的接口包装一下就行了。但实际上,技能的定义方式直接决定了Agent的灵活性和可维护性。
传统API的设计思路是“面向资源”,比如GET /orders、POST /orders、DELETE /orders/{id}。这种设计适合人类开发者调用,但不适合Agent调用。因为Agent需要的是“面向意图”的能力,比如“查询订单”“创建订单”“取消订单”。每个能力应该是一个完整的业务操作,而不是一个HTTP方法。
我通常会把技能定义成三个部分:技能描述、参数定义、执行逻辑。技能描述用自然语言说明这个技能能做什么,什么情况下应该调用它。参数定义明确每个参数的类型、是否必填、取值范围。执行逻辑就是具体的代码实现,可以是调用内部服务,也可以是操作数据库,甚至可以是调用外部系统。
举个例子,一个“查询订单”技能的定义可能是这样的:
{ "name": "query_order", "description": "根据订单号或用户信息查询订单详情,适用于用户询问订单状态、物流信息等场景", "parameters": { "order_id": { "type": "string", "required": false, "description": "订单号,如果用户提供了订单号则使用此参数" }, "user_id": { "type": "string", "required": false, "description": "用户ID,如果用户没有提供订单号但提供了用户信息则使用此参数" }, "time_range": { "type": "object", "required": false, "description": "时间范围,用于筛选特定时间段内的订单" } } }这种定义方式的好处是,大脑可以根据用户的自然语言描述,自动判断应该使用哪个参数。比如用户说“帮我查一下我上周买的那个东西到哪了”,大脑会识别出用户没有提供订单号,但提供了时间范围“上周”,于是自动填充time_range参数,调用技能查询。
技能层的另一个关键点是技能粒度。粒度太粗,大脑无法灵活组合;粒度太细,大脑需要调用太多次,效率低下。我的经验是,一个技能应该对应一个完整的业务操作,而不是一个技术步骤。比如“发送邮件”是一个技能,“查询用户信息”是一个技能,但“连接数据库”不应该是一个技能,因为它是技术细节,不是业务能力。
2.4 护栏层:安全合规的最后一道防线
护栏层是通用Agent架构里最容易被忽视,但出事之后最要命的一层。我见过太多团队在开发阶段只关注功能实现,等到上线之后才发现Agent会做出各种意想不到的操作。比如用户说“帮我清理一下不用的文件”,Agent理解成“删除所有文件”,结果把重要数据删了。护栏的作用就是在这些危险操作发生之前拦住它。
护栏的设计思路有两种:规则式护栏和模型式护栏。规则式护栏基于预定义的规则做判断,比如“删除操作必须经过二次确认”“涉及金额超过一千元的操作必须人工审批”。这种护栏实现简单,但覆盖范围有限,只能处理已知的风险场景。模型式护栏用一个专门的模型来判断操作是否安全,比如把用户请求和Agent计划的操作一起输入模型,让模型判断是否存在风险。这种护栏覆盖范围广,但需要额外的模型推理成本。
我的建议是两者结合。规则式护栏处理高频、明确的风险场景,模型式护栏处理低频、模糊的风险场景。比如“删除数据”这种明确的高风险操作,直接用规则拦截;“修改用户偏好”这种看起来无害但可能被滥用的操作,用模型判断。
护栏的另一个关键点是执行时机。护栏可以在三个位置介入:大脑推理之前、技能调用之前、技能执行之后。大脑推理之前拦截,可以防止Agent理解错误意图;技能调用之前拦截,可以防止危险操作被执行;技能执行之后拦截,可以回滚已经发生的错误操作。我的经验是,技能调用之前是最关键的拦截点,因为这时候操作还没有真正发生,拦截成本最低。
注意:护栏规则不要写得太死。我见过一个团队把护栏规则写成了“所有涉及用户数据的操作都必须人工审批”,结果Agent几乎什么都做不了,用户体验极差。护栏的目的是防止危险操作,不是阻止正常操作。规则要精确,不要一刀切。
3. 实操落地:从零搭建一个通用Agent系统的完整流程
3.1 环境准备与技术选型
搭建通用Agent系统,第一步是选型。市面上的框架很多,但核心组件就那么几个:大模型、技能运行时、护栏引擎、状态存储。
大模型的选择取决于你的场景。如果是内部系统,对数据安全要求高,可以选择私有化部署的开源模型。如果是面向消费者的应用,对推理能力要求高,可以选择云端API。我的经验是,不要一开始就追求最强模型,先用中等能力的模型跑通流程,等架构稳定了再升级。因为模型能力越强,推理成本越高,调试难度也越大。
技能运行时负责加载技能定义、执行技能逻辑、管理技能生命周期。我习惯用Python或者TypeScript来实现,因为这两种语言的生态最丰富,集成各种服务最方便。技能运行时的核心是一个注册中心,所有技能在这里注册,大脑通过注册中心查询可用技能。
护栏引擎负责加载护栏规则、执行规则判断、记录拦截日志。规则可以用JSON或者YAML来定义,方便非技术人员维护。护栏引擎需要支持热更新,因为业务规则经常变化,不能每次改规则都重启服务。
状态存储负责保存对话历史、任务状态、用户偏好等信息。可以用Redis做短期存储,用关系型数据库做长期存储。我的经验是,对话历史不要存全量,只存最近N轮和关键摘要,否则存储成本会很高。
3.2 技能封装的具体步骤与参数设计
技能封装是实操中最耗时的环节。我通常按照以下步骤来做:
第一步,梳理现有系统的能力。把现有系统的所有接口列出来,按照业务操作分类。比如订单系统有“创建订单”“查询订单”“取消订单”“修改订单”四个操作,每个操作对应一个技能。
第二步,定义技能描述。用自然语言写清楚这个技能能做什么,什么情况下应该调用它。描述要具体,不要写“处理订单”这种模糊的表述,要写“根据用户提供的商品信息和收货地址创建新订单”。
第三步,定义参数。每个参数都要明确类型、是否必填、取值范围、默认值。参数名要用业务术语,不要用技术术语。比如用order_id而不是oid,用time_range而不是tr。
第四步,实现执行逻辑。这一步就是写代码,调用内部服务或者操作数据库。执行逻辑要处理好异常情况,比如服务不可用、参数不合法、权限不足等。
第五步,编写测试用例。每个技能都要有对应的测试用例,覆盖正常流程和异常流程。测试用例可以用自然语言描述,比如“用户提供有效的订单号,返回订单详情”“用户提供不存在的订单号,返回错误提示”。
参数设计有一个容易被忽视的点:默认值。很多参数在大多数情况下都有合理的默认值,比如查询订单时默认查询最近一个月的订单,创建订单时默认使用用户的默认收货地址。设置合理的默认值可以减少大脑的推理负担,提高执行效率。
3.3 护栏规则的配置与动态调整
护栏规则的配置需要业务人员和技术人员共同参与。业务人员定义规则内容,技术人员实现规则引擎。
规则的定义格式我推荐用YAML,因为可读性好,非技术人员也能看懂。比如一条“删除操作需要二次确认”的规则可以这样写:
- name: "delete_requires_confirmation" description: "删除类操作必须经过用户二次确认" trigger: skill_pattern: "delete_*" condition: - type: "user_confirmation" required: true action: - type: "block" message: "此操作需要您确认后才能执行"规则引擎需要支持多种条件类型,比如用户角色判断、金额阈值判断、时间范围判断、操作频率判断等。条件之间可以用AND/OR组合,实现复杂的规则逻辑。
动态调整是护栏规则的关键能力。业务规则经常变化,比如促销期间放宽退款条件,或者风控期间收紧审批流程。规则引擎需要支持热更新,修改规则后立即生效,不需要重启服务。我的做法是把规则存在配置中心,规则引擎定时拉取最新规则,或者通过消息通知触发更新。
3.4 大脑提示词的迭代与优化
大脑提示词的迭代是一个持续的过程。我通常按照“观察-分析-调整-验证”的循环来优化。
观察阶段,收集Agent的实际表现。记录每次推理的输入和输出,标记出推理错误、技能调用错误、参数填充错误等情况。分析阶段,找出错误的原因。是提示词描述不清,还是技能定义有歧义,还是上下文信息不足。调整阶段,修改提示词或者技能定义,解决发现的问题。验证阶段,用之前的错误案例重新测试,确认问题是否解决。
提示词优化的一个实用技巧是少样本学习。在提示词里加入几个典型的输入输出示例,让大脑模仿。比如:
用户输入:帮我查一下我上周买的那个东西到哪了 大脑输出:{"skill": "query_order", "parameters": {"time_range": {"start": "2024-01-08", "end": "2024-01-14"}}}这种示例可以显著提高大脑的推理准确率,尤其是对于格式要求严格的场景。
另一个技巧是约束前置。把最重要的约束条件放在提示词的最前面,因为大脑对前面的内容注意力更集中。比如“你不能直接修改财务数据”这条约束,应该放在提示词的开头,而不是结尾。
4. 常见问题与排查技巧实录
4.1 大脑推理错误的典型场景与修复方法
大脑推理错误是最常见的问题,表现形式多种多样。我整理了几种典型场景和对应的修复方法。
第一种是意图识别错误。用户说“帮我看看我的账户”,大脑理解成“查询账户余额”,但实际上用户想看的是账户的交易记录。这种错误的修复方法是丰富技能描述,在“查询账户余额”和“查询交易记录”两个技能的描述里明确区分使用场景。
第二种是参数填充错误。用户说“帮我订一张明天下午的票”,大脑把“明天下午”理解成了“明天14:00”,但实际上用户可能指的是“明天12:00到18:00之间的任意时间”。这种错误的修复方法是在参数定义里明确时间范围的格式,或者在提示词里加入时间解析的示例。
第三种是技能选择错误。用户说“帮我取消订单”,大脑调用了“删除订单”技能,而不是“取消订单”技能。这两个技能在业务上完全不同,取消订单是正常流程,删除订单是管理操作。修复方法是在技能描述里明确区分,并且在护栏层加一条规则,禁止对普通用户开放删除订单技能。
第四种是多步推理断裂。用户说“帮我订一张明天下午去某地的票,靠窗,价格别太离谱”,大脑只执行了“查询票”这一步,没有继续执行“筛选靠窗”“按价格排序”“下单”等步骤。这种错误的修复方法是优化提示词,明确要求大脑必须完成所有步骤才能返回结果。
4.2 技能调用失败的排查思路
技能调用失败的原因很多,排查时需要按照一定的顺序来定位。
第一步,检查技能是否注册。大脑调用技能之前,会先查询技能注册中心。如果技能没有注册,或者注册信息不完整,大脑就找不到这个技能。排查方法是查看技能注册中心的日志,确认技能是否成功注册。
第二步,检查参数是否合法。技能执行之前会做参数校验,如果参数类型不对、必填参数缺失、参数值超出范围,校验会失败。排查方法是查看参数校验日志,确认哪个参数出了问题。
第三步,检查执行逻辑是否异常。技能执行过程中可能会遇到各种异常,比如服务不可用、数据库连接失败、权限不足等。排查方法是查看技能执行日志,定位具体的异常信息。
第四步,检查护栏是否拦截。如果技能调用被护栏拦截了,大脑会收到拦截信息。排查方法是查看护栏日志,确认是哪条规则拦截了,以及拦截原因是什么。
我通常会把排查步骤做成一个检查清单,遇到问题按顺序过一遍,基本能定位到原因。
| 排查步骤 | 检查内容 | 常见问题 |
|---|---|---|
| 技能注册 | 技能是否在注册中心 | 技能未注册或注册信息不完整 |
| 参数校验 | 参数类型、必填项、取值范围 | 参数类型错误、必填项缺失 |
| 执行逻辑 | 服务可用性、数据库连接、权限 | 服务不可用、连接失败、权限不足 |
| 护栏拦截 | 护栏规则是否触发 | 规则配置过严、规则误判 |
4.3 护栏误拦截的处理经验
护栏误拦截是另一个常见问题。护栏的目的是防止危险操作,但如果规则配置不当,会把正常操作也拦住。
我遇到过一个案例:护栏规则里有一条“涉及金额超过一千元的操作必须人工审批”。结果用户报销一笔一千零五十元的打车费,被护栏拦住了,需要人工审批。但实际上这笔费用完全符合报销政策,人工审批完全是浪费时间。
修复方法是把规则改得更精确。不是所有超过一千元的操作都需要审批,而是“涉及金额超过一千元且费用类型不在白名单里的操作”才需要审批。这样既保证了安全,又减少了不必要的拦截。
另一个经验是护栏规则要分级。不是所有规则都同等重要,有些规则是硬性约束,绝对不能违反;有些规则是软性建议,可以在特定情况下放宽。我把护栏规则分成三级:红色规则(绝对禁止)、黄色规则(需要确认)、绿色规则(允许通过)。红色规则比如“禁止删除财务数据”,黄色规则比如“大额操作需要确认”,绿色规则比如“查询操作直接放行”。分级之后,护栏的拦截行为更加合理,用户体验也更好。
4.4 性能优化的几个关键点
通用Agent系统的性能瓶颈通常出现在三个地方:大脑推理、技能调用、护栏判断。
大脑推理的优化方法是减少提示词长度、使用更快的模型、缓存常见推理结果。我试过把提示词从两千字压缩到八百字,推理速度提升了将近一倍。另外,对于常见的用户请求,可以缓存大脑的推理结果,下次遇到相同请求直接返回缓存,不需要重新推理。
技能调用的优化方法是并行调用、批量调用、异步调用。如果大脑需要调用多个技能,而且这些技能之间没有依赖关系,可以并行调用,减少总耗时。如果大脑需要调用同一个技能多次,可以批量调用,减少网络开销。如果技能调用耗时较长,可以异步调用,先返回一个任务ID,等技能执行完成后再通知用户。
护栏判断的优化方法是规则预编译、条件短路、结果缓存。规则预编译把规则转换成可执行代码,减少每次判断的解析开销。条件短路在第一个条件不满足时直接返回,不需要判断后续条件。结果缓存把常见的判断结果缓存起来,下次遇到相同请求直接返回。
提示:性能优化不要过早进行。先把功能跑通,再考虑优化。我见过一个团队在功能还没完善的时候就开始优化性能,结果优化了半天,功能改了,优化全白做了。
5. 影响范围与未来演进:谁会被改变,怎么改变
5.1 对开发者的影响:从写代码到定义能力
通用Agent架构对开发者的影响是深远的。以前开发者的核心能力是写代码,把业务逻辑翻译成程序指令。以后开发者的核心能力是定义能力,把业务操作封装成技能,让Agent去编排。
这个转变意味着开发者需要具备更强的业务理解能力。以前你只需要知道怎么实现一个功能,以后你需要知道这个功能在什么场景下使用、有什么限制条件、和其他功能有什么关系。你需要站在Agent的角度思考问题,而不是站在代码的角度。
另一个影响是开发者的工作方式会发生变化。以前是“需求-设计-开发-测试-上线”的线性流程,以后是“定义技能-配置护栏-优化提示词-持续迭代”的循环流程。技能和护栏是相对稳定的,提示词是需要持续优化的。开发者的工作重心会从写代码转向调优。
5.2 对产品经理的影响:从设计流程到设计意图
产品经理的工作也会发生根本性变化。以前产品经理的核心工作是设计流程,画流程图、写需求文档、定义交互细节。以后产品经理的核心工作是设计意图,定义用户可以用自然语言表达哪些意图,以及这些意图应该如何被理解和执行。
这意味着产品经理需要更深入地理解业务逻辑。以前你只需要知道用户点击按钮之后发生什么,以后你需要知道用户说一句话之后,Agent会怎么理解、怎么拆解、怎么执行。你需要考虑各种可能的表达方式,以及对应的处理逻辑。
另一个影响是产品经理需要和开发者更紧密地协作。技能的定义需要产品经理和开发者共同完成,护栏的配置需要产品经理和业务人员共同参与。产品经理不再是需求的传递者,而是能力的定义者。
5.3 对系统架构的影响:从微服务到技能编排
系统架构的变化是最明显的。传统的微服务架构把系统拆成多个独立的服务,每个服务负责一个业务领域。通用Agent架构把系统拆成多个技能,每个技能负责一个业务操作。微服务之间通过API调用,技能之间通过Agent编排。
这个变化带来的最大好处是灵活性。微服务架构下,新增一个业务功能需要开发新的服务、定义新的接口、修改调用方。通用Agent架构下,新增一个业务功能只需要定义一个新的技能,Agent会自动发现并调用它。不需要修改调用方,不需要重新部署。
另一个好处是可观测性。微服务架构下,一个请求可能经过多个服务,排查问题需要跨服务追踪。通用Agent架构下,所有技能调用都经过Agent,Agent可以记录完整的调用链路,排查问题更加方便。
5.4 未来演进:从“大脑+技能+护栏”到更复杂的架构
“大脑+技能+护栏”三层架构是一个起点,不是终点。随着Agent能力的增强和应用场景的扩展,架构会继续演进。
一个可能的演进方向是多大脑协作。不同的Agent负责不同的领域,比如一个Agent负责客服,一个Agent负责销售,一个Agent负责售后。这些Agent之间可以互相调用,形成一个Agent网络。用户只需要和其中一个Agent交互,这个Agent会自动协调其他Agent完成任务。
另一个方向是技能自学习。Agent在执行任务的过程中,可以自动发现新的技能需求,甚至自动生成技能定义。比如Agent发现用户经常问“我的订单什么时候到”,但现有的技能只能查询订单状态,不能预测到达时间。Agent可以自动创建一个“预测到达时间”的技能,调用物流接口获取预计到达时间。
还有一个方向是护栏自适应。护栏规则不再需要人工配置,而是根据Agent的实际表现自动调整。比如Agent经常在某个操作上出错,护栏可以自动收紧这个操作的规则;Agent在某个操作上表现很好,护栏可以自动放宽这个操作的规则。
这些演进方向目前还处于探索阶段,但趋势是明确的:软件架构正在从“以功能为中心”转向“以意图为中心”。通用Agent是这个转变的核心驱动力,而“大脑+技能+护栏”是这个转变的架构基础。
我在实际落地过程中最大的体会是:不要试图一步到位。先把最简单的场景跑通,比如一个查询技能加一个护栏规则,然后逐步扩展。每扩展一个技能,就优化一次提示词;每遇到一次误拦截,就调整一次护栏规则。这个过程是迭代的,不是一次性的。踩过的坑越多,架构就越稳定。