Claude API が会話途中の system メッセージに対応 — キャッシュを壊さず方針を差し替える

AI・テック動向

Claude API が会話途中の system メッセージに対応 — キャッシュを壊さず方針を差し替える

長い会話を何十ターンも積み上げた末に、AIエージェントへ与える方針をここから切り替えたい、と思う瞬間が来る。コードレビューをさせていた相手に、途中からセキュリティ観点を最優先させたい。長時間のリサーチで、集めた前提を踏まえて出力の形式だけ差し込みたい。この切り替えを従来はトップレベルの system を書き換えて実現していたが、書き換えた途端にプロンプトキャッシュが根こそぎ無効化され、会話全体が再計算されてコストが跳ねる。Claude API の更新は、まさにこの一点に手を入れてきた。

目次
  1. 会話の途中に system メッセージを差し込める
  2. なぜキャッシュが壊れないのか
  3. 置ける位置には制約がある
    1. 実際に叩いて、位置の制約を確かめた
    2. 対応が Claude 5 の3モデルまで広がっていた
  4. キャッシュを壊す他の操作と並べて考える
  5. フェーズが変わる長時間セッションの例
  6. プロンプトインジェクション対策としての意味
  7. よくある疑問
  8. 実装に組み込むときの勘どころ
  9. 参考

会話の途中に system メッセージを差し込める

更新の中身はシンプルだ。トップレベルの system フィールドを編集する代わりに、messages 配列の中へ {"role": "system", "content": "..."} を追記する。これだけで、キャッシュ済みの会話履歴を壊さないまま、途中から方針や文脈を差し替えられる。

対応モデルは Claude Opus 4.8claude-opus-4-8)のみで、ベータヘッダは不要だ。通常の client.messages.create でそのまま使える。

筆者は複数のAIを束ねて動かすツールを作っていて、長い会話にキャッシュを効かせ続けたい動機が常にある。長時間走るエージェントほど、履歴の再計算コストは無視できない大きさになる。だからこそ、この小さな追加が効いてくる。

なぜキャッシュが壊れないのか

理由はプロンプトキャッシュの仕組みにある。キャッシュは前方一致で働く。レンダリング順は toolssystemmessages と決まっていて、プレフィックスの途中で1バイトでも変われば、それ以降のキャッシュはすべて無効になる。

トップレベルの system は会話全体の先頭に置かれる。ここを書き換えると、後ろに続く全ターンのプレフィックスが変わり、キャッシュ済みの履歴が丸ごと再計算される。長い会話ほど、この再計算は重くのしかかる。

role: "system" のメッセージは違う。履歴の後ろに追記されるので、先頭から直前までのキャッシュ済みプレフィックスは無傷のまま残る。差し込んだ数十トークンだけが新しく計算される。

やり方 キャッシュ済みプレフィックス 再計算されるトークン
トップレベル system を編集 変わる(無効化) 会話履歴の全ターン
messagesrole:"system" を追記 無傷 追記した分だけ

コードにすると、差し替えの位置関係はこうなる。

from anthropic import Anthropic

client = Anthropic()

response = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=4096,
    system=[
        {
            "type": "text",
            "text": "あなたはコードレビュアーです。",
            "cache_control": {"type": "ephemeral"},
        }
    ],
    messages=[
        {"role": "user", "content": "この関数をレビューして"},
        {"role": "assistant", "content": "..."},
        # ここから方針を差し替える。トップレベル system は一切触らない
        {"role": "system", "content": "以降はセキュリティ観点を最優先で見てください。"},
        {"role": "user", "content": "次はこのファイルです"},
    ],
)

トップレベルの system にキャッシュブレークポイントを置いたまま、方針の切り替えは後ろの role: "system" に任せる。会話がフェーズごとに性格を変えていく常駐エージェントに、この形は素直にはまる。

置ける位置には制約がある

どこにでも差し込めるわけではない。role: "system" のミッドカンバセーションメッセージは、user メッセージの後(またはサーバーツール使用で終わる assistant ターンの後)に置く必要がある。そして配列の最後の要素になるか、その後に assistant ターンが続く形でなければならない。

