你的Laravel应用加了一个AI Agent。控制器里的动作看起来人畜无害:一条用户消息,一次模型调用,顶多再带一两个工具。

然后,一个真实租户接入了共享收件箱、工单线程或文档库。Agent开始“调查”了。它调用搜索,读取一条记录,再调用搜索。每一轮它都把同样的40KB对话重新发送一遍。超时之后,它还会重试。用户只看到一次按钮点击,你的计费仪表盘看到的却是一场小规模的“分布式钱包拒绝服务攻击”。

打开网易新闻 查看精彩图片

AI Agent的失败方式,和普通功能完全不同——它是乘法式的。

成本公式:为什么第十轮对话才是账单杀手

一个普通API端点的成本是相当可预测的:一次数据库查询、一次HTTP调用、一次渲染。Agent端点的成本却由一个循环决定:

成本 = 每一轮(输入token × 输入价格 + 输出token × 输出价格 + 工具输出重新塞回上下文的token)

第一轮提示词通常很便宜。但到了第十轮——经过六次工具调用、三次文档检索之后——账单就开始变得“私人订制”了。

核心结论:生产环境的AI Agent需要一套token预算框架,而不只是一个max_tokens参数。把token当钱来管,计量真实供应商用量,限制循环次数,裁剪上下文,限制工具输出,按任务路由模型,强制执行租户配额——在财务部门发现之前,先盯住烧钱速度。

开发环境没问题,生产环境就出事

大多数Laravel团队起步时写的是这样的代码:

$response = Http::withToken(config('services.openai.key'))    ->post('https://api.openai.com/v1/chat/completions', [        'model' => 'gpt-4.1',        'messages' => $messages,    ]);

对简单的补全功能来说,这没问题。但Agent不一样。Agent通常会这样做:

  • 每一轮迭代都会重新发送大量之前的上下文
  • 工具输出变成未来的输入
  • 工具schema本身也在消耗token
  • 失败的尝试仍然消耗输入token
  • 流式输出并不会让token变免费
  • 如果第一次尝试已经处理了很大的提示词,重试可能让账单翻倍

生产环境里最危险的情况并不罕见,反而很普通:开发时你测试的是短提示词,一切正常。生产环境里,一个租户把20页的合同粘贴进提示词,然后问“有哪些风险?”——账单瞬间就失控了。

预算必须是运行时的一等公民

如果token只出现在调试日志里,那没人会去想它,直到账单寄到。预算应该像请求输入、授权、速率限制一样,成为运行时的一等公民值

解决方案:创建一个显式的预算对象,并把它贯穿整个Agent执行路径。

这个预算对象的核心思路是:在代码里显式地跟踪“已经用了多少token”和“总共能花多少token”。它不是事后诸葛亮,而是执行过程中的实时闸门。

把token当钱管,不是技术洁癖,是生产环境的生存法则。一个按钮点击背后可能是几十轮循环、几百KB的上下文重发。等你看到账单再反应,已经晚了。