Claude Platform Docs
MessagesKontextverwaltung

Cache-Diagnose

Diagnostiziere unerwartete Prompt-Cache-Fehlschläge, indem du aufeinanderfolgende Anfragen vergleichst und genau identifizierst, wo das Prompt-Präfix abgewichen ist.

Prompt-Caching reduziert Latenz und Kosten erheblich, aber nur, wenn der Anfang deines Prompts Byte für Byte identisch mit einer kürzlichen Anfrage ist. Ein umgeordnetes Tool, ein in deinen System-Prompt interpolierter Zeitstempel oder eine Bearbeitung einer früheren Nachricht kann den Cache stillschweigend ungültig machen. Ohne Cache-Diagnose ist das einzige Signal, dass usage.cache_read_input_tokens auf null fällt, ohne Hinweis darauf, was sich geändert hat.

Die Cache-Diagnose schließt diese Lücke. Übergib die id deiner vorherigen Antwort, und die API vergleicht die beiden Anfragen und teilt dir mit, wo sie abgewichen sind (das Modell, der System-Prompt, die Tools oder der Nachrichtenverlauf), sodass du die Ursache beheben kannst, anstatt zu raten.

Wie die Cache-Diagnose funktioniert

Wenn der Beta-Header vorhanden ist, speichert die API einen leichtgewichtigen Fingerabdruck jeder Anfrage, indiziert nach der Antwort-id. Füge bei deiner nächsten Anfrage diese id als diagnostics.previous_message_id hinzu. Die API erstellt den Fingerabdruck für die neue Anfrage neu, vergleicht ihn mit dem gespeicherten und hängt ein diagnostics-Objekt an die Antwort an, das den ersten Abweichungspunkt beschreibt.

Der Vergleich bezieht sich auf die Anfragestruktur, unabhängig davon, ob der Cache tatsächlich getroffen wurde. Siehe Diagnose zusammen mit der Nutzung lesen, um zu erfahren, wie du das diagnostics-Ergebnis mit usage.cache_read_input_tokens kombinierst.

Fingerabdrücke enthalten nur Hashes und Token-Anzahl-Schätzungen (niemals rohen Prompt-Inhalt), werden für eine begrenzte Zeit aufbewahrt, sind auf deine Organisation und deinen Workspace beschränkt und werden für keinen anderen Zweck verwendet.

Grundlegende Verwendung

Sende den Beta-Header bei jedem Zug. Übergib beim ersten Zug "previous_message_id": null, um dich ohne eine vorherige Nachricht zum Vergleich anzumelden. Übergib bei nachfolgenden Zügen die id aus der vorherigen Antwort.

client = anthropic.Anthropic()

SYSTEM = "You are an AI assistant analyzing a large document. <document>...</document>"

# Runde 1: Aktivierung mit previous_message_id=None
r1 = client.beta.messages.create(
    model="claude-opus-5",
    max_tokens=1024,
    cache_control={"type": "ephemeral"},
    system=SYSTEM,
    messages=[{"role": "user", "content": "Summarize section 1."}],
    diagnostics={"previous_message_id": None},
    betas=["cache-diagnosis-2026-04-07"],
)

# Runde 2: Verweise auf die vorherige Response-ID
r2 = client.beta.messages.create(
    model="claude-opus-5",
    max_tokens=1024,
    cache_control={"type": "ephemeral"},
    system=SYSTEM,
    messages=[
        {"role": "user", "content": "Summarize section 1."},
        {"role": "assistant", "content": r1.content},
        {"role": "user", "content": "Now summarize section 2."},
    ],
    diagnostics={"previous_message_id": r1.id},
    betas=["cache-diagnosis-2026-04-07"],
)

diagnostics = r2.diagnostics
if diagnostics is None:
    print("No divergence detected.")
elif diagnostics.cache_miss_reason is None:
    print("Comparison still pending.")
else:
    print(f"cache_miss_reason: {diagnostics.cache_miss_reason.type}")

Streaming

In Streaming-Antworten erscheint diagnostics im message_start-Event.

# Runde 2: Streaming, unter Bezugnahme auf die vorherige Response-ID
with client.beta.messages.stream(
    model="claude-opus-5",
    max_tokens=1024,
    cache_control={"type": "ephemeral"},
    system=SYSTEM,
    messages=[
        {"role": "user", "content": "Summarize section 1."},
        {"role": "assistant", "content": r1.content},
        {"role": "user", "content": "Now summarize section 2."},
    ],
    diagnostics={"previous_message_id": r1.id},
    betas=["cache-diagnosis-2026-04-07"],
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)
    print()
    r2 = stream.get_final_message()

diagnostics = r2.diagnostics
if diagnostics is None:
    print("No divergence detected.")
elif diagnostics.cache_miss_reason is None:
    print("Comparison still pending.")
else:
    print(f"cache_miss_reason: {diagnostics.cache_miss_reason.type}")

Das message_start-Event trägt das vollständige diagnostics-Feld; siehe Antwortformat für die möglichen Werte.

Diagnose durch eine Gesprächsschleife führen

In einem Gespräch mit mehreren Zügen trägst du die neueste Antwort-id bei jedem Zug als previous_message_id weiter. Die erste Iteration übergibt null, um sich anzumelden; jede nachfolgende Iteration übergibt die id aus der vorherigen Antwort.

client = anthropic.Anthropic()

SYSTEM = "You are an AI assistant analyzing a large document. <document>...</document>"

messages = []
prev_id = None

for i, user_message in enumerate(
    ["Summarize section 1.", "Now section 2.", "Now section 3."]
):
    messages.append({"role": "user", "content": user_message})

    r = client.beta.messages.create(
        model="claude-opus-5",
        max_tokens=1024,
        cache_control={"type": "ephemeral"},
        system=SYSTEM,
        messages=messages,
        diagnostics={"previous_message_id": prev_id},
        betas=["cache-diagnosis-2026-04-07"],
    )

    if r.diagnostics is not None and r.diagnostics.cache_miss_reason is not None:
        print(f"Turn {i + 1} cache_miss_reason: {r.diagnostics.cache_miss_reason.type}")

    messages.append({"role": "assistant", "content": r.content})
    prev_id = r.id

Antwortformat

Das diagnostics-Feld in der Antwort-Message hat vier mögliche Zustände:

WertBedeutung
Feld fehltDie Anfrage enthielt kein diagnostics, oder der Beta-Header fehlte.
nullEntweder war previous_message_id null (erster Zug, nichts zu vergleichen), oder ein Vergleich wurde durchgeführt und fand keine Abweichung.
{"cache_miss_reason": null}Der Vergleich lief noch, als die Antwort serialisiert wurde. Dies kann passieren, wenn die Antwort sehr schnell beginnt. Behandle es als nicht schlüssig und prüfe den nächsten Zug.
{"cache_miss_reason": {...}}Ein cache_miss_reason ist angehängt. Für *_changed-Typen identifiziert dies den ersten Abweichungspunkt; previous_message_not_found und unavailable sind Fälle, in denen kein Vergleich erzeugt wurde.

Wenn cache_miss_reason nicht null ist, sieht es so aus:

{
  "id": "msg_01Xyz...",
  "type": "message",
  "role": "assistant",
  "content": [{ "type": "text", "text": "..." }],
  "usage": {
    "input_tokens": 42,
    "cache_read_input_tokens": 0,
    "cache_creation_input_tokens": 41850,
    "output_tokens": 210
  },
  "diagnostics": {
    "cache_miss_reason": {
      "type": "system_changed",
      "cache_missed_input_tokens": 41850
    }
  }
}

Cache-Miss-Grund-Typen

cache_miss_reason ist eine diskriminierte Union über type. Die Antwort meldet nur die früheste Abweichung, also behebe diese zuerst; spätere könnten dahinter verborgen sein.

TypWas es bedeutetWas zu ändern ist
model_changedDas model unterscheidet sich von der vorherigen Anfrage (zum Beispiel hat ein Router, A/B-Test oder Fallback ein anderes Modell ausgewählt). Der Cache ist pro Modell.Halte das Modell innerhalb eines gecachten Gesprächs konstant.
system_changedDer system-Parameter unterscheidet sich. Typischerweise wurde ein Zeitstempel, eine Anfrage-ID oder ein anderer Wert pro Anfrage in den System-Prompt interpoliert.Mache den System-Prompt zu einer Byte-stabilen Konstante und verschiebe dynamische Daten in die erste user-Nachricht nach deinem Cache-Breakpoint.
tools_changedDas tools-Array unterscheidet sich: Tools wurden zwischen Zügen hinzugefügt, entfernt oder umgeordnet, oder das Tool-input_schema-JSON wurde nicht-deterministisch serialisiert.Sende bei jedem Zug dieselbe Tool-Liste in fester Reihenfolge mit deterministisch serialisierten Schemas (zum Beispiel sortierte Schlüssel).
messages_changedDas Modell, das System und die Tools stimmen alle überein, aber ein früherer Eintrag in messages wurde geändert, umgeordnet oder entfernt, anstatt angehängt zu werden. Typischerweise wurde der Gesprächsverlauf gekürzt oder bearbeitet, oder Assistenten-Züge und tool_result-Blöcke wurden beim erneuten Senden anders re-serialisiert.Behandle den Verlauf als nur-anhängend; gib Assistenten-content und Tool-Ergebnisse wortwörtlich zurück.
previous_message_not_foundFür die angegebene previous_message_id existiert kein gespeicherter Fingerabdruck. Dies ist kein Beweis dafür, dass sich deine Anfrage geändert hat. Typischerweise trug die vorherige Anfrage nicht den Beta-Header, sie kam aus einem anderen Workspace, oder seit dem Senden ist zu viel Zeit vergangen.Sende den Beta-Header bei jedem Zug und halte aufeinanderfolgende Züge zeitlich nah beieinander.
unavailableFür diese Anfrage waren keine Diagnoseinformationen verfügbar. Dies schließt den Fall ein, in dem model, system und tools übereinstimmen, aber ein anderer Prompt-beeinflussender Anfrageparameter (tool_choice, thinking, context_management, output_config, output_format oder die Menge der aktiven anthropic-beta-Header) sich unterscheidet, sowie sehr lange Gespräche, bei denen die Abweichung jenseits des Vergleichshorizonts liegt. Deine Anfrage wurde normal verarbeitet.Halte die Prompt-beeinflussenden Anfrageparameter für die Lebensdauer eines gecachten Gesprächs konstant. Wenn es anhält, wende die manuellen Prüfungen unter Häufige Probleme beheben auf der Prompt-Caching-Seite an.

Diagnose zusammen mit der Nutzung lesen

diagnostics beantwortet „hat sich meine Anfrage geändert?“, während usage.cache_read_input_tokens beantwortet „hat der Cache getroffen?“. Die Kombination sagt dir, wo du suchen musst.

Diese Matrix gilt für Züge, bei denen du eine echte previous_message_id übergeben hast. Beim ersten Zug (previous_message_id: null) ist diagnostics immer null und cache_read_input_tokens ist normalerweise null, weil der Cache geschrieben und nicht gelesen wird; keine Fehlerbehebung ist nötig. Die Matrix gilt auch nicht, wenn cache_miss_reason null ist (der Vergleich steht noch aus; prüfe den nächsten Zug) oder wenn sein type previous_message_not_found oder unavailable ist (kein Vergleich wurde erzeugt).

Diagnose-ErgebnisCache-Read-TokensInterpretation
nullhochFunktioniert wie erwartet. Dein Präfix ist stabil und der Cache hat getroffen.
nullniedrig oder nullDeine Anfragen stimmen überein, aber der Cache-Eintrag war nicht mehr verfügbar. Erwäge, die Lücken zwischen den Zügen zu verkürzen oder die 1-Stunden-Cache-TTL zu verwenden.
cache_miss_reason ist ein *_changed-Typniedrig oder nullDein Bug. Die Anfrage hat sich geändert; behebe die durch type angegebene Ursache.
cache_miss_reason ist ein *_changed-TyphochSelten. Eine Änderung trat spät im Prompt auf, aber ein früherer cache_control-Breakpoint hat dennoch getroffen. Wert, behoben zu werden, aber geringe Auswirkung.

Einschränkungen

  • Beta: Feldnamen und Semantik können sich ändern, während sich diese Funktion in der Beta befindet.
  • Nur Claude API: Nicht verfügbar auf Amazon Bedrock oder Google Cloud.
  • Begrenzte Aufbewahrung: Fingerabdrücke für die previous_message_id-Suche laufen nach einer kurzen Zeit ab. Führe Diagnosevergleiche zwischen eng beieinander liegenden Anfragen durch.
  • Gleicher Workspace: Die vorherige Anfrage muss in derselben Organisation und demselben Workspace ausgeführt worden sein. Um dies zu prüfen, vergleiche den anthropic-workspace-id-Antwort-Header der beiden Antworten.
  • Vergleichshorizont: Bei sehr langen Gesprächen, bei denen die einzige Änderung tief in der Nachrichtenliste liegt, kann die Antwort unavailable statt eines genauen Ortes sein.
  • Best-Effort: Die Diagnose blockiert oder lässt deine Anfrage niemals fehlschlagen. Wenn keine Diagnoseinformationen verfügbar sind, gibt die Antwort unavailable zurück, oder cache_miss_reason: null, wenn der Vergleich noch lief.

Datenaufbewahrung

Die Cache-Diagnose ist ZDR-berechtigt (qualifiziert). Anthropic speichert für diese Funktion nicht den Rohtext deiner Prompts oder Claudes Ausgaben.

Der für jede Anfrage gespeicherte Fingerabdruck besteht nur aus kryptografischen Hashes und Token-Anzahl-Schätzungen, indiziert nach der Antwort-id und beschränkt auf deine Organisation und deinen Workspace. Fingerabdrücke laufen nach einer kurzen Zeit ab und werden für keinen anderen Zweck verwendet.

Für die ZDR-Berechtigung über alle Funktionen hinweg siehe API und Datenaufbewahrung.

Siehe auch

Compatibility

Supported platforms
  • Claude APIBeta

Was this page helpful?