System-Nachrichten und Tool-Änderungen mitten im Gespräch
Ändere Systemanweisungen oder die Tool-Verfügbarkeit mitten in einem Gespräch, ohne das gecachte Präfix davor ungültig zu machen.
Systemanweisungen stehen normalerweise im Top-Level-Feld system, vor jeder Nachricht im Gespräch. Diese Position ist ideal für „prompt caching“ (Prompt-Caching): Der „system prompt“ (System-Prompt) ist Teil des stabilen Präfixes, sodass nachfolgende Turns den Cache treffen. Für Anweisungen, von denen du erst mitten in einer Sitzung merkst, dass du sie brauchst, ist diese Position dagegen ungünstig. Wenn du das Top-Level-Feld system bearbeitest, änderst du nämlich den allerersten Teil des Prompts und machst den Cache für alles Nachfolgende ungültig.
„Mid-conversation system messages“ (System-Nachrichten mitten im Gespräch) schließen diese Lücke. Anstatt das Top-Level-Feld system zu bearbeiten, hängst du eine {"role": "system"}-Nachricht an der Stelle im Gespräch an, an der die neue Anweisung relevant wird. Das gecachte Präfix bleibt gleich, sodass die nächste Anfrage es weiterhin aus dem Cache liest. Die neue Anweisung wird trotzdem als Systemanweisung angewendet und nicht als gewöhnlicher Benutzertext.
Tool-Änderungen mitten im Gespräch
Das tools-Array steht im gehashten Anfragepräfix noch vor dem obersten system-Feld, daher macht eine Änderung daran den Prompt-Cache für das gesamte Gespräch ungültig. Tool-Änderungen mitten im Gespräch sind das Gegenstück zu Systemnachrichten mitten im Gespräch für Tools. Anstatt die Tool-Liste für die gesamte Dauer des Gesprächs festzulegen, änderst du zwischen den Turns, welche Tools dem Modell angeboten werden: Deklariere den vollständigen Tool-Satz vorab in tools und verwende dann tool_addition- und tool_removal-Blöcke, um dem Modell ein Tool ab einem bestimmten Punkt im Gespräch anzubieten oder es zurückzuziehen. Das tools-Array selbst ändert sich nie, sodass das gecachte Präfix intakt bleibt. Tool-Änderungen mitten im Gespräch sind in der Beta und verwenden auf der Claude API den Beta-Header inline-tools-2026-09-15.
tool_addition und tool_removal sind Content-Blöcke im content-Array einer role: "system"-Nachricht und können in derselben Nachricht mit text-Blöcken kombiniert werden. Die Nachricht folgt den Platzierungsregeln für jede Systemnachricht mitten im Gespräch, mit einer zusätzlichen Einschränkung nach einem pausierten Turn (siehe Einschränkungen), und die Änderung gilt ab diesem Punkt im Gespräch. Das tool-Feld jedes Blocks referenziert ein Tool, anstatt eines zu definieren: {"type": "tool_reference", "name": "..."} benennt ein Tool, das im tools-Array der Anfrage deklariert ist, und Tools des MCP-Connectors können einzeln mit mcp_tool_reference (server_name und name) oder als ganzes Toolset mit mcp_toolset_reference (server_name) referenziert werden. Die Referenzierung eines Namens, der nicht in tools deklariert ist, gibt einen 400-Fehler zurück (auf der Claude API mit error.details.error_code auf tool_reference_unresolved gesetzt). Ein tool_addition-Block kann stattdessen die vollständige Definition des Tools enthalten, was der Header mid-conversation-tool-changes-2026-07-01 nicht unterstützt.
Jedes in tools deklarierte Tool wird dem Modell ab Beginn des Gesprächs angeboten, es sei denn, es ist mit defer_loading: true deklariert. Dann bleibt es zurückgehalten, bis ein tool_addition-Block es verfügbar macht. tool_addition bietet außerdem ein Tool erneut an, das ein früherer tool_removal-Block entzogen hat.
Die folgende Anfrage deklariert get_weather in tools und zieht es nach dem ersten Benutzer-Turn mit einem tool_removal-Block zurück. Die Anfrage sendet den Beta-Header inline-tools-2026-09-15.
client = anthropic.Anthropic()
response = client.beta.messages.create(
model="claude-opus-5-5",
max_tokens=1024,
betas=["inline-tools-2026-09-15"],
# Das vollständige Tool-Set wird vorab deklariert und ändert sich nie, sodass der
# gecachte Präfix intakt bleibt.
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.",
},
# Ab hier get_weather zurückziehen. Der Block referenziert
# das Tool per Name, statt `tools` zu bearbeiten, sodass frühere Turns
# byte-identisch bleiben und der Cache weiterhin trifft.
{
"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)Tools in einer Nachricht definieren (Beta)
Mit dem Beta-Header inline-tools-2026-09-15 kann ein tool_addition-Block ein Tool per Wert definieren, also mit seiner vollständigen Definition, statt es per Referenz zu benennen. So kannst du ein Tool, das zu Beginn des Gesprächs unbekannt ist oder dessen Schema sich später ändert, durch Anhängen einer role: "system"-Nachricht einführen. Das tools-Array und alle früheren Nachrichten bleiben genau so, wie sie gesendet wurden, sodass der Prompt-Cache weiterhin trifft und nur die angehängte Nachricht als neue Eingabe verarbeitet wird. Die einzige Ausnahme, ein tools-Array ohne nicht zurückgestelltes Tool, wird in den Regeln unten behandelt. Der Header deckt auch das Hinzufügen und Entfernen von Tools per Referenz ab, sodass du mid-conversation-tool-changes-2026-07-01 nicht zusätzlich senden musst.
Verpacke die Definition in ein tool-Objekt vom Typ tool_definition. Die definition ist ein tools-Eintrag, etwa ein benutzerdefiniertes Tool oder ein von Anthropic definiertes Client- oder Server-Tool, mit seiner üblichen Konfiguration, einschließlich cache_control und defer_loading. Während der Beta-Phase können einige Tool-Typen (darunter das Computer-Use-Tool) noch nicht in einer Nachricht definiert werden und geben einen 400-Fehler mit einem entsprechenden Hinweis zurück; deklariere diese in tools und füge sie per Referenz hinzu. So definierst du beispielsweise ein benutzerdefiniertes Tool mitten im Gespräch:
{
"role": "system",
"content": [
{
"type": "tool_addition",
"tool": {
"type": "tool_definition",
"definition": {
"name": "db_query",
"description": "Run a read-only SQL query against the analytics database.",
"input_schema": {
"type": "object",
"properties": { "sql": { "type": "string" } },
"required": ["sql"]
}
}
}
}
]
}Ab dieser Position kann das Modell das Tool genauso aufrufen wie ein in tools deklariertes Tool. Das erneute Senden einer identischen Definition ändert nichts, sodass ein Client sie gefahrlos erneut senden kann, zum Beispiel bei einem Retry.
Die folgende Anfrage behält get_weather in tools und definiert db_query nach dem ersten Benutzer-Turn:
client = anthropic.Anthropic()
response = client.beta.messages.create(
model="claude-opus-5-5",
max_tokens=1024,
betas=["inline-tools-2026-09-15"],
# Behalte mindestens ein nicht verzögertes Tool in `tools`, damit ein Tool, das
# später definiert wird, den Anfang des gerenderten Prompts nicht verändert.
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": "How many orders shipped yesterday?"},
# Definiere db_query ab hier per Wert. `tools` und die
# früheren Nachrichten bleiben exakt wie gesendet, daher greift der Cache weiterhin.
{
"role": "system",
"content": [
{
"type": "tool_addition",
"tool": {
"type": "tool_definition",
"definition": {
"name": "db_query",
"description": "Run a read-only SQL query against the analytics database.",
"input_schema": {
"type": "object",
"properties": {"sql": {"type": "string"}},
"required": ["sql"],
},
},
},
},
],
},
],
)
for block in response.content:
if block.type == "tool_use":
print(block.name, block.input)Der content der Antwort enthält einen tool_use-Block für das neue Tool, zum Beispiel:
{
"type": "tool_use",
"id": "toolu_01A09q90qw90lq917835lq9",
"name": "db_query",
"input": {
"sql": "SELECT COUNT(*) FROM orders WHERE shipped_at::date = CURRENT_DATE - 1"
}
}Um das Schema eines Tools zu ändern oder ein Server-Tool auf eine neuere Version umzustellen, sende eine andere Definition unter demselben Namen. Die neue Definition ersetzt die frühere ab dieser Position. Eine Definition, die den Namen eines Tools eines anderen Typs wiederverwendet, gibt einen 400-Fehler zurück, bei dem error.details.error_code auf tool_name_conflict gesetzt ist. Eine neuere Version desselben Tools gilt nicht als anderer Typ. tool_removal nimmt weiterhin eine Referenz entgegen, und ein entferntes Tool kann später erneut definiert oder wieder angeboten werden.
Aus der Stelle, an der die Definition gerendert wird, ergeben sich einige Regeln:
- Deklariere vorab, was du weißt. Ein Tool, das dir bei der ersten Anfrage bekannt ist, gehört in
tools, mitdefer_loading: trueund einer späterentool_addition-Referenz, falls das Modell es noch nicht sehen soll. Definiere nur das per Wert, was bei der ersten Anfrage unbekannt ist oder sich später ändert. - Behalte mindestens ein nicht zurückgestelltes Tool in
tools. Ein Gespräch, dessentools-Array kein nicht zurückgestelltes Tool enthält, wird akzeptiert, aber das erste Tool, das es per Wert definiert, verändert den Anfang des gerenderten Prompts, was bei dieser Anfrage einen vollständigen Cache-Miss kostet. Ein Tool-Search-Tool zählt als nicht zurückgestellt. - Datierte Tool-Typen behalten ihre eigenen Beta-Header. Wenn ein Server-Tool, das du per Wert definierst, einen eigenen Beta-Header erfordert, sende diesen Header bei jeder späteren Anfrage im Gespräch.
cache_controlgehört entweder an den Block oder in die Definition, nicht an beide, und zählt zum Breakpoint-Limit der Anfrage. Eine zurückgestellte Definition kann keincache_controlenthalten.
Eine Anfrage gibt einen 400-Fehler zurück, bei dem error.details.error_code auf available_tools_limit_exceeded gesetzt ist, wenn eines dieser Limits überschritten wird:
- Nach einer beliebigen Nachricht sind mehr als 10.000 zurückgestellte Tools verfügbar.
- Nach einer beliebigen Nachricht sind mehr als 10.000 Tools verfügbar, die nach der ersten Benutzernachricht definiert wurden.
- Die nach der ersten Benutzernachricht gesendeten Tool-Definitionen, die nach einer beliebigen Nachricht noch verfügbar sind, umfassen insgesamt mehr als 4 MB (4.194.304 Bytes).
- Der gerenderte Tool-Text ist größer als 4 MB (4.194.304 Bytes).
Einen MCP-Server mitten im Gespräch hinzufügen (Beta)
Um mitten in einem Gespräch einen Server des MCP-Connectors hinzuzufügen, sende den Beta-Header mcp-client-2026-09-15 zusammen mit inline-tools-2026-09-15. Die definition in einem tool_addition-Block kann dann ein mcp_toolset sein, sodass die Tools des Servers verfügbar werden, ohne tools zu bearbeiten. Gib die Verbindungsdetails des Servers wie gewohnt in mcp_servers an und hänge dann das Toolset an der Stelle an, an der der Server verfügbar wurde:
{
"role": "system",
"content": [
{
"type": "tool_addition",
"tool": {
"type": "tool_definition",
"definition": { "type": "mcp_toolset", "mcp_server_name": "calendar" }
}
}
]
}Das mcp_toolset-Objekt ist dasselbe, das du in tools angeben würdest, einschließlich default_config und configs. Ein tool_addition-Block enthält niemals eine Server-URL oder ein Token. Diese bleiben in mcp_servers.
Die folgende Anfrage behält get_weather in tools, listet den Kalenderserver in mcp_servers auf und fügt das Toolset des Servers nach dem ersten Benutzer-Turn hinzu:
client = anthropic.Anthropic()
response = client.beta.messages.create(
model="claude-opus-5-5",
max_tokens=1024,
betas=["inline-tools-2026-09-15", "mcp-client-2026-09-15"],
mcp_servers=[
{
"type": "url",
"url": "https://mcp.example.com/calendar",
"name": "calendar",
"authorization_token": "YOUR_TOKEN",
},
],
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": "What's on my calendar tomorrow?"},
# Stelle die Tools des Kalender-Servers ab diesem Punkt zur Verfügung.
# Der Block benennt den Server; er enthält nie eine URL oder ein Token.
{
"role": "system",
"content": [
{
"type": "tool_addition",
"tool": {
"type": "tool_definition",
"definition": {
"type": "mcp_toolset",
"mcp_server_name": "calendar",
},
},
},
],
},
],
)
# Die Antwort beginnt mit einem mcp_tool_listing-Block für den Kalender-Server,
# prüfe also den Typ jedes Blocks, statt content[0] zu lesen.
for block in response.content:
match block.type:
case "mcp_tool_listing":
print(block.mcp_server_name, [tool.name for tool in block.tools])
case "text":
print(block.text)Mit mcp-client-2026-09-15 beginnt eine Antwort, für die die API die Tool-Liste eines Servers abgerufen hat, mit einem mcp_tool_listing-Block, einem für jeden abgerufenen Server. Wenn dein Code content[0] liest, überspringe diese Blöcke. Sende die Assistant-Nachricht unverändert zurück, einschließlich dieses Blocks, und sende mcp-client-2026-09-15 weiterhin bei jeder Anfrage, die ihn enthält. Spätere Anfragen verwenden dann die aufgezeichnete Liste, statt den Server erneut abzufragen. Um ein Toolset selbst zu fixieren, kopiere diese Liste in das Feld tools des mcp_toolset, wie unter Die Tool-Liste eines MCP-Servers fixieren beschrieben.
mcp-client-2026-09-15 umfasst alles, was mcp-client-2025-11-20 umfasst, sodass du nicht beide senden musst. Diese Funktionen sind auf der Claude API verfügbar. Für Anfragen, die den MCP-Connector verwenden, gelten weiterhin dessen Bedingungen zur Datenaufbewahrung.
Wann eine System-Nachricht mitten im Gespräch sinnvoll ist
Prompt-Caching hasht das Anfragepräfix der Reihe nach: tools, dann system, dann messages. Ein Cache-Treffer erfordert, dass das Präfix bis zum Cache-Breakpoint Byte für Byte exakt mit einer kürzlich gestellten Anfrage übereinstimmt.
Diese Reihenfolge bedeutet, dass das Top-Level-Feld system ganz am Anfang des gehashten Präfixes liegt. Jede Änderung daran, selbst das Anhängen eines Satzes, erzeugt einen anderen Hash, und die Anfrage verfehlt den Cache für den System-Prompt und jede gecachte Nachricht danach.
Mit System-Nachrichten mitten im Gespräch kannst du die Anweisung stattdessen am Ende des Nachrichtenverlaufs hinzufügen. Alles vor der neuen Anweisung bleibt unverändert, sodass der bestehende Cache-Eintrag weiterhin passt und nur die neue Nachricht als frische Eingabe verarbeitet wird.
Einige Situationen, in denen das wichtig ist:
- Richtlinien- oder Persona-Änderungen mitten in der Sitzung. Eine lange agentische Sitzung benötigt nach Dutzenden gecachter Turns eine neue Einschränkung („schreibe ab jetzt alle SQL-Abfragen als parametrisierte Queries“). Sie dem Top-Level-Feld
systemhinzuzufügen, würde den gesamten Verlauf neu verarbeiten. - Turn-bezogener Kontext, der maßgeblich sein muss. Du möchtest einen Aktualitätshinweis, eine Sitzungsfrist oder eine Änderung der Tool-Verfügbarkeit mit Systemgewicht einfügen, und er ändert sich zu oft, um im gecachten Präfix zu stehen.
- Turn-bezogene Erinnerungen, die sich nicht anhäufen sollen. Ein Harness stupst das Modell nach jedem Stapel von Tool-Ergebnissen an („fordere unabhängige Lesevorgänge gemeinsam an“, „der Benutzer hat schon eine Weile nichts von dir gehört“) und möchte, dass das Modell nur die neueste Kopie sieht. Eine turn-bezogene System-Nachricht wird für einen Turn gerendert und kostet danach nichts, ohne dass etwas aus dem Verlauf gelöscht wird.
- Zustandsänderungen, die deine Anwendung beobachtet. Deine Anwendung bemerkt etwas, das Claude als Tatsache auf Betreiberebene behandeln sollte: Dateien auf der Festplatte haben sich geändert, der Benutzer hat eine Auto-Approve-Einstellung umgeschaltet, die verfügbaren Tools haben sich geändert oder das verbleibende Token-Budget ist unter einen Schwellenwert gefallen.
- Benutzereingaben, die eine agentische Schleife nicht unterbrechen sollen. Ein Benutzer tippt eine Folgefrage, während Claude noch Tools für die vorherige Anfrage ausführt. Wenn du sie als System-Nachricht nach dem nächsten Tool-Ergebnis weiterleitest, kann Claude die neue Eingabe in die bereits laufende Arbeit einbeziehen, anstatt sie als neue Anfrage zu behandeln, zu der gewechselt werden muss. Hänge bei Claude Sonnet 5.5 und Claude Haiku 5.5 die Worte des Benutzers stattdessen als
text-Block nach dem letztentool_resultin derselbenuser-Nachricht an. Siehe Platzierung nach Tool-Ergebnissen. - Moduswechsel, die dauerhafte Berechtigungen erteilen. Ein Modus auf Sitzungsebene kann eine System-Nachricht mitten im Gespräch verwenden, um eine dauerhafte Zustimmung zu einer teuren Fähigkeit zu erteilen, etwa dem automatischen Starten von Multiagenten-Workflows, mit einer kurzen Auffrischung alle paar Turns und einem Hinweis beim Verlassen, wenn der Modus ausgeschaltet wird. Ein ausgearbeitetes Beispiel findest du unter Einen Orchestrierungsmodus erstellen.
In all diesen Fällen könntest du die Anweisung in eine reguläre user-Nachricht setzen, und Claude befolgt durchaus Anweisungen, die in Benutzer-Turns eintreffen. Der Unterschied liegt in der Priorität: Eine user-Nachricht wird so behandelt, als käme sie vom Endbenutzer, während eine system-Nachricht so behandelt wird, als käme sie von dir, dem Betreiber der Anwendung. Wenn beide in Konflikt stehen, haben Systemanweisungen Vorrang. Verwende daher die system-Rolle für Tatsachen und Einschränkungen auf Betreiberebene, die auch dann gelten sollen, wenn der Endbenutzer etwas anderes verlangt. Eine System-Nachricht mitten im Gespräch behält diese Priorität auf Betreiberebene, ohne die Cache-Miss-Kosten für das Bearbeiten des Top-Level-Felds system zu zahlen.
Funktionsweise
Füge dem messages-Array eine Nachricht mit "role": "system" hinzu. Verwende für content einen einfachen String oder Content-Blöcke, genau wie bei einem user- oder assistant-Turn. Die Anweisung gilt ab diesem Punkt im Gespräch. Wenn Anweisungen im Widerspruch stehen, haben spätere System-Nachrichten Vorrang vor früheren, und System-Nachrichten mitten im Gespräch haben für die nachfolgenden Turns Vorrang vor dem Top-Level-Feld system.
Du kannst das Top-Level-Feld system weiterhin für Anweisungen setzen, die für das gesamte Gespräch gelten sollen. Reserviere System-Nachrichten mitten im Gespräch für Anweisungen, die erst später relevant werden oder die du hinzufügen möchtest, ohne das gecachte Präfix ungültig zu machen.
Eine role: "system"-Nachricht kann außerdem output_config.effort enthalten, um das Effort-Level mitten in einem Gespräch zu ändern. Dies ist als Beta für Claude Fable 5.1, Claude Mythos 5.1, Claude Opus 5.5, Claude Opus 5, Claude Sonnet 5.5 und Claude Haiku 5.5 auf der Claude API und Google Cloud verfügbar und erfordert den Beta-Header mid-conversation-output-config-2026-07-01. Auf Amazon Bedrock ist es als Beta für Claude Fable 5.1, Claude Mythos 5.1 und Claude Opus 5.5 verfügbar, mit demselben Beta-Wert. Claude Opus 5 unterstützt es auf Amazon Bedrock nicht. Siehe Effort pro Nachricht.
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-opus-5-5",
max_tokens=1024,
# Automatisches Prompt-Caching: Jede Anfrage cacht die bisherige Konversation,
# und die nächste Anfrage liest das unveränderte Präfix aus dem Cache.
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().",
},
# Der Reviewer merkt mitten in der Sitzung, dass alle Vorschläge
# auch die strikte Typisierungsrichtlinie des Teams erfüllen müssen. Hängst du die
# Anweisung hier an, bleiben frühere Turns byte-identisch, sodass das
# von der vorherigen Anfrage gecachte Präfix weiterhin aus dem Cache gelesen wird.
{
"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)Dieses Beispiel aktiviert automatisches Caching mit dem Top-Level-Feld cache_control. Prompt-Caching ist optional: Wenn eine Anfrage kein cache_control-Feld enthält (automatisch oder als expliziter Breakpoint), wird nichts gecacht, und jede Anfrage zahlt den regulären Preis für Eingabe-Token für das gesamte Gespräch. Bei aktiviertem Caching lässt das Anhängen der System-Nachricht die bereits gecachten Turns unverändert, sodass die Anfrage mit der neuen Anweisung sie weiterhin aus dem Cache liest, statt sie erneut zu verarbeiten. Caching setzt außerdem voraus, dass das Gespräch die minimale cachebare Prompt-Länge erreicht; ein so kurzes Beispiel wie dieses liegt darunter, sodass cache_creation_input_tokens und cache_read_input_tokens bei 0 bleiben, bis das Gespräch wächst.
Eine System-Nachricht mitten im Gespräch, die Inhalt enthält (text-, tool_addition- oder tool_removal-Blöcke), muss unmittelbar auf einen user-Turn folgen (oder auf einen assistant-Turn, der mit einem Server-Tool-Ergebnis endet) und muss entweder der letzte Eintrag in messages sein oder unmittelbar von einem assistant-Turn gefolgt werden. Eine user-Nachricht mit tool_result-Blöcken zählt ebenfalls: In einer agentischen Schleife kannst du die System-Nachricht direkt nach den Tool-Ergebnissen platzieren, vor Claudes nächstem Turn. Jede andere Position für eine Nachricht mit Inhalt, auch eine zwischen einem assistant-tool_use-Block und dem tool_result, das ihn beantwortet, gibt einen 400-Fehler zurück. Eine Nachricht mit leerem content, die nur output_config.effort setzt, wird überall in messages akzeptiert. Aufeinanderfolgende system-Nachrichten werden gemeinsam beurteilt, sodass eine reine Effort-Nachricht neben einer Nachricht mit Inhalt der Regel für Inhalte folgt.
Platzierung nach Tool-Ergebnissen
In einer agentischen Schleife steht die System-Nachricht nach der user-Nachricht, die die Tool-Ergebnisse liefert. Bei den meisten Modellen ist dies auch die Stelle, an der deine Anwendung Eingaben weiterleiten kann, die der Benutzer getippt hat, während Claude gearbeitet hat, sodass der neue Kontext aufgenommen wird, ohne den Turn neu zu starten (für Claude Sonnet 5.5 und Claude Haiku 5.5 siehe das Ende dieses Abschnitts):
[
{ "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."
}
]Formuliere den Systeminhalt als Kontext und nicht als Befehl, der den Benutzer übersteuert. Nenne die Tatsache („neue Eingabe vom Benutzer eingetroffen: X“, „das verbleibende Token-Budget beträgt jetzt Y“) und lass Claude darauf reagieren. Claude ist darauf trainiert, Anweisungen zu widerstehen, die gegen den Benutzer zu arbeiten scheinen, und dieser Schutz gilt auch für die System-Rolle. Formulierungen wie „ignoriere, was der Benutzer gesagt hat“ sind daher weniger wirksam als die Angabe, was sich geändert hat.
Dieses Muster dient dazu, Eingaben des eigenen Endbenutzers des Gesprächs weiterzuleiten. Verwende es nicht, um Tool-Ausgaben, abgerufene Dokumente oder andere Inhalte Dritter zu übergeben; belasse solche Inhalte in tool_result-Blöcken (siehe Einschränkungen).
Übermittle bei Claude Sonnet 5.5 und Claude Haiku 5.5 die Worte des Benutzers stattdessen im Benutzer-Turn. Diese Modelle sind darauf trainiert, Prompt-Injection über Tool-Ergebnisse zu widerstehen, sodass sie eine direkt nach einem Tool-Ergebnis platzierte System-Nachricht als nicht vertrauenswürdigen Text behandeln und ignorieren können. Hänge die Worte des Benutzers als text-Block nach dem letzten tool_result in derselben user-Nachricht an. Behalte Harness-Hinweise, etwa Erinnerungen, in einer separaten System-Nachricht mitten im Gespräch nach dieser user-Nachricht, und setze niemals einen Hinweis und die Worte des Benutzers in denselben Block:
[
{ "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" },
{ "type": "text", "text": "Also update the changelog before you finish." }
]
}
]Mehr zu diesem Verhalten findest du unter Prompting für Claude Sonnet 5.5 und Prompting für Claude Haiku 5.5.
Turn-bezogene System-Nachrichten
Um eine role: "system"-Nachricht auf den aktuellen Turn zu beschränken, setze ihr Feld clear_at. Es nimmt einen von zwei Werten an:
"never"(Standard): Die Nachricht wird bei jeder Anfrage, die sie enthält, an ihrer Position gerendert. Das Weglassen des Felds ist gleichbedeutend."next_user_message": Die Nachricht ist „turn-scoped“ (Turn-bezogen). Ihr Text wird nur gerendert, solange inmessageskeinerole: "user"-Nachricht nach ihr folgt. Eine Benutzernachricht, die nurtool_result-Blöcke enthält, zählt hier als Benutzernachricht. Sobald eine spätere Benutzernachricht existiert, wird die Nachricht „cleared“ (geleert): Sie bleibt im Array, rendert aber nichts und kostet keine Eingabe-Token, bei dieser Anfrage und bei jeder späteren.
Turn-bezogene System-Nachrichten befinden sich in der Beta-Phase. Füge den Beta-Header mid-conversation-system-clear-at-2026-08-21 hinzu. Ohne ihn wird clear_at als unbekanntes Feld abgelehnt.
{
"role": "system",
"clear_at": "next_user_message",
"content": "First privately list what you need next; then request every item that doesn't depend on another's result in this one response."
}Der Hauptanwendungsfall ist eine Erinnerung pro Turn in einer Tool-Schleife. Hänge die Erinnerung jedes Mal nach der tool_result-Nachricht an, wenn das Modell sie sehen soll, und lass jede frühere Kopie an ihrem Platz. Das Modell sieht nur die Kopien, die nach der letzten Benutzernachricht kommen, sodass sich die Erinnerung nie anhäuft. Nichts weiter vorne in messages ändert sich, sodass der Prompt-Cache weiterhin übereinstimmt. Auf Claude Fable 5.1, Claude Opus 5.5, Claude Sonnet 5.5 und Claude Haiku 5.5 hält dies außerdem spätere Thinking-Blöcke gültig: Das Löschen einer früheren Erinnerung würde das Gespräch vor diesen Blöcken verändern und die Gesprächsprüfung fehlschlagen lassen, während eine geleerte Nachricht im Array bleibt und dieses Gespräch unverändert lässt.
Die folgende Anfrage ist ein späterer Schritt einer Agent-Schleife. messages[3] wurde bei der früheren Anfrage gerendert, als sie die letzte Nachricht im Array war. Sobald messages[5] (eine spätere Benutzernachricht) existiert, wird messages[3] geleert: Die geleerte Nachricht bleibt im Array, sodass das Gespräch vor dem Thinking-Block in messages[4] unverändert ist, aber das Modell sieht ihren Text nicht mehr. messages[6] und messages[7] werden beide in dieser Reihenfolge gerendert.
{
"model": "claude-fable-5-1",
"max_tokens": 16000,
"messages": [
{ "role": "user", "content": "Fix the failing test." },
{
"role": "assistant",
"content": [
{ "type": "thinking", "thinking": "", "signature": "..." },
{
"type": "tool_use",
"id": "toolu_01",
"name": "read_file",
"input": { "path": "test_auth.py" }
}
]
},
{
"role": "user",
"content": [{ "type": "tool_result", "tool_use_id": "toolu_01", "content": "..." }]
},
{
"role": "system",
"clear_at": "next_user_message",
"content": "Request independent reads in one turn."
},
{
"role": "assistant",
"content": [
{ "type": "thinking", "thinking": "", "signature": "..." },
{
"type": "tool_use",
"id": "toolu_02",
"name": "read_file",
"input": { "path": "auth.py" }
},
{
"type": "tool_use",
"id": "toolu_03",
"name": "read_file",
"input": { "path": "tokens.py" }
}
]
},
{
"role": "user",
"content": [
{ "type": "tool_result", "tool_use_id": "toolu_02", "content": "..." },
{
"type": "tool_result",
"tool_use_id": "toolu_03",
"content": "...",
"cache_control": { "type": "ephemeral" }
}
]
},
{
"role": "system",
"clear_at": "next_user_message",
"content": "Request independent reads in one turn."
},
{
"role": "system",
"clear_at": "next_user_message",
"content": "The shell exited with status 137."
}
]
}Regeln für Turn-bezogene Nachrichten:
- Sende geleerte Nachrichten wortgetreu erneut. Eine geleerte Nachricht ist weiterhin Teil des Gesprächsverlaufs. Sie aus dem aktuellen Zustand neu aufzubauen (eine frische Token-Zählung, ein Zeitstempel), sie als überflüssig wegzulassen oder ihren
clear_at-Wert zu ändern, ist eine Bearbeitung einer früheren Nachricht. Der Prompt-Cache verfehlt ab diesem Punkt, und auf Claude Fable 5.1, Claude Opus 5.5, Claude Sonnet 5.5 und Claude Haiku 5.5 besteht jeder danach erzeugte Thinking-Block die Gesprächsprüfung nicht. - Nur Text.
contentbesteht aus einem oder mehrerentext-Blöcken (oder einem String).tool_addition- undtool_removal-Blöcke geben bei einer Turn-bezogenen Nachricht einen 400-Fehler zurück, ebensooutput_config. Verwende dafür eine separaterole: "system"-Nachricht ohneclear_at. - Kein
cache_controlan ihren Blöcken. Eine geleerte Nachricht ist nie Teil eines Cache-Schlüssels, daher könnte ein Breakpoint an ihr nie übereinstimmen. Setze den Breakpoint stattdessen an den letzten Block des vorangehenden Benutzer-Turns, wie im Beispiel. Das oberste Feld für automatisches Caching überspringt Turn-bezogene Nachrichten, wenn es einen Breakpoint auswählt. Bei der Anfrage, die eine Nachricht leert, endet das wiederverwendbare gecachte Präfix beim Benutzer-Turn davor, sodass nur der eine Assistant-Turn zwischen dieser Nachricht und der neuen Benutzernachricht erneut verarbeitet wird. - Platzierungsregeln gelten weiterhin, ob geleert oder nicht. Eine Turn-bezogene Nachricht muss auf einen
user-Turn folgen (oder auf einenassistant-Turn, der mit einem Server-Tool-Ergebnis endet) und einemassistant-Turn vorangehen oder das Array beenden, wie jede Systemnachricht mitten im Gespräch. Eine, die das Array beendet, wird immer gerendert. Eine, auf die direkt eine weitereuser-Nachricht folgt, ist ein 400-Fehler und keine geleerte Nachricht: Fasse alle Ergebnisse einer Tool-Runde in einer Benutzernachricht zusammen und setze die Erinnerungen danach. - Assistant-Turns leeren sie nicht. Ein vorausgefüllter oder pausierter Assistant-Turn nach der Nachricht oder eine serverseitige Tool-Schleife fügt keine Benutzernachricht hinzu, sodass die Nachricht bei dieser Fortsetzung weiterhin gerendert wird. Um eine Erinnerung während einer clientseitigen Tool-Schleife sichtbar zu halten, hänge sie nach jeder
tool_result-Nachricht erneut an. - Die Token-Zählung folgt dem, was gerendert wird. Eine geleerte Nachricht trägt nichts zu
usage.input_tokensoder zu einer Token-Zählung bei. - Importierter Verlauf. In einem Transkript, das du in einem Schritt erstellst (Few-Shot-Beispiele, ein migriertes Gespräch), wird eine Turn-bezogene Nachricht, auf die bereits ein Assistant-Turn und eine Benutzernachricht folgen, ab der ersten Anfrage geleert und nie gerendert. Das ist der richtige Zustand für eine Erinnerung pro Turn, die du übernimmst. Lass
clear_atnur bei einer Nachricht ungesetzt, die das Modell bei jeder Anfrage sehen soll.
Die Validierungsfehler sind:
messages.3.clear_at: Extra inputs are not permitted
messages.3.clear_at: clear_at is only permitted on role 'system' messages
messages.3.clear_at: Input should be 'next_user_message' or 'never'
messages.3: a turn-scoped system message supports text blocks only (clear_at: 'next_user_message')
messages.3: output_config is not permitted on a turn-scoped system message (clear_at: 'next_user_message')
messages.3.content.0: cache_control is not permitted on a turn-scoped system message (clear_at: 'next_user_message')Der erste ist der Fehler, der ohne den Beta-Header zurückgegeben wird. Sende auf Google Cloud und Claude in Amazon Bedrock den Beta-Wert im anthropic-beta-Header, wie auf der Claude API (siehe Beta-Header). Mit der Amazon Bedrock InvokeModel API setzt du ihn stattdessen in das anthropic_beta-Array des Anfrage-Bodys.
Setze über das SDK clear_at auf dem role: "system"-Eintrag in messages und sende den Beta-Header. Das folgende Beispiel hängt eine Turn-bezogene Erinnerung nach dem Benutzer-Turn an; bei der nächsten Anfrage, sobald eine spätere Benutzernachricht existiert, bleibt die Erinnerung im Array, wird aber nicht mehr gerendert:
client = anthropic.Anthropic()
response = client.beta.messages.create(
model="claude-fable-5-1",
max_tokens=4096,
messages=[
{
"role": "user",
"content": "Draft a short status update on the database migration for the team channel.",
},
# Turn-bezogene Erinnerung: wird für diesen Turn gerendert und entfernt, sobald eine spätere User-Nachricht existiert.
{
"role": "system",
"clear_at": "next_user_message",
"content": "The reader is on call: keep this reply under 50 words.",
},
],
betas=["mid-conversation-system-clear-at-2026-08-21"],
)
for block in response.content:
if block.type == "text":
print(block.text)Kombination mit Prompt-Caching
System-Nachrichten mitten im Gespräch und Prompt-Caching sind für die gemeinsame Verwendung konzipiert:
- Aktiviere das Caching explizit. Caching findet nur statt, wenn die Anfrage
cache_controlenthält, entweder als Top-Level-Feld für automatisches Caching oder als expliziten Breakpoint an einem Content-Block. Eine System-Nachricht mitten im Gespräch erzeugt von sich aus keinen Cache-Eintrag, und ohne aktiviertes Caching gibt es keine Einsparungen, die erhalten bleiben könnten. - Cache das stabile Präfix wie gewohnt. Setze
cache_controlan den letzten Block, der über Anfragen hinweg gleich bleibt, sei es das Ende des Top-Level-Feldssystem, das Ende deiner Tool-Definitionen oder ein stabiler Punkt im Nachrichtenverlauf. - Hänge die System-Nachricht nach dem Breakpoint an. Da sie nach dem gecachten Präfix kommt, ändert sie den Präfix-Hash nicht, und der Cache wird weiterhin getroffen.
- Eine System-Nachricht mitten im Gespräch ist selbst cachebar. Sobald sie Teil des Gesprächs ist, gehört sie zum stabilen Verlauf. Im nächsten Turn kannst du deinen Cache-Breakpoint hinter sie verschieben (oder dich darauf verlassen, dass automatisches Caching dies übernimmt), und die System-Nachricht wird wie jeder andere Turn aus dem Cache gelesen.
Vermeide es, eine bereits gesendete System-Nachricht mitten im Gespräch zu bearbeiten oder zu entfernen. Wie jede andere Änderung an früheren Nachrichten macht dies den Cache ab diesem Punkt ungültig. Auf Claude Fable 5.1, Claude Opus 5.5, Claude Sonnet 5.5 und Claude Haiku 5.5 macht es außerdem die Thinking-Blöcke in jedem späteren Assistant-Turn ungültig. Für Hinweise, die nur für einen Turn gelten sollen, verwende eine Turn-bezogene System-Nachricht und lass sie an ihrem Platz. Wenn sich die Anweisung weiterentwickeln muss, hänge eine neue System-Nachricht an, anstatt die alte umzuschreiben. Aufeinanderfolgende System-Nachrichten werden akzeptiert und als ein einziger System-Abschnitt behandelt, der als Ganzes derselben Platzierungsregel folgt.
Einschränkungen
- Nicht für die erste Nachricht. Eine
system-Nachricht mit Inhalt kann nicht der erste Eintrag inmessagessein. Verwende das Top-Level-Feldsystemfür Anweisungen, die von Anfang an gelten. - Die Platzierung ist eingeschränkt. Eine
system-Nachricht mit Inhalt (text-,tool_addition- odertool_removal-Blöcke) muss unmittelbar auf einenuser-Turn folgen (einschließlich einesuser-Turns mittool_result-Blöcken) oder auf einenassistant-Turn, der mit einem Server-Tool-Ergebnis endet, und muss einemassistant-Turn vorangehen oder das Array beenden. Sie kann nicht zwischen einemtool_use-Block und seinemtool_resultstehen. Eine Platzierung an anderer Stelle gibt einen 400-Fehler zurück. Eine Ausnahme:tool_addition- undtool_removal-Blöcke werden unmittelbar nach einem pausiertenassistant-Turn (einem, der mit einem Server-Tool-Ergebnis endet) nicht akzeptiert,text-Blöcke hingegen schon; setze zuerst den pausierten Turn fort und sende die Tool-Änderung dann in der nächstensystem-Nachricht. Eine Nachricht mit leeremcontent, die nuroutput_config.effortsetzt, rendert an ihrer Position nichts und wird überall inmessagesakzeptiert, auch als erster Eintrag oder zwischen einemassistant-Turn und einemuser-Turn. Aufeinanderfolgendesystem-Nachrichten werden gemeinsam beurteilt, sodass das Hinzufügen einer Nachricht mit Text neben einer reinen Effort-Nachricht dazu führt, dass die gesamte Gruppe der Regel für Inhalte folgt. - Turn-bezogene Nachrichten enthalten nur Text und werden unverändert erneut gesendet. Eine
clear_at: "next_user_message"-Nachricht enthält keintool_addition,tool_removal,output_configodercache_control, und sobald sie geleert ist, muss sie bei späteren Anfragen Byte für Byte inmessagesbleiben. Siehe Turn-bezogene Systemnachrichten. - Kein Ort für nicht vertrauenswürdige Inhalte. Claude behandelt Systeminhalte als Operator-Anweisungen und befolgt sie. Platziere keinen Text von außerhalb der Konversation, etwa rohe Tool-Ausgaben, abgerufene Dokumente oder Webinhalte, direkt in einer Systemnachricht; dadurch erhält dieser Text Autorität auf Operator-Ebene. Belasse solche Daten in
tool_result-Blöcken und befolge weiterhin Jailbreaks und Prompt-Injections abwehren.
Verwandte Themen
Wie Caching funktioniert, wo Breakpoints platziert werden und wie die Cache-Nutzungsfelder zu lesen sind.
Finde genau heraus, wo zwei Anfragen voneinander abwichen, wenn ein erwarteter Cache-Treffer nicht eintritt.
Nachrichtenstruktur, Gespräche über mehrere Turns und das system-Feld.
Effektive Prompts und Systemanweisungen schreiben.
Wie tool_use- und tool_result-Blöcke im messages-Array strukturiert sind.
Was this page helpful?