この機能はZero Data Retention(ZDR)の対象です。組織がZDR契約を締結している場合、この機能を通じて送信されたデータは、APIレスポンスが返された後に保存されることはありません。
システム指示は通常、トップレベルの system フィールドに配置され、会話内のすべてのメッセージより前に位置します。この位置はプロンプトキャッシングに適しています。システムプロンプトは安定したプレフィックスの一部であるため、後続のターンはキャッシュにヒットします。しかし、セッションの途中で初めて必要だと判明する指示には不向きな位置です。トップレベルの system フィールドを編集すると、プロンプトの冒頭部分が変更され、それ以降のすべてのキャッシュが無効化されてしまうためです。
会話途中のシステムメッセージは、このギャップを埋めます。トップレベルの system フィールドを編集する代わりに、新しい指示が関連する会話内の位置に {"role": "system"} メッセージを追加します。キャッシュされたプレフィックスは変わらないため、次のリクエストでも引き続きキャッシュから読み取られ、新しい指示は通常のユーザーテキストとしてではなく、システム指示として適用されます。
会話途中のシステムメッセージは、Claude APIおよびClaude Platform on AWSで利用できます。Amazon Bedrock、Vertex AI、Microsoft Foundryでは利用できません。
この機能はClaude Opus 4.8でのみ利用可能です。ベータヘッダーは不要です。
プロンプトキャッシングは、リクエストのプレフィックスを tools、system、messages の順にハッシュ化します。キャッシュヒットには、キャッシュブレークポイントまでのプレフィックスが、最近のリクエストとバイト単位で完全に一致する必要があります。
この順序により、トップレベルの system フィールドはハッシュ化されるプレフィックスの冒頭付近に位置します。一文を追加するだけでも、変更があれば異なるハッシュが生成され、そのリクエストはシステムプロンプトおよびそれ以降にキャッシュされたすべてのメッセージについてキャッシュミスとなります。
会話途中のシステムメッセージを使用すると、代わりにメッセージ履歴の末尾に指示を追加できます。新しい指示より前の部分はすべて変更されないため、既存のキャッシュエントリは引き続き一致し、新しいメッセージのみが新規入力として処理されます。
これが重要となる状況の例をいくつか挙げます。
system フィールドに追加すると、履歴全体が再処理されてしまいます。これらすべてのケースで、指示を通常の user メッセージに入れることもでき、Claudeはユーザーターンで届いた指示にも従います。違いは優先度です。user メッセージはエンドユーザーからのものとして扱われ、system メッセージはアプリケーションオペレーターであるあなたからのものとして扱われます。両者が矛盾する場合、システム指示が優先されます。そのため、エンドユーザーが異なることを要求しても維持されるべきオペレーターレベルの事実や制約には system ロールを使用してください。会話途中のシステムメッセージは、トップレベルの system フィールドを編集することによるキャッシュミスのコストを払うことなく、そのオペレーターレベルの優先度を維持します。
messages 配列に "role": "system" を持つメッセージを追加します。content には、user や assistant ターンと同様に、プレーンな文字列またはコンテンツブロックを使用します。指示は会話内のその位置以降に適用されます。指示が矛盾する場合、後のシステムメッセージが前のものより優先され、会話途中のシステムメッセージは、それ以降のターンについてトップレベルの system フィールドより優先されます。
会話全体に適用すべき指示には、引き続きトップレベルの system フィールドを設定できます。会話途中のシステムメッセージは、後になって初めて関連する指示、またはキャッシュされたプレフィックスを無効化せずに追加したい指示のために取っておいてください。
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-opus-4-8",
max_tokens=1024,
# 自動プロンプトキャッシング:各リクエストはそれまでの会話をキャッシュし、
# 次のリクエストは変更されていないプレフィックスをキャッシュから読み取ります。
cache_control={"type": "ephemeral"},
system="You are a code review assistant. Be concise.",
messages=[
{
"role": "user",
"content": "Review process() in utils.py for performance issues.",
},
{
"role": "assistant",
"content": "The list comprehension is fine for small inputs. For large inputs, consider a generator to avoid materializing the full list.",
},
{
"role": "user",
"content": "Now review the calling code that invokes process().",
},
# レビュアーはセッションの途中で、すべての提案がチームの厳格な
# 型付けポリシーにも準拠する必要があると気づきます。ここで指示を
# 追記することで以前のターンはバイト単位で同一に保たれ、前回の
# リクエストでキャッシュされたプレフィックスは引き続きキャッシュから読み取られます。
{
"role": "system",
"content": "From now on, every suggestion must include explicit type annotations.",
},
],
)
print(response.content[0].text)この例では、トップレベルの cache_control フィールドで自動キャッシングを有効にしています。プロンプトキャッシングはオプトインです。リクエストに cache_control フィールド(自動または明示的なブレークポイント)がない場合、何もキャッシュされず、すべてのリクエストで会話全体に対して通常の入力トークン料金が発生します。キャッシングを有効にすると、システムメッセージを追加してもすでにキャッシュされたターンは変更されないため、新しい指示を含むリクエストでも、それらを再処理するのではなくキャッシュから読み取ります。キャッシングには、会話がキャッシュ可能な最小プロンプト長を満たす必要もあります。この例のように短いものはその閾値を下回るため、会話が長くなるまで cache_creation_input_tokens と cache_read_input_tokens は0のままです。
会話途中のシステムメッセージは、user ターン(またはサーバーツール使用で終わる assistant ターン)の直後に配置する必要があり、messages の最後のエントリであるか、直後に assistant ターンが続く必要があります。tool_result ブロックを含む user メッセージもこれに該当します。エージェントループでは、ツール結果の直後、Claudeの次のターンの前にシステムメッセージを配置できます。許可されない唯一の位置は、assistant の tool_use ブロックとそれに応答する tool_result の間です。
エージェントループでは、システムメッセージはツール結果を届ける user メッセージの後に配置します。これは、Claudeが作業中にユーザーが入力した内容をアプリケーションが中継できる位置でもあり、ターンを再開することなく新しいコンテキストが取り込まれます。
[
{ "role": "user", "content": "Run the test suite and fix any failures." },
{
"role": "assistant",
"content": [{ "type": "tool_use", "id": "toolu_01", "name": "run_tests", "input": {} }]
},
{
"role": "user",
"content": [
{ "type": "tool_result", "tool_use_id": "toolu_01", "content": "12 passed, 0 failed" }
]
},
{
"role": "system",
"content": "The user sent the following message while you were working: also update the changelog before you finish."
}
]システムコンテンツは、ユーザーを上書きする命令としてではなく、コンテキストとして表現してください。事実を述べ(「ユーザーから新しい入力が届きました:X」、「残りのトークン予算は現在Yです」)、Claudeにそれに基づいて行動させます。Claudeはユーザーに不利に働くように見える指示に抵抗するよう訓練されており、その保護はシステムロールにも適用されます。そのため、「ユーザーが言ったことを無視してください」のような表現は、何が変わったかを述べるよりも効果が低くなります。
このパターンは、会話自体のエンドユーザーからの入力を中継するためのものです。ツール出力、取得したドキュメント、その他のサードパーティコンテンツを渡すために使用しないでください。そのようなコンテンツは tool_result ブロックに保持してください(制限事項を参照)。
会話途中のシステムメッセージとプロンプトキャッシングは、組み合わせて使用するように設計されています。
cache_control(トップレベルの自動キャッシングフィールド、またはコンテンツブロック上の明示的なブレークポイント)が含まれている場合にのみ発生します。会話途中のシステムメッセージはそれ自体でキャッシュエントリを作成せず、キャッシングが有効でなければ維持すべき節約もありません。system フィールドの末尾、ツール定義の末尾、メッセージ履歴内の安定した位置など、リクエスト間で変わらない最後のブロックに cache_control を配置します。すでに送信された会話途中のシステムメッセージを編集または削除することは避けてください。以前のメッセージへの他の変更と同様に、その位置以降のキャッシュが無効化されます。指示を変更する必要がある場合は、古いものを書き換えるのではなく、新しいシステムメッセージを追加してください。連続するシステムメッセージは許可されていません。指示を1つのメッセージにまとめるか、次のユーザーターンを待ってから追加してください。
system メッセージは messages の最初のエントリにはできません。最初から適用される指示にはトップレベルの system フィールドを使用してください。system メッセージは、user ターン(tool_result ブロックを含む user ターンを含む)またはサーバーツール使用で終わる assistant ターンの直後に配置する必要があり、assistant ターンの前に来るか、配列の末尾である必要があります。tool_use ブロックとその tool_result の間には配置できません。それ以外の位置に配置すると400エラーが返されます。tool_result ブロックに保持し、引き続きジェイルブレイクとプロンプトインジェクションの軽減に従ってください。キャッシングの仕組み、ブレークポイントの配置場所、キャッシュ使用状況フィールドの読み方。
期待したキャッシュヒットが発生しなかった場合に、2つのリクエストがどこで分岐したかを正確に特定します。
メッセージ構造、マルチターン会話、system フィールドについて。
効果的なプロンプトとシステム指示の書き方。
messages 配列内での tool_use および tool_result ブロックの構造。
Was this page helpful?