深夜 11:47,Muse 拿到了夹克,却没有付款权限
一位买家告诉 Muse,自己想要一件两百美元以下的防雨外套。Muse 搜索、比较四件夹克、打开一个商品页、选好尺码、填好收货地址、走到订单复核页面,然后停了下来。总价就在屏幕上,卡也已经在档,什么都没发生。
Muse 并没有被拒绝。它撞上的是架构刻意划出的一条边界,而智能体商务中所有有意思的东西都落在这条边界的两侧。搜索是读取操作,答错不费一分钱。支付是写入操作,带着财务后果,因此需要自己的权限模型、自己的失败路径和自己的证据链。Meta 围绕这一区分构建了 Muse,Shopify 则把它的商家一侧写进了一个有版本、可测试、也相当不宽容的协议。
本文下面有两类来源。消费者流程、审批规则与钱包限额来自 Muse 内部智能体提示词语料的泄露副本,该副本以 asgeirtj/system_prompts_leaks 之名发布在 GitHub 上,并与 Meta 的工程文章、Stripe 的公告以及围绕二者的媒体报道做了交叉核对。商家侧的合约来自 Shopify 的智能体商务文档和 Universal Commerce Protocol 规范,我是逐页读完的,而不是看片段。两者冲突时,以协议为准,文中也会说明。
Muse 的五个步骤,以及第二步那堵墙
Meta 于 2026 年 9 月 8 日在美国推出 Muse,落地在 Muse 应用和 WhatsApp 之内。提供支付通道的 Stripe 三周后报告称,通过 Link 完成的智能体购买在一个月内增长了 38 倍。无论你怎么看待这款产品,这个体量都足以说明:支撑它的协议值得读一遍。
一笔购买由五个步骤承载。
查找与比较。 商品目录搜索不需要购买审批。Meta Catalog 有自己的搜索权限,默认设为允许,因此一个任务中的首次搜索可能询问一次,而这次批准覆盖该任务余下的部分。呈现结果不涉及任何资金流动。
结账。 后台浏览器任务驱动商家的结账流程,直到最终条款可供复核;对于支持智能体结账的目录商品,则通过 UCP 打开一个会话,不需要真实浏览器。创建结账同样不涉及资金流动。如果缺少尺码、颜色或型号,Muse 会询问。
复核。 最终商品、已选选项、配送与联系信息、总价和支付方式一起呈现。对于钱包支付,只有在钱包配置完成之后才会出现复核界面。
确认。 对于钱包支付,支付提供方的批准卡片就是确认。它授权的是那张已复核的订单,而 Muse 被明确要求不要在聊天中索取第二次确认。对于其他浏览器支付方式,买家在聊天中确认,一个简单的"是"即可接受。
完成。 获批之后,任务完成结账并提交订单。Shop Pay 返回一个一次性令牌。Stripe Link 发放一张为此笔购买注资的一次性虚拟卡。
墙就立在第二步。除了花钱,Muse 什么都能做;而花钱的权限稍后才到,从模型之外而来,绑定一笔交易和一个失效时间。
Shopper { # Shopper
s1: circle label:"Ask for a jacket under 200 dollars"
s2: rectangle label:"Approve one order one amount one method"
s3: circle label:"Order confirmed"
s4: circle label:"No order approval expired"
s1.handle(right) -> Agent.a1.handle(left)
a3.handle(bottom) -> s2.handle(top) [label="Approval card"]
s2.handle(right) -> Agent.a4.handle(top) [label="Approved"]
a4.handle(bottom) -> s4.handle(left) [label="Refused or late"]
}
Agent { # Agent
a1: rectangle label:"Search and compare products"
a2: rectangle label:"Prepare checkout and totals"
a3: rectangle label:"Present reviewed order"
a4: diamond label:"Approved within ten minutes"
a5: rectangle label:"Pay with one-time credential"
a6: circle label:"Submit order"
a1.handle(right) -> a2.handle(left)
a2.handle(right) -> a3.handle(left)
a4.handle(right) -> a5.handle(left) [label="Yes"]
a5.handle(right) -> a6.handle(left)
a6.handle(bottom) -> Shopper.s3.handle(top) [label="Confirmation"]
}
让 Muse 的闸门成立的四条规则
一道 Muse 能靠话术绕过去的批准,就不算闸门。四条规则关上了这扇门,其中三条在对话之外强制执行。
每一次购买都要重新弹出确认。 批准绑定到那一笔具体的结账:同一商家、同一金额、同一支付选择。三者中任何一项改变,都会触发一张新的批准卡片。唯一的例外在卡片本身:买家可以另选一张已保存的钱包卡,此时批准即覆盖该选择。
批准不能被预先授予、批量授予或自动化。 对话中的一句友好同意不算批准,系统会拒绝任何被存储或可复用的消费授权。一个计划任务可以一路走到待批准的卡片,然后它就在那里等待。这就是无人值守故事的全部内容,而商家侧现在用自己的语言说了同一件事:一个没有买家在场的智能体发起令牌层调用会失败,因为 Shopify 没有买家 IP 地址的占位值,也不会退而使用智能体自己的地址。
批准的有效期很短。 一个待处理的结账大约十分钟后过期,过期后流程从搜索重新开始。另外,在浏览器任务中到达结账页面本身可能触发一次同意卡片;一旦它被批准,同一任务中、同一商家下后续的结账页面在约三小时内不会再询问。
浏览与消费是两套机制。 一个站点可以为浏览赢得按站点永久允许。消费永远不能。Meta 自己的文档把这一点说得很直白,协议也照此镜像:让智能体能准备购买的这项能力,并不是让它能完成购买的那项能力。
闸门之后是钱包限额。Link 通过 wallet.get_user_info 提供单笔限额以及日窗口和三十天窗口的限额,Muse 在每次购买时都重新读取,而不是引用一个更早的数字。Link 的购买保护适用于符合条件的订单:损坏、失窃或丢失最高 500 美元,降价最高 500 美元,退货运费与重新上架最高 250 美元,退款保障下最高 1,000 美元。这些计划属于 Stripe 而不属于 Meta,并且 Muse 被禁止告诉买家某笔具体购买受到保障。
商家一侧:四个能力族,五个端点
消费者协议只有在商家发布机器可读接口时才成立。这个接口就是 Universal Commerce Protocol,由 Google、Shopify、Etsy、Wayfair、Target、Walmart、Amazon、Microsoft、Meta 和 Stripe 为购物场景共同开发,运行在 MCP 之上的 JSON-RPC 2.0 上,REST 是另一种被认可的传输方式。
Shopify 用四个能力族实现它,由五个端点提供服务。如果你想看序列层面的同一套握手,本博客早前那份 UCP 流程地图 仍然成立;它早于的是购物车这部分接口,而大部分运营风险如今正落在这里。这个区分比数量更重要,因为中间两个能力族做的是不同的工作,带着不同的限额。
| 能力族 | 端点 | 工具 | 是否涉及资金 |
|---|---|---|---|
| 全球目录(Global Catalog) | catalog.shopify.com/api/ucp/mcp | search_catalog、get_product、lookup_catalog | 否 |
| 店铺目录(Storefront Catalog) | {shop}/api/ucp/mcp | 同样三个工具名,范围限定在单个商家 | 否 |
| 购物车(Cart) | 商家 MCP 端点 | create_cart、get_cart、update_cart、cancel_cart | 否 |
| 结账(Checkout) | 商家 UCP 端点,/api/ucp/mcp | create_checkout、get_checkout、update_checkout、complete_checkout、cancel_checkout | 仅 complete_checkout |
| 订单(Order) | 商家 MCP 端点,外加 webhooks | get_order | 否 |
这张表直接引出两个后果,而多数集成在第一次就把两个都做错了。
购物车用于思考,结账用于承诺。 购物车是长期存在、对未认证请求友好的容器:添加行项目、设置国家、估算总额、把购物车的 continue_url 分享给买家,并在多轮对话中持续迭代。结账则短暂、对新鲜度和幂等性更严格,限流也更狠。数字是公开的:全球目录流量为每个 API 客户端每秒 5 次请求,店铺目录流量按店铺限制。Shopify 在结账页上用一句话说清了:用 Cart MCP 迭代,把 Checkout MCP 留给已经准备购买的买家。一个一冲动就调用 create_checkout 的智能体,会把限流额度消耗在一个还在比较颜色的买家身上,而它损失的转化永远不会以错误的形式出现。
两者之间的转换是一个字段,而不是一次重建。 create_checkout 接受一个可选的 cart_id,把用 Cart MCP 建好的购物车变成一个结账会话。行项目不会被重建,总额也不由智能体重算。
Agent { # Agent
b1: circle label:"Buyer starts shopping"
b2: rectangle label:"Iterate lines and context on cart"
b3: rectangle label:"Buyer commits to the order"
b4: rectangle label:"Open a checkout from the cart"
b5: rectangle label:"Complete once with the same key"
b6: circle label:"Order placed"
b1.handle(right) -> b2.handle(left)
b2.handle(right) -> b3.handle(left)
b3.handle(right) -> b4.handle(left)
b4.handle(right) -> b5.handle(left)
b5.handle(right) -> b6.handle(left)
b2.handle(bottom) -> Business.c1.handle(top) [label="update_cart"]
c1.handle(bottom) -> b3.handle(bottom) [label="Live totals"]
b4.handle(bottom) -> Business.c2.handle(top) [label="create_checkout"]
c2.handle(bottom) -> b5.handle(bottom) [label="ready_for_complete"]
}
Business { # Merchant API
c1: rectangle label:"Cart tools answer at the highest rate limit"
c2: rectangle label:"Checkout tools answer once then throttle"
}
协商、层级,以及谁才有权真正完成交易
下一个意外之处是:商家并不提供一份固定菜单。它进行协商。
你在一个 HTTPS URL 上发布平台档案,并在每个请求中通过 meta.ucp-agent.profile 引用它。商家在 /.well-known/ucp 发布自己的业务档案,声明协议版本、能力、支付处理器和签名密钥。Shopify 随后抓取并校验你的档案,检查版本是否对齐,把你声明的能力与店铺支持的能力求交集,并剪除任何父能力未能在交集中存活的扩展。协商由服务器选定。你暴露的是一份会被协商的合约,而不是一份会被列出的商品目录。
接下来是层级,它决定唯一在商业上重要的问题:这个智能体可以完成交易,还是必须把买家交还回去。Shopify 记录了三个层级,差别完全在于商家对调用者的身份了解多少。
| 层级 | 目录、购物车、结账工具 | complete_checkout |
订单工具 |
|---|---|---|---|
| 令牌(Token),具备购买权限 | 可用,且与买家关联的令牌会个性化搜索并应用自动折扣 | 可用 | 可用,需 read_global_api_orders,范围限于你的智能体下的订单 |
| 已签名(Signed) | 可用 | 不可用 | 不可用 |
| 匿名(Anonymous) | 可用 | 不可用 | 不可用 |
这张表里藏着两个运营细节。令牌层请求必须在每一次 tools/call 上携带 Shopify-Buyer-IP 头,包括只读调用;IP 缺失或无效会返回 HTTP 422,没有回退,也没有占位。已签名和匿名流量保留读取与准备的权利,但完全失去完成能力,还失去大部分限流额度。一个说不出自己是谁的智能体仍然可以浏览目录、构建购物车,而这正是商家愿意给出的信任水平。
Agent { # Agent
n1: circle label:"Call create_checkout with profile URI"
n2: rectangle label:"Publish platform profile over HTTPS"
n3: rectangle label:"Declare checkout and extensions"
n4: diamond label:"Negotiated set includes checkout"
n5: circle label:"Muse completes the order"
n6: circle label:"Prepare only and hand back"
n1.handle(right) -> n2.handle(left)
n2.handle(right) -> n3.handle(left)
n3.handle(bottom) -> Shopify.m1.handle(top) [label="meta.ucp-agent.profile"]
m4.handle(bottom) -> n4.handle(top) [label="Active capability set"]
n4.handle(bottom) -> n5.handle(top) [label="Token with permission"]
n4.handle(right) -> n6.handle(left) [label="Read only"]
}
Shopify { # Shopify business
m1: rectangle label:"Fetch and validate the profile"
m2: diamond label:"Protocol versions align"
m3: rectangle label:"Intersect capabilities"
m4: rectangle label:"Prune orphan extensions"
m5: circle label:"Return an error path"
m1.handle(right) -> m2.handle(left)
m2.handle(bottom) -> m3.handle(top) [label="Yes"]
m2.handle(right) -> m5.handle(left) [label="No"]
m3.handle(right) -> m4.handle(left)
}
你的接口必须满足的六项要求
语法是最容易的部分。下面六项决定这套集成能否活过第一个月,而每一项都是明文记录的,而不是推断出来的。
两个破坏性动词上的幂等性。 complete_checkout 与 cancel_checkout 要求在 meta["idempotency-key"] 中提供一个 UUID。一个遭遇网络超时的智能体并不知道订单是否存在,于是它重试;没有这个键,一次重试就变成第二笔订单。把该键当作意图的身份标识,而不是请求的标识:由结账会话加上意图推导它,在会话存续期间保留它,并在 429 之后重试时原样复用。
购物车用于迭代,结账用于承诺。 限流设计本身就是一条设计指令。购物车工具接受未认证请求,并以最高限额应答。结账工具在每个层级都被更狠地限流。把购物这一轮建立在购物车工具上,只有买家做出决定后才打开结账。
把升级当作一等答案。 一个结账携带 status 和一个 messages 数组,每条消息携带一个 severity。recoverable 意味着调用 update_checkout 并修正数据。requires_buyer_input 或 requires_buyer_review 意味着把 continue_url 交给买家。围绕这些严重级别写十二行代码,就替代了一个支持队列,而且其中没有一条是失败路径:3-D Secure、账户创建、年龄验证和会员门槛都以同样的方式到达,这是设计使然。
把价格、库存、运费和税费当作数据。 智能体无法谈判。每个响应都应当携带结账状态、版本或 updated-at 标记、币种,以及拆分为商品、运费和税费的总价。如果可售性或配送成本只存在于渲染后的页面里,结账会在最后一屏失败,而那时买家已经批准了一个总价。
诚实的身份,以及一个你能守住的层级。 说明调用者是谁,接受买家 IP 的要求,并按照你实际够格的层级来设计,而不是按路演材料里的那个层级。另一种结局是被封禁,Muse 在 Amazon 遇到的就是这件事。
一次扣款,有上限。 钱包路径发放一次性凭证,商家只扣一次。绝不存储智能体提供的凭证,也绝不授权买家没有看见过的金额。
状态生命周期值得单独一段,因为正是在这里,闸门从一个提示词里的段落变成了一种协议状态。
Agent { # Agent
d1: circle label:"Checkout session opened"
d2: rectangle label:"Fix missing data"
d3: diamond label:"Buyer review required"
d4: rectangle label:"Complete with the same key"
d5: circle label:"Order completed"
d6: circle label:"Session expired"
d1.handle(right) -> d2.handle(left)
d2.handle(right) -> d3.handle(left)
d3.handle(bottom) -> Buyer.f1.handle(top) [label="requires_buyer_review"]
f1.handle(right) -> f2.handle(left)
f2.handle(bottom) -> d4.handle(top) [label="Yes"]
f2.handle(right) -> f4.handle(left) [label="No"]
f4.handle(bottom) -> d6.handle(top) [label="Abandoned"]
d4.handle(right) -> d5.handle(left)
}
Buyer { # Buyer
f1: rectangle label:"Open continue_url and review"
f2: diamond label:"Buyer approves"
f4: rectangle label:"Buyer closes the page"
}
五个状态是 incomplete、requires_escalation、ready_for_complete、completed 和 canceled。只有 ready_for_complete 允许 complete_checkout。其他任何状态要么通过 update_checkout 修正,要么通过 continue_url 交给买家,而一个没人完成的会话会过期。在你写下第一行提示词之前,先用一个 switch 语句处理这五个词,因为我见过的这个领域每一宗生产事故,都是落进 default 分支的第六种情况。
continue_url 也有一些读起来像安全建议的规则,因为它确实就是。解析它,拒绝任何不是 HTTPS 的地址;不要要求主机名与你调用的端点一致,因为它完全可以合法地落在店铺的 myshopify.com 域名、其结账域名或 shop.app 上。只与那位买家分享,并且不要把它写进日志。
商品目录是不可信输入
一个智能体店铺读取的是别人写的文本:标题、描述、评论正文、配送备注,在市场平台上还有第三方卖家想输入的任何内容。这些文本进入模型的上下文,于是它成了一个挂着支付的注入面。
规则无聊且绝对。目录内容是数据,永远不是指令。在它进入模型之前标记为不可信,对它跑一遍分类器,剔除任何读起来像指令的内容,并在任何写入之前检查出站。Muse 分层实施这一点:外部数据标记为不可信,一组独立训练的注入分类器集成,以及即使模型被说服越界也依然成立的确定性边界。注意这套设计为何有效:这些层在模型之外。一句"忽略目录中的指令"的提示词指令,是攻击者同样能控制的第四层。
智能体付款的三种方式
支付通道决定了商家和智能体各自能看到什么,而每一套商家集成都应该知道自己站在哪条通道上。Muse 跑在 Link 上;Agentic Commerce Protocol 是 OpenAI 一侧的对应物,同一套闸门逻辑在那里以不同的名字重新出现。
钱包令牌。 Shop Pay 返回一个安全的一次性令牌。商家只扣一次,智能体始终看不到卡号。支持的币种包括 USD、CAD、MXN 和 EUR。
钱包虚拟卡。 Stripe Link 发放一张为获批购买注资的一次性虚拟卡,智能体把它输入商家普通的卡片表单,所以商家不需要任何专门的按钮。Link 为该卡注资到不超过精确总价五个单位之上的最大整数,这部分余量永远不会被扣。这就是为什么商家不必是 Link 商家也能被购买。
浏览器接管。 如果两条钱包路径都失败,或者买家有已存档的卡片,智能体交出浏览器,买家在商家页面上输入支付信息。扣款是真实的。流程依然受限:智能体转述商品、运费、总价和已保存的支付方式,然后等待明确的确认。
Agent { # Agent
p1: circle label:"Approval covers one purchase"
p2: diamond label:"Wallet rail available"
p3: rectangle label:"Mint a single-use credential"
p4: circle label:"Buyer types the card in the browser"
p1.handle(right) -> p2.handle(left)
p2.handle(bottom) -> p3.handle(top) [label="Yes"]
p3.handle(bottom) -> Merchant.q1.handle(top) [label="Credential"]
p2.handle(top) -> p4.handle(bottom) [label="No"]
}
Merchant { # Merchant
q1: rectangle label:"Verify merchant amount and method"
q2: rectangle label:"Charge once and issue receipt"
q3: circle label:"Payment settled"
q1.handle(right) -> q2.handle(left)
q2.handle(right) -> q3.handle(left)
}
什么先击倒了 Muse,以及什么会击倒你
有四类失败反复出现,没有一类是通常意义上的缺陷。
Muse 因身份被封。 亚马逊从 9 月 20 日那个星期日开始在其站点封禁 Muse,那是在发布十二天之后,也是 Patrick Wardle 的零日漏洞公开的同一个周末;Meta 在披露十二个多小时之后才发出热修复。亚马逊封禁的明面理由并不是这个漏洞。该智能体在浏览时没有表明自己的身份,而亚马逊事先也没有被告知 Muse 会访问其商店。亚马逊的原则是:代表客户购物的第三方应用应当公开运作,并尊重提供方是否愿意参与。如果你的接口说不出调用者是谁,就等着同样的回答,而且要快。
批准在买家行动之前就过期了。 十分钟对一次卡片点击很宽裕,对新设备上的一次 3-D Secure 挑战则偏紧。正确的做法是从复核重新开始,而不是复用那张过期的批准,并告诉买家原因。
协商会悄悄移除结账能力。 能力求交在剪掉你依赖的那项能力之前,一直是个好特性。对你实际收到的协商范围做埋点,与发布说明里的承诺做对比,并对差异告警。
浏览器路径会弹出一张没人预料到的同意卡片。 当智能体驱动真实浏览器并落到结账页面时,客户端可以发起自己的同意请求,独立于支付批准。有些团队把它读成双重确认,于是砍掉两者之一。两者都保留:一个属于客户端、覆盖站点,另一个属于支付、覆盖金额。
上线顺序
如果你这个季度要做商家侧,能扛住截止日期的那套顺序是这样的。
- 先发布业务档案和只读接口:先目录,再购物车。
- 让
complete_checkout和cancel_checkout幂等,并用同一个键对沙盒订单重放来证明它。 - 在你接受第一笔真实支付之前,返回带有可用
continue_url的requires_escalation。 - 对协商范围和实际收到的工具调用做埋点,然后与发布说明核对。
- 只有到那时才暴露结账完成能力,并且只在你守得住的层级上。
对 Shopify 商家来说,决定有一半已经替你做完了:通过 Meta 直接结账对符合条件的店铺默认开启,可以关闭,关闭之后买家只是被重定向到你的店铺页面。资格取决于你销售所覆盖的国家,加拿大在名单上。没有替你做的是那场内部对话:当买家从不访问你的站点时,你的退货政策、库存数据和履约承诺是否还站得住。
小结
- Muse 的闸门就是协议。 五个步骤,只有最后两步涉及资金,而花钱的权限绑定到一个商家、一个金额、一种支付方式,限期约十分钟。
- 商家侧是一份经过协商的合约,含四个能力族。 目录用于发现,购物车用于迭代,结账用于承诺,订单用于凭证。多数团队把中间两个搞反了,然后去怪模型。
- 大多数生产故障都是合约故障。 缺失的幂等、过期的批准、静默的能力剪除、说不出自己是谁的智能体,以及一个把
requires_escalation吞掉的 default 分支。
资料来源
- Meta, Introducing Muse (8 September 2026): https://about.fb.com/news/2026/09/introducing-muse-personal-ai-agent/
- Meta AI, Muse for Shopping: https://ai.meta.com/muse/shopping/
- Meta AI Research, How We Built Safety Into Muse: https://research.meta.ai/blog/security-and-safety-for-ai-agents-our-approach-with-muse
- Muse agent prompt corpus (leaked),
docs/payments-and-purchases.md: https://github.com/asgeirtj/system_prompts_leaks/tree/main/Meta/muse-agent - Shopify, Build commerce agents with UCP: https://shopify.dev/docs/agents
- Shopify, Cart MCP server: https://shopify.dev/docs/agents/carts-and-checkout/cart-mcp
- Shopify, Checkout MCP server: https://shopify.dev/docs/agents/carts-and-checkout/checkout-mcp
- Shopify, Agent profiles and UCP negotiation: https://shopify.dev/docs/agents/profiles
- Shopify, Auth and rate limiting: https://shopify.dev/docs/agents/profiles/auth-and-rate-limiting
- Shopify, Order MCP server: https://shopify.dev/docs/agents/orders/order-mcp
- Shopify Help, Selling on Meta: https://help.shopify.com/en/manual/online-sales-channels/agentic-storefronts/meta
- Universal Commerce Protocol specification: https://ucp.dev/
- Stripe Newsroom, Stripe helps Muse shop with Link (8 September 2026): https://stripe.com/newsroom/news/stripe-helps-meta-muse-shop-with-link
- Stripe Blog, Helping personal agents shop more intelligently and reliably with Link (29 September 2026): https://stripe.com/blog/helping-personal-agents-shop-more-intelligently-and-reliably-with-link
- Link, Protect your purchases: https://link.com/protections
- Ars Technica, Muse, Meta's extraordinarily privileged AI assistant, has a serious 0-day: https://arstechnica.com/security/2026/09/muse-metas-extraordinarily-privileged-ai-assistant-has-a-serious-0-day/
- Reuters, Meta bolsters Muse safety warning (25 September 2026): https://www.reuters.com/technology/meta-bolsters-muse-safety-warning-after-security-vulnerability-found-information-2026-09-25/
- CNBC, Meta Muse shopping: checkout, payments, privacy (3 October 2026): https://www.cnbc.com/2026/10/03/meta-muse-shopping-ai-agent.html
