1. 为什么“能聊天的 Agent”一进业务就废
我见过太多团队在演示环境里把 Agent 调得风生水起:问它一句“帮我查一下上个月的订单”,它噼里啪啦调几个接口,答案漂漂亮亮。可一旦把这套东西塞进真实业务流程,问题立刻炸出来——它不知道“上个月”是自然月还是滚动 30 天,不知道当前登录的人有没有权限看这批订单,更不知道查完之后该把结果写回哪个工单系统。演示和落地之间,隔着的不是模型能力,而是上下文和权限这两道坎。
先把话说透:Agent 接进真实业务流程,本质上是三件事的叠加——上下文注入、权限校验、动作执行。模型只负责“想”,业务系统负责“给边界”和“兜底”。很多人一上来就纠结用哪个大模型、提示词怎么写,其实方向就偏了。真实业务里,模型换一个可能只是效果波动 10%,但上下文给错了、权限放开了,那是直接出生产事故的级别。
这篇文章适合谁看?如果你正在做企业内部助手、工单自动化、数据分析 Agent、客服辅助这类东西,并且已经过了“跑通 Demo”的阶段,正卡在“怎么让它真正干活”上,那接下来的内容应该对你有用。我会按一个真实落地项目的推进顺序来讲:先解决上下文怎么给,再解决权限怎么卡,然后是动作怎么安全执行,最后是上线后怎么观测和迭代。全程用从业者的视角,把每一步“为什么这么设计”讲清楚。
需要提前说明的是,下面涉及的具体系统名称、字段名、接口路径都是脱敏后的示意,你在自己项目里要替换成真实的业务对象。但设计思路和踩坑点是通用的,可以直接抄作业。
2. 上下文注入:别把整个数据库塞给模型
2.1 上下文不是越多越好,而是要“刚刚好”
新手最容易犯的错,是觉得模型上下文窗口大,就把能拿到的数据全塞进去。我试过一个反面案例:某次为了让它回答“这个客户最近怎么样”,直接把客户近半年的所有交互记录、订单、工单全拼进提示词,结果两万多 token 下去,模型反而抓不住重点,回答得又慢又泛。后来砍到只给最近 5 条关键交互加一个结构化摘要,准确率立刻上来了。
这里有个核心原则:上下文的价值密度比总量重要。你要给模型的不是原始数据,而是经过筛选和结构化的“决策所需最小信息集”。具体怎么筛?我一般分三层:
- 会话层:当前这轮对话的历史,通常保留最近 3 到 5 轮就够,再往前用摘要压缩。
- 业务层:跟当前任务直接相关的业务对象,比如当前工单、当前客户、当前订单,按需拉取。
- 规则层:这次任务要遵守的业务规则、话术规范、字段定义,这部分相对固定,可以做成模板。
三层拼起来,才是喂给模型的完整上下文。很多人只做了会话层,业务层靠模型自己“猜”,规则层干脆没有,那 Agent 当然不靠谱。
2.2 用“槽位”思路把模糊表达翻译成确定参数
真实业务里,用户说的话永远是模糊的。“帮我处理一下那个超时的单子”——哪个单子?超时多久算超时?处理是关闭还是转派?这些都得在上下文注入阶段解决。
我的做法是引入槽位填充机制。在把用户输入交给模型之前,先用一轮轻量的意图识别加实体抽取,把关键参数抠出来,缺的再反问用户。举个具体例子,用户说“查一下上周华东区的异常订单”,我会先解析出:
| 槽位 | 抽取结果 | 来源 |
|---|---|---|
| 时间范围 | 上周(需转成具体日期区间) | 用户输入 |
| 区域 | 华东 | 用户输入 |
| 订单状态 | 异常 | 用户输入 |
| 操作类型 | 查询 | 意图识别 |
然后“上周”这种相对时间,必须结合当前系统时间和业务日历转成绝对区间。这里有个坑:不同业务对“上周”的定义不一样,有的是周一到周日,有的是滚动 7 天。这个规则必须写死在配置里,不能让模型自由发挥,否则同一个问题今天问和明天问答案不一致,业务方直接不信任你。
2.3 上下文窗口管理:什么时候该压缩,什么时候该丢弃
长会话是上下文管理的重灾区。一个客服 Agent 跟用户聊了 20 轮,前面聊的内容早就超出有效范围了。我的策略是滑动窗口加关键信息锚定:
- 保留最近 N 轮原文(N 一般取 5)。
- 把更早的对话做一次摘要,摘要里只保留“已确认的事实”和“未完成的动作”。
- 关键业务对象(比如工单号、客户 ID)单独拎出来,每轮都带上,不参与压缩。
这样既控制了 token 消耗,又不会丢掉关键线索。实测下来,一个原本要 8000 token 的会话,压缩后稳定在 2500 左右,响应速度提升明显,而且因为噪声少了,模型跑偏的概率也低了。
提示:压缩摘要这一步建议用便宜的小模型来做,别用主力模型,成本能省一大截。摘要质量只要保证事实不丢就行,不需要文采。
3. 权限校验:Agent 不能比用户权限大
3.1 最危险的设计:用超级账号跑所有请求
我见过一个真实事故:某团队为了让 Agent 能查所有数据,直接给它配了一个管理员账号。结果一个普通员工通过对话,让 Agent 查到了他本不该看到的其他部门数据。这不是模型的问题,是权限设计从根上就错了。
铁律只有一条:Agent 的权限必须等于当前发起用户的权限,绝不能更大。实现方式有两种,我强烈推荐第一种:
- 用户身份透传:Agent 调业务接口时,带上当前登录用户的身份凭证,由业务系统自己做权限判断。Agent 只是个“代驾”,方向盘还是用户的。
- 权限预校验:Agent 在规划动作前,先调一个权限服务,问“这个用户能不能做这件事”,能才继续。
第一种更彻底,因为权限判断始终在业务系统内部,Agent 绕不过去。第二种适合业务系统改造困难的情况,但要注意预校验和实际执行之间可能有时间差,得加二次校验。
3.2 把权限判断前置到“规划阶段”
很多人把权限校验放在动作执行前一刻,这其实晚了。更好的做法是在 Agent 做任务规划时就把权限考虑进去。比如用户说“把这个工单转给张三”,Agent 规划出的动作是“转派工单”,这时候就应该先校验:当前用户有没有转派权限?张三是不是合法接收人?两个都过了,才生成执行计划。
这样做的好处是,如果权限不够,Agent 可以直接告诉用户“你没有转派权限,需要找主管”,而不是执行到一半失败,留下一个半完成的状态。半完成状态在业务系统里是最难清理的,能避免就避免。
3.3 敏感操作的二次确认与审计留痕
有些操作即使权限够,也不能让 Agent 自动执行,比如删除数据、批量修改、对外发送。这类操作我统一加一道二次确认:Agent 把要执行的动作、影响范围列清楚,让用户明确点确认,才真正执行。
同时,所有 Agent 发起的动作都要留审计日志,记录清楚:谁发起的、什么时间、Agent 规划了什么、实际执行了什么、结果如何。这份日志在出问题时是救命稻草。我一般会把日志结构设计成下面这样:
{ "trace_id": "唯一追踪ID", "user_id": "发起用户", "session_id": "会话ID", "intent": "识别到的意图", "planned_actions": ["规划的动作列表"], "executed_actions": ["实际执行的动作"], "permission_check": "权限校验结果", "result": "执行结果", "timestamp": "时间戳" }有了 trace_id,一次会话里所有环节都能串起来,排查问题效率翻倍。
4. 动作执行:让 Agent 干活,但别让它闯祸
4.1 工具调用的边界设计:只暴露必要的接口
Agent 能调哪些工具,是安全的第一道闸门。我的原则是最小暴露:只给它当前任务真正需要的接口,而且每个接口都要做参数校验和范围限制。
举个例子,查询订单的接口,不要给它一个“传任意 SQL”的能力,而是封装成“按订单号查”“按时间范围查”“按客户查”几个明确的函数。每个函数内部再做参数合法性检查,比如时间范围不能超过 90 天,单次返回不能超过 100 条。这样即使模型被诱导,也闯不出大祸。
工具描述也要写清楚边界。我见过工具描述写得太模糊,模型以为能查全量数据,结果传了个空参数,把整张表拉出来了。工具描述里一定要写明:必填参数、可选参数、返回上限、适用场景。
4.2 幂等与回滚:动作执行的安全网
真实业务里,动作执行失败是常态,网络抖动、下游超时、并发冲突都会导致失败。如果 Agent 重试时不做幂等,就可能重复下单、重复发消息。所以每个写操作接口都要支持幂等键,Agent 每次执行带一个唯一键,下游系统根据这个键去重。
回滚更复杂一些。对于多步操作,我一般用补偿事务的思路:每一步都记录正向操作和对应的补偿操作,如果中途失败,就按逆序执行补偿。比如“创建工单”失败了,就补偿“删除工单”;“扣减库存”失败了,就补偿“回补库存”。这套机制要在 Agent 框架层面统一实现,不能指望每个工具自己处理。
4.3 失败重试与人工兜底的分界线
不是所有失败都值得重试。我的经验是分三类处理:
- 瞬时故障(网络超时、限流):自动重试 2 到 3 次,指数退避。
- 业务规则拒绝(权限不足、状态不允许):不重试,直接反馈用户。
- 未知异常:重试一次,还失败就转人工。
转人工这个兜底特别重要。Agent 再聪明也有搞不定的时候,这时候要能平滑地把上下文交接给人工坐席,而不是让用户重新描述一遍。我一般会把当前会话的摘要、已执行的动作、失败原因打包成一个工单,人工接手时一目了然。
5. 上线之后:观测、评估与持续迭代
5.1 别只看“回答对不对”,要看“动作准不准”
评估 Agent 的指标,很多人只看回答质量。但接进业务流程后,更关键的是动作准确率:它规划的动作对不对、参数填得对不对、执行成功率多少。我一般会盯这几个指标:
| 指标 | 含义 | 健康值参考 |
|---|---|---|
| 意图识别准确率 | 理解用户想干什么 | 95% 以上 |
| 槽位填充完整率 | 关键参数是否齐全 | 90% 以上 |
| 动作规划准确率 | 规划的动作是否合理 | 90% 以上 |
| 动作执行成功率 | 实际执行是否成功 | 98% 以上 |
| 人工转接率 | 需要人工兜底的比例 | 10% 以下 |
这些指标要按天看趋势,突然掉下来往往意味着上游数据或接口变了。
5.2 用真实会话做回归测试
每次改提示词、换模型、加工具,都要跑一遍回归测试。测试集从哪来?就从真实会话里采样。我一般会攒一个 200 到 500 条的测试集,覆盖高频场景和已知的坑,每次改动都跑一遍,看指标有没有退化。这比拍脑袋上线靠谱得多。
测试集要定期更新,把新出现的失败案例加进去。我习惯每周花半小时过一遍本周的失败会话,挑典型的补充进测试集。这个习惯坚持下来,Agent 的稳定性会肉眼可见地提升。
5.3 迭代节奏:小步快跑,但要有回滚能力
Agent 的迭代不能像传统软件那样攒个大版本再发。我的做法是灰度加开关:新版本先放 5% 流量,观察指标,没问题再逐步放量。同时每个能力都要有开关,出问题能一键关掉,降级到人工或旧逻辑。
这套机制听起来麻烦,但真出事的时候能救命。我经历过一次模型供应商那边接口抖动,导致动作执行大面积失败,幸好有开关,五分钟内切回旧逻辑,业务没受大影响。从那以后,我对“可回滚”这件事的重视程度提到了最高。
6. 几个我踩过的坑和对应的解法
6.1 上下文里的“脏数据”比没有数据更可怕
有一次 Agent 回答客户问题时引用了错误的订单金额,排查半天发现是上游数据同步延迟,上下文里拿到的是旧值。模型本身没错,错在数据源。后来我加了一道数据新鲜度校验:关键字段带时间戳,超过阈值就标记为“可能过期”,让 Agent 在回答时主动说明,或者干脆重新拉取。
6.2 权限校验别信模型自己判断
早期我试过在提示词里写“请只查询当前用户有权限的数据”,指望模型自觉。结果模型该查还是查。权限这种事,必须靠代码卡,不能靠提示词。提示词是建议,代码才是约束。
6.3 工具描述写不好,模型就会乱调
工具描述是模型理解工具的唯一途径。我踩过的坑是描述里没写清楚参数格式,模型传了个自然语言字符串进去,接口直接报错。后来我把每个工具的描述都按“功能、参数、返回、示例”四段式写,模型调用准确率明显提升。这个投入非常值。
6.4 别让 Agent 一次做太多事
一个 Agent 如果既能查数据、又能改数据、还能发通知,出问题的面就太大了。我的做法是按职责拆分:查询类 Agent、操作类 Agent、通知类 Agent 分开,各自权限和工具集独立。这样即使某个 Agent 出问题,影响范围也可控。
7. 写在最后的一点个人体会
把 Agent 接进真实业务流程,技术难度其实不在模型,而在工程。上下文怎么给、权限怎么卡、动作怎么安全执行、上线后怎么观测,这四件事做扎实了,Agent 才真正从“玩具”变成“工具”。我自己的经验是,前期在权限和审计上多花的时间,后期都会以“少出事故”的形式还回来。
如果你现在正卡在某个环节,我的建议是先别急着优化模型效果,回头看看上下文和权限这两块是不是有漏洞。很多时候,Agent 表现不好,不是它笨,是我们没把该给的信息给对,没把该卡的边界卡住。把这两件事理顺,你会发现它的表现比想象中好得多。