commerce-prompt-caching について
ショッピングおよびマーチャントエージェント向けに、キャッシュが安定するリクエストの組み立て方を示すスキルです。静的なプロンプト、ターンごとのコンテキスト、メッセージのローリング境界を分け、キャッシュ動作の検証方法も説明します。
主な機能
- 01静的プロンプトと動的コンテキストの分離
- 02ツールリストの固定順序
- 03メッセージ境界のローリング設定
- 04古いツール結果の圧縮
- 05プロンプトキャッシュ動作の検証
活用シーン
- 01ターン間のプロンプト接頭部の変化を抑制
- 02会話キャッシュ読み取りの低下を調査
- 03コマースエージェントのプロンプト組み立て
インストール
コマンドをコピーしてターミナルで実行します。
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/ です。
3つのブレークポイント
リクエストのキャッシュ可能なプレフィックスは、tools、system、メッセージの順に並びます。ブレークポイントは、次の呼び出しで読み戻すスパンを区切ります。参照エージェントでは、3つのブレークポイントをすべて commerce_common/prompt_assembly.py に配置しています。
- 最後のツール:
with_tool_cache_control(tools)。 - 静的なシステムテキスト:
build_system_blocks(static, context)でマークし、マークのないコンテキストブロックを追加します。 - 最新の永続化メッセージ:
build_request_messages(messages, rolling_breakpoint=...)で、送信するリクエスト上の最後の永続化ブロックにのみマークを付けます。次の呼び出しでは、検索ペイロードを含む前のラウンドをキャッシュから読み込みます。
リクエストごとに変わる内容はすべてコンテキストブロックに入れます。このブロックは、各ロールの build_dynamic_context(...) がターンごとに一度生成します。静的ブロックやツールリストに入れると、その内容によってシステムスパンまたはツールスパンが毎回のリクエストで途切れます。コンテキストブロックに入れる場合は、カート、ページ、事実が変化したターンに会話を1回読み直すだけで済み、ローリングマーカーはそのターンの次のラウンドから有効になります。時刻は時間単位で生成されるため(context_clock)、分が変わっても内容は変わりません。
実装されている分割
- 各ロールの
prompt.pyにあるbuild_static_system(config, skills)は、設定とインストール済みのスキルから、アイデンティティ、最大ターン数のルール、フェンス通知、スキルインデックスを生成します。これらはデプロイの存続期間中、同一のバイト列です。 - 同じモジュールにある
build_dynamic_context(...)は、ロールのデータフェンス内にリクエストごとの内容を生成します。shopping では設定、メモリの事実、カート、ページ、アカウントブロック、時刻を取得し、merchant ではストアコンテキスト、メモリの事実、時刻を取得します。バックエンドのコンテキストブロックには、それぞれ独自のサイズ上限があります。 ShoppingAgent.__init__とMerchantAgent.__init__(各ロールのruntime-messages-apiにあるorchestrator.py)は、プロセスごとに_static_systemと_toolsを一度だけ構築します。stream_turnはターンごとにコンテキストブロックを生成し、モデル呼び出しごとにbuild_request_messagesを呼び出します。- 各ロールの
tools/registry.pyにあるbuild_toolsは、組み込みツールを固定順で出力します(merchant のビルダーでは、有効時にその後へrun_analysisを追加します)。続いてload_skillの列挙値をソートして出力し、その後に指定された順序で拡張機能を追加し、有効な場合は最後にweb_searchを追加します。登録済みのツールはすべてのリクエストに含まれ、呼び出しを処理できるかどうかは、呼び出しを受け取ったときにエグゼキューターが判断します。 - Agent SDK ランタイムは、同じ静的テキスト(および
SKILL_TOOL_ADAPTER)と同じコントラクトを渡し、SDK がそれらをキャッシュします。ホスト型マニフェストでは、テキストをsystem.mdとして保持し、scripts/check.pyがビルダーの内容と比較します。
ローリングマーカーを省略する場合
マーカーを付けないラウンドは2種類あります。1つ目は、メッセージが1つだけの単独の初回呼び出しです。単発のセッションでは書き込み後に読み込みが発生せず、2回目の呼び出しのマーカーが最初のメッセージもカバーするためです。2つ目は、tool_choice が auto 以外のラウンド(グラウンディングを強制する最初のイテレーションと、テキスト出力を強制する最後のイテレーション)です。tool_choice はメッセージスパンのキーになるため、強制ラウンドで書き込まれたエントリーは、その後の auto ラウンドから読み取れません。システムスパンとツールスパンは引き続きキャッシュにヒットします。どちらの処理も build_request_messages とループの rolling_breakpoint= 引数で行われます。rolling_conversation_cache を使うと、デバッグ用にマーカーを無効にできます。
会話が圧縮された場合
あるターンで最後に呼び出されたツールの使用量が compact_history_above_tokens 以上になると(使用量に表示されます。デフォルトはプラットフォーム独自のツール結果クリアのデフォルト値で、ウィンドウの 10 分の 1 です)、commerce_common/turn.py の compact_history が実行され、会話が以前の半分のサイズになるまで、保存済みの会話内の最も古いツール結果が 1 行のマーカーに置き換えられます。次のターンの最初のラウンドでメッセージの範囲が一度書き換えられ、以降のラウンドでは短縮されたものが読み込まれます。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 などです。コンテキストブロックに含まれるのは最初の 4 つです。リクエスト ID はどこにも含めません。
- プロンプトテキストまたはスキーマに、ソートせずに反復処理した集合または辞書を含めること。
- リクエストごとに
tools[]の構成を決めること(構築時に一度だけ読み取るフラグを、リクエストごとに読み取ること)。 - コンストラクターではなく、ターン内で静的テキストまたはツールリストを再構築すること。
- ローリングマーカーを保存済みの会話に永続化し、ターンごとにマーカーが 1 つずつ増えること。
- 実行中のデプロイで
(prompt)フィールド、スキル、拡張機能を切り替えること。いずれも再デプロイが必要です。 - デプロイごとではなく、リクエストごとにプロンプトのバリアントを選択すること。
- モデルのキャッシュ可能な最小長に満たないプレフィックス。何も書き込まれません。
- 強制された
tool_choice(最初に grounding、最後にnone)ではメッセージの範囲のみがキャッシュミスになります。ループではその範囲のマーカーをスキップします。
検証方法
turn_completeにはusage(commerce_common/turn.pyのusage_totals。そのターンの呼び出し分を合算)とelapsed_msが含まれます。また、各呼び出しについても同じカウンターと個別の所要時間を含む行が 1 行ログに記録されます(shopping_agent_runtime.orchestratorとmerchant_agent_runtime.orchestratorのlog_model_call)。会話の 2 ターン目にキャッシュ読み取りが 0 件なら、プレフィックスが変わっています。構成バージョンごとにグラフ化する指標は、入力に占めるキャッシュ読み取りの割合、elapsed_ms、ターンあたりのラウンド数、ゲートごとのブロックされたtool_resultイベントです。tests/test_role_registries.pyは各ロールのプロンプトとツールを 2 回構築してバイト列を比較し、キャッシュマーカーを確認するとともに、プロンプト以外の設定を変更しても何も変わらないことを検証します。commerce-common/tests/test_prompt_assembly.pyはブロックビルダー、コンテキストクロック、ローリングマーカー、スキップケースを網羅します。tests/test_turn_loop.pyは、両方のループでブロック、マーカー、履歴がクリーンであることを確認します。デプロイ環境のテストでも、同じ 3 つのチェックを実施します。- デプロイ環境で 3 ターンの会話を 1 回実行し、2 ターン目と 3 ターン目の使用量を確認します。リクエストを書き換えるプロキシやリトライレイヤーがあれば、その影響はここにだけ現れます。