跳到主要内容

AP2 (Agent Payments Protocol) — 架构与原理

30 秒导读: AP2 是 Google 主导的开放协议,解决一个新问题——当 AI agent 替你花钱时,商家/银行凭什么相信这笔钱是你授权的? 它的答案是 mandate(授权书):把「人批准了什么」写成一份密码学签名的凭证,agent 每次付款都要出示它,任何验证方都能离线核验、事后追责。

1. 这是什么(零基础也能懂)

一句话定义: AP2 是一层叠加在电商协议之上的安全协议,让 AI agent 发起的支付带上「人类确实授权过」的密码学证据。

解决什么问题 / 给谁用

想象你对一个购物 agent 说:「帮我买双红色高帮篮球鞋,200 美元以内。」agent 跑去跟商家谈、组购物车、刷你的卡。这里有个信任黑洞:

  • 商家怎么知道这个 agent 真的被你授权买这双鞋,而不是 agent 自己乱花钱或被人劫持?
  • 银行 / 支付处理方怎么知道该不该放行这笔卡交易?
  • 真出了纠纷,凭什么证据说清「用户当时到底批准了什么」?

传统电商假设「点付款的就是持卡人本人」。可一旦中间多了个非确定性的 LLM agent,这个假设就破了——agent 自己就可能是攻击面。AP2 就是来补这个洞的。

它能做什么(功能)

  • 把用户的购买授权固化成可验证凭证(mandate),商家/银行可独立核验。
  • 支持两种模式:用户在场(人亲自点确认)和用户不在场(人先设好约束,agent 自主成交)。
  • 用**约束(constraints)**框住 agent 的自主权:金额上限、限定商家、限定商品、预算、执行日期……
  • 选择性披露只露出验证必需的字段,保护隐私。
  • 结算后回一张收据(receipt),密码学绑回那份授权,作为纠纷证据。
  • 与传输无关:示例跑在 A2A(Agent-to-Agent)和 MCP 上,但协议本身不绑定任何一种。

用起来什么样

AP2 的「核心动作」其实就三步,SDK 把它收成三个方法(code/sdk/python/ap2/sdk/mandate.py:153 MandateClient):

# 示意,非源码:一笔「用户不在场」授权的最小骨架
client = MandateClient()

# 1. 用户(经银行/可信表面)签发一张「开」mandate:只设约束,不绑具体交易
open_token = client.create(payloads=[open_payment_mandate], issuer_key=user_key)

# 2. agent 在它上面追加一跳,签出「闭」mandate:绑定到这笔具体交易
chain = client.present(holder_key=agent_key, mandate_token=open_token,
payloads=[closed_payment_mandate], nonce="tx_abc", aud="merchant")

# 3. 商家/银行验证整条链:签名对不对、约束满不满足
payloads = client.verify(token=chain, key_or_provider=lookup_user_key,
expected_aud="merchant", expected_nonce="tx_abc")

一句话直觉 / 类比

把 mandate 想成一张「带条件的授权委托书」。 用户签的「开」委托书写的是规则(「200 刀以内、任意鞋店都行」);agent 拿着它去成交,再补签一张「闭」委托书填上真实成交细节(「就这双鞋、就这家店、就 $179.99」)。验证方拿到两张一对照:闭的有没有越过开的规则?两张是不是同一条信任链上的?——全程不需要联系用户本人,纯靠密码学。


2. 顶层全景(它大概怎么转)

五种角色

AP2 把一笔 agentic 交易拆成五个职责(docs/ap2/specification.md:30-52)。一个公司可以兼任多个角色,但职责是分开的:

角色干什么是否「agentic」
Shopping Agent (SA)主 agent:找货、组购物车、发起购买预期是 agentic(LLM 驱动)
Credential Provider (CP)持有用户支付凭证,放行 token可 agentic / 可非 agentic
Merchant (M)提供并完成 checkout,保证库存与价格可 agentic / 可非 agentic
Merchant Payment Processor (MPP)处理支付,核验凭证是否绑对了这单可 agentic / 可非 agentic
Trusted Surface (TS)拿到用户知情同意、签出用户 mandate 的 UI必须非 agentic

关键洞察:协议把「LLM 是潜在攻击者」当成前提(specification.md:86-89)。所以所有验证/处理必须跑在确定性代码里,不能交给 LLM(specification.md:96-98);唯一能签发用户授权的 Trusted Surface 也强制非 agentic(specification.md:78-80)。

一张图:一笔交易怎么流

下面是「用户不在场」的高层数据流。从上到下是时间顺序,左边是人/agent 侧,右边是验证方。

