news 2026/11/1 1:55:58

Agent 花钱的两道闸:Salesforce Model Wallet 与沃尔玛 Agent Profile 拆解,预算为什么必须在请求前拦住

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Agent 花钱的两道闸:Salesforce Model Wallet 与沃尔玛 Agent Profile 拆解,预算为什么必须在请求前拦住

十月的最后两周,两件看起来不相关的事撞在了一起。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 减 1,200 轮的输入总量会涨到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, ledger="wallet_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", encoding="utf-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 保证跨进程重试收敛到同一条预留,步骤序号区分同一次任务里的多次调用,工具名防止不同工具的键互相碰撞。这样即使网关重启、队列重投,同一笔逻辑调用也只会占一次额度。

人工审批门常被当成万能兜底,但它有两个硬约束。延迟上,一次审批要在几十秒内完成才有意义,超过几分钟,智能体的任务上下文已经开始失真,人批的其实是过期的意图。疲劳上,如果一个智能体每天产生两百条待批请求,审批人会开始无差别点同意,闸门形同虚设。合理的做法是分层:低额度自动、中额度抽检加事后审计、高额度逐笔人工,并且把审批通过率当成一个需要监控的指标,而不是假设人一定会认真看。

六、上线前的六项检查

  1. 预算粒度是否已经定义到能归因的那一层:智能体、实例、业务单元,还是档案?三个都想要就先选一个,别一次全上。
  2. 计量口径能不能和最终账单对齐:费率表用的是官网标价还是实际结算价,缓存命中和批量折扣有没有单独的价目。
  3. 闸门是不是真的在请求前:关掉账单页面之后,系统能不能在超支之前拒绝下一次调用。
  4. 幂等键是否覆盖所有重试路径:网络超时、网关重发、队列重投,三条路径必须收敛到同一个键。
  5. 异常路径是否显式释放:超时、进程被杀、上游 5xx,每一条都要有回冲动作,否则额度会慢慢漏光。
  6. 预测与人工门的位置:预警提前多久、超过多少比例转人工、谁能一键拉停。这三项如果不写进运行手册,出事时没人敢按。

小团队不需要先买一个控制平面。在自己的模型调用出口放一层薄代理,维护一张按实际结算价更新的单位成本表,把预留、结算、释放跑通,再接一个能拉停的开关,就已经覆盖了八成的失控场景。剩下的两成是跨平台与跨云,那才是控制平面真正值钱的地方。

最容易放错的位置有三个。放在客户端里,等于把闸门交给了被约束的一方,任何一次绕过都无声无息;放在异步计费链路里,闸门永远晚一步,只能记账不能拦截;放在单实例的进程内存里,多副本部署下每个副本各自以为还有额度,合计起来超支三倍。这三个错误和限额设多少无关,是结构问题。

七、下一层是授权链

当钱包被拆成账户结构和预算对象之后,审计的对象也跟着变了。要回答的问题不再是"这个月花了多少",而是"哪一笔是哪个智能体的哪个实例花的、谁批的预算、失败重试算在谁的账上、撤销之后有没有残留的授权"。沃尔玛用独立档案和可删除授权回答前一半,Salesforce 用按实例切分的预算和拉停开关回答后一半。两边都指向同一个方向:智能体的可治理性,最终落在一串可以被机器验证的授权事实上。

再具体一点,一条合格的授权事实至少要说清四件事:谁授予的,也就是用户或预算负责人;授予给谁,也就是哪个智能体、哪个实例;允许做什么,也就是工具集与金额区间;什么时候失效,也就是时长或次数上限。这四项缺任何一项,事后都无法判定一笔操作是否越权。沃尔玛的档案结构大致覆盖了这四项,Salesforce 的预算对象覆盖了后三项,第一项依赖平台自身的账户体系。自建系统时,这四项应该直接落成一张表,而不是散落在配置文件和一串代码分支里。

一个可以拿来自测的问题:把账单页面关掉,把监控面板也关掉,只看你的系统本身,它还能不能在超支之前拒绝下一次请求。能,说明闸门在正确的位置;不能,说明现在有的只是报表。智能体从"能干活"走到"会花钱",中间隔的不是模型能力,是这一道闸。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/11/1 1:53:33

05-原理篇-Wi-Fi-6-6E-7新特性-OFDMA-BSS-Coloring-MU-MIMO

05-原理篇-Wi-Fi 6/6E/7新特性——OFDMA、BSS Coloring与MU-MIMO Wi-Fi 5&#xff08;802.11ac&#xff09;解决了"快"的问题&#xff0c;Wi-Fi 6&#xff08;802.11ax&#xff09;解决的是"多"的问题。当会议室里有50个人同时用WiFi&#xff0c;Wi-Fi 5会…

作者头像 李华
网站建设 2026/11/1 1:53:33

毕设答辩老师最爱问的15个问题,提前准备好直接过

⚠️ 免责声明&#xff1a;本文项目仅供技术学习参考&#xff0c;严禁直接作为毕业设计或课程作业提交。请结合自身需求进行二次开发与创新&#xff0c;学术诚信从我做起 &#x1f642;论文和答辩这关怎么过 代码写完了&#xff0c;还有最后一关&#xff1a;论文 答辩。 很多同…

作者头像 李华
网站建设 2026/11/1 1:53:09

【维克】事件策略进阶:跨市场事件与连锁反应

"风起于青萍之末&#xff0c;浪成于微澜之间。"——宋玉《风赋》大洋彼岸的财报能让第二天开盘的港股跳空&#xff1b;一次中东的炮火能让国内的化工股集体涨停&#xff1b;汇率的波动能让出口企业的股价瞬间变脸。风起于青萍之末&#xff0c;而你看到的浪&#xff0…

作者头像 李华
网站建设 2026/11/1 1:52:56

RAG一 文档切分核心思路

RAG 文档切分核心思路文档切分的核心逻辑是「先保语义&#xff0c;再控大小&#xff0c;最后补细节」&#xff0c;全程遵循「3 步核心流程」&#xff0c;所有操作都围绕「不破坏语义、适配检索」展开&#xff0c;具体步骤如下。第一步&#xff1a;先做「语义分层」&#xff08;…

作者头像 李华