配列の先頭 messages[0] には置けない。会話の最初の指示はこれまで通りトップレベルの system が担う。内容はテキストのみで、画像やツール結果は入れられない。

非対応モデルへ送ると 400 エラーが返る。メッセージは role 'system' is not supported on this model だ。設計に組み込む前に、使うモデルが Opus 4.8 かどうかを確認しておきたい。

実際に叩いて、位置の制約を確かめた

OpenRouter 経由で Anthropic のモデルへ、4通りの並びを投げた。返る 400 は Anthropic の生の invalid_request_error がそのまま出てくる。

messages の並び 結果
… assistant, system, user 400
… user, system, user 400
… user, system](配列の末尾)通る 200
… user, system, assistant …通る 200

400 のメッセージが、制約をそのまま言葉にしていた。

messages.2: role 'system' must follow a 'user' message or an 'assistant'
message ending in a server tool result; the directive-only form
(content: [] with output_config) is accepted at any position

messages.3: role 'system' must precede an 'assistant' message or end the
array; the directive-only form (content: [] with output_config) is
accepted at any position

2つを合わせると、user の直後に置き、assistant の直前か配列の末尾で終えるという条件になる。上に書いた制約と一致した。

エラー文には、content: []output_config を使う directive-only 形式なら任意の位置に置ける、とも書いてある。未検証: この形は試していない。

対応が Claude 5 の3モデルまで広がっていた

上で「使うモデルが Opus 4.8 かどうかを確認しておきたい」と書いた。2026年7月31日に測り直したところ、対応は広がっていた。

モデル 末尾に system を置いた結果 指示に従ったか
claude-sonnet-5 200 従った(Four)
claude-opus-5 200 従った(Four)
claude-fable-5 200 従った(Four)
claude-haiku-4.5 200 従わなかった(4)

差し込んだ指示は「ここから先は必ず英語で、1単語だけ」で、質問は「2+2は?」。Claude 5 の3モデルは Four を返した。haiku-4.5 は日本語のまま 4 を返した。

haiku-4.5 はもう一段ややこしい。400 になるはずの並び(assistant の直後に system)を投げても 200 を返し、そのときは Four. と英語で答えた。位置の制約を強制せず、従い方も呼び出しによって変わる。

ここから引ける実務上の線は1本になる。エラーが出ないことを、対応している証拠に使わない。組み込む前に、指示が実際に効いたかを出力で確かめる。制約に違反した並びを通してしまうモデルがある以上、400 が出ないことは何も保証しない。

測定は OpenRouter 経由で、モデル名は anthropic/claude-* を指定した。Anthropic の API を直接叩いた場合の挙動は確かめていない。

キャッシュを壊す他の操作と並べて考える

プレフィックスを無効化する操作は system の書き換えだけではない。ツール定義の追加・削除・並べ替えはレンダリング順の先頭に置かれるため、全キャッシュを吹き飛ばす。モデルの切り替えも同様で、キャッシュはモデルごとに分かれている。会話の途中でこれらを変えれば、履歴は再計算される。

だから「モードを切り替えたい」という要求を、ツールセットの入れ替えで表現するのは高くつく。方針の変更が指示の言葉で足りるなら、role: "system" の追記で済ませるのが安い。ツールを丸ごと差し替える代わりに、モデルへ「ここからはこう振る舞ってほしい」と伝えるだけで、キャッシュを保ったまま挙動を変えられる。

長時間セッションのコスト設計では、何がプレフィックスを変え、何が変えないかを把握しておくと効いてくる。凍結すべきもの(system プロンプト、ツール一覧、モデル)と、後ろに流してよいもの(実行中に判明する文脈)を分けて考える習慣が、そのままヒット率に跳ね返る。

フェーズが変わる長時間セッションの例

