跳到主要内容

那个在行动已发出后才生效的预算上限

· 阅读需 10 分钟
Tian Pan
Software Engineer

一个超级用户在第三天早上 9 点就耗尽了你的月度 token 预算。熔断机制(kill-switch)准确触发——网关返回 429,模型停止调用,账单停止增长。与此同时,智能体(agent)已经订好了机票,发送了确认邮件,并将支持工单标记为已解决。仪表盘显示“支出已停止”。用户却问:“为什么要为我从未要求的行程扣费?”两者都没错。预算上限阻止了模型思考,但它没能阻止世界的改变。

这是几乎每个智能体预算护栏都会携带的失效模式:上限信号位于 支出 平面,但损害发生在 行动 平面,而这两个平面在连接时并没有共享的事务边界。告诉模型停止并不等同于告诉世界撤销模型刚刚所做的一切。

这种模式在不同团队中如此一致,以至于你在阅读复盘报告(postmortem)之前就能预测结果。检测到失控。熔断机制因触发迅速而受到赞扬。随后,客户支持队列中充满了针对熔断机制在技术上无力阻止的行动的退款请求,因为这些行动发生在最后一次工具调用和上限评估之间的半秒钟内。“我们停止了支出”被视为胜利。而“我们停止了行动”实际上从未在考虑范围内。

两个平面从未在同一个循环中

大多数智能体运行时的成本控制和工具执行路径是独立演化的。成本控制存在于网关:token 计数器、每用户配额、预算封口、流量限制。工具执行存在于智能体运行时:函数调用、HTTP 请求、数据库写入、第三方 API 调用。网关看到模型流量。运行时看到副作用。两者都无法全局审视,也没有人负责回答“如果我们现在停止,接下来的行动是否可恢复”这个问题。

结果是,这种检查顺序在理论上看起来正确,但在实践中却失败了。流程如下:模型调用 → 带有工具调用的响应 → 网关计算 token → 工具执行 → 下一次模型调用 → 网关检查预算 → 熔断。上限在模型调用 之间 触发。它不在 工具调用 之间触发。因此,一个先发出重度推理响应,紧接着是三个快速工具调用的链条,将在预算检查有机会介入之前执行所有三个工具调用。

更糟糕的是,该链条中的工具调用往往是不可逆的。模型进行昂贵的思考,决定该做什么,然后发出廉价的行动——send_emailconfirm_bookingpost_messageclose_ticket。预算信号在这些廉价行动之后到达,因为这些廉价行动恰恰是预算认为不值得暂停检查的。以成本作为控制手段失效了,因为成本从来不是衡量影响力的良好指标。

成本不等于影响力

将 token 视为智能体风险的通用货币是更深层次的错误。一个只有 100 token 的 delete_customer_record 调用可能是一个监管事件。而一段 50,000 token 的推理追踪,如果只是解决问题而不触及任何工具,则不会产生外部后果。因此,按 token 制定预算混淆了两个几乎没有因果关系的东西——模型思考了多少,以及世界将记住模型思考了多少。

一旦你看到了这个差距,架构上的调整就是将预算分成两个独立的账户:token 账户和行动账户。token 账户是网关已经在衡量的。行动账户则是没有人衡量但应该衡量的:一个针对每个动作的“爆炸半径”权重,用于捕获副作用是内部的还是外部的、可逆的还是不可逆的、幂等的还是单次的、软状态的还是硬提交的。

一个在生产环境中行之有效的务实分类法:

  • 免费(Free):纯模型推理且不含工具调用、沙盒读取、工具自身标记为预览的试运行查询。
  • 廉价(Cheap):写入智能体拥有的、可以撤销的内部存储,具有已知补偿动作的幂等写入,发送到预发或测试频道。
  • 昂贵(Expensive):写入记录系统、客户可见的沟通、资金变动、更改外部状态的第三方 API 调用。
  • 单向(One-way):原则上无法补偿的行动——没有墓碑标记的删除记录、已被阅读的邮件、已向现已关闭的卡收取的款项、现实世界的事件(如打印发货单或派遣快递)。

一旦有了这个账户,预算上限将不再仅仅针对 token 触发。它将针对该会话剩余部分的预期单向行动计数触发。如果用户已经用掉了 80% 的 token 预算,而智能体的下一步计划是 send_external_email,那么无论 token 成本如何,上限都应拒绝该步骤。如果用户处于 99% 的 token 预算,而下一步是沙盒搜索,则上限应允许其通过。

加载中…
References:Let's stay in touch and Follow me for more thoughts and updates