先设计失败路径,再设计 Agent
设计 Agent 时,最容易开始的地方是成功路径:用户给出完整输入,模型理解正确,工具一次可用,系统生成漂亮结果。它适合演示,也最容易让人相信“能力已经有了”。
但成功路径通常只覆盖了真实产品里最顺的一条路。Agent 一旦进入业务环境,就会遇到缺资料、权限变化、外部超时、结果冲突、用户取消和工具部分成功。如果这些状态没有设计,所谓自主性只是把异常藏进黑盒。
因此,我更愿意先画失败路径,再决定 Agent 应该做什么。
失败路径会暴露真正的产品边界
拿一个“自动整理并提交材料”的 Agent 来说,成功路径很简单:读取文件、填入结构、提交系统。只要问四个反事实,边界立刻出现:
- 文件缺页时,它能否猜测缺失内容?
- 提交接口超时后,它能否再提交一次?
- 用户在提交途中取消,已经发生的动作怎么办?
- 材料包含高风险决定时,谁有权确认?
这些问题并不是工程细节。它们决定系统是在生成草稿、提出建议,还是在改变现实状态;也决定错误发生时由谁承担后果。
四类失败,不能只给一个“重试”
第一类是输入不成立。资料不全、对象不清、版本冲突时,任务还没有合法开始。正确动作是保存已有进度、指出缺口、等待补充,而不是让模型补齐一个看似合理的答案。
第二类是能力失败。检索没有证据、工具明确拒绝、权限不足,都已经给出可解释结论。系统应换合法路径、降级或停止,不应把确定性拒绝包装成临时故障。
第三类是结果未知。请求发出却没有回执,超时只证明通信没有按时返回,不证明业务没有发生。此时重试可能产生第二份副作用,正确动作是用稳定业务标识查询、对账,必要时转人工。
第四类是部分成功。一组动作中有的已经完成、有的失败。系统需要保留成功项,只修复失败部分。全量回滚或全量重做,往往比原错误更危险。
同样一句“失败了”,背后是四种完全不同的产品决定。
可恢复性来自状态,而不是长对话
Agent 失败后能不能继续,不取决于模型是否还记得上下文,而取决于系统是否保存了权威状态:本次委托是什么、哪些步骤已完成、哪些外部动作已发生、证据属于哪个版本、下一步需要等待谁。
如果只有聊天记录,恢复时模型只能重新解释一遍过去;它无法证明某次写入究竟成功没有,也无法判断旧审批在对象更新后是否仍有效。
可恢复设计至少要保存任务状态、阶段成果、外部动作回执和等待条件。恢复时先读回最新事实,再决定继续,而不是从上一句对话接着猜。
人工接管不是一句“转人工”
很多方案在异常分支末尾写“转人工”,仿佛把责任交出去就完成了。真正可用的人工接管需要一份接管包:当前对象和版本、Agent 已做的动作、证据与冲突、没有做的动作、风险原因、人工可选决定,以及决定后从哪个检查点恢复。
人工还需要权限和时限。谁能接、多久必须处理、超时如何升级、用户在等待期间看到什么,都属于产品设计。没有这些,转人工只是把黑盒换成队列。
页面要呈现不确定性,而不是掩盖它
失败路径最终会回到交互。用户需要区分“正在处理”“等待你补充”“等待审批”“结果未知,正在对账”“已停止新动作”和“已完成”。这些状态不能都显示成加载动画。
取消也要说清现实后果。停止等待不等于撤销已经发生的业务动作。页面应列出已完成部分、仍在途的动作和后续通知方式,让用户能基于事实做决定。
一个成熟的 Agent 页面,不只是展示它正在想什么,而是让用户看见它还能做什么、不能做什么,以及自己何时需要介入。
上线前,故意把它弄坏
失败设计不能停在流程图。上线前应该做失败注入:删掉一项必填输入,让知识返回冲突版本,让工具超时但实际成功,让旧回调晚到,让权限在执行前被撤回,让用户在关键动作前取消。
每次演练都要检查三个结果:系统有没有越过任务边界,现实副作用有没有多一份,用户能否理解并继续。最终答案对不对只是其中一部分。
成功路径证明能力,失败路径证明产品
成功 Demo 证明模型和工具在理想条件下可以合作。失败路径证明团队理解了现实责任:什么时候拒绝、什么时候等待、什么时候对账、什么时候让人接管。
Agent 不是因为会做更多事才成为产品,而是因为在做不下去时仍能诚实、可控地收口。先设计失败路径,往往会让第一版 Agent 做得更少,却更接近真正可用。