用户 Shopping Agent 验证方(商家 / CP / MPP)
│ │ │
│ 1. 设任务+约束 │ │
│──────────────────────▶│ │
│ 2.(经 Trusted Surface)│ │
│ 签「开」mandate │ │
│◀─────────签名─────────▶│ │
│ 用户离场 │ │
│ │ 3. 跟商家谈、组车、拿 checkout JWT
│ │───────────────────────────▶│
│ │ 4. 用 agent 私钥追加一跳, │
│ │ 签出「闭」mandate │
│ │ 5. 出示整条链(开+闭) │
│ │───────────────────────────▶│
│ │ │ 验签 + 查约束
│ │ 6. 收据(reference 绑回闭 mandate)
│ │◀───────────────────────────│

主线走一遍(不进代码):

  1. 授权阶段 — 用户在 Trusted Surface 上批准一份「开」mandate(只含约束 + agent 公钥),用户私钥签名。这是整条信任链的根。
  2. 成交阶段 — agent 自主跟商家组好购物车,拿到商家签名的 checkout。
  3. 绑定阶段 — agent 用自己的私钥,在「开」mandate 之上追加一跳,签出「闭」mandate,把真实成交细节绑死。
  4. 验证阶段 — 验证方拿到整条链:先用**只信任的根(用户/银行公钥)**验第一跳,再顺着每跳的 cnf(下一跳公钥)往下验,最后逐条评估约束。
  5. 结算 + 追责 — 通过则回一张收据,其 reference = sha256(闭 mandate JWT),把结算结果永久绑回那份授权,作为纠纷证据。

部件一句话职责(SDK)

部件干什么在哪个文件
MandateClient对外门面:create / present / verifycode/sdk/python/ap2/sdk/mandate.py:153
sd_jwt根 SD-JWT(链的第一跳)签发与验证code/sdk/python/ap2/sdk/sdjwt/sd_jwt.py:23
kb_sd_jwtKB-SD-JWT 委托跳(中间/终端)code/sdk/python/ap2/sdk/sdjwt/kb_sd_jwt.py:35
chain.verify_chain顺链验证,跟着 cnfcode/sdk/python/ap2/sdk/sdjwt/chain.py:121
constraints约束评估器(金额/商家/预算/配货…)code/sdk/python/ap2/sdk/constraints.py:489
ReceiptClient收据创建与验证code/sdk/python/ap2/sdk/receipt_wrapper.py:18

3. 接下来读哪章

这个项目有两面:一套协议规范(docs/)一套真实实现(code/sdk + code/samples),而且实现里还并存两代数据模型。按下面顺序读最省力:

  1. 01-mandates-and-roles.md — 先把「开 vs 闭 mandate」「五种角色」「人在场 vs 不在场」这几个核心概念吃透。所有人必读。
  2. 02-sdjwt-delegation-chain.md — SDK 的心脏:委托链怎么用 SD-JWT + KB-SD-JWT 一跳跳拼出来、验证方怎么顺着 cnf 一路验下来。想读源码的从这章进。
  3. 03-constraints-and-receipts.md — agent 自主权的「护栏」:约束怎么逐条评估(含一个用最大流做配货匹配的巧妙实现),收据怎么把结算绑回授权。
  4. 04-two-model-generations.md — 诚实章:仓库里 ap2/models/(Intent/Cart/Payment)和 ap2/sdk/generated/(Open/Closed Checkout/Payment)是两代设计,哪套用在哪个样例、规范站在哪一边。读懂这章才不会被「同一个仓库两套 mandate 名字」搞晕。

4. 代码地图(导航索引)

主题文件符号名
协议规范 v0.2docs/ap2/specification.md(Roles / Mandates / Verification)
授权框架(开/闭、委托、收据)docs/ap2/agent_authorization.md(Mandate Delegation / Action Authorization)
两种流程示例docs/ap2/flows.md(Human Present / Human Not Present)
旧版 Pydantic 模型code/sdk/python/ap2/models/mandate.pyIntentMandate CartMandate PaymentMandate
W3C 支付对象code/sdk/python/ap2/models/payment_request.pyPaymentRequest PaymentResponse
SDK 门面code/sdk/python/ap2/sdk/mandate.pyMandateClient
SD-JWT 原语code/sdk/python/ap2/sdk/sdjwt/sd_jwt.pycreate verify
委托跳原语code/sdk/python/ap2/sdk/sdjwt/kb_sd_jwt.pycreate verify
链编排code/sdk/python/ap2/sdk/sdjwt/chain.pyverify_chain
约束引擎code/sdk/python/ap2/sdk/constraints.pycheck_payment_constraints
配货最大流code/sdk/python/ap2/sdk/max_flow_helper.pyevaluate_line_items_max_flow
收据code/sdk/python/ap2/sdk/receipt_wrapper.pyReceiptClient
A2A 扩展 URIcode/samples/python/src/common/a2a_extension_utils.pyEXTENSION_URI