Agent 获准支付 100 后,实际执行金额谁来验证?

作者:袖梨 2026-09-15

当 Agent 开始代替用户订阅、充值或下单,支付安全就不能只停留在“是否允许付款”。即使授权签名、预算上限和商户范围全部校验通过,模型最终生成的调用参数仍可能发生偏移。真正需要补上的,是请求离开进程前对金额、币种、收款方与幂等键进行确定性核对。

适用人群:正在做 Agent 自主支付、订阅扣款、自动充值、代下单的开发者。 一句话:支付协议解决的是「这笔钱能不能付」,还没解决「实际执行的那次调用,是不是你批准的那一次」。

一、一张 1600 万美元的「幽灵」

2026 年 7 月,一位韩国的免费层开发者收到了两封来自 Anthropic 官方域名、经 Stripe 发出的邮件:

  • 第一封:$1,669,875
  • 不到 24 小时后的第二封:$16,627,739.70

而他的账号没有任何 API 用量、没有可计费的 Key、也没有绑定支付方式

钱最终没有被划走——但拦住它的不是 Anthropic 的计费系统,而是他的单笔限额。反复的扣款尝试导致他的主卡被银彳冻结。整件事从发生到解决花了 4 天、约 18 封客服邮件,其中相当一部分是自动回复。

Anthropic 在 7 月 12 日确认这是一次错误,原因是**「自动充值设置不正确」**,并把该配置作为预防措施关闭;官方同时说明没有未授权访问、没有资金被收取。

值得注意的是——Anthropic 没有解释,这个自动充值值是怎么变成一个如此极端的数字的。

这起事故常被当作「AI 公司也会出 bug」的花絮来讲。但对做 Agent 支付的人来说,它指向一个更具体的问题:

从「系统决定要收这笔钱」到「这笔钱真的被收走」,中间没有任何一层在核对金额。

二、这不是孤例

同一年的几组数据放在一起看,会清楚很多。

平台侧的事故(2026-01)。 Claude 状态页记录了一次「新订阅激活与支付问题」事故:部分新订阅在未正确开通权益的情况下向客户收费,官方描述为 accidental double or triple payments(意外的两次或三次扣款)。事故从 1 月 8 日晚开始,1 月 10 日凌晨修复完成,官方承诺为所有被错误扣款的用户退款。

企业侧的对账(2026)。 审计公司 Vaudit 复核了 60 家企业客户在 2026 年 3 月至 6 月间的 3,400万∗∗AI发票,发现约∗∗3,400 万** AI 发票,发现约 **3,400AI发票,发现约170 万 的误计费,错误率约 5%;客户名单中包含 Panasonic、HP、Honda。错误类型包括:按更贵的新模型费率计费、对失败的请求计费,以及**「重试风暴」——Agent 反复重试任务,每一次重试都被计费**。约 80% 的超收最终由各家厂商退还。

机构侧的经历(2026)。 BioCatch《Future of Digital Trust》调查访问了 25 个国家、1,440 名银彳反欺诈、反xi銭与合规负责人:

  • 80% 的机构表示已经遇到过使用 agentic AI 的攻击——不是预测,是已发生
  • 84% 认为 AI Agent 可能成为明年行业面临的突出可被利用漏洞(该报告中列为受访者的首要担忧)
  • 88% 说 AI 已经提升了欺诈与扎片手法的复杂度
  • 72% 认为未来很难区分「合法的 AI 辅助动作」与「被操纵的 AI 动作」
  • 81% 报告欺诈尝试同比上升(上一年为 71%),76% 报告欺诈损失上升(上一年为 59%)

而市场一侧,Juniper Research 在 2026 年 4 月 7 日发布的预测是:agentic commerce 交易额将从 2026 年的 80亿∗∗增长到2030年的∗∗80 亿** 增长到 2030 年的 **80亿增长到2030年的1.5 万亿、2031 年的 $3.5 万亿(2026–2031 增幅 43,240%);用户数从不足 3 亿(2026)增长到 13 亿(2031)。同一份报告里,消费者信任被列为阻碍普及的主要障碍

交易量在爆发,信任是瓶颈,而 80% 的银彳已经挨过打。

三、协议层已经做了很多——但它们都在授权侧

先把已有的工作讲清楚,才能看清缺口在哪。

AP2(Agent Payments Protocol)可验证数字凭证取代了开放式凭据,结构上是三重 mandate:

  • Intent mandate:用户的前置授权——「这个 Agent 可以在某商户、某品类、某时间窗内,花不超过某个额度」
  • Cart mandate:绑定到具体这笔报价——「以这个价格结算这个购物车」,用 intent_id 与意图绑死
  • Payment mandate:最终付款授权

mandate 是签名的(生态实现里常见 Ed25519 对规范化序列化结果签名,也有 EIP-712 形式),并携带作用域信息:max_amount 总上限、max_per_tx 单笔上限、商户白名单、品类白名单、nbf / exp 时间戳与 nonce

校验发生在调用之前。 一个 pre-call 花费闸门会检查:签名是否有效、密钥是否在受信任的 keyring 里、mandate 链是否闭合、购物车是否在意图范围内、是否还在预算内。任何一项不过就是硬停,返回结构化的拒绝原因——IntentCartMismatchMissingSignatureUnknownKeyInvalidSignatureIntentScopeMismatchCartOverCeiling

x402 则解决了另一半:用 HTTP 原生的 402 状态码做机器支付结算。两者互补——AP2 定义授权的语义,x402 负责结算落地。

