TikTok 的 SRE Salman Munaf 最近有一场演讲,开场问题问得很漂亮:
你的 AI Agent 调用退款接口,网络超时了。那退款到底成功没有?
他的答案是:超时从来不意味着失败,而意味着「未知」。Agent 遇到失败的第一反应是重试,没有请求 ID、幂等键和状态查询,这个本能就会把一笔退款退成两笔。整场演讲的论点一句话概括:模型一旦开始调用外部服务,问题就从模型问题变成了分布式系统问题——几十年前命名过的故障模式全部回归,SRE 工具箱必须整体搬进 Agent 架构。
我同意。但我想在他的问题后面再问一句:
就算退款成功了——那笔退款,退得对吗?
这两个问题之间的距离,就是这篇文章要讲的东西。
一、工具箱里有什么
先把 Salman 的清单快速过一遍。他的核心观察是:传统系统里协调多步工作流的服务是 确定性 的——每一步做什么、出错怎么办,预先定义好了;而 Agent 是 概率性协调器,下一步会做什么,变化范围大到决策树覆盖不了。所以必须用确定性控制去约束概率性行为。
具体的武器,他列了这些:
| 故障模式 | 工具箱对策 |
|---|---|
| 超时≠失败(状态未知) | 请求 ID + 幂等键 + 状态查询 |
| 重试风暴、级联故障 | 最大轮次、指数退避、熔断器 |
| 多步操作中途失败 | 预定义补偿事务、事务边界 |
| 权限失控 | 作用域凭证、读写分离、工具白名单 |
| 预算失控 | 花费上限、最大并行度 |
| 审批滥用 | 审批绑定具体动作、金额、时间戳、过期时间 |
| 出错后无法重建现场 | 全链路追踪:看到什么、做了什么、为什么认为对 |
这份清单的每一项都成立。尤其是「审批绑定具体参数」那条——用户批了 30 美元的退款,这个批准不能变成接下来 300 美元退款的授权——讲得比大多数企业权限设计文档都好。
Salman 自己举了两个事故案例来论证「系统思维缺失」的代价:一个是 AI Agent 删除生产数据库(他在演讲里说的是 Replicate;公开记录里广泛报道的同类事故是 2025 年 7 月的 Replit——Jason Lemkin 的数据库在 code freeze 期间被 Agent 删掉,Fortune 有报道),另一个是 Air Canada 的聊天机器人做出错误的退款承诺。
他说,删库案如果有作用域权限和稳健备份就不会发生。对。
然后他说,Air Canada 案如果有「权威真相来源」就不会发生。
这句话有问题。 问题不在它错,而在它悄悄越界了——越出了他自己画的那张分布式系统地图。下面我用 Air Canada 这个案子一查到底,把越界的地方指出来。
二、Air Canada:一次完美的系统故障
把案卷摊开(Moffatt v. Air Canada, 2024 BCCRT 149,不列颠哥伦比亚省民事仲裁庭,2024 年 2 月 14 日判决)。
2022 年 11 月,Jake Moffatt 的祖母去世。他上 Air Canada 官网订机票去参加葬礼,订票前问了官网上的聊天机器人:丧亲票价(bereavement fare)怎么申请?
机器人回答:可以先按全价买票,然后在 出票后 90 天内 提交退款申请,追溯享受丧亲折扣。
Moffatt 信了,买了 1,630.36 加元的机票。事后申请折扣,Air Canada 拒绝——因为真实政策是:丧亲折扣必须在 出票前 申请,不能事后追溯。
机器人的回答是编造的。政策文本一直挂在 Air Canada 自己的官网上,机器人给出的版本和它冲突。
Moffatt 把 Air Canada 告上仲裁庭。Air Canada 的抗辩理由值得原文记录:聊天机器人是「一个独立的法律实体,需要为自己的行为负责」,所以航空公司不为它的话担责。
仲裁庭驳回了这个抗辩:机器人仍然是 Air Canada 网站的一部分,航空公司对网站上所有信息负有注意义务。判决 Air Canada 构成过失性失实陈述(negligent misrepresentation),赔偿总计 812.02 加元。
现在,拿这个案子去撞 Salman 的工具箱,逐项打钩:
- 幂等键:机器人的回答只发生了一次。没有重复副作用,幂等键无事可做。
- 请求 ID / 状态查询:整条链路没有任何一次调用失败。没有「未知」状态需要澄清——系统非常确定地、成功地,给出了一个错误答案。
- 熔断器 / 指数退避:下游健康,没有重试风暴。
- 补偿事务:道歉邮件?法律上已经构成失实陈述,赔偿已经成立。补偿事务能回滚数据库写入,回滚不了一个乘客基于错误信息做出的消费决策。
- 作用域权限:机器人本来就有回答票务政策的权限——这正是它存在的目的。权限收窄到不回答政策问题,产品就没意义了。
- 预算上限:没有失控的开销。
- 全链路追踪:这条能事后帮你 看清 它是怎么错的——检索了什么、生成了什么。但可观测性是验尸工具,不是防火墙。看清一次 812 加元的赔偿怎么发生的,不阻止它发生。
打钩结果:七项里七项落空。 不是工具箱质量不行,是这个故障根本不在工具箱的射程里。
三、两类故障
因为 Agent 的故障其实有两种,而分布式系统四十年积累的,只是第一种。
执行故障(execution failure):动作在「执行」这个环节坏掉。超时、分区、重复请求、级联雪崩、资源耗尽。它的特征是——可枚举。分布式系统文献之所以能积累成工具箱,是因为故障模式是一个有限的集合:FLP 不可能性、CAP、拜占庭将军,几十年下来该命名的都命名了。幂等键防重复,熔断器防雪崩,退避防风暴,每一种武器对应一种已知的敌人。
语义故障(semantic failure):动作完美执行了,副作用只发生了一次,链路全绿,超时为零——但 内容是错的。机器人流畅地、自信地、一次性地编造了一条不存在的退款政策。它的特征是——不可枚举。执行故障的样本空间是有限的协议状态机,语义故障的样本空间是「所有可能说错的话」,这个集合没有边界。你没法给「错误答案」写一张和超时、分区并列的故障表,因为每一个业务事实、每一条政策、每一次解释,都可能是一个独立的出错点。
Salman 的演讲标题是「AI Agents 说到底就是分布式系统」。这句话对了一半:Agent 的动作层是分布式系统,Agent 的内容层不是。 动作层继承了几十年的现成武器;内容层继承不了任何东西,因为分布式系统从来不需要回答「这句话对不对」——传统服务不会编造事实,它的输出要么送达要么没送达,不存在「送达了一个不存在的东西」。
这就是为什么他在分析 Air Canada 时不得不说出「权威真相来源」这个词——这是他整场演讲里唯一一个不属于分布式系统词汇表的词。他说出它的时候,已经跨过了自己画的边界,只是没有意识到。
而「权威真相源」这个词一旦成立,紧跟着的问题就来了:谁是权威?谁定义「真」?错了算谁的? 这三个问题,幂等键一个都回答不了。
四、内容侧的三道防火墙
执行故障靠工具箱,语义故障靠什么?我的答案是 定义权机制——不是更聪明的模型,而是把「什么算对」的定义权,从模型的生成过程里拿出来,交给一个可签字、可验证、可追责的结构。三道墙,每一道都回到 Air Canada 检验一次。
第一道:评测集签字。 如果 Air Canada 上线机器人之前,有一组业务方签过字的评测题——「丧亲折扣可以在出票后申请吗?标准答案:不可以,必须出票前」——这个 case 会在上线前的回归测试里红掉。「90 天内可追溯」这种编造,恰恰是评测集最擅长抓的故障,因为它是一个 具体的、可判定的业务事实。问题从来不是没人想到要测,而是没人对「什么算对」签字负责。这正是我在 评测集是一份没人签字的文件 里讲的那件事:考卷必须业务出,判分标准必须有人签字——签字这个动作,就是把语义的定义权从工程侧拿回到业务侧。
第二道:完成标准写进角色契约。 机器人的职责如果是「回答票务政策」,那它的完成标准就不能是「生成了一个回答」,而必须是「回答可以溯源到现行政策文本的具体条款」。回答不带出处,就不算完成。这是我在 Grok Bot 能当队友,还当不了员工 里拆解的角色契约公式——职责范围 + 完成标准 + 验证证据——在语义层的用法:完成标准是内容侧的作用域权限。 执行层你不敢给 Agent 删库权限,内容层凭什么给它「无出处作答」的权限?
第三道:端到端探针。 健康检查不能只探「进程活着、接口 200」,要探「一次真实任务能不能端到端走对」。我昨天刚为这个交过学费:谁停掉了数字员工的早读? 里,我的数字员工连续三次兜底失败,而健康检查全程报「健康」——因为它查的是进程和端口,从不真正碰一次模型。Air Canada 的探针版本是什么?每小时用签过字的评测题真枪实弹地问一次机器人,答案对不上标准,立刻摘牌下线。探针探的必须是 业务事实的正确性,不是链路的连通性。这个原则在 面向 Agent 开发:可测试和可运维第一次真正成为前提条件 里我从系统接口角度讲过一遍,这里是它的另一面。
三道墙的分工很清楚:签字定义「对」,契约要求「可验证的对」,探针持续确认「还在对」。 没有一道墙需要模型变得更聪明——Air Canada 的机器人再聪明一点,也只是把编造的政策说得更流畅。
五、结语
Salman 演讲的收尾问题,我认为是全场最好的一句话:
在构建 AI Agent 的时候,最该问的一个问题其实是:当它犯错的时候,系统允许它做到哪个程度?
这是爆炸半径问题,是执行侧的终极问题,工具箱为它而生。我想给它配一个对偶问题,内容侧的:
当它犯错的时候,谁有权说这是一个错?
执行故障,系统自己知道——超时了就是超时了,日志里有。语义故障,系统永远不知道——机器人说出「90 天内可追溯」的那一刻,链路上每一个组件都认为自己成功了。知道这个错的,只有政策的所有者。所以定义权不在工程侧,签字的笔必须递到业务手里。
AI Agent 是分布式系统。但 Air Canada 那 812 加元赔的不是分布式——赔的是没人对「什么算对」签过字。
你的 Agent 系统里,工具箱和签字笔,现在各有几支?欢迎留言聊聊你踩过的两类故障。