关于 commerce-ui-tools
为购物与商家 Agent 定义结构化展示工具及其数据验证、丰富和流式事件契约。适合构建由会话记录数据驱动的界面组件,并支持扩展垂直领域组件。
主要功能
- 01验证并丰富展示组件数据
- 02从会话记录关联事实
- 03流式发送 UI 与部分 UI 事件
- 04提供建议提示芯片
- 05支持扩展展示组件
适用场景
- 01展示商品、对比和订单状态
- 02呈现商家指标与变更预览
- 03在工具参数到达时逐步渲染界面
- 04为旅行或电信场景添加定制卡片
MCP 相关
文档提及 MCP 服务可采用扩展工具集或自定义 executor 接入展示扩展;这些服务不会添加 status 参数。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ anthropics/ commerce-agents --skill commerce-ui-tools安装后在 Claude Code 中输入/commerce-ui-tools确认已加载。
详细介绍
展示工具
参考仓库中的路径:commerce_common/ 对应 commerce-common/commerce_common/,shopping_agent/ 对应
shopping-agent/core/shopping_agent/,merchant_agent/ 对应 merchant-agent/core/merchant_agent/。
契约
- 组件就是一种工具。模型的参数承载其判断:使用哪些 ID、顺序如何、每项的理由或备注,以及比较哪些内容。服务端会从本轮工具返回的记录中汇总所有事实(标题、价格、图片、指标值、变更记录),因此前端绝不会渲染模型编造的值。
- 每个组件都有一份规范:
commerce_common/presentation.py中的PresentationComponent指定工具名称、宿主渲染的component字符串、用于验证参数的payload_model(每个角色的tools/presentation.py),以及enrich钩子(每个角色的enrichment.py,汇总在PRESENTATION_COMPONENTS中)。 commerce_common/presentation.py中的run_presentation是唯一的运行器:验证、补充数据并发送ui事件。模型会读取执行器的displayed_text和钩子的备注;补充后的负载仅发送给宿主。- 补充数据钩子会丢弃没有来源依据的 ID,并附加注明这些 ID 的备注;如果没有剩余内容,就会引发
PresentationRefused,若其中指定了门控,则作为被挂起的调用返回,否则作为错误返回。 - Shopping 会从
ShoppingSessionState.seen_products、购物车或订单读取中汇总数据;merchant 会从MerchantSessionState.latest_snapshot、seen_series、seen_campaigns、seen_analyses、seen_listings和seen_changes汇总数据。enrich_change_preview还会移除货币或星期与变更记录不一致的模型文本。 - 组合规则(哪个组件结束回合、文本承载推理、卡片承载数据)是静态提示词材料;每个组件的使用时机说明是其工具描述(commerce-architecture 的层级表)。
建议
present_suggestions是唯一承载本回合快捷选项的工具,最多四条;模型会在本轮最后一个组件的同一轮中调用它,若本轮没有组件,则在文本之后调用。点击的快捷选项会作为下一条用户消息发送。其他任何负载,无论内置还是扩展,都不承载快捷选项。commerce_common/fencing.py中的sanitize_suggestion_chips会处理PresentSuggestionsPayload:移除不可见字符和控制字符、合并空白、删除空项,每条最多 80 个字符,最多四条。如果清理后没有剩余快捷选项,负载验证会失败。- 包含
present_suggestions的一轮干净展示调用会结束回合(commerce_common/turn.py中的round_closes_turn,配置中的close_on_presentation):Messages API 循环会在此处停止,Agent SDK 运行时则通过PostToolBatch钩子(close_on_presentation_hook,位于commerce_common/agent_sdk.py)停止。在宿主审批模式下,merchant 提示词会说明快捷选项不会批准或应用任何内容。
流式传输
事件列表见 commerce_common/streaming.py 的文档字符串;to_sse 会为每个事件添加帧,宿主会忽略不认识的类型。ui 携带一个补充数据后的组件,ui_partial 在其调用仍处于流式传输时携带同一组件,cart_update 在购物车写入后携带整个购物车,change_update 在变更移动后携带一条变更记录。commerce_common/turn.py 中的 outcome_events 会将每个 ui 事件标记为带有其调用 ID 的 stream_id,并在其后附上 tool_result,其 status 为 ok、error 或 blocked。任何非展示工具都可以将 status 作为第一个参数(commerce_common/execution.py 中的 with_status):几句给等待者看的简短说明,执行器会在调用运行前将其移除,运行时则将其作为 tool_call 事件的 label 发出;Web 层会将其显示为活动状态行。MCP 服务会在不带此参数的情况下构建工具。Agent SDK 运行时会运行同一个执行器,但会在回合结束后将各负载一并返回到 result.ui。
渐进式渲染
带有 enrich_partial 钩子的规格会在参数到达时渲染:请求会将其工具标记为
eager_input_streaming(在 commerce_common/prompt_assembly.py 中使用 with_eager_input),编排器使用
parse_partial_json 解析缓冲区(仍在写入的字符串会连同其键一起略过),调用 enrich_partial
(commerce_common/presentation.py),并在 partial_signature 发生变化时生成 ui_partial(commerce_common/turn.py
中的 StreamedRound.frame;配置启用 eager_partial_frames 时,每次可见变化都会生成);最终的 ui 事件
携带相同的 stream_id 并替换它。以非 JSON 文本形式流入的输入会以错误结果返回给模型,本轮随后继续
(StreamedRound)。部分
钩子是同步的,且只会从会话状态中汇集信息(shopping_agent/enrichment.py 中的 partial_products、partial_comparison、partial_plan、
partial_guide;merchant_agent/enrichment.py 中的 partial_metrics、partial_digest、partial_change_preview)。
内置组件
- Shopping(
shopping_agent/enrichment.py):present_products、present_comparison、present_plan、present_guide、present_order_status、checkout(渲染购物车;不扣款)、present_suggestions和present_disclosure; 仅在启用enable_disclosures时注册,内容通过StorefrontBackend.get_disclosure填充。 - Merchant(
merchant_agent/enrichment.py):present_metrics、present_digest、present_change_preview、present_suggestions。
添加垂直领域组件
- 构建一个
PresentationExtension(commerce_common/presentation.py):模型可见的工具描述和input_schema、 用于验证相同形状的payload_model、component名称,以及 enrich 钩子。 - 将其作为
extra_presentation_tools传入ShoppingAgent或MerchantAgent(examples/travel/api/main.py);在 Agent SDK 和 MCP 路径中,可为工具集创建子类,或传入executor_class=,以便执行器将其作为extensions接收。build_tools会拒绝与内置工具名称冲突的名称, 而扩展的字节会加入缓存的工具列表(commerce-prompt-caching)。 - 仓库中的七个组件:
examples/travel/api/itinerary.py、examples/travel/api/occupancy.py、examples/telecom/api/plan_matrix.py、examples/telecom/api/plan_mix.py、examples/entertainment/api/venue_map.py、examples/entertainment/api/hold_view.py、examples/entertainment/api/event_pacing.py。每个组件都在垂直领域中保留自身的类型 和卡片;核心包中不会添加任何内容。