每一个构建过 AI Agent 的人都遇到过同一个问题:边缘情况太多了。输入格式稍微变一下,Agent 就不知道怎么办了;用户换一种方式描述需求,结果就完全不同;上一次运行成功的工作流,这一次莫名其妙地失败了。
我们本能的反应是:把这些边缘情况都处理掉。但这个想法有一个根本问题------在非确定性系统中,边缘情况是无限的。
可靠性是消耗品
想象你在玩一个游戏:每一步的成功率为 95%。听起来很高,对吧?但如果要走 20 步呢?
| 步骤数 | 累积可靠性 |
|---|---|
| 1 | 95.0% |
| 5 | 77.4% |
| 10 | 59.9% |
| 15 | 46.3% |
| 20 | 35.8% |
15 步之后,可靠性已经跌到一半以下。20 步之后,失败几乎是必然的。
这就是 AI Agent 面临的现实:每一步决策都在消耗可靠性预算。而且,成功的运行和失败的运行,从前半段来看几乎是一模一样的------你根本不知道偏差什么时候开始累积的。
非确定性的来源
为什么 Agent 的可靠性会衰减?因为非确定性来自多个层面,而且无法消除。
模型本身的不确定性:模型的 token 采样是随机的。同样的输入,可能因为一个 token 的差异,导致后续输出完全不同。
环境的不确定性:搜索引擎会故意打乱结果,推荐系统会注入随机性,相同的查询可能因为会话状态不同而返回不同的答案。
工具和基础设施的不确定性:API 调用可能超时,数据库可能返回不同的行,服务端批处理可能影响推理结果。
这些非确定性叠加在一起,让 Agent 的每一步都可能偏离预期。
调试几乎不可能
更糟糕的是:当 Agent 失败时,你很难找到原因。
因为信号随步骤指数衰减------第一步的小偏差,经过十几步放大后,可能导致完全不同的结果。但要追溯"到底是哪一步出了问题",成本非常高。
更好的调试工具也解决不了这个问题------这是数学上的限制。
三层分类法
既然无法处理所有的边缘情况,我们就需要换一个思路。把边缘情况分成三层:
第一层:必须处理的
- 数据丢失或损坏
- 安全漏洞
- 财务损失
- 法律/合规违规
这些不是"用户体验"问题,而是"灾难性的后果"。无论概率多低,都必须在代码层面处理。
处理方式:验证、回滚、告警、人工审批。
第二层:应该检测并优雅恢复
- 意外的输入格式
- 缺失的上下文
- 模糊的指令
- 工具调用失败
这些不会导致灾难,但会让用户困惑。可以不必"完美地处理每种情况",但要"检测到异常时给出清晰的反馈"。
例如:用户说"帮我处理那个东西",Agent 不应该猜测"那个东西"是什么,而应该问:"你指的是哪个东西?"
第三层:写好文档,帮用户避免
- 罕见的条件组合
- 模糊的边缘场景
- "99% 有效的情况"的情况
对于那些罕见的边缘情况,处理成本远高于收益。而且,处理它们会让系统过度复杂,反而降低可维护性。
处理方式:清晰的文档、使用示例、已知限制说明。
三个问题做决定
在决定是否处理某个边缘情况时,问三个问题:
1. 如果它失败,后果是什么?
- 灾难性--->第一层
- 令人困惑但可恢复--->第二层
- 几乎不会发生--->第三层
2. 用户能自己恢复吗?
- 不能(数据丢失)--->必须处理
- 能(重试、换种方式)--->文档化
3. 这个边缘情况实际会发生吗?
- 高频--->处理
- 低频--->文档化
- 假设的--->忽略
两个实用模式
渐进式自主权
从严格约束开始,监控行为,随着信心增长,逐步扩展 Agent 的自主权。
优雅降级
每一个 AI 组件都应该有降级策略:
- 分类模型失败--->降级到规则系统
- 生成式响应失败--->降级到模板
- Agent 超时--->降级到更简单的工作流
系统的可靠性不取决于 AI 在一切正常时表现有多好,而取决于 AI 失败时系统能否优雅地降级。
总结
边缘情况是无限的,但资源是有限的,不是所有的边缘情况都需要处理。
你不必做二元选择。你可以设计这样的系统:在关键路径上使用确定性的工作流,在需要灵活性的地方使用 Agent。
记住:一个处理了 95% 的常见情况、文档清晰、降级优雅的系统,比一个试图处理 100% 的情况但过度复杂、难以维护的系统更有价值。