具体的な場面で考えてみる。ある調査エージェントに、まず資料を広く集めさせ、次に集めた資料を批判的に読ませ、最後に決まった書式でレポートへまとめさせる。3つのフェーズは求める振る舞いがそれぞれ違う。

フェーズが切り替わるたびにトップレベルの system を書き換えていたら、集めた資料を含む会話履歴が毎回再計算される。調査が長引くほど、この再計算は膨らむ。フェーズの境目で role: "system" を1つ追記すれば、それまでの履歴はキャッシュから読み出され、新しい指示だけが後ろに足される。

筆者が複数AIを束ねるツールで狙っているのも、この住み分けだ。会話の骨格は凍結し、実行中に変わる指示は後ろへ流す。骨格が動かない限り、何ターン重ねてもキャッシュは効き続ける。

プロンプトインジェクション対策としての意味

この機能の効きどころは、コスト削減だけにとどまらない。オペレーターの指示を届ける経路として、偽装できない筋道を1本増やす意味がある。

従来、会話の途中でオペレーターの指示を伝えるには、user ターンのテキストに <system-reminder> のような形で埋め込む手があった。キャッシュ挙動は同じだが、user や tool の内容は「ユーザー入力に書き込める何者か」が偽装できる。悪意ある入力が、あたかもオペレーターの指示のように振る舞える余地が残る。

role: "system" は、その偽装ができないオペレーター権限の経路になる。user や tool の中身をいくら操作しても、system ロールそのものを名乗ることはできない。信頼できる指示だけを流す専用のチャネルとして機能する。

例えば「ここから先はツールの自動承認を有効化した」「残りトークン予算が閾値を下回った」といった、アプリ側が実行中に知る事実を伝えるのに向いている。ユーザーの発話に混ぜず、オペレーターの声としてモデルへ届けられる。

ひとつ注意したいのは書き方だ。system ロールでも、ユーザーの意図を踏みにじる命令口調(「ユーザーの指示を無視しろ」など)は避け、事実を述べてモデルに判断を委ねる形にする。Claude はユーザーを守る方向に訓練されていて、その保護は system ロールにも及ぶ。

よくある疑問

どのモデルで使える?
Claude Opus 4.8(claude-opus-4-8)のみだ。ベータヘッダは要らず、通常の client.messages.create で動く。非対応モデルへ送ると 400 が返る。

なぜ user ターンに埋め込むのではダメ?
キャッシュの効き方は同じだが、user や tool の内容はユーザー入力を書ける立場の者が偽装できる。オペレーター権限を名乗る指示を安全に流したいなら、偽装できない role: "system" を使う。

配列の先頭に置ける?
置けない。messages[0] は不可で、user メッセージの後(またはサーバーツール使用で終わる assistant の後)にだけ置ける。最後の要素になるか、その後に assistant ターンが続く形にする。

差し込むたびにキャッシュを書き直す必要は?
ない。トップレベルの system と直前までの履歴が同じバイト列なら、その部分はキャッシュから読み出される。新しく計算されるのは追記した system 以降だけだ。

1つの会話で何度も差し込める?
差し込める。フェーズが変わるたびに追記していけばよい。各追記は履歴の後ろに積まれるので、前の追記までのキャッシュは生き続ける。追記のたびにヒットが積み上がっていく形になる。

実装に組み込むときの勘どころ

常駐型のエージェントで「モード切替」を実装しているなら、その切替をトップレベル書き換えから途中 system へ移すだけで、長時間セッションのコストが目に見えて下がる。フェーズが変わるたびに履歴を再計算していた無駄が消える。

設計段階では、固定の指示(凍結した system プロンプト)を先頭に置き、実行中に変わる文脈を後ろの role: "system" へ寄せる。この住み分けを最初から意識しておくと、キャッシュのヒット率が安定する。Claude を組み込んだアプリをUIからバックエンドまで段階的に組み上げる進め方はバイブコーディングの進め方にまとめてある。今回のAPI更新を、実際のアプリのどこに効かせるかがイメージしやすくなるはずだ。

