关于 commerce-prompt-caching
为购物与商家 Agent 提供稳定组装提示词请求的技能,通过区分静态内容、动态上下文和滚动消息断点来减少缓存失效。适合维护相关运行时及排查提示词缓存命中问题。
主要功能
- 01静态提示词与动态上下文分离
- 02工具列表固定排序
- 03滚动消息缓存断点
- 04压缩历史工具结果
- 05提供缓存命中验证方法
适用场景
- 01减少每轮请求的提示词前缀变化
- 02排查对话缓存读取率下降
- 03配置购物与商家 Agent 的提示词组装
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ anthropics/ commerce-agents --skill commerce-prompt-caching安装后在 Claude Code 中输入/commerce-prompt-caching确认已加载。
详细介绍
缓存稳定的请求组装
commerce_common/ 是 commerce-common/commerce_common/,shopping_agent/ 是 shopping-agent/core/shopping_agent/,而
merchant_agent/ 是 merchant-agent/core/merchant_agent/。
三个断点
请求中可缓存的前缀依次为 tools、system 和消息;断点会结束一个跨度,供下一次调用读回。参考 Agent 在 commerce_common/prompt_assembly.py 中设置了三个断点:
- 最后一个工具:
with_tool_cache_control(tools)。 - 静态系统文本:
build_system_blocks(static, context)为其标记,并追加未标记的上下文块。 - 最新的持久化消息:
build_request_messages(messages, rolling_breakpoint=...)只在发出的请求中标记最后一个持久化块;这样,下次调用便能从缓存读取更早的轮次,包括搜索载荷。
每个请求的数据都放在上下文块中,该角色的 build_dynamic_context(...) 会在每个轮次渲染一次。若把这些字节放入静态块或工具列表,每个请求都会打断系统或工具跨度;放在上下文块中,则只会在购物车、页面或事实发生变化的轮次重新读取一次对话,而滚动标记会从该轮次的下一轮开始生效。时钟按小时渲染(context_clock),因此分钟变化不会造成任何改变。
实际实现的拆分方式
- 每个角色的
prompt.py中的build_static_system(config, skills)会根据配置和已安装的技能渲染身份信息、最大轮次数规则、围栏说明和技能索引:在一次部署的整个生命周期内,这些字节都保持不变。 - 同一模块中的
build_dynamic_context(...)会在该角色的数据围栏内渲染每个请求所需的内容:购物 Agent 使用偏好、记忆事实、购物车、页面、账户块和时间;商家 Agent 使用商店上下文、记忆事实和时间。后端上下文块各自有大小上限。 ShoppingAgent.__init__和MerchantAgent.__init__(分别位于各角色的runtime-messages-apiorchestrator.py中)会在每个进程启动时构建_static_system和_tools;stream_turn会在每个轮次渲染上下文块,并在每次模型调用时调用build_request_messages。- 每个角色的
tools/registry.py中的build_tools会按固定顺序输出内置工具(商家构建器在启用时会在这些工具之后添加run_analysis),接着是按排序排列的load_skill枚举,然后是按给定顺序排列的扩展,最后是在启用时添加web_search;每个已注册的工具都会随每个请求一同发送,执行器会在收到调用时判断是否能够处理。 - Agent SDK 运行时会传递相同的静态文本(以及
SKILL_TOOL_ADAPTER)和相同的契约,并由 SDK 缓存;托管清单将这些文本存放在system.md中,scripts/check.py会将其与构建器进行比较。
跳过滚动标记的情况
有两种轮次不带标记。第一种是纯粹的首次调用(只有一条消息):一次性会话会付出写入成本,却没有后续读取,而第二次调用的标记无论如何都会覆盖第一条消息。第二种是 tool_choice 不为 auto 的轮次(被强制要求进行检索的首轮迭代,以及被强制要求输出文本的最后一轮):tool_choice 是消息跨度的键,因此,在强制轮次下写入的条目无法被之后的自动轮次读取;系统和工具跨度仍然可以命中缓存。这两种情况都由 build_request_messages 和循环中的 rolling_breakpoint= 参数处理;rolling_conversation_cache 可在调试时关闭该标记。
对话被压缩时
当某一轮最后一次调用的使用量达到或超过 compact_history_above_tokens(该轮的 usage 会显示;默认值为平台自身的工具结果清除默认值,即上下文窗口的十分之一)时,这一轮会在 commerce_common/turn.py 中以 compact_history 结束。它会将存储对话中最旧的工具结果替换为一行标记,直到对话缩短至原来大小的一半。下一轮的第一轮处理会重写一次消息片段,之后的轮次则读取较短的版本;turn_complete.results_cleared 会告知会追加其记录文本的宿主需要重写。系统和工具片段、消息以及写入门控不受影响;来源信息保存在会话状态中。
会占用提示词字节数的配置字段
commerce_common/config.py 和各角色配置中标记为 (prompt) 的字段,以及商家工具构建器读取的 enable_analysis 和 max_items_per_change,都会渲染为静态文本或工具列表;更改其中任何一项都需要重新部署,并会导致下一次请求未命中:
| 配置 | 字段 |
|---|---|
BaseAgentConfig(commerce_common/config.py) | brand_name、assistant_name、brand_voice、enable_web_search |
ShoppingAgentConfig(shopping_agent/config.py) | domain_search_notes、enable_disclosures,以及系统开关 enable_cart、enable_orders、enable_policies、enable_fulfillment |
MerchantAgentConfig(merchant_agent/config.py) | enable_analysis、require_host_approval、approval_surface、stage_shows_preview,以及系统开关 enable_listing_edits、enable_inventory、enable_pricing、enable_campaigns;max_items_per_change 和 max_search_results 用于设置工具架构中的 maxItems 和 maximum |
技能、呈现扩展和委派对象也会占用提示词字节数。门控词典、护栏限制、记忆设置、延迟参数(eager_tool_dispatch、rolling_conversation_cache、eager_partial_frames、close_on_presentation)、购物车上限和 compact_history_above_tokens 则不会;tests/test_role_registries.py 会逐项断言这一点。
哪些情况会导致未命中
- 静态区块或工具列表中的任何逐请求变化内容:名称、购物车数量、页面、时钟、请求 ID。上下文区块会包含前四项;请求 ID 不应出现在任何位置。
- 将集合或字典写入提示词文本或工具架构时未排序。
- 按请求决定
tools[]的成员(而不是在构造时读取一次标志)。 - 在轮次内部而非构造函数中重新构建静态文本或工具列表。
- 将滚动标记持久化到存储的对话中,导致每轮都增加一个标记。
- 在运行中的部署上切换
(prompt)字段、技能或扩展;每项变更都需要重新部署。 - 按请求而非按部署选择提示词变体。
- 前缀短于模型可缓存的最小长度,因此不会写入任何内容。
- 强制指定
tool_choice(先 grounding,最后none)只会导致消息片段未命中;循环会在该处跳过标记。
验证方法
turn_complete会携带usage(即commerce_common/turn.py中的usage_totals,为该轮各次调用的总和)和elapsed_ms;每次调用也会记录一行日志,其中包含相同的计数器以及该次调用耗时(log_model_call,位于shopping_agent_runtime.orchestrator和merchant_agent_runtime.orchestrator中)。如果对话第二轮的缓存读取量为零, 就意味着前缀发生了变化。每个配置版本值得绘制图表的指标包括:缓存读取量占输入的比例、elapsed_ms、每轮的轮数,以及按门控统计的被阻止的tool_result事件。tests/test_role_registries.py会分别构建每个角色的提示词和工具两次并比较字节内容、检查缓存标记, 还会检查非提示词设置不会造成任何变化;commerce-common/tests/test_prompt_assembly.py涵盖区块构建器、上下文时钟、 滚动标记和跳过情形;tests/test_turn_loop.py会验证两个循环使用相同的区块、标记和干净的历史记录。部署的测试也包含相同的三项检查。- 在已部署的环境中运行一次三轮对话,并读取第二轮和第三轮的 usage;代理或重试层改写请求的情况会在这里显现,别处不会。