电商 Agent 怎么搭?Claude 开源骨架拆解

关键词:Claude Commerce Agents、Anthropic、电商 Agent、SKILL.md、结构化工具调用、暂存变更、Backend 接口


目录


一、先说清楚:它不是能直接上线的产品

2026 年 9 月 2 日,Anthropic 在 GitHub 开源了 anthropics/commerce-agents,Apache 2.0 协议。它包含两个 Agent:购物 Agent(嵌在商家自己的店铺里给顾客用)和商家 Agent(给运营人员在后台用),外加零售、旅行、电信、票务四个可以真跑起来的垂直行业示例。

但有三件事必须先看明白,否则会误判这个仓库的价值:

第一,它是参考实现,不是产品。 Anthropic 明确说明不会把它当产品维护,也不接受外部贡献。这意味着 fork 之后就是自己的了——安全补丁、依赖升级、API 变更适配全得自己扛。

第二,整个仓库跑在一个虚构世界里。 所有公司、品牌、商品、人物都叫 ACME,demo 里没有任何一笔真实下单或真实扣款。这么做的目的是让工程团队能看清"骨架长什么样",然后照着同样的 prompt、技能、工具契约去接自己的系统。

第三,也是最容易被误读的一点:它不含支付,不含结算,不含广告层。 购物 Agent 能做的是搜索、比较、规划、组购物车、回答订单和政策问题,到结算环节就交还给商家自己的收银台。所以任何人把它理解成"全自动无人店铺",都是在想象一个没有发布的东西。

把这三件事想清楚,这个仓库的正确用法也就清楚了:照抄它的工程结构,替换掉它的数据和后端


二、从目录结构读设计意图

先走读一遍仓库结构。整体拆成七个 pip 包,公共部分 commerce-common 之外,两个 Agent 各有 core / runtime / SDK 三层——Agent 逻辑与传输层是分开的,这是它能同时跑在 Messages API、Claude Agent SDK、Managed Agents 三条路径上的原因。

结构示意(以官方仓库为准):

commerce-agents/
├── commerce-common/          # 共享:工具契约、护栏、类型
├── shopping-agent/
│   ├── core/                 # Agent 定义:prompt + skills + tools
│   ├── runtime/              # 运行时适配(API / SDK / Managed)
│   ├── sdk/
│   └── skills/               # 五个业务技能
│       ├── search-discovery/        # 商品发现与搜索
│       ├── purchase-research/       # 购买研究与比较
│       ├── planning-goals/          # 购物目标与计划
│       ├── customer-care/           # 订单与政策问答
│       └── memory-personalization/  # 记忆与个性化
├── merchant-agent/
│   ├── skills/
│   │   ├── performance-insights/    # 经营分析
│   │   ├── catalog-listings/        # 商品目录
│   │   ├── inventory-operations/    # 库存运营
│   │   ├── pricing-promotions/      # 定价与促销
│   │   └── marketing-campaigns/     # 营销活动
│   └── ...
├── examples/                 # 四个垂直行业的可跑示例
│   ├── retail/  travel/  telecom/  entertainment/
├── plugins/claude-code/      # Claude Code 插件
└── scripts/run_demo.py

图一:整体分层架构

在这里插入图片描述

(图一:业务能力外置到 Skills 和 Backend,模型只负责理解与规划)

从目录能读出三个设计意图:

意图一:业务能力是文件,不是代码里的分支。 十个业务技能各是一个目录,里面是 SKILL.md——描述流程、规则、要用哪些工具。改一个业务流程等于改一份 Markdown,不用动 Agent 主逻辑,也不用重新训练任何东西。

意图二:Agent 定义只写一次。 同一份 prompt + skills + 工具契约能跑在三条不同的运行路径上,不需要为每种部署方式重写一遍。

意图三:示例必须能跑。 四个垂直行业 demo 用虚构数据但真实可运行,这让团队在决定投入前能先看到"这东西跑起来是什么样",而不是对着文档猜。