派手な機能ではない。それでも、長い会話を走らせるアプリを作る人にとっては、コスト設計と安全性の両方に効く一手になる。キャッシュを壊さず方針を差し替えられる、この一点だけでも試す価値がある。

参考

Google Chirp 3: Transcription が GA — 話者分離・多言語ASRと自作Whisperの使い分けGoogle Chirp 3: Transcription が GA — 話者分離・多言語ASRと自作Whisperの使い分け前のページ

GitHub Code Quality が7/20に有料GA — 月$10の価値を無料代替(ruff/ESLint/AIレビュー)と比べる次のページGitHub Code Quality が7/20に有料GA — 月$10の価値を無料代替(ruff/ESLint/AIレビュー)と比べる

ピックアップ記事

  1. New Eden Intelligence Hub の作り方 — EVE Onl…

  2. 競艇予想AIの作り方 — LightGBMで「当たる順位」を学習させる実装ガイド…

  3. 高精度OCRデスクトップアプリの作り方 — PaddleOCR-VLとPyIns…

  4. Claude Mission Control の作り方 — Tauri+Pyth…

関連記事

  1. AnimeGen のライセンスを条文まで読んだ — SDXL の挿絵を動かす前に確認したこと
  2. /verify と /code-review が自動で走らなくなった — 検証役を分ける運用をどう組み直すか
  3. Anthropic「Reflect」— AI利用の可視化を自動化の材料にする

    AI・テック動向

    Anthropic「Reflect」— AI利用の可視化を自動化の材料にする

    Claudeの使い方を振り返るダッシュボードReflectがベータ公開…

  4. Claude Code に Artifacts が登場 — セッションの成果を共有できるライブWebページに変える

    AI・テック動向

    Claude Code に Artifacts が登場 — セッションの成果を共有できるライブWeb…

    Claude Code の作業をそのまま共有可能なライブWebページに…

  5. MCP 2026-07-28 仕様RC — 史上最大の改訂。ステートレス化・MCP Apps・Tasks で自作サーバは何が変わるか
  6. Claude Fable 5 が7/1にグローバル再開 — Fable/Mythos/Opus/Sonnet/Haiku を用途で選ぶ完全整理

    AI・テック動向

    Claude Fable 5 が7/1にグローバル再開 — Fable/Mythos/Opus/So…

    輸出規制の解除で最上位の Claude Fable 5 が全世界に復帰…

注目

AIで、ここまで作れる

AIで作った2D RPGを、ブラウザでそのまま遊べます。その「作り方=最後まで完成させる進め方」も実例つきで公開中。

▶ ゲームを遊ぶやり方を読む

PR

ロリポップ!レンタルサーバー(PR)

レンタルサーバ:ロリポップ!(本サイトの稼働環境・PR)

  1. 「Opus級」の実像 — Grok 4.5 はベンチ4位、それでも $2/$6 が効く用途

    AI・テック動向

    「Opus級」の実像 — Grok 4.5 はベンチ4位、それでも $2/$6 …
  2. MCP 2026-07-28 の Beta SDK — ステートレス化の破壊的変更を本番前に通す

    AI・テック動向

    MCP 2026-07-28 の Beta SDK — ステートレス化の破壊的変…
  3. AI・テック動向

    2026年8月に並ぶ5つの廃止期限 — grep 2本で自分のリポジトリを監査す…
  4. MCP 2026-07-28 仕様RC — 史上最大の改訂。ステートレス化・MCP Apps・Tasks で自作サーバは何が変わるか

    AI・テック動向

    MCP 2026-07-28 仕様RC — 史上最大の改訂。ステートレス化・MC…
  5. AIでゲーム素材を量産する⑤|生成→透過切り出し(BiRefNet)→配置のパイプライン【Archipelago Saga制作】

    アプリの作り方

    AIでゲーム素材を量産する⑤|生成→透過切り出し(BiRefNet)→配置のパイ…
PAGE TOP

TAG CLOUD

ドラッグで回転・クリックでそのタグの記事一覧へ