Claude Platform Docs
PesanManajemen konteks

Pesan sistem dan perubahan alat di tengah percakapan

Ubah instruksi sistem atau ketersediaan alat di tengah percakapan tanpa membatalkan prefiks yang di-cache sebelumnya.

Instruksi sistem biasanya berada di field system tingkat atas, sebelum setiap pesan dalam percakapan. Posisi tersebut sangat baik untuk "prompt caching" (caching prompt): "system prompt" (prompt sistem) merupakan bagian dari prefiks yang stabil, sehingga giliran berikutnya mengenai cache. Namun, posisi itu kurang tepat untuk instruksi yang baru Anda sadari diperlukan di tengah sesi, karena mengedit field system tingkat atas mengubah bagian paling awal dari prompt dan membatalkan cache untuk semua yang mengikutinya.

Pesan sistem di tengah percakapan menutup celah tersebut. Anda menambahkan pesan {"role": "system"} pada titik dalam percakapan ketika instruksi baru menjadi relevan, alih-alih mengedit field system tingkat atas. Prefiks yang di-cache tetap sama, sehingga permintaan berikutnya tetap membacanya dari cache, dan instruksi baru tetap diterapkan sebagai instruksi sistem, bukan sebagai teks pengguna biasa.

Perubahan alat di tengah percakapan

Array tools berada lebih awal lagi dalam prefiks permintaan yang di-hash dibandingkan field system tingkat atas. Karena itu, mengeditnya membatalkan cache prompt untuk seluruh percakapan. Perubahan alat di tengah percakapan adalah padanan pesan sistem di tengah percakapan untuk alat. Daftar alat tidak perlu tetap sepanjang percakapan. Anda dapat mengubah alat yang ditawarkan kepada model di antara giliran: deklarasikan set alat lengkap di tools sejak awal, lalu gunakan blok tool_addition dan tool_removal untuk menawarkan alat kepada model, atau menariknya, mulai dari titik tertentu dalam percakapan. Array tools itu sendiri tidak pernah berubah, sehingga prefiks yang di-cache tetap utuh. Perubahan alat di tengah percakapan tersedia dalam beta dan menggunakan header beta inline-tools-2026-09-15 di Claude API.

tool_addition dan tool_removal adalah blok konten dalam array content dari pesan role: "system", dan keduanya dapat dicampur dengan blok text dalam pesan yang sama. Pesan tersebut mengikuti aturan penempatan untuk pesan sistem di tengah percakapan mana pun, dengan satu batasan tambahan setelah giliran yang dijeda (lihat Keterbatasan), dan perubahan berlaku mulai dari titik tersebut dalam percakapan dan seterusnya. Field tool pada setiap blok mereferensikan alat alih-alih mendefinisikannya: {"type": "tool_reference", "name": "..."} menyebut alat yang dideklarasikan dalam array tools permintaan, dan alat konektor MCP dapat direferensikan secara individual dengan mcp_tool_reference (server_name dan name) atau sebagai satu toolset utuh dengan mcp_toolset_reference (server_name). Mereferensikan nama yang tidak dideklarasikan di tools mengembalikan error 400 (di Claude API, dengan error.details.error_code diatur ke tool_reference_unresolved). Sebagai alternatif, blok tool_addition dapat membawa definisi lengkap alat, yang tidak didukung oleh header mid-conversation-tool-changes-2026-07-01.

Setiap alat yang dideklarasikan di tools ditawarkan kepada model sejak awal percakapan, kecuali alat yang dideklarasikan dengan defer_loading: true. Alat tersebut ditahan sampai blok tool_addition memunculkannya. tool_addition juga dapat menawarkan kembali alat yang sebelumnya ditarik oleh tool_removal.

