你的AI Agent调用退款接口,网络超时了,那退款到底成功没有?TikTok站点可靠性工程师Salman Munaf用这个例子抛出一个关键判断:超时从来不意味着失败,而意味着“未知”。Agent遇到失败的第一反应往往是重试,如果没有请求标识符、幂等键以及状态查询,这种“先重试再说”的本能就可能导致同一笔退款被执行两次。
从吐字模型到会执行副作用的外部系统协调器
Salman在TikTok从事站点可靠性工程工作。他认为,一旦模型开始调用外部服务,问题就不再只是模型问题,而变成了分布式系统问题。这也意味着,它会遇到这个领域几十年来已经反复研究和命名的各种故障模式。日前,他在一场演讲中系统拆解了为什么AI Agent已经从单纯的LLM调用演化成了真正的分布式系统,以及开发者必须从分布式系统工具箱里搬来哪些“武器”,才能让Agent在犯错时不至于造成不可逆的后果。
最初,当LLM还只是聊天机器人时,我们输入提示词,输出文本,没有副作用,Agent没有与任何其他系统交互。然而,在AI Agent时代,现在这些Agent通过接收提示词,可以运行Agent Loop、调用外部服务和工具,还可以执行状态变更,架构边界已经远远超出了LLM模型本身,可以对外部世界产生副作用。所以在构建AI Agent时,重要的是要认识到它正在与哪些外部系统通信,它正在与哪些状态交互,它拥有什么凭证,以及它可以执行哪些操作。
Salman强调了一个非常关键的对比。在分布式系统里,我们以前也有服务在协调多步工作流,但它们是确定性的,每一步做什么、出错了怎么办,都是预先定义的。但AI Agent不一样,它本质上是一个概率性的协调器。它能执行的动作种类、下一步会做什么,变化范围太大了,不是一个传统的决策树能覆盖的。如果这些操作没有确定性控制来约束,它们可能会产生严重后果。因此,确保我们有确定性控制措施,确保AI Agent不会执行任何可能有问题的操作,这一点非常重要。
Agent循环里的每一步都在跨越系统边界
一个典型的Agent循环是什么样的?首先它做规划,然后基于规划执行一个动作,接着观察这个动作的结果,可能把结果持久化到某个数据存储里,然后决定下一步做什么。这个循环里的每一步都在跨越系统边界。规划阶段,它要跟数据源交互去检索信息。行动阶段,它要调用外部API、工具、数据库,执行真实的操作。观察阶段,它拿到的是部分结果,然后基于这些部分结果决定后续动作。它可以持久化错误的数据,也可以在决策时选择执行一个不正确的动作,更糟糕的是,它可能会发起“重试风暴”。
所以构建Agent循环时,有一个原则特别重要:每一个步骤都必须被持久化。Agent做的每个动作、检索到的每一份上下文,都必须记录下来。为什么?因为如果哪一步失败了,Agent需要知道自己在哪个位置失败了,它才能执行可逆的操作,执行撤销。同时,每一步都必须明确事务边界。比如Agent做了一个调用,这个调用失败了,它应该怎么办?对于不可逆或者不安全的操作,补偿是什么?如果Agent给错误的客户发了一封邮件,它该怎么弥补?这些问题必须在设计阶段回答,而不是等事故发生了再想。
工具调用就是包装了外部API、数据库、队列
工具调用本质上就是包装了外部API、数据库、队列等等。当你发起远程调用时,就必须面对那些分布式系统早就遇到过的失败模式:网络延迟、超时、重复请求,还有最微妙的——服务端可能已经成功了,但客户端收到的是错误报告。Salman说,我们见过很多这样的情况:数据库已经写入了数据,但由于一些别的错误,服务端给客户端报了错。有人的时候,我们可以去看数据库里的真实状态,然后做出正确的纠正动作。但Agent没有这个直觉,它看到错误就重试,它不知道自己对系统的真实状态一无所知。
举一个非常具体的例子。Agent调用一个“客户退款”工具,这个工具执行了退款操作,然后请求超时了。退款到底发生了没有?Agent会怎么推断?会重新退款吗?关键认知在这里:超时不代表失败,超时代表未知。设计这些工具的时候,有几件事是必须做的。第一,要有请求ID和幂等键。当重复请求进来的时候,下游系统能识别出这是同一个请求,不会产生重复的副作用。第二,系统要能执行状态查询,去查之前那个请求的状态,搞清楚它到底成功了还是失败了。
AI Agent面对失败的第一反应就是重试,这是它的默认行为,所以你必须把幂等性焊死在工具层里。如果同样的请求再次进来,工具必须识别出这是一个重复请求,并且确保没有任何副作用发生。但幂等性只解决了“重复不产生副作用”,它没解决“重试风暴”的问题。Agent如果不停地重试,它会对你的外部API造成海啸式的调用压力,而且这种压力会往下游传导,导致级联故障。所以我们需要设置最大轮次数、预算、花费上限、最大并行调用数,确保它的扇出不会太大。还要有指数退避,让下游依赖有喘息的空间。对于有副作用的操作,补偿操作必须预先定义好。
上下文能影响行动时,它就是状态
很多团队在构建AI Agent时,把Agent持有的上下文只当作“上下文”。但Salman要强调:当上下文能够影响行动时,它就是状态。而状态会变成过期的,状态会和权威数据冲突,状态会污染Agent后续的行动。他把Agent的记忆分成两类。短期记忆,就是这个执行线程里的上下文。长期记忆,就是项目文件、系统提示词、它交互的数据库、缓存层等等。当这些不同的数据源之间出现信息冲突的时候,你必须决定什么才是权威的真相来源。
Salman给出的原则是:我们应该把记忆当作缓存来处理,它应该可以被失效,它应该带着来源信息。一个无害的模型,当它能执行不安全的操作时,就会变得危险。日志不够用了,你必须记录Agent每一步看到了什么、据此做了什么、为什么认为这样是对的。
大家可能听说过由AI Agent引发的事故。Replicate的AI Agent删除了生产数据库,Air Canada的聊天机器人做出了错误的退款承诺。这些事故的背后,都是系统思维的缺失。比如,Replicate那个案例,如果我们有稳健的备份,如果我们有作用域权限,本来就不应该允许AI Agent去删除生产数据库,这件事根本不会发生。Air Canada的案子也一样,如果它有一个权威的真相来源,确保它不会基于过时的或错误的政策做决策,那个错误的退款承诺就不会出现。
热门跟贴