「zero data retention」(ゼロデータ保持)、すなわちZDRがこの機能にどのように適用されるかについては、APIとデータ保持を参照してください。
システム指示は通常、会話のすべてのメッセージより前にあるトップレベルの system フィールドに置かれます。この位置はプロンプトキャッシングにとって最適です。システムプロンプトは安定したプレフィックスの一部であるため、後続のターンはキャッシュにヒットします。しかし、セッションの途中で必要になったと気づいた指示にとっては不向きな位置です。トップレベルの system フィールドを編集するとプロンプトの最初の部分が変わり、それ以降のすべてのキャッシュが無効化されるためです。
会話途中のシステムメッセージは、このギャップを埋めます。トップレベルの system フィールドを編集する代わりに、新しい指示が関連するようになった会話の時点に {"role": "system"} メッセージを追加します。キャッシュ済みプレフィックスは変わらないため、次のリクエストは引き続きキャッシュから読み取り、新しい指示は通常のユーザーテキストとしてではなく、システム指示として適用されます。
このページでは2つの機能を扱います。一般提供されている会話途中のシステムメッセージと、Claude Opus 5 で導入されたベータ機能で、同じアプローチを tools 配列に適用する会話途中のツール変更です。
会話途中のシステムメッセージは、Claude API、Claude in Amazon Bedrock、および Google Cloud で利用できます。
この機能は Claude Fable 5、Claude Mythos 5、Claude Opus 4.8、Claude Opus 5 で利用できます。会話途中のシステムメッセージにベータヘッダーは必要ありません。この機能は Claude Sonnet 5 では利用できません。代わりにトップレベルの system フィールドを使用してください。
会話途中のツール変更はベータ版であり、mid-conversation-tool-changes-2026-07-01 ベータヘッダーが必要です。Claude Fable 5、Claude Mythos 5、Claude Opus 4.8、Claude Opus 5 で、Claude API、Amazon Bedrock、Google Cloud 上で利用できます。
tools 配列は、ハッシュ化されるリクエストプレフィックスの中でトップレベルの system フィールドよりもさらに前に位置するため、これを編集すると会話全体のプロンプトキャッシュが無効化されます。Claude Opus 5 で導入されたベータ機能である会話途中のツール変更は、会話途中のシステムメッセージのツール版です。会話の存続期間中ツールリストを固定する代わりに、ターン間でモデルに提供するツールを変更します。最初に tools で完全なツールセットを宣言し、その後 tool_addition と tool_removal ブロックを使用して、会話の特定の時点以降、モデルにツールを提供したり、取り下げたりします。tools 配列自体は決して変わらないため、キャッシュ済みプレフィックスはそのまま維持されます。
tool_addition と tool_removal は role: "system" メッセージの content 配列内のコンテンツブロックであり、同じメッセージ内で text ブロックと混在させることができます。このメッセージは他の会話途中のシステムメッセージと同じ配置ルールに従い(制限事項を参照)、変更はその時点以降の会話に適用されます。各ブロックの tool フィールドはツールを定義するのではなく参照します。{"type": "tool_reference", "name": "..."} はリクエストの tools 配列で宣言されたツールを指定し、MCP コネクタのツールは mcp_tool_reference(server_name と name)で個別に参照するか、mcp_toolset_reference(server_name)でツールセット全体として参照できます。tools で宣言されていない名前を参照すると 400 エラーが返されます。
tools で宣言されたすべてのツールは、defer_loading: true で宣言されていない限り、会話の最初からモデルに提供されます。defer_loading: true が指定されたツールは、tool_addition ブロックが表面化させるまで保留されます。tool_addition は、以前の tool_removal で取り下げられたツールを再提供することもできます。
client = anthropic.Anthropic()
response = client.beta.messages.create(
model="claude-opus-5",
max_tokens=1024,
betas=["mid-conversation-tool-changes-2026-07-01"],
# 完全なツールセットは最初に宣言され、その後変更されないため、
# キャッシュされたプレフィックスはそのまま維持されます。
tools=[
{
"name": "get_weather",
"description": "Get the current weather for a location.",
"input_schema": {
"type": "object",
"properties": {
"location": {"type": "string", "description": "City name"},
},
"required": ["location"],
},
},
],
messages=[
{
"role": "user",
"content": "Say OK.",
},
# この時点以降 get_weather を撤回します。このブロックは `tools` を編集する
# 代わりにツールを名前で参照するため、以前のターンはバイト単位で
# 同一のまま保たれ、キャッシュは引き続きヒットします。
{
"role": "system",
"content": [
{
"type": "tool_removal",
"tool": {"type": "tool_reference", "name": "get_weather"},
},
],
},
],
)
for block in response.content:
if block.type == "text":
print(block.text)会話途中のツール変更はベータ版です。使用するには、リクエストにベータヘッダー mid-conversation-tool-changes-2026-07-01 を含めてください。Claude Fable 5、Claude Mythos 5、Claude Opus 4.8、Claude Opus 5 で、Claude API、Amazon Bedrock、Google Cloud 上で利用できます。
プロンプトキャッシングは、リクエストプレフィックスを tools、次に system、次に messages の順にハッシュ化します。キャッシュヒットには、キャッシュブレークポイントまでのプレフィックスが最近のリクエストとバイト単位で完全に一致する必要があります。
この順序により、トップレベルの system フィールドはハッシュ化されるプレフィックスの最初の方に位置します。文を1つ追加するだけでも、変更があれば異なるハッシュが生成され、リクエストはシステムプロンプトとそれ以降のすべてのキャッシュ済みメッセージについてキャッシュミスとなります。
会話途中のシステムメッセージを使用すると、代わりにメッセージ履歴の末尾に指示を追加できます。新しい指示より前のすべては変更されないため、既存のキャッシュエントリは引き続き一致し、新しいメッセージだけが新規入力として処理されます。
これが重要になるいくつかの状況:
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-5",
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.",
},
],
)
for block in response.content:
if block.type == "text":
print(block.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 の間を含め、それ以外の位置では 400 エラーが返されます。
エージェントループでは、システムメッセージはツール結果を届ける 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(トップレベルの自動キャッシングフィールド、またはコンテンツブロック上の明示的なブレークポイント)が含まれている場合にのみ行われます。会話途中のシステムメッセージ自体はキャッシュエントリを作成せず、キャッシングが有効でなければ保持すべき節約もありません。cache_control を配置します。それがトップレベルの system フィールドの末尾であっても、ツール定義の末尾であっても、メッセージ履歴の安定した地点であっても構いません。すでに送信された会話途中のシステムメッセージを編集したり削除したりすることは避けてください。以前のメッセージへの他の変更と同様に、その時点以降のキャッシュが無効化されます。指示を進化させる必要がある場合は、古いものを書き換えるのではなく、新しいシステムメッセージを追加してください。連続するシステムメッセージは受け入れられ、単一のシステムセクションとして扱われ、全体として同じ配置ルールに従います。
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?