Permintaan berikut mendeklarasikan get_weather di tools, lalu menariknya setelah giliran pengguna pertama dengan blok tool_removal. Permintaan ini mengirim header beta 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"],
    # Seluruh set alat dideklarasikan di awal dan tidak pernah berubah, sehingga
    # prefiks yang di-cache tetap utuh.
    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.",
        },
        # Tarik get_weather mulai titik ini. Blok ini merujuk
        # alat berdasarkan nama alih-alih mengedit `tools`, sehingga giliran sebelumnya tetap
        # identik per byte dan cache tetap hit.
        {
            "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)

Mendefinisikan alat dalam pesan (beta)

Dengan header beta inline-tools-2026-09-15, blok tool_addition dapat mendefinisikan alat berdasarkan nilai, yaitu dengan membawa definisi lengkapnya, alih-alih menyebutnya berdasarkan referensi. Dengan begitu, Anda dapat memperkenalkan alat yang belum diketahui di awal percakapan, atau alat yang skemanya berubah kemudian, cukup dengan menambahkan pesan role: "system". Array tools dan setiap pesan sebelumnya tetap persis seperti yang dikirim. Akibatnya, cache prompt tetap mengenai dan hanya pesan yang ditambahkan yang diproses sebagai input baru. Satu-satunya pengecualian, yaitu array tools tanpa alat yang tidak ditangguhkan, dibahas dalam aturan di bawah. Header ini juga mencakup penambahan dan penghapusan alat berdasarkan referensi, sehingga Anda tidak perlu mengirim mid-conversation-tool-changes-2026-07-01 juga.

Bungkus definisi dalam objek tool bertipe tool_definition. definition adalah entri tools dengan konfigurasi biasanya, termasuk cache_control dan defer_loading. Contohnya adalah alat kustom, atau alat klien maupun alat server yang didefinisikan Anthropic. Selama beta, beberapa tipe alat (termasuk alat computer use) belum dapat didefinisikan dalam pesan. Alat tersebut menghasilkan error 400 yang menyatakan hal itu. Deklarasikan alat tersebut di tools dan tambahkan berdasarkan referensi. Misalnya, untuk mendefinisikan alat kustom di tengah percakapan:

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

Mulai dari posisi tersebut, model dapat memanggil alat itu dengan cara yang sama seperti memanggil alat yang dideklarasikan di tools. Mengirim definisi yang identik lagi tidak mengubah apa pun, sehingga klien dapat mengirimnya ulang dengan aman, misalnya saat mencoba ulang.

Permintaan berikut mempertahankan get_weather di tools dan mendefinisikan db_query setelah giliran pengguna pertama:

client = anthropic.Anthropic()

response = client.beta.messages.create(
    model="claude-opus-5-5",
    max_tokens=1024,
    betas=["inline-tools-2026-09-15"],
    # Pertahankan setidaknya satu alat non-deferred di `tools`, agar alat yang didefinisikan
    # belakangan tidak mengubah bagian awal prompt yang dirender.
    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?"},
        # Definisikan db_query secara langsung (by value) mulai titik ini. `tools` dan
        # pesan sebelumnya tetap persis seperti yang dikirim, sehingga cache tetap hit.
        {
            "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)

content dalam respons menyertakan blok tool_use untuk alat baru tersebut, misalnya:

{
  "type": "tool_use",
  "id": "toolu_01A09q90qw90lq917835lq9",
  "name": "db_query",
  "input": {
    "sql": "SELECT COUNT(*) FROM orders WHERE shipped_at::date = CURRENT_DATE - 1"
  }
}

Untuk mengubah skema alat, atau untuk memindahkan alat server ke versi yang lebih baru, kirim definisi yang berbeda dengan nama yang sama. Definisi baru menggantikan definisi sebelumnya mulai dari posisi tersebut. Definisi yang menggunakan ulang nama dari tipe alat yang berbeda menghasilkan error 400 dengan error.details.error_code diatur ke tool_name_conflict. Versi yang lebih baru dari alat yang sama tidak dihitung sebagai tipe yang berbeda. tool_removal tetap menerima referensi, dan alat yang telah dihapus dapat didefinisikan atau ditawarkan kembali nanti.

Beberapa aturan berlaku karena posisi tempat definisi dirender:

  • Deklarasikan apa yang Anda ketahui sejak awal. Alat yang sudah Anda ketahui pada permintaan pertama sebaiknya ditempatkan di tools. Jika model belum boleh melihatnya, gunakan defer_loading: true dan referensi tool_addition di kemudian hari. Definisikan berdasarkan nilai hanya alat yang belum diketahui pada permintaan pertama atau yang berubah kemudian.
  • Pertahankan setidaknya satu alat yang tidak ditangguhkan di tools. Percakapan yang array tools-nya tidak memiliki alat yang tidak ditangguhkan tetap diterima. Namun, alat pertama yang didefinisikan berdasarkan nilai akan mengubah awal prompt yang dirender, sehingga permintaan tersebut mengalami satu cache miss penuh. Alat tool search dihitung sebagai alat yang tidak ditangguhkan.
  • Tipe alat bertanggal tetap memerlukan header beta masing-masing. Jika alat server yang Anda definisikan berdasarkan nilai memerlukan header beta sendiri, kirim header tersebut pada setiap permintaan berikutnya dalam percakapan.
  • cache_control ditempatkan pada blok atau di dalam definisi, bukan keduanya. Field ini juga dihitung terhadap batas breakpoint permintaan. Definisi yang ditangguhkan tidak dapat membawa cache_control.

Permintaan menghasilkan error 400 dengan error.details.error_code diatur ke available_tools_limit_exceeded jika salah satu batas berikut terlampaui:

  • Lebih dari 10.000 alat yang ditangguhkan tersedia setelah pesan mana pun.
  • Lebih dari 10.000 alat yang didefinisikan setelah pesan pengguna pertama tersedia setelah pesan mana pun.
  • Definisi alat yang dikirim setelah pesan pengguna pertama dan masih tersedia setelah pesan mana pun berjumlah total lebih dari 4 MB (4.194.304 byte).
  • Teks alat yang dirender lebih besar dari 4 MB (4.194.304 byte).

Menambahkan server MCP di tengah percakapan (beta)

Untuk menambahkan server konektor MCP di tengah percakapan, kirim header beta mcp-client-2026-09-15 bersama inline-tools-2026-09-15. Dengan begitu, definition dalam blok tool_addition dapat berupa mcp_toolset, sehingga alat-alat server menjadi tersedia tanpa mengedit tools. Cantumkan detail koneksi server di mcp_servers seperti biasa, lalu tambahkan toolset pada titik ketika server menjadi tersedia:

{
  "role": "system",
  "content": [
    {
      "type": "tool_addition",
      "tool": {
        "type": "tool_definition",
        "definition": { "type": "mcp_toolset", "mcp_server_name": "calendar" }
      }
    }
  ]
}

Objek mcp_toolset sama dengan yang akan Anda tempatkan di tools, termasuk default_config dan configs. Blok tool_addition tidak pernah memuat URL server atau token. Keduanya tetap berada di mcp_servers.

Permintaan berikut mempertahankan get_weather di tools, mencantumkan server kalender di mcp_servers, dan menambahkan toolset server tersebut setelah giliran pengguna pertama:

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?"},
        # Sediakan alat dari server kalender mulai titik ini dan seterusnya.
        # Blok ini menyebutkan nama server; blok ini tidak pernah memuat URL atau token.
        {
            "role": "system",
            "content": [
                {
                    "type": "tool_addition",
                    "tool": {
                        "type": "tool_definition",
                        "definition": {
                            "type": "mcp_toolset",
                            "mcp_server_name": "calendar",
                        },
                    },
                },
            ],
        },
    ],
)

# Respons diawali dengan blok mcp_tool_listing untuk server kalender,
# jadi periksa tipe setiap blok alih-alih membaca content[0].
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)

