给客服智能体的提示词里加了一行字:“如果工具调用失败,重试一次。”离线评测通过率96%,高于95%的门槛,于是全量上线。38分钟后,212个客户被退款了两次。
评测没有算错,它只是看不见。被模拟的退款工具永远在50毫秒内返回,重试分支根本没被触发过。
这次事故留下的规则很直接:评测门禁判断的是版本,冒烟评测判断的是环境。前者管代码逻辑,后者管真实依赖。
到底哪里断了
应用代码一行没改。真实支付接口的p95延迟是4.8秒,而工具超时设的是3秒。
于是生产环境里发生了这样一串事:
- 退款调用超过3秒,被标记为“失败”。
- 智能体严格执行新加的那行指令,发起重试。
- 第一次退款其实已经成功,第二次也成功了。
错误率看起来一切正常,因为重试后的退款都返回了成功。问题是从客户工单和财务对账里发现的,监控没有报警。
门禁不弱,只是视野有限
这套评测门禁并不简陋:400个用例来自真实脱敏对话,每个用例跑三次,因为智能体本身不确定。一个版本要同时满足六项阈值才算通过:
- 任务成功率 ≥ 95%
- 工具调用正确率 ≥ 98%
- 策略违规 = 0
- p95延迟 ≤ 6秒
- 单次对话成本 ≤ 0.04美元
- 相比上一个好版本,跌幅不超过2个百分点
在它能看到的范围内,它对那个坏提示词的判断是正确的。问题在于它能看到的范围。
模拟工具快、免费、确定性强,所以适合在每次提交时校验逻辑和工具契约。但模拟永远比真实世界更快、更宽容。50毫秒的模拟永远不会超时,也就永远不会走到重试指令那一步。
评测门禁只能判断测试环境允许发生的事情。
两种检查,回答两个问题
冒烟评测也不是健康检查。健康检查告诉你进程还活着;冒烟评测告诉你,智能体用这套凭证、对着这些依赖,还能不能干成它的活。
这套冒烟评测只有20个必须通过的用例,速度就是它的意义——慢检查在压力下会被跳过。它查四件事:
- 可达性:每个关键工具都能连上,鉴权有效,每个工具一个用例。
- 无重复副作用:单次对话中,每个有副作用的工具最多被调用一次。
- 结构:输出符合下游系统的预期。
- 关键流程:每个流程在测试账号上完整跑通一次,不会真的扣款或退款。
能抓住这212次重复退款的那个用例,核心只有一行判断:if n > 1。不管提示词怎么写,有副作用的工具在一次对话里最多跑一次。每次对话是一条trace,每次工具调用是一个span。
失败之后会发生什么:发布控制器停下,把流量切回上一个版本,不需要有人半夜起来做决定。在5%的灰度比例下,这个bug三分钟内就会被抓住,而不是在100%流量下跑满38分钟。
这条规则什么时候失效
当冒烟评测被当成质量门槛时——20个用例决定不了一个版本好不好,那是门禁的活。当完整测试集被当成冒烟评测时——每步发布后跑40分钟,凌晨两点一定有人跳过它。
还有一种情况:测试环境的依赖比生产更快。沙箱接口不一定复现生产延迟,所以门禁现在跑在回放上——录制的响应配上真实延迟,2%的工具调用返回录制的超时或服务端错误,让提示词里的每条失败路径都真的被执行一次。
以及,别把检测当成预防。冒烟评测抓的是症状。真正的修复是把重试从提示词挪到工具层,让有副作用的工具接受幂等键。工具层知道一次调用能不能安全重复,模型不知道。
接下来20分钟可以查什么
- 在提示词里搜“重试”。每一处命中,都是工具层不知道的一次重试。
- 把每个模拟工具的延迟和同一接口的生产p95对比,标出p95高于工具超时的那些。
- 列出所有有副作用的工具,逐个确认是否接受幂等键。
- 写一个冒烟用例:单次对话中,每个有副作用的工具最多被调用一次。
- 确认冒烟用例失败会中止发布,而不只是往某个地方发条消息。
评测门禁判断版本,冒烟评测判断环境。只带其中一个上线,你只测了系统的一半。
热门跟贴