Claude Platform Docs
MessagesManajemen konteks

Diagnostik cache

Diagnosis cache miss prompt yang tidak terduga dengan membandingkan permintaan berurutan dan mengidentifikasi secara tepat di mana prefiks prompt menyimpang.

Caching prompt memangkas latensi dan biaya secara signifikan, tetapi hanya ketika bagian awal prompt Anda identik byte demi byte dengan permintaan terbaru. Alat yang diurutkan ulang, timestamp yang diinterpolasi ke dalam "system prompt" (prompt sistem) Anda, atau pengeditan pada pesan sebelumnya dapat secara diam-diam membatalkan cache. Tanpa diagnostik cache, satu-satunya sinyal adalah usage.cache_read_input_tokens yang turun menjadi nol, tanpa indikasi apa pun tentang apa yang berubah.

Diagnostik cache menutup celah tersebut. Teruskan id dari respons sebelumnya, dan API akan membandingkan kedua permintaan serta memberi tahu Anda di mana keduanya menyimpang (model, prompt sistem, alat, atau riwayat pesan) sehingga Anda dapat memperbaiki akar masalahnya alih-alih menebak-nebak.

Cara kerja diagnostik cache

Ketika header beta disertakan, API menyimpan fingerprint (sidik jari) ringan dari setiap permintaan, dengan kunci berupa id respons. Pada permintaan berikutnya, sertakan id tersebut sebagai diagnostics.previous_message_id. API membangun ulang fingerprint untuk permintaan baru, membandingkannya dengan fingerprint yang tersimpan, dan melampirkan objek diagnostics pada respons yang menjelaskan titik penyimpangan pertama.

Perbandingan ini berkaitan dengan struktur permintaan, terlepas dari apakah cache benar-benar hit atau tidak. Lihat Membaca diagnostik bersama usage untuk cara menggabungkan hasil diagnostics dengan usage.cache_read_input_tokens.

Fingerprint hanya berisi hash dan estimasi jumlah token (tidak pernah berisi konten prompt mentah), disimpan untuk waktu yang terbatas, dibatasi pada organisasi dan workspace Anda, dan tidak digunakan untuk tujuan lain apa pun.

Penggunaan dasar

Kirim header beta pada setiap giliran. Pada giliran pertama, teruskan "previous_message_id": null untuk ikut serta tanpa pesan sebelumnya untuk dibandingkan. Pada giliran berikutnya, teruskan id dari respons sebelumnya.

client = anthropic.Anthropic()

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

# Giliran 1: ikut serta dengan 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"],
)

# Giliran 2: rujuk id respons sebelumnya
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

Dalam respons streaming, diagnostics muncul pada event message_start.

# Giliran 2: streaming, merujuk ke id respons sebelumnya
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}")

Event message_start membawa field diagnostics lengkap; lihat Format respons untuk nilai-nilai yang mungkin.

Meneruskan diagnostik melalui loop percakapan

Dalam percakapan multi-giliran, bawa id respons terbaru ke depan sebagai previous_message_id pada setiap giliran. Iterasi pertama meneruskan null untuk ikut serta; setiap iterasi berikutnya meneruskan id dari respons sebelumnya.

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

Format respons

Field diagnostics pada Message respons memiliki empat kemungkinan status:

NilaiArti
field tidak adaPermintaan tidak menyertakan diagnostics, atau header beta tidak ada.
nullEntah previous_message_id bernilai null (giliran pertama, tidak ada yang dibandingkan), atau perbandingan telah dijalankan dan tidak menemukan penyimpangan.
{"cache_miss_reason": null}Perbandingan masih berjalan ketika respons diserialisasi. Ini dapat terjadi ketika respons dimulai dengan sangat cepat. Anggap sebagai tidak konklusif dan periksa giliran berikutnya.
{"cache_miss_reason": {...}}Sebuah cache_miss_reason dilampirkan. Untuk tipe *_changed, ini mengidentifikasi titik penyimpangan pertama; previous_message_not_found dan unavailable adalah kasus di mana tidak ada perbandingan yang dihasilkan.

Ketika cache_miss_reason tidak null, bentuknya seperti ini:

{
  "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
    }
  }
}

Tipe alasan cache miss

cache_miss_reason adalah discriminated union pada type. Respons hanya melaporkan penyimpangan paling awal, jadi perbaiki itu terlebih dahulu; penyimpangan selanjutnya mungkin tersembunyi di baliknya.

TipeArtinyaYang perlu diubah
model_changedmodel berbeda dari permintaan sebelumnya (misalnya, router, pengujian A/B, atau fallback memilih model yang berbeda). Cache bersifat per-model.Pertahankan model tetap konstan dalam percakapan yang di-cache.
system_changedParameter system berbeda. Biasanya timestamp, ID permintaan, atau nilai per-permintaan lainnya diinterpolasi ke dalam prompt sistem.Jadikan prompt sistem sebagai konstanta yang stabil secara byte dan pindahkan data dinamis ke pesan user pertama setelah breakpoint cache Anda.
tools_changedArray tools berbeda: alat ditambahkan, dihapus, atau diurutkan ulang antar giliran, atau JSON input_schema alat diserialisasi secara non-deterministik.Kirim daftar alat yang sama pada setiap giliran dalam urutan tetap dengan skema yang diserialisasi secara deterministik (misalnya, urutkan kunci).
messages_changedModel, system, dan tools semuanya cocok, tetapi entri sebelumnya dalam messages diubah, diurutkan ulang, atau dihapus alih-alih ditambahkan di akhir. Biasanya riwayat percakapan dipotong atau diedit, atau giliran asisten dan blok tool_result diserialisasi ulang secara berbeda saat dikirim kembali.Perlakukan riwayat sebagai append-only; kembalikan content asisten dan hasil alat secara verbatim.
previous_message_not_foundTidak ada fingerprint tersimpan untuk previous_message_id yang diberikan. Ini bukan bukti bahwa permintaan Anda berubah. Biasanya permintaan sebelumnya tidak membawa header beta, berasal dari workspace yang berbeda, atau terlalu banyak waktu telah berlalu sejak permintaan itu dikirim.Kirim header beta pada setiap giliran dan jaga agar giliran berurutan berdekatan dalam waktu.
unavailableInformasi diagnostik tidak tersedia untuk permintaan ini. Ini mencakup kasus di mana model, system, dan tools cocok tetapi parameter permintaan lain yang memengaruhi prompt (tool_choice, thinking, context_management, output_config, output_format, atau kumpulan header anthropic-beta yang aktif) berbeda, serta percakapan yang sangat panjang di mana penyimpangan berada di luar horizon perbandingan. Permintaan Anda diproses secara normal.Pertahankan parameter permintaan yang memengaruhi prompt tetap konstan selama masa hidup percakapan yang di-cache. Jika terus terjadi, terapkan pemeriksaan manual di bagian Memecahkan masalah umum pada halaman caching prompt.

Membaca diagnostik bersama usage

diagnostics menjawab "apakah permintaan saya berubah?" sedangkan usage.cache_read_input_tokens menjawab "apakah cache hit?". Menggabungkan keduanya memberi tahu Anda di mana harus mencari.

Matriks ini berlaku untuk giliran di mana Anda meneruskan previous_message_id yang nyata. Pada giliran pertama (previous_message_id: null), diagnostics selalu null dan cache_read_input_tokens biasanya nol karena cache sedang ditulis, bukan dibaca; tidak diperlukan pemecahan masalah. Matriks ini juga tidak berlaku ketika cache_miss_reason bernilai null (perbandingan masih tertunda; periksa giliran berikutnya) atau ketika type-nya adalah previous_message_not_found atau unavailable (tidak ada perbandingan yang dihasilkan).

Hasil diagnostikToken cache readInterpretasi
nulltinggiBerfungsi sesuai harapan. Prefiks Anda stabil dan cache hit.
nullrendah atau nolPermintaan Anda cocok tetapi entri cache tidak lagi tersedia. Pertimbangkan untuk memperpendek jeda antar giliran atau menggunakan TTL cache 1 jam.
cache_miss_reason bertipe *_changedrendah atau nolBug Anda. Permintaan berubah; perbaiki penyebab yang ditunjukkan oleh type.
cache_miss_reason bertipe *_changedtinggiJarang. Perubahan terjadi di bagian akhir prompt tetapi breakpoint cache_control sebelumnya masih hit. Layak diperbaiki, tetapi dampaknya rendah.

Keterbatasan

  • Beta: Nama field dan semantik dapat berubah selama fitur ini dalam tahap beta.
  • Hanya Claude API: Tidak tersedia di Amazon Bedrock atau Google Cloud.
  • Retensi terbatas: Fingerprint untuk pencarian previous_message_id kedaluwarsa setelah periode singkat. Jalankan perbandingan diagnostik antara permintaan yang berdekatan waktunya.
  • Workspace yang sama: Permintaan sebelumnya harus dijalankan dalam organisasi dan workspace yang sama. Untuk memeriksanya, bandingkan header respons anthropic-workspace-id pada kedua respons.
  • Horizon perbandingan: Untuk percakapan yang sangat panjang di mana satu-satunya perubahan berada jauh di dalam daftar pesan, responsnya mungkin unavailable alih-alih lokasi yang tepat.
  • Best-effort: Diagnostik tidak pernah memblokir atau menggagalkan permintaan Anda. Jika informasi diagnostik tidak tersedia, respons mengembalikan unavailable, atau cache_miss_reason: null ketika perbandingan masih berjalan.

Retensi data

Diagnostik cache memenuhi syarat ZDR (dengan kualifikasi). Anthropic tidak menyimpan teks mentah prompt Anda atau output Claude untuk fitur ini.

Fingerprint yang disimpan untuk setiap permintaan hanya terdiri dari hash kriptografis dan estimasi jumlah token, dengan kunci berupa id respons dan dibatasi pada organisasi dan workspace Anda. Fingerprint kedaluwarsa setelah periode singkat dan tidak digunakan untuk tujuan lain apa pun.

Untuk kelayakan ZDR di seluruh fitur, lihat API dan retensi data.

Lihat juga

Compatibility

Supported platforms
  • Claude APIBeta

Was this page helpful?