Dengan mcp-client-2026-09-15, respons yang memerlukan API mengambil daftar alat server diawali dengan blok mcp_tool_listing, satu untuk setiap server yang diambil. Jika kode Anda membaca content[0], lewati blok-blok ini. Kirim kembali pesan asisten tanpa perubahan, termasuk blok ini, dan terus kirim mcp-client-2026-09-15 pada setiap permintaan yang membawanya. Permintaan berikutnya kemudian menggunakan daftar yang tercatat alih-alih menanyakan server lagi. Untuk menyematkan toolset sendiri, salin daftar tersebut ke field tools milik mcp_toolset, seperti yang dijelaskan dalam Menyematkan daftar alat server MCP.

mcp-client-2026-09-15 mencakup semua yang dicakup mcp-client-2025-11-20, sehingga Anda tidak perlu mengirim keduanya. Fitur-fitur ini tersedia di Claude API. Permintaan yang menggunakan konektor MCP tetap tunduk pada ketentuan retensi data konektor tersebut.

Kapan menggunakan pesan sistem di tengah percakapan

Caching prompt melakukan hash pada prefiks permintaan secara berurutan: tools, lalu system, lalu messages. Cache hit mengharuskan prefiks cocok persis, byte demi byte, dengan permintaan terbaru hingga breakpoint cache.

Urutan tersebut berarti field system tingkat atas berada di dekat awal prefiks yang di-hash. Perubahan apa pun padanya, bahkan sekadar menambahkan satu kalimat, menghasilkan hash yang berbeda. Akibatnya, permintaan mengalami cache miss untuk prompt sistem dan setiap pesan yang di-cache setelahnya.