跑起来的门槛不高:Python 3.11+、Node 22、一个 API key。

git clone https://github.com/anthropics/commerce-agents.git
cd commerce-agents
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env          # 填 ANTHROPIC_API_KEY
(cd examples && npm ci)
python scripts/run_demo.py retail          # API :8000 + 店铺前端 :3000
python scripts/run_demo.py retail --merchant  # 改成起后台门户

一次完整交互长什么样

跑起来之后,购物 Agent 处理的是自然语言需求,中间不需要人在菜单里点选:

用户:我要一顶帐篷、一个睡袋和一个炉子,周末带两个孩子去,预算 3000 以内。

Agent 会自己走完这么一段:先做商品发现,按"帐篷 / 睡袋 / 炉子"三类分别检索并用人数、季节、预算过滤;然后进购买研究,把候选按重量、容量、适用温度横向比较,找出互相冲突的项(比如三件都选高端款会超预算);接着做计划与目标,给出两套组合方案让用户选;用户选定后组装购物车;期间如果用户问"这个能退吗",走客户服务流程去查退换政策;最后用户说过"两个孩子"这类信息会被记忆下来,下次对话不用重复交代。

关键在于这五段流程是在同一个 Agent 的同一段上下文里连续完成的,不是五个服务互相调。这就是为什么它坚持不拆子 Agent——上面这个例子里,预算余额、已选商品、孩子人数、政策答复,每一轮都在被交叉引用。


三、Backend 接口:边界全写在方法签名里

这个仓库里我认为最值得抄的一段设计,是它没有把商品、库存、订单逻辑硬编码进 Agent,而是定义了一套 Backend 接口让企业接自己的系统。

图二:Backend 接口与边界

在这里插入图片描述

(图二:能碰什么、碰不到什么,全在方法签名里写死了)

顾客侧要实现的 StorefrontBackend14 个方法的接口,覆盖目录、搜索、库存、购物车、订单、配送政策、退换政策这些:

class StorefrontBackend(Protocol):
    # 结构示意,字段与方法名以官方仓库为准
    def search_products(self, query: str, filters: dict) -> list[Product]: ...
    def get_product(self, product_id: str) -> Product | None: ...
    def check_inventory(self, product_id: str) -> Inventory: ...
    def get_cart(self, session_id: str) -> Cart: ...
    def add_to_cart(self, session_id: str, product_id: str, qty: int) -> Cart: ...
    def update_cart_item(self, session_id: str, item_id: str, qty: int) -> Cart: ...
    def remove_from_cart(self, session_id: str, item_id: str) -> Cart: ...
    def get_orders(self, customer_id: str) -> list[Order]: ...
    def get_shipping_policy(self) -> Policy: ...
    def get_return_policy(self) -> Policy: ...
    # ... 共 14 个

后台侧的 MerchantBackend 接销售分析、目录、库存、定价、促销、营销系统。

这个设计解决的是一个很实际的问题:价格、库存、促销条件这类实时数据,如果让模型从上下文里"回忆",它一定会过时或编造。 现在这些数据全部由企业系统提供,Agent 只负责理解需求、规划步骤、调用接口。

还有一层好处:接口即契约。14 个方法划出了 Agent 能做的事情的全集——没在接口里出现的能力,Agent 就做不到,这比在 prompt 里写"你不许做 X"可靠得多,因为它是类型系统层面的约束,不是自然语言层面的恳求。


四、为什么不拆成多个 Agent?

现在业界的默认动作是"复杂任务拆成多个子 Agent"。这个仓库明确选择不拆,而且给了理由。

用户说一句"我需要一顶帐篷、一个睡袋和一个炉子,周末带两个孩子去",Agent 会自己走完搜索、研究、规划、加购,中间不路由给任何子 Agent,全部在一个「推理 / 行动 / 观察」循环里完成。

工程上的理由是:购物车状态、顾客偏好、订单历史、商品数据这四者耦合得太紧。拆开之后,每跨一个 Agent 就要传一次状态,既丢上下文,又成倍放大 token 消耗和响应延迟。

图四左:单 Agent 决策

在这里插入图片描述

(图四:不拆 Agent,以及同一份定义跑三条部署路径)

这里我想补一句:这个结论不是通用的,是有前提的

它成立的条件是"状态高度耦合、且需要跨轮次互相引用"。反例就在这个仓库自己身上——它把前台和后台拆成了两个独立 Agent,因为两者的读写边界、审批链、风险等级完全不同,几乎不共享状态。

所以能提炼出来的规则不是"别用 multi-agent",而是:

按状态耦合度切分,不按功能域切分。

很多团队的做法恰好相反:按"搜索 Agent / 推荐 Agent / 客服 Agent"这种功能划分去切,然后再花大力气在中间传上下文。判断标准其实很简单——如果两件事需要频繁引用同一份状态,它们就该在同一个 Agent 里;如果它们之间只需要传一个明确的输入和输出,那就可以拆。


五、商品卡片不是模型生成的 HTML

电商 Agent 有个绕不开的问题:怎么把商品展示给用户?

最直觉的做法是让模型生成 Markdown 商品列表,或者直接吐 HTML。这个仓库明确否掉了这条路——商品卡片、比价网格、购物车面板、行程、座位图,全部是类型化的工具调用(typed tool call),由服务端校验并填充真实记录。

{
  "tool": "render_product_cards",
  "args": {
    "product_ids": ["sku_10231", "sku_10455", "sku_10890"],
    "layout": "grid",
    "highlight": "battery_life",
    "caption": "三款都支持 12 小时以上续航"
  }
}

前端拿到的是结构化数据,用固定组件渲染。这样做有四个直接好处:

第一,参数能校验。 product_ids 必须是真实存在的 SKU,服务端一查就知道。模型没法凭空编一个商品出来——它编的 ID 在服务端过不了。

第二,UI 一致性有保证。 卡片长什么样由前端组件决定,不受模型当次输出风格影响。不会出现今天一个样式明天一个样式。

第三,这次的工具调用会进入会话上下文。 于是下一轮模型可以说"左边第三个",而这句话能被解析成真实的商品 ID——因为上一轮渲染时用的 ID 就在上下文里。

这个能力值得展开讲,因为它是结构化方案和生成式方案最本质的差距。看一段真实会发生的对话:

用户:给我看几款续航长的笔记本。
Agent:(调 render_product_cards,ids = [A, B, C, D]
用户:左边第三个有货吗?
Agent:(调 check_inventory,id = C

"左边第三个"能被正确解析,是因为上一轮的 product_ids: [A, B, C, D] 连同 layout 参数都在上下文里,模型能按渲染顺序推出第三个是 C

如果换成生成 Markdown 的方案会怎样?模型输出的是一段文本,商品以标题和描述的形式存在。用户说"左边第三个",模型只能靠文本顺序去数——而一旦中间插了推荐语、分隔符、或者某款商品因为缺货被跳过,这个"第三"就数错了。更要命的是,即使数对了,它手上拿到的也只是一个商品名,还得再去查一次 ID,多一次出错机会。

所以电商场景里"指代能不能落实"不是体验细节,是能不能正确下单的问题。这也是为什么仓库宁可多定义一层 tool contract,也不让模型直接生成展示内容。这种指代消解在纯 Markdown 方案里几乎做不了。

第四,可审计。 每一次展示都有结构化的记录,事后能查"这个用户当时看到了什么"。

对电商这种"展示错了要担责"的场景,这四点比"生成得快"重要得多。顺带说一句,这也是当下 Agent 工程的一个共识方向:让模型决定"展示什么",但不要让它决定"怎么渲染"。


六、结算 URL 为什么不让模型看到?

这是整个仓库里我觉得设计得最精巧的一处。

支付环节的做法是:Agent 调用结算工具,工具渲染购物车,后端把结算 URL 直接返回给宿主应用(店铺前端),模型从头到尾看不到这个 URL

注意这个设计的力度。它不是"不给模型支付工具"这种粗粒度限制——粗粒度限制下,如果 URL 曾经出现在上下文里,模型仍有可能在后续对话中复述、修改或替换它。而这里是连 URL 都不让它进上下文

它防的是两类风险:

  • 模型自身出错:哪怕没有恶意,模型也可能在复述 URL 时截断、拼接错误,导致用户被导向错误页面。
  • 提示注入:如果商品评论、商品描述、或者用户粘贴的文本里藏了诱导指令,模型可能被引导去替换跳转地址。URL 不在上下文里,这类攻击就失去了着力点。

这里我想指出它的边界:这个设计防的是"模型篡改 URL",不防另外两类问题——后端本身有漏洞,或者宿主渲染层被污染。也就是说,它把风险收窄到了模型这一环,但其他环节的安全仍然是接入方自己的责任。

另外要提醒一句:仓库里的示例没有认证,MCP 服务绑定在 loopback 上。这是刻意的实验室姿态,不是生产配置。要上生产,认证和网络控制得自己补一整套。


七、改价这种操作,凭什么不能直接写库?

后台 Agent 涉及改价格、改库存、改商品信息、发营销活动——这些操作一旦出错,直接影响营收。

仓库的做法是 staged change(暂存变更):Agent 不直接写生产库,而是先生成一个待审批的变更,等人批准或丢弃。

图三:暂存变更流程

在这里插入图片描述

(图三:护栏在暂存时和落库前各跑一次,中间是人的审批)

流程是五步:Agent 生成变更 → 进暂存队列 → 护栏第一次校验 → 人批准或丢弃 → 护栏第二次校验 → 才落库。

护栏检查的项包括:单次变更的条目数、促销折扣上限、改价幅度限制、补货数量、活动预算、以及受保护字段(比如不允许改商品的成本价)。

为什么护栏要跑两次?

这是很容易被忽略但很关键的一点:暂存和落库之间存在时间窗。

举个例子:Agent 上午 10 点提议"给 SKU-123 补货 50 件",当时库存是 5,这个提议合理。运营下午 3 点才批准,这中间已经卖出去 30 件、别的同事也补了 20 件。如果直接用上午的参数执行,就会超补。

第二次校验防的正是这个时间窗。 落库前重新检查一遍当前状态和护栏条件,通不过就不写。

我的保留意见:审批在规模下会退化

这套机制是大多数 Agent demo 会跳过的纪律,值得抄。但我对它在真实规模下的有效性有保留。

一天 20 个改价,运营会认真看每一个;一天 500 个,人会开始无脑点"全部批准"。这时候 staged change 就从安全机制退化成了责任转移机制——出了事有审批记录可查,但实际上没人真的在审。

真要落地,我觉得得配两样东西:

  • 按变更幅度分级:改价 3% 以内自动通过,超过阈值才拦人。让人的注意力花在真正高风险的地方。
  • 抽检 + 事后审计:不追求 100% 事前拦截,改用事后抽查加全量留痕。

单纯"所有变更都等一个人点按钮",撑不住规模。

分析委托:给数据切片能力,不给写权限

还有一个设计值得一提。后台经常需要"帮我看一下华东区上个月滞销的 SKU"这类分析需求,如果为了这个给模型开数据库写权限,风险太大。

仓库的做法是设一个只读的分析委托:给一份简报和只读工具,让一个分析过程返回单个经过 schema 校验的结果——一条 SELECT 语句,不允许注释,限制返回行数和字符数,并有 wall-clock 时间预算

这样运营能拿到想要的数据切片,而模型对数据库没有任何写权限。


八、记忆与 eval:两个最容易被漏看的部分

这两个模块在介绍里往往一笔带过,但它们决定了这套东西能不能长期跑。

记忆:分层的,且提取是异步的

顾客侧的长期偏好(尺码、品牌偏好、常用配送方式、门店)存在企业自己的记忆库里,分三层:

  • 高频信息直接进上下文(比如已知尺码);
  • 当前任务相关信息提前检索;
  • 低频信息通过记忆工具按需查询。

关键设计是提取用异步的小模型单独跑。主对话保持便宜,对话结束后另起一趟用轻量模型从对话里抽新事实、更新长期记忆。Anthropic 公布的 Commerce Memory Eval 数据显示,异步提取让事实召回率提升 13%——注意这是官方自测数据,不是第三方复现结果。

从工程角度看,异步提取的价值在于它把"记忆维护"的成本从主链路摘出去了,不会拖慢用户正在进行的对话。

Eval:authoring pattern 比 eval 结果更重要

仓库里带的是一套 eval 编写范式,而不仅是一组跑分。对电商这种流程固定的场景,eval 要覆盖的不只是"答案对不对",还包括:

  • 该调的工具调了没有、参数对不对;
  • 多轮对话里状态有没有串;
  • 遇到库存不足、政策冲突这类边界情况,处理是否符合业务规则;
  • 结构化 UI 的 tool call 参数是否合法。

我认为这套 eval 编写范式比仓库里的具体跑分更值得抄,因为后者是针对虚构 ACME 数据调出来的,换到真实业务上就得重做;而前者是方法论,能直接迁移。


九、在 AI 大模型开发里的四个落点

落点一:把业务流程从代码搬到 SKILL.md

这一条不局限于电商。任何"多步骤、有明确流程、需要频繁调整"的业务,都可以把流程外置成 SKILL.md,让 Agent 按需加载。

一份技能文件大致长这样(结构示意,字段以官方仓库为准):

skills/purchase-research/
└── SKILL.md

---
name: purchase-research
description: 用户已有多件候选商品、需要横向比较或确认是否适配时使用
tools: [compare_products, check_inventory, get_return_policy]
---

【触发条件】
用户已经看过商品、开始问「这两个哪个好」「哪个更轻」时进入本流程。

【执行流程】
1. 确认比较维度;用户没说就按历史偏好推断,并明确告知用了什么维度。
2. 调 compare_products,一次不超过 4 款。
3. 遇到缺货或价格冲突,先说明再给替代方案,不要静默替换。
4. 结论给出推荐 + 理由 + 取舍,不只给排序。

【硬性约束】
- 价格、库存一律以工具返回为准,不得凭上下文推测。
- 不得替用户做最终决定。

这份文件里藏着三个值得注意的做法:

description 字段是路由依据。 Agent 靠它判断当前该加载哪个技能,所以这里写的是"什么时候用"而不是"这个技能做什么"。很多团队写反了,导致技能该触发时不触发。

约束写在文件里,不写在主 prompt 里。 "价格以工具返回为准"这类规则跟着技能走,技能不加载这条规则就不生效——既省上下文,又避免规则互相打架。

技能是可版本化的资产。 改一次比较逻辑等于改一个文件,可以 review、可以回滚、可以 A/B。这是它相对"把规则塞进主 prompt"的最大优势——主 prompt 一旦堆了十几条互不相干的规则,改任何一条都要冒影响其他流程的风险。

好处总结起来就是:改流程不用发版、不用重训,而且技能和主逻辑解耦。这也是当下 Agent 工程的主流路径:改行为,不改权重。

落点二:用接口划边界,而不是用 prompt 恳求

很多团队的 Agent 安全策略是写在 prompt 里的"你不许做 X"。这个仓库给出的示范是:把允许的操作定义成接口,接口之外的事情模型根本调不到。

类型系统层面的约束比自然语言层面的叮嘱可靠得多。如果你在做任何带写权限的 Agent,这一点值得优先照搬。

落点三:给模型开只读通道,而不是给写权限

分析委托那个设计(单条 SELECT、禁注释、限行数、有时间预算)是个可以泛化的模式:当用户的需求是"看数据"时,给一条严格受限的只读通道,而不是开写权限再靠护栏去拦。

这个顺序很重要。很多系统的做法是"先给完整权限,再用规则去拦危险操作"——这条路的问题是规则永远有漏网的。反过来做,默认不给,只在明确需要的场景开一条最小的缝,漏网的空间就小得多。而且那三个限制(禁注释、限行数、时间预算)各自针对一类真实风险:禁注释防的是注释里夹带额外语句,限行数防的是拖垮数据库,时间预算防的是一条烂查询把服务卡死。

同样的思路可以用在日志查询、报表生成、监控数据检索等场景。

落点四:结构化输出优先于生成式输出

商品卡片用 typed tool call 而非生成 HTML,这个原则适用于所有"输出要被下游系统消费"的场景。模型决定内容,代码决定形式,中间用结构化契约连接。

判断口径:如果这份输出错了要担责(价格、库存、合同条款、医疗建议),就用结构化;如果只是聊天,那生成式没问题。

关于那几个效果数字

Anthropic 公布的数据是:Agent 组出的购物车金额最高提升 35%,购买完成率最高提升 60%,小商家通过 Agent 销售转化提升 40%,以及生产部署的 prompt cache 命中率能到 90%~99%。

这些数字该怎么看?三点提醒:

  • 全部是 Anthropic 自报,没有对照组、没有样本说明、没有行业细分;
  • "最高"是挑选过的结果,不是平均值;
  • "购物车金额 +35%"这个指标本身有歧义——它可能来自推荐了更贵的商品,不等于用户更满意。要判断真实价值,应该看退货率、复购率、客诉率。

我的建议是:这些数字可以用来判断"值不值得做个实验",不能用来签业务case。


给你的落点:这套骨架到底能直接用吗?

拆完这些,给个直接的判断。

能直接用、值得抄的:

  • Backend 接口的分层思路。用接口划 Agent 边界,比在 prompt 里写禁令可靠得多,这个可以直接照搬。
  • staged change + 双重护栏。尤其是"落库前再校验一次"这个细节,很多团队会漏,而它防的是真实存在的时间窗问题。
  • 结构化 UI 的 tool contract。输出要被下游消费时,typed tool call 是比生成 HTML 更稳的选择。
  • 三条运行路径共用一份 Agent 定义。如果你也在做多平台部署,这个分层方式省事。
  • eval 编写范式。方法论可迁移,比具体跑分有用。

要自己重做、指望不上的:

  • 认证与网络控制。示例里没有认证、MCP 绑 loopback,上生产必须自己补全套。
  • 长期维护。官方不维护、不收 PR,API 变更和安全补丁都得自己跟。
  • 支付与结算。仓库里本来就没有,得接自己的收银台。
  • 真实业务的数据与规则。四个 demo 都是虚构 ACME 数据,接自己的目录和政策才是主要工作量。

三个最该记住的判断:

  1. 按状态耦合度切分 Agent,不按功能域切分。 需要频繁共享状态的就放一起,只有明确输入输出关系的才拆开。
  2. 让模型决定"是什么",让代码决定"怎么渲染"和"能不能写"。 内容归模型,形式与安全归代码。
  3. 暂存审批要配分级和抽检,否则规模一大就会退化成橡皮图章。 有审批记录不等于有人真在审。

最后一点观察:这个仓库真正的价值,不在于"Anthropic 也做电商了",而在于它把一批原本停留在经验层面的工程选择——为什么不拆 Agent、为什么 URL 不给模型、为什么写操作要暂存、为什么卡片要用 tool call——全部写成了带理由的代码

对做 Agent 开发的人来说,读一遍这些决策记录,可能比跑一遍 demo 收获更大。

#ClaudeCommerceAgents #Anthropic #电商Agent #SKILLmd #结构化工具调用 #暂存变更 #Agent工程

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