
十月的最后两周两件看起来不相关的事撞在了一起。10 月 21 日沃尔玛宣布 Agent Profiles、Agent Gateway 和一份专门写给 AI 智能体的条款10 月 27 日Salesforce 把 Agent Fabric 的 FinOps Dashboard、Model Wallet 与 Cost Optimization Policies 推到正式可用。一个是零售商的购物车一个是企业的 AI 控制平面落在同一个工程结论上预算这道闸必须在请求发出去之前合上而不是等账单到了再解释。过去一年讨论 Agent 可靠性重心多半在回答得对不对幻觉率、工具调用成功率、回归集通过率。这两件事把话题推到了下一个维度——花得对不对。推理钱包烧的是 token交易钱包烧的是真钱两种货币两道闸但闸门的形状几乎一样谁在花、花多少、什么时候必须拦住、拦错了怎么追溯。这篇文章把两边的公开信息拆开再把闸门的内核写成一段能跑的代码。一、交易钱包沃尔玛把限额做成了账户结构Agent Profile 的做法比给个额度更彻底。每个智能体首次通过 Agent Gateway 购物时沃尔玛自动为它建一个独立档案挂在用户名下用户登录自己的账号完成授权绑定然后设置控制项可以要求每一笔购买都由本人批准也可以授权智能体在设定的额度内直接下单官方给出的量级是 50、100、200 美元任何时刻都能删掉这个档案权限随之失效。关键在于它不是一个全局开关而是一等公民的账户对象——智能体的消费和本人的消费在账本上分离能分别查看、分别归因。配套的三条硬边界同样值得抄下来。智能体拿不到卡号也不能新增或修改用户的支付方式只能访问完成当前任务所必需、且用户明确允许的信息默认姿态是人工审批额度内自动下单属于用户主动授予的例外而不是系统默认送的便利。沃尔玛自己的类比是给信用卡加一张附属卡给了支付路径设了额度还能查到这张卡怎么被用的。区别在于附属卡持有人是人而这里的持有人是一个会因为上下文膨胀而反复重试的程序。Agent Gateway 本身是一个 MCP 服务器把智能体从用浏览器点人用的页面改成走机器用的接口。官方描述的能力范围是发现商品、加入购物车、下单、跟踪订单同时保留了平台侧的约束类目限制、速率限制、合规护栏违反条款的智能体会被屏蔽。写接口这件事本身就是治理动作——浏览器自动化没有稳定的计量点而 MCP 网关天然知道每一次工具调用的身份、参数和结果限额和审计才有地方挂。同一时期亚马逊在拦外部智能体沃尔玛在铺红毯。两种策略的分歧不在技术在商业判断但一旦决定让智能体进来就必须有账户结构去承载它。没有独立档案就没有归因没有归因限额只能拍脑袋限额拍不准风控就只能一刀切地禁止。这是把一个模糊的产品愿望翻译成可执行的账户模型的过程也是很多团队在自建 Agent 时最容易跳过的一步。条款里还有一条最容易被忽略的内容责任归属。沃尔玛写明默认需要用户批准购买即使设置了额度平台也可能在额度内再要求一次确认智能体拿不到卡号也不能改动支付方式如果智能体没有按用户意图行事既有的退货流程照常适用。把这四条连起来看责任链条是完整的——平台定义智能体能做什么用户定义它被允许花多少出问题时退回消费者保护流程。工程含义是限额不只是一个数字它还得能回答这笔交易是否在授权范围内也就是每一笔都要有可回放的授权上下文。顺带区分两个经常被混为一谈的机制速率限制管的是单位时间的请求数预算管的是累计金额。前者防打爆后者防破产。一个智能体完全可以在速率限制之内、用极长的上下文把预算烧穿反过来也可能在预算充足时瞬间打爆下游接口。两个维度必须同时存在任何一边单独上线都会留下缺口。二、推理钱包Model Wallet 把预算做成预留Salesforce 这边的数字先摆出来Agent Fabric 每天处理超过 12 亿次请求发布稿里引用的一个调研数字是 96% 的企业在不止一个平台上跑智能体。跨平台意味着单点面板不够用治理必须放在流量经过的那一层。Model Wallet 就是干这个的按智能体、按实例、按业务单元三类粒度设预算随着消费累积实时更新钱包见底时在超支之前介入而不是等发票开出来才发现预测功能会提前几天标出预计超支给运维留出改路由、改预算、改并发的时间窗。为什么必须是三类粒度而不是一个总预算值得单独说清。一个智能体往往同时存在多个实例灰度实例、调试实例、按区域拆分的生产实例。只有智能体级预算时跑在调试环境里的实例可以合法地烧掉整个智能体的额度把生产流量挡在门外只有实例级预算时跨团队的总额又没人负责。业务单元这一层解决的是分摊问题——预算最终要对到一张组织架构图上否则财务无法回答哪个部门的 AI 支出涨了三成。三层同时存在才有既拦得住又说得清的可能。整件事里技术含量最高的一句藏在计量口径上。Model Proxy 站在流量路径里按服务商实际收取的费率给每一个请求定价所以面板上的花费能和最终发票对上。做过成本看板的人都清楚第一个坏掉的环节从来不是限额而是口径——官网标价、折扣价、缓存命中价、批量价、不同区域价五种价格混在一张报表里数字就失去了行动价值。口径一旦和账单同源预算才是一个可以被信任的硬约束而不是一个估算游戏。第二层是减少浪费。Cost Optimization Policies 在三项机制上做文章语义缓存、请求负载压缩、响应裁剪官方给出的测试场景结论是最多降低 75% 的 token 消耗。具体策略有名字Progressive Disclosure 按需展开上下文Smart Response Trimming 剪掉响应里对当前步骤无用的部分TOON 压缩在网关侧重编码负载。这三项都发生在网关不改 MCP 服务器、不改客户端代码这意味着存量接进去就能受益而不需要每个业务团队各自重构一遍提示词。这三项要真正生效前提是上下文的契约足够规整。语义缓存的键如果每次都带上时间戳或随机 ID命中率会趋近于零Progressive Disclosure 要求工具描述能可靠地分层展开否则模型在需要参数时拿不到定义响应裁剪依赖调用方说清楚这一轮需要哪些字段。换句话说网关能省下的钱上限由客户端契约的规整程度决定。这也解释了官方的表述——省掉的是逐团队改造的成本不是免掉设计本身。第三层是止损与验证。Agent Kill Switch 已经可用Agent Evals 与 API Evals 走的是十一月 beta、明年一月正式发布的路线。故事线是完整的先看见花费再优化花费然后设硬上限最后用评测确认降本之后质量没塌。那个零售订单支持的例子说得直白——换便宜模型省钱评测发现延迟配送的回答开始出错平台请求人工授权把该智能体隔离团队改指令、用便宜模型复验再放回生产。降本和降质被拆成了两个可以分别验收的动作。三、两道闸共同的形状把两家放在一起真正共通的不是限额这个词而是三条工程约束。第一闸门必须在请求之前、必须失败即拒绝Model Wallet 在钱包见底时拦的是入站请求沃尔玛默认要求逐笔人工批准两者都把拒绝放在了动作发生之前而不是事后追责。第二计量口径必须和最终账单同源一个用服务商真实费率计价一个承诺智能体看到的价格和人类看到的一致、费用在下单前展示。第三身份与授权必须独立且可撤销预算挂在具体的智能体或实例上Agent Profile 可以随时删除。差异同样清楚而且差异来自业务性质而不是设计偏好。粒度的单位不同推理侧按智能体、实例、业务单元三级切交易侧按每一个档案切因为它对应的是一个个具体的消费者。超限后的动作不同推理侧直接拒绝请求并抛错交易侧可以拒单也可以转成一次人工审批把决定权交回人手里。可优化的空间也不同推理侧能在不改变业务语义的前提下压缩上下文、复用缓存交易侧几乎没有这种弹性能做的只有减少购买或降低商品规格。维度推理钱包Model Wallet交易钱包Agent Profile计量对象token 与模型调用商品、履约与支付预算粒度智能体、实例、业务单元每一个智能体档案闸门位置流量路径上的模型代理MCP 网关与下单接口之前超限动作拒绝入站请求拒单或转人工审批默认姿态硬上限加预测预警默认逐笔人工批准口径基准服务商实际费率对齐发票与人同价费用下单前展示撤销方式调预算或拉停开关删除档案随时生效这张表的读法是自上而下的先问计量对象是什么再问粒度切到哪一层然后才轮到限额设多少。顺序反过来就会出问题——很多团队一上来就争论一天给多少 token却没定义清 token 是怎么算的、算在谁头上、跨副本怎么合并。粒度没定义清楚限额数字再精确也只是个心理安慰。四、为什么事后对账一定失效第一层原因是账期错位。服务商的账单按小时或按天聚合而一个失控的智能体循环按秒烧钱。等到日报里出现一条异常的曲线钱已经花完了。事后对账能回答花了多少永远回答不了下一次怎么在花出去之前停下因为它的输入是已经发生的事实。第二层原因是上下文膨胀带来的非线性。假设每轮基础输入 2000 token、每轮输出 800 token跑 200 轮。如果每轮都用一个固定的短窗口输入总量是 40 万 token按每百万输入 3 美元、每百万输出 15 美元计总成本约3.6 美元。如果把上一轮的输出全部拼回上下文第 n 轮的输入变成 2000 加 800 乘以 n 减 1200 轮的输入总量会涨到1632 万 token总成本约51.36 美元。同一个任务、同一个模型只因为窗口策略不同成本差14.3 倍。这个差额不是账单寄到才知道的是在第 30 轮左右就开始积累的。还有一个被低估的变量优化手段本身会改变成本曲线的形状。语义缓存命中率高的时候单位成本很低一旦业务话术变了、缓存键大面积失效单位成本会在几个小时内跳回原价。做过这类系统的人都知道最危险的不是成本高而是成本忽然从低变高——容量规划按低值做账单按高值来。所以预测门不能只拟合历史均值得把缓存命中率、上下文长度、重试率这三个变量单独监控任何一个偏离基线就提前预警。第三层原因是静默失败。智能体出错时通常不会叫停而是重试、换工具、换措辞再试一次每一次重试都是一次完整的模型调用。预留时按 0.004 美元估算、结算时真实花了 0.37 美元偏差 92 倍放大到 1000 次调用就是 370 美元。这种量级的偏差只有请求前的预留能兜住——先把额度占住真实用量回来再回冲事中就能发现预估和实际差两个数量级而不是月底对着报表发呆。五、把闸门写成代码最小内核只有三段预留、结算、释放。请求发出前按预估占额度真实用量回来后结算并把差额回冲异常路径上必须显式释放否则额度会被永久占住——这是预算闸最常见的生产事故比限额设错更隐蔽。再叠两个东西幂等键防重放同一笔请求重试不会占两次额度锁保证同一钱包上的预留和结算是原子的多副本部署下必须落到共享存储而不是进程内存。import json, threading, uuid from dataclasses import dataclass class BudgetExceeded(Exception): pass dataclass class Reservation: rid: str wallet: str micro: int # 预留额单位微美元 state: str reserved # reserved / settled / released class ModelWallet: 预留-结算-释放三段式预算闸纯标准库可直接运行。 def __init__(self, ledgerwallet_ledger.jsonl): self.cap, self.reserved, self.settled {}, {}, {} self.records, self.ledger {}, ledger self.lock threading.Lock() def set_cap(self, wallet, usd): self.cap[wallet] int(round(usd * 1_000_000)) def _used(self, w): return self.reserved.get(w, 0) self.settled.get(w, 0) def can_afford(self, wallet, estimate_usd): need int(round(estimate_usd * 1_000_000)) return self._used(wallet) need self.cap.get(wallet, 0) def reserve(self, wallet, estimate_usd, idem_key): with self.lock: if idem_key in self.records: # 幂等重试不重复占额度 return self.records[idem_key] if not self.can_afford(wallet, estimate_usd): raise BudgetExceeded(wallet 预算不足请求不发出) r Reservation(uuid.uuid4().hex, wallet, int(round(estimate_usd * 1_000_000))) self.reserved[wallet] self.reserved.get(wallet, 0) r.micro self.records[idem_key] r self._log(r, reserve, idem_key) return r def settle(self, idem_key, real_usd): with self.lock: r self.records[idem_key] if r.state ! reserved: return r real int(round(real_usd * 1_000_000)) self.reserved[r.wallet] - r.micro self.settled[r.wallet] self.settled.get(r.wallet, 0) real r.state, r.micro settled, real self._log(r, settle, idem_key) return r def release(self, idem_key): with self.lock: r self.records.get(idem_key) if r and r.state reserved: self.reserved[r.wallet] - r.micro r.state released self._log(r, release, idem_key) return r def _log(self, r, op, idem_key): with open(self.ledger, a, encodingutf-8) as f: f.write(json.dumps({op: op, rid: r.rid, wallet: r.wallet, micro: r.micro, idem: idem_key}) \n) w ModelWallet(demo_ledger.jsonl) w.set_cap(order-support, 100.0) a w.reserve(order-support, 0.5, req-1) b w.reserve(order-support, 0.5, req-1) assert a.rid b.rid # 幂等键命中同一条预留 w.settle(req-1, 0.42) # 真实用量 0.42回冲 0.08 try: w.reserve(order-support, 100.0, req-2) assert False # 走到这里说明闸门漏了 except BudgetExceeded: pass print(ok, w.settled) # ok {order-support: 420000}这段代码可以原样粘进一个文件跑起来断言全部通过。它有刻意留下的边界钱用整数微美元表示避免浮点误差累积账本按行追加方便重放和审计settle之后状态机就锁死重复结算直接返回原记录。真正上生产还需要补两件事把锁换成共享存储上的原子操作把账本换成带事务的存储以及给预留加一个过期时间让崩溃的进程占住的额度能自动回收。幂等键怎么生成比要不要幂等更重要。用请求体哈希会把同一意图的两次合法调用误判成重放用随机 UUID 又等于没有幂等。实际可用的方案是三元组调用方声明的一次任务 ID、步骤序号、工具名。任务 ID 保证跨进程重试收敛到同一条预留步骤序号区分同一次任务里的多次调用工具名防止不同工具的键互相碰撞。这样即使网关重启、队列重投同一笔逻辑调用也只会占一次额度。人工审批门常被当成万能兜底但它有两个硬约束。延迟上一次审批要在几十秒内完成才有意义超过几分钟智能体的任务上下文已经开始失真人批的其实是过期的意图。疲劳上如果一个智能体每天产生两百条待批请求审批人会开始无差别点同意闸门形同虚设。合理的做法是分层低额度自动、中额度抽检加事后审计、高额度逐笔人工并且把审批通过率当成一个需要监控的指标而不是假设人一定会认真看。六、上线前的六项检查预算粒度是否已经定义到能归因的那一层智能体、实例、业务单元还是档案三个都想要就先选一个别一次全上。计量口径能不能和最终账单对齐费率表用的是官网标价还是实际结算价缓存命中和批量折扣有没有单独的价目。闸门是不是真的在请求前关掉账单页面之后系统能不能在超支之前拒绝下一次调用。幂等键是否覆盖所有重试路径网络超时、网关重发、队列重投三条路径必须收敛到同一个键。异常路径是否显式释放超时、进程被杀、上游 5xx每一条都要有回冲动作否则额度会慢慢漏光。预测与人工门的位置预警提前多久、超过多少比例转人工、谁能一键拉停。这三项如果不写进运行手册出事时没人敢按。小团队不需要先买一个控制平面。在自己的模型调用出口放一层薄代理维护一张按实际结算价更新的单位成本表把预留、结算、释放跑通再接一个能拉停的开关就已经覆盖了八成的失控场景。剩下的两成是跨平台与跨云那才是控制平面真正值钱的地方。最容易放错的位置有三个。放在客户端里等于把闸门交给了被约束的一方任何一次绕过都无声无息放在异步计费链路里闸门永远晚一步只能记账不能拦截放在单实例的进程内存里多副本部署下每个副本各自以为还有额度合计起来超支三倍。这三个错误和限额设多少无关是结构问题。七、下一层是授权链当钱包被拆成账户结构和预算对象之后审计的对象也跟着变了。要回答的问题不再是这个月花了多少而是哪一笔是哪个智能体的哪个实例花的、谁批的预算、失败重试算在谁的账上、撤销之后有没有残留的授权。沃尔玛用独立档案和可删除授权回答前一半Salesforce 用按实例切分的预算和拉停开关回答后一半。两边都指向同一个方向智能体的可治理性最终落在一串可以被机器验证的授权事实上。再具体一点一条合格的授权事实至少要说清四件事谁授予的也就是用户或预算负责人授予给谁也就是哪个智能体、哪个实例允许做什么也就是工具集与金额区间什么时候失效也就是时长或次数上限。这四项缺任何一项事后都无法判定一笔操作是否越权。沃尔玛的档案结构大致覆盖了这四项Salesforce 的预算对象覆盖了后三项第一项依赖平台自身的账户体系。自建系统时这四项应该直接落成一张表而不是散落在配置文件和一串代码分支里。一个可以拿来自测的问题把账单页面关掉把监控面板也关掉只看你的系统本身它还能不能在超支之前拒绝下一次请求。能说明闸门在正确的位置不能说明现在有的只是报表。智能体从能干活走到会花钱中间隔的不是模型能力是这一道闸。