这套设计是扎实的。问题在于它的语义边界:

pre-call 闸门证明的是「这笔调用被允许」,它不证明「实际发出去的那次调用,就是被批准的那一次」。

四、缺口在中间那一层

从闸门放行到请求真正发出去,中间还隔着一层:由 LLM 生成的工具调用参数

这正是整个链路里主要的非确定性来源。而它出错的方式,恰好都不会触发上面那些拒绝原因:

1. 参数生成漂移。 模型生成 amount 字段时单位、精度或字段名出错——100 元 / 100 分 / 100 美元、amount 写成 total、小数位截断。格式上完全合法,语义上完全错误。有行业复盘指出,Agent 工具调用失败中相当大比例属于工具名越权与参数值越权——参数一致性是主要的失败面之一。

2. 注入改写。 间接提示注入不需要攻破签名,它只需要改写模型下一轮生成的那个参数。上下文里一段被污染的内容,就能让「付给 A 商户 100」变成「付给 B 地址 1000」。BioCatch 调查里那 72% 认为「很难区分合法动作与被操纵动作」的负责人,担心的就是这一层。

3. 非幂等重试。 支付成功但回调丢失,Agent 重跑整个循环,于是钱扣了两次。这不是假设——Vaudit 在 60 家企业账上看到的「重试风暴」就是这个形态,Anthropic 那次 double or triple payments 的官方描述也是这个形态。

4. 静默降级。 上游把请求路由到另一个模型或另一个工具,参数被「尽力而为」地修补后继续执行。调用是成功的,日志是干净的,只有金额变了。

这四种失效有一个共同点:它们全部发生在授权之后。 你签的 mandate 没错,闸门判断也没错——错的是执行那一瞬间实际带出去的参数,而没有任何一层在核对它。

五、执行层要验什么:三条原则

原则一:验证过程不能调用 LLM。

用 LLM 去检查 LLM 的输出,等于把不确定性乘了两次,而且把「可验证」变成了「可解释」。金额比对是字符串和整数的事,把它交给一次模型推理,就同时失去了确定性和速度。

原则二:验的是参数级,不是调用成败。

「调用返回 200」和「付的是 100」是两件事。要逐字段比对声明值 vs 实际值——金额、币种、收款方、数量、幂等键——任何一项不一致就拒绝,而不是重试。

原则三:结论要能被第三方独立复核。

如果验证结论只能由出具方自己解释,那它本质上还是「请相信我们」。密码学签名是这条的现成解法:签名由私钥产生,任何人都能用公钥离线验证,验证过程不需要联网、不需要信任签发方,也不需要对方在线配合。

工程上再补一条成本很低、立竿见影的:幂等键。让每次支付调用携带稳定的幂等键,第 3 条那类「重试风暴」就直接消失。

把前三条落到代码里,形状大概是这样:

# 示意:执行层断言(确定性,零 LLM 调用)
def verify_call(intent, actual_call, receipt_pubkey):
    assert actual_call.tool == intent.tool
    assert actual_call.amount_cents == intent.amount_cents      # 整数分,不用浮点
    assert actual_call.currency == intent.currency
    assert actual_call.payee == intent.payee
    assert actual_call.idempotency_key == intent.idempotency_key

    if not ed25519_verify(intent.signature, actual_call.canonical(), receipt_pubkey):
        raise SignatureError("参数被改写或签名不匹配")

    return issue_receipt(actual_call)   # 签名的执行收据,可被任何人离线复核

关键点不是这段代码本身,而是它的位置:它必须在参数已经生成完毕、请求即将离开你的进程那一刻执行——也就是闸门之后、网络之前。

六、今天就能做的五件事

  1. 给每个会花钱的工具调用加幂等键,让重试不产生第二次扣款。
  2. 金额一律用最小单位整数(分 / cents),从源头掐掉浮点和单位歧义。
  3. 在调用出口加一道确定性断言:声明值 vs 实际值逐字段比对,不一致就拒绝并告警,不要自动重试。
  4. 最小权限——Agent 不需要的凭据就不要给它。在让它碰钱之前,先看看它的配置里到底被允许了什么:npx correctover-scan@latest(github.com/DSHCorrecto…,MIT 开源,本地运行,配置文件不上传)。
  5. 保留可独立复核的记录,让「这次调用到底带了什么参数」在事后可被第三方验证,而不是只能看厂商日志。

结语

Agent 支付这两年补的是「能不能付」——授权、额度、商户白名单、签名 mandate,这一层已经相当完整。

但那次 1600 万美元的提醒我们,「能不能付」和「付了多少」是两道题。授权侧做得再严密,执行侧那一层参数如果没人核对,缺口就一直在那儿开着。

而它其实不难补:参数级的确定性比对,加上一份能被任何人离线验证的收据。剩下的只是决定把它放在哪个位置。


数据来源:Juniper Research《Agentic Commerce Market: 2026-2031》新闻稿(2026-04-07)· BioCatch《The Future of Digital Trust》(2026,n=1,440 / 25 国)· Claude 状态页事故记录 incidents/pttlfp1vg4g3(2026-01)· Vaudit 对 60 家企业 $3,400 万 AI 发票的审计(经 The Information 报道,2026)· Anthropic 幽灵事故的公开报道与官方确认(2026-07)· AP2 / x402 生态公开文档。文中所有百分比与金额均来自上述来源,未做推算。

相关文章

精彩推荐