Pesan sistem di tengah percakapan memungkinkan Anda menambahkan instruksi di akhir riwayat pesan. Semua yang ada sebelum instruksi baru tidak berubah, sehingga entri cache yang ada tetap cocok, dan hanya pesan baru yang diproses sebagai input baru.

Beberapa situasi ketika hal ini penting:

  • Perubahan kebijakan atau persona di tengah sesi. Sesi agentik yang panjang memerlukan batasan baru ("mulai sekarang, tulis semua SQL sebagai kueri berparameter") setelah puluhan giliran yang di-cache. Menambahkannya ke field system tingkat atas akan memproses ulang seluruh riwayat.
  • Konteks per giliran yang harus otoritatif. Anda ingin menyisipkan catatan kebaruan, tenggat sesi, atau perubahan ketersediaan alat dengan bobot tingkat sistem. Informasi tersebut berubah terlalu sering untuk ditempatkan di prefiks yang di-cache.
  • Pengingat per giliran yang tidak boleh menumpuk. Sebuah harness mengingatkan model setelah setiap kumpulan hasil alat ("minta pembacaan yang independen secara bersamaan", "pengguna sudah lama tidak mendengar kabar dari Anda") dan ingin model hanya melihat salinan terbaru. Pesan sistem berlingkup giliran dirender untuk satu giliran, lalu tidak menimbulkan biaya apa pun, tanpa menghapus apa pun dari riwayat.
  • Perubahan status yang diamati aplikasi Anda. Aplikasi Anda mendeteksi sesuatu yang harus diperlakukan Claude sebagai fakta tingkat operator. Contohnya: file berubah di disk, pengguna mengaktifkan pengaturan persetujuan otomatis, alat yang tersedia berubah, atau sisa anggaran token turun di bawah ambang batas.
  • Input pengguna yang tidak boleh menginterupsi loop agentik. Pengguna mengetik pertanyaan lanjutan saat Claude masih menjalankan alat untuk permintaan sebelumnya. Jika input tersebut diteruskan sebagai pesan sistem setelah hasil alat berikutnya, Claude dapat memadukannya ke dalam pekerjaan yang sedang dilakukan. Claude tidak akan memperlakukannya sebagai permintaan baru yang mengharuskannya beralih tugas. Pada Claude Sonnet 5.5 dan Claude Haiku 5.5, tambahkan kata-kata pengguna sebagai blok text setelah tool_result terakhir dalam pesan user yang sama sebagai gantinya. Lihat Penempatan setelah hasil alat.
  • Peralihan mode yang memberikan izin tetap. Mode tingkat sesi dapat menggunakan pesan sistem di tengah percakapan untuk memberikan persetujuan tetap atas kemampuan yang mahal, seperti meluncurkan alur kerja multiagen secara otomatis. Mode tersebut dapat disertai pengingat singkat setiap beberapa giliran dan pemberitahuan keluar saat mode dinonaktifkan. Untuk contoh lengkap, lihat Membangun mode orkestrasi.

Dalam semua kasus ini, Anda sebenarnya dapat menempatkan instruksi dalam pesan user biasa, dan Claude memang mengikuti instruksi yang datang dalam giliran pengguna. Perbedaannya terletak pada prioritas. Pesan user diperlakukan sebagai berasal dari pengguna akhir, sedangkan pesan system diperlakukan sebagai berasal dari Anda, operator aplikasi. Jika keduanya bertentangan, instruksi sistem lebih diutamakan. Karena itu, gunakan peran system untuk fakta dan batasan tingkat operator yang harus tetap berlaku meskipun pengguna akhir meminta hal yang berbeda. Pesan sistem di tengah percakapan mempertahankan prioritas tingkat operator tersebut tanpa menanggung biaya cache miss akibat mengedit field system tingkat atas.

Cara kerjanya

Tambahkan pesan dengan "role": "system" ke array messages. Gunakan string biasa atau blok konten untuk content, sama seperti giliran user atau assistant. Instruksi berlaku mulai dari titik tersebut dalam percakapan dan seterusnya. Ketika instruksi bertentangan, pesan sistem yang lebih baru lebih diutamakan daripada yang lebih lama, dan pesan sistem di tengah percakapan lebih diutamakan daripada field system tingkat atas untuk giliran-giliran yang mengikutinya.

