Agent 工程化:从 demo 到生产的距离
过去半年我交付了 3 个 Agent 项目,每一个都经历了同样的曲线:demo 当天所有人鼓掌,灰度第一周bug报告。一开始我以为是模型不够好,后来发现是我对”能用”的定义太宽松。
这篇文章记录我从 demo 到生产之间补上的那些课。不谈框架选型,只谈那些让你在上线夜睡不着觉的问题。
demo 阶段的三个幻觉
demo 之所以惊艳,是因为它在一个被精心控制的环境里运行。这个环境给你三个幻觉:
- 输入幻觉。demo 时你用的是自己准备的 5–10 个问题,每个都经过测试。你以为用户会问类似的问题,但真实用户的输入分布完全不同。
- 工具幻觉。demo 时你调用的 API 都在正常响应,数据源都在线。你以为这些服务永远可用,但生产环境它们会超时、返回脏数据、甚至直接 500。
- 状态幻觉。demo 是单轮的,没有上下文堆积。你以为 Agent 记得住,但生产环境一个会话可能有 20 轮,前面任何一轮的错误都会被带到最后。
**核心判断:**demo 验证的是”能不能做到”,生产验证的是”做不做得到稳定”。这两个问题的难度差一个数量级。
生产环境的四个失败点
1. 输入分布漂移
这是最隐蔽的失败。Agent 在 demo 时表现完美,上线后准确率从 95% 掉到 60%,但你看日志找不到明显错误——因为问题不在单条输入,而在输入分布。
真实用户的提问方式和工程师完全不同。工程师会问”查询 A 产线 CNC-088 的最近 10 条遥测数据”,用户会问”088 那台机器最近咋样”。你的 intent 解析在标准问句上表现很好,在口语化输入上直接崩掉。
我的做法是上线前做一轮输入分布采样:找 5 个不懂技术的人,每人提 20 个问题,把这些问题和 demo 的问题放一起做 intent 分类。如果分类准确率掉超过 10 个百分点,说明你的 intent 解析过拟合了 demo 分布。
2. 工具调用失败
Agent 调用工具时,你默认它会成功。但生产环境工具会失败,而且失败方式千奇百怪:API 超时、返回空、返回格式变了、返回的数据里有脏值。
最危险的不是工具失败本身,而是Agent 对失败的处理。我见过一个 Agent 在工具超时后,自己编了一个结果继续往下走,最后输出了一个完全虚构的答案。用户以为是真的,因为前面几轮都对。
解决这个问题的核心是给每个工具调用加一个”失败协议”:
- 超时后重试几次?重试间隔多长?
- 重试失败后是降级(用兜底数据)还是中止(告诉用户”暂时无法查询”)?
- 降级时用的兜底数据是否有时效性?过期了怎么办?
这个协议不是写在 prompt 里就完了,要写在代码里。prompt 告诉 Agent”如果工具失败就如实告诉用户”,但 Agent 经常不听。代码层面的熔断和降级才是兜底。
3. 状态管理失控
多轮 Agent 最容易出问题的是状态。一个会话进行到第 15 轮,前面的错误判断、过期的工具返回值、用户的改口,全部累积在上下文里。Agent 会基于一个已经被污染的上下文继续回答。
我在第三个项目里加了一个上下文压缩 + 状态快照机制:每 5 轮做一次上下文摘要,把前 5 轮的关键事实提取出来,丢掉原始对话。这样上下文长度可控,且历史错误不会无限传播。
但摘要本身有风险——它会丢失细节。所以摘要里只保留事实性信息(用户是谁、查询过什么、结论是什么),绝不保留推理过程。推理过程一旦被摘要,下一轮的推理就失去了依据。
4. 成本与延迟
demo 时没人关心一次调用花多少钱、要多久。生产环境这两个数字直接决定产品能不能活。
我踩过的坑:一个 Agent demo 时单次调用 8 秒、花 0.3 元,觉得可以接受。上线后发现真实场景平均要调用 4 次工具 + 2 次 LLM,单次响应 25 秒、花 1.2 元。日活 500 的情况下一个月成本 1.8 万,而产品定价根本覆盖不了。
从那以后我形成了一个习惯:demo 阶段就做成本和延迟的预算。按”单次响应 ≤ 10 秒、单次成本 ≤ 0.5 元”倒推,决定能用几次 LLM 调用、几次工具调用、能不能用小模型替代部分环节。
从 demo 到生产要补的课
如果让我列一个最小清单,从 demo 到生产至少要补这五件事:
- 输入分布采样。上线前用真实用户的提问方式测一遍,不能只用自己的问题。
- 工具失败协议。每个工具调用都要有超时、重试、降级策略,写在代码里不写在 prompt 里。
- 上下文管理。多轮会话必须有压缩机制,否则状态会失控。摘要只保留事实,不保留推理。
- 成本与延迟预算。demo 阶段就做预算,按预算倒推调用链路。
- 全链路日志。每一步的输入、输出、耗时、成本都要记录。出问题时能回放,否则线上 bug 永远查不清。
一个真实的上线复盘
第三个 Agent 项目上线第一天,我们收到了 47 条反馈,其中 31 条是”答非所问”。我慌了,以为模型崩了。
回放日志后发现:47 条反馈里,只有 9 条是 Agent 真的答错了。剩下的 38 条分三类:
- 18 条:用户问的问题超出了 Agent 的能力范围,但 Agent 没有说”我不知道”,而是硬编了一个答案。
- 12 条:Agent 答对了,但回答方式让用户以为它答错了(比如用户问”今天有几条告警”,Agent 答了告警列表但没说总数)。
- 8 条:工具调用超时,Agent 没有告知用户,等了 20 秒后给了一个基于过期数据的答案。
真正需要修的是后两类——表达层和工具层的工程问题,不是模型问题。我们花了三天加了一个”回答先给结论再给细节”的表达模板,以及一个工具超时提示,反馈率从 47 条/天降到了 6 条/天。
结语
Agent 项目的难度不在”让它能跑”,在”让它稳定地跑在不可控的环境里”。demo 阶段你控制输入,生产阶段输入控制你。
从 demo 到生产的距离,不是”再调调 prompt”能弥合的。它需要一整套工程实践:输入分布管理、工具失败协议、状态管理、成本预算、全链路日志。这些不性感,但它们决定了你的 Agent 是一个产品,还是一个 demo。