Anda tetap dapat mengatur field system tingkat atas untuk instruksi yang harus berlaku di seluruh percakapan. Gunakan pesan sistem di tengah percakapan khusus untuk instruksi yang baru menjadi relevan kemudian, atau yang ingin Anda tambahkan tanpa membatalkan prefiks yang di-cache.

Pesan role: "system" juga dapat membawa output_config.effort untuk mengubah tingkat effort di tengah percakapan. Fitur ini berstatus beta di Claude Fable 5.1, Claude Mythos 5.1, Claude Opus 5.5, Claude Opus 5, Claude Sonnet 5.5, dan Claude Haiku 5.5 di Claude API dan Google Cloud, dan memerlukan header beta mid-conversation-output-config-2026-07-01. Di Amazon Bedrock, fitur ini berstatus beta di Claude Fable 5.1, Claude Mythos 5.1, dan Claude Opus 5.5, dengan nilai beta yang sama. Claude Opus 5 tidak mendukungnya di Amazon Bedrock. Lihat Effort per pesan.

client = anthropic.Anthropic()

response = client.messages.create(
    model="claude-opus-5-5",
    max_tokens=1024,
    # Caching prompt otomatis: setiap permintaan menyimpan percakapan sejauh ini ke cache,
    # dan permintaan berikutnya membaca prefiks yang tidak berubah dari 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().",
        },
        # Di tengah sesi, peninjau menyadari bahwa semua saran juga harus
        # lolos kebijakan typing ketat milik tim. Menambahkan
        # instruksi di sini menjaga giliran sebelumnya tetap identik per byte, sehingga
        # prefiks yang di-cache oleh permintaan sebelumnya tetap dibaca dari cache.
        {
            "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)

Contoh ini mengaktifkan caching otomatis dengan field cache_control tingkat atas. Caching prompt bersifat opt-in: jika permintaan tidak memiliki field cache_control (otomatis atau breakpoint eksplisit), tidak ada yang di-cache dan setiap permintaan membayar harga token input reguler untuk seluruh percakapan. Dengan caching diaktifkan, menambahkan pesan sistem membiarkan giliran yang sudah di-cache tidak berubah, sehingga permintaan yang membawa instruksi baru tetap membacanya dari cache alih-alih memprosesnya lagi. Caching juga mengharuskan percakapan memenuhi panjang prompt minimum yang dapat di-cache; contoh sependek ini berada di bawahnya, sehingga cache_creation_input_tokens dan cache_read_input_tokens tetap bernilai 0 hingga percakapan bertambah panjang.

Pesan sistem di tengah percakapan yang membawa konten (blok text, tool_addition, atau tool_removal) harus langsung mengikuti giliran user (atau giliran assistant yang diakhiri dengan hasil alat server), dan harus menjadi entri terakhir di messages atau langsung diikuti oleh giliran assistant. Pesan user yang membawa blok tool_result juga dihitung: dalam loop agentik Anda dapat menempatkan pesan sistem tepat setelah hasil alat, sebelum giliran Claude berikutnya. Posisi lain apa pun untuk pesan yang membawa konten, termasuk di antara blok tool_use milik assistant dan tool_result yang menjawabnya, mengembalikan error 400. Pesan dengan content kosong yang hanya mengatur output_config.effort diterima di mana saja dalam messages. Pesan system yang berurutan dinilai bersama, sehingga pesan yang hanya berisi effort di sebelah pesan yang membawa konten mengikuti aturan untuk konten.

Penempatan setelah hasil alat

Dalam loop agentik, pesan sistem ditempatkan setelah pesan user yang mengirimkan hasil alat. Pada sebagian besar model, di sinilah juga aplikasi Anda dapat meneruskan input yang diketik pengguna saat Claude sedang bekerja, sehingga konteks baru diserap tanpa memulai ulang giliran (untuk Claude Sonnet 5.5 dan Claude Haiku 5.5, lihat akhir bagian ini):

[
  { "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."
  }
]

Rumuskan konten sistem sebagai konteks, bukan sebagai perintah yang mengesampingkan pengguna. Nyatakan faktanya ("input baru datang dari pengguna: X", "sisa anggaran token sekarang Y") dan biarkan Claude bertindak berdasarkan fakta tersebut. Claude dilatih untuk menolak instruksi yang tampak merugikan pengguna, dan perlindungan itu tetap berlaku untuk peran sistem. Karena itu, kalimat seperti "abaikan apa yang dikatakan pengguna" kurang efektif dibandingkan menyatakan apa yang berubah.

Pola ini ditujukan untuk meneruskan input dari pengguna akhir percakapan itu sendiri. Jangan gunakan pola ini untuk meneruskan output alat, dokumen yang diambil, atau konten pihak ketiga lainnya. Simpan konten tersebut di blok tool_result (lihat Keterbatasan).

Pada Claude Sonnet 5.5 dan Claude Haiku 5.5, sampaikan kata-kata pengguna dalam giliran pengguna sebagai gantinya. Model-model ini dilatih untuk menahan injeksi prompt melalui hasil alat, sehingga mereka dapat memperlakukan pesan sistem yang ditempatkan tepat setelah hasil alat sebagai teks yang tidak tepercaya dan mengabaikannya. Tambahkan kata-kata pengguna sebagai blok text setelah tool_result terakhir dalam pesan user yang sama. Simpan pemberitahuan harness, seperti pengingat, dalam pesan sistem di tengah percakapan yang terpisah setelah pesan user tersebut, dan jangan pernah menempatkan pemberitahuan dan kata-kata pengguna dalam blok yang sama:

[
  { "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." }
    ]
  }
]

Untuk informasi lebih lanjut tentang perilaku ini, lihat Prompting untuk Claude Sonnet 5.5 dan Prompting Claude Haiku 5.5.

Pesan sistem berlingkup giliran

Untuk membatasi lingkup pesan role: "system" pada giliran saat ini, atur field clear_at-nya. Field ini menerima salah satu dari dua nilai:

  • "never" (default): pesan dirender pada posisinya di setiap permintaan yang menyertakannya. Menghilangkan field ini sama saja.
  • "next_user_message": pesan bersifat berlingkup giliran. Teksnya hanya dirender selama tidak ada pesan role: "user" yang muncul setelahnya di messages. Pesan pengguna yang hanya membawa blok tool_result dihitung sebagai pesan pengguna di sini. Begitu ada pesan pengguna yang lebih baru, pesan tersebut dibersihkan: pesan tetap berada di array tetapi tidak merender apa pun dan tidak memakan token input, pada permintaan tersebut dan setiap permintaan berikutnya.

Pesan sistem berlingkup giliran berstatus beta. Sertakan header beta mid-conversation-system-clear-at-2026-08-21. Tanpanya, clear_at ditolak sebagai field yang tidak dikenal.

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

Kegunaan utamanya adalah pengingat per giliran dalam loop alat. Tambahkan pengingat setelah pesan tool_result setiap kali Anda ingin model melihatnya, dan biarkan setiap salinan sebelumnya di tempatnya. Model hanya melihat salinan yang muncul setelah pesan pengguna terakhir, sehingga pengingat tidak pernah menumpuk. Tidak ada yang berubah di bagian awal messages, sehingga cache prompt tetap cocok. Di Claude Fable 5.1, Claude Opus 5.5, Claude Sonnet 5.5, dan Claude Haiku 5.5 hal ini juga menjaga blok thinking tetap valid di kemudian hari: menghapus pengingat sebelumnya akan mengubah percakapan sebelum blok-blok tersebut dan menggagalkan pemeriksaan percakapan, sedangkan pesan yang dibersihkan tetap berada di array dan membiarkan percakapan tersebut tidak berubah.

Permintaan berikut adalah langkah selanjutnya dari loop agen. messages[3] dirender pada permintaan sebelumnya, ketika pesan tersebut merupakan pesan terakhir di array. Begitu messages[5] (pesan pengguna yang lebih baru) ada, messages[3] dibersihkan: pesan yang dibersihkan tetap berada di array, sehingga percakapan sebelum blok thinking di messages[4] tidak berubah, tetapi model tidak lagi melihat teksnya. messages[6] dan messages[7] keduanya dirender, secara berurutan.

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

Aturan untuk pesan berlingkup giliran:

  • Kirim ulang pesan yang dibersihkan apa adanya. Pesan yang dibersihkan tetap merupakan bagian dari riwayat percakapan. Membangunnya ulang dari status saat ini (jumlah token baru, timestamp), menghapusnya karena dianggap berlebihan, atau mengubah nilai clear_at-nya merupakan pengeditan terhadap pesan sebelumnya. Cache prompt mengalami miss mulai dari titik tersebut, dan di Claude Fable 5.1, Claude Opus 5.5, Claude Sonnet 5.5, dan Claude Haiku 5.5 setiap blok thinking yang dihasilkan setelahnya gagal dalam pemeriksaan percakapan.
  • Hanya teks. content berupa satu atau lebih blok text (atau string). Blok tool_addition dan tool_removal mengembalikan error 400 pada pesan berlingkup giliran, begitu pula output_config. Gunakan pesan role: "system" terpisah tanpa clear_at untuk hal-hal tersebut.
  • Tidak ada cache_control pada bloknya. Pesan yang dibersihkan tidak pernah menjadi bagian dari kunci cache, sehingga breakpoint padanya tidak akan pernah cocok. Tempatkan breakpoint pada blok terakhir dari giliran pengguna sebelumnya, seperti yang dilakukan contoh. Field caching otomatis tingkat atas melewati pesan berlingkup giliran saat memilih breakpoint. Pada permintaan yang membersihkan sebuah pesan, prefiks cache yang dapat digunakan kembali berakhir pada giliran pengguna sebelumnya, sehingga hanya satu giliran asisten di antara pesan tersebut dan pesan pengguna baru yang diproses ulang.
  • Aturan penempatan tetap berlaku, baik dibersihkan maupun tidak. Pesan berlingkup giliran harus mengikuti giliran user (atau giliran assistant yang diakhiri dengan hasil alat server) dan mendahului giliran assistant atau mengakhiri array, seperti pesan sistem di tengah percakapan lainnya. Pesan yang mengakhiri array selalu dirender. Pesan yang langsung diikuti oleh pesan user lain merupakan error 400, bukan pesan yang dibersihkan: tempatkan semua hasil dari satu putaran alat dalam satu pesan pengguna dan pengingat setelahnya.
  • Giliran asisten tidak membersihkannya. Giliran asisten yang di-prefill atau dijeda setelah pesan, atau loop alat sisi server, tidak menambahkan pesan pengguna, sehingga pesan tetap dirender pada kelanjutan tersebut. Untuk menjaga pengingat tetap terlihat sepanjang loop alat sisi klien, tambahkan lagi setelah setiap pesan tool_result.
  • Penghitungan token mengikuti apa yang dirender. Pesan yang dibersihkan tidak menambahkan apa pun ke usage.input_tokens atau ke penghitungan token.
  • Riwayat yang diimpor. Dalam transkrip yang Anda susun dalam satu langkah (contoh few-shot, percakapan yang dimigrasikan), pesan berlingkup giliran yang sudah memiliki giliran asisten dan pesan pengguna setelahnya dibersihkan sejak permintaan pertama dan tidak pernah dirender. Itulah status yang tepat untuk pengingat per giliran yang Anda bawa. Biarkan clear_at tidak diatur hanya pada pesan yang harus dilihat model di setiap permintaan.

Error validasinya adalah:

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')

Yang pertama adalah error yang dikembalikan tanpa header beta. Di Google Cloud dan Claude di Amazon Bedrock, kirim nilai beta di header anthropic-beta, seperti di Claude API (lihat Header beta). Dengan InvokeModel API Amazon Bedrock, tempatkan di array anthropic_beta pada body permintaan sebagai gantinya.

Melalui SDK, atur clear_at pada entri role: "system" di messages dan kirim header beta. Contoh berikut menambahkan pengingat berlingkup giliran setelah giliran pengguna; pada permintaan berikutnya, begitu ada pesan pengguna yang lebih baru, pengingat tetap berada di array tetapi tidak lagi dirender:

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.",
        },
        # Pengingat lingkup giliran: dirender untuk giliran ini, lalu dihapus setelah ada pesan pengguna berikutnya.
        {
            "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)

Menggabungkan dengan caching prompt

Pesan sistem di tengah percakapan dan caching prompt dirancang untuk digunakan bersama:

  • Aktifkan caching secara eksplisit. Caching hanya terjadi ketika permintaan menyertakan cache_control, baik field caching otomatis tingkat atas maupun breakpoint eksplisit pada blok konten. Pesan sistem di tengah percakapan tidak membuat entri cache dengan sendirinya, dan tanpa caching diaktifkan tidak ada penghematan yang perlu dipertahankan.
  • Cache prefiks yang stabil seperti biasa. Tempatkan cache_control pada blok terakhir yang tetap sama di seluruh permintaan, baik itu akhir field system tingkat atas, akhir definisi alat Anda, atau titik stabil dalam riwayat pesan.
  • Tambahkan pesan sistem setelah breakpoint. Karena pesan tersebut muncul setelah prefiks yang di-cache, pesan tersebut tidak mengubah hash prefiks dan cache tetap mengenai.
  • Pesan sistem di tengah percakapan itu sendiri dapat di-cache. Begitu berada dalam percakapan, pesan tersebut menjadi bagian dari riwayat yang stabil. Pada giliran berikutnya Anda dapat memindahkan breakpoint cache melewatinya (atau mengandalkan caching otomatis untuk melakukannya) dan pesan sistem dibaca dari cache seperti giliran lainnya.

Hindari mengedit atau menghapus pesan sistem di tengah percakapan yang sudah dikirim. Seperti perubahan lain pada pesan sebelumnya, hal itu membatalkan cache mulai dari titik tersebut dan seterusnya. Di Claude Fable 5.1, Claude Opus 5.5, Claude Sonnet 5.5, dan Claude Haiku 5.5 hal itu juga membatalkan blok thinking di setiap giliran asisten berikutnya. Untuk panduan yang hanya berlaku untuk satu giliran, gunakan pesan sistem berlingkup giliran dan biarkan di tempatnya. Jika instruksi perlu berkembang, tambahkan pesan sistem baru alih-alih menulis ulang yang lama. Pesan sistem yang berurutan diterima dan diperlakukan sebagai satu bagian sistem, yang secara keseluruhan mengikuti aturan penempatan yang sama.

Keterbatasan

  • Tidak untuk pesan pertama. Pesan system yang membawa konten tidak dapat menjadi entri pertama di messages. Gunakan field system tingkat atas untuk instruksi yang berlaku sejak awal.

  • Penempatan dibatasi. Pesan system yang membawa konten (blok text, tool_addition, atau tool_removal) harus langsung mengikuti salah satu dari berikut:

    • giliran user, termasuk giliran user yang membawa blok tool_result,
    • giliran assistant yang diakhiri dengan hasil alat server.

    Pesan tersebut juga harus mendahului giliran assistant atau mengakhiri array. Pesan tersebut tidak dapat berada di antara blok tool_use dan tool_result-nya. Menempatkannya di tempat lain menghasilkan error 400.

    Ada beberapa pengecualian:

    • Blok tool_addition dan tool_removal tidak diterima tepat setelah giliran assistant yang dijeda (yang diakhiri dengan hasil alat server), meskipun blok text diterima. Lanjutkan giliran yang dijeda terlebih dahulu, lalu kirim perubahan alat dalam pesan system berikutnya.
    • Pesan dengan content kosong yang hanya mengatur output_config.effort tidak merender apa pun pada posisinya. Pesan seperti ini diterima di mana saja di messages, termasuk sebagai entri pertama atau di antara giliran assistant dan giliran user.

    Pesan system yang berurutan dinilai bersama. Jika Anda menambahkan pesan yang membawa teks di samping pesan yang hanya berisi effort, seluruh kelompok tersebut harus mengikuti aturan konten.

  • Pesan bercakupan giliran hanya berisi teks dan dikirim ulang apa adanya. Pesan clear_at: "next_user_message" tidak membawa tool_addition, tool_removal, output_config, atau cache_control. Setelah dibersihkan, pesan tersebut harus tetap berada di messages byte demi byte pada permintaan berikutnya. Lihat Pesan sistem berlingkup giliran.

  • Bukan tempat untuk konten yang tidak tepercaya. Claude memperlakukan konten sistem sebagai instruksi operator dan mengikutinya. Jangan tempatkan teks dari luar percakapan, seperti output alat mentah, dokumen yang diambil, atau konten web, langsung di pesan sistem. Tindakan itu memberikan otoritas tingkat operator pada teks tersebut. Simpan data tersebut di blok tool_result dan terus ikuti panduan Memitigasi jailbreak dan injeksi prompt.

Cara kerja caching, tempat menempatkan breakpoint, dan cara membaca field penggunaan cache.

Temukan titik persis tempat dua permintaan berbeda ketika cache hit yang Anda harapkan tidak terjadi.

Struktur pesan, percakapan multi-giliran, dan field system.

Menulis prompt dan instruksi sistem yang efektif.

Cara blok tool_use dan tool_result disusun dalam array messages.

Was this page helpful?