Claude Platform Docs
  • Messages
  • Managed Agents
  • Admin

Search...
⌘K
Langkah pertama
Pengenalan ClaudeMulai cepat
Membangun dengan Claude
Ikhtisar fiturMenggunakan Messages APIAlasan berhenti dan fallbackPenolakan dan fallbackKredit fallback
Kemampuan model
Pemikiran diperpanjangPemikiran adaptifUpayaAnggaran tugas (beta)Mode cepat (pratinjau riset)Output terstrukturSitasiStreaming MessagesPemrosesan batchHasil pencarianStreaming penolakanDukungan multibahasaEmbeddings
Alat
IkhtisarCara kerja penggunaan alatTutorial: Membangun agen pengguna alatMendefinisikan alatMenangani panggilan alatPenggunaan alat paralelTool Runner (SDK)Penggunaan alat ketatAlat serverAlat pencarian webAlat pengambilan webAlat eksekusi kodeAlat penasihatAlat pencarian alatAlat memoriAlat BashAlat editor teksAlat penggunaan komputerPemecahan masalah
Infrastruktur alat
Referensi alatMengelola konteks alatKombinasi alatPenggunaan alat dengan caching promptPemanggilan alat terprogramStreaming alat terperinci
Manajemen konteks
Jendela konteksPemadatanPengeditan konteksCaching promptPesan sistem di tengah percakapanMembangun mode orkestrasiDiagnostik cache (beta)Penghitungan token
Bekerja dengan file
Files APIDukungan PDF
Skills
IkhtisarMulai cepatPraktik terbaikSkills untuk enterpriseSkills di API
MCP
Server MCP jarak jauhKonektor MCP
Claude di platform cloud
Amazon BedrockAmazon Bedrock (lama)Claude Platform di AWSGoogle CloudMicrosoft Foundry

Log in
Alasan berhenti dan fallback
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Claude Platform Docs

Solutions

  • AI agents
  • Code modernization
  • Coding
  • Customer support
  • Education
  • Financial services
  • Government
  • Life sciences

Partners

  • Claude on AWS
  • Claude on Google Cloud

Learn

  • Blog
  • Courses
  • Use cases
  • Connectors
  • Customer stories
  • Engineering at Anthropic
  • Events
  • Powered by Claude
  • Service partners
  • Startups program

Company

  • Anthropic
  • Careers
  • Economic Futures
  • Research
  • News
  • Responsible Scaling Policy
  • Security and compliance
  • Transparency

Learn

  • Blog
  • Courses
  • Use cases
  • Connectors
  • Customer stories
  • Engineering at Anthropic
  • Events
  • Powered by Claude
  • Service partners
  • Startups program

Help and security

  • Availability
  • Status
  • Support
  • Discord

Terms and policies

  • Privacy policy
  • Responsible disclosure policy
  • Terms of service: Commercial
  • Terms of service: Consumer
  • Usage policy
Messages/Membangun dengan Claude

Alasan berhenti dan fallback

Pelajari arti setiap nilai stop_reason dan cara menangani pemotongan, penggunaan alat, giliran yang dijeda, dan penolakan dalam aplikasi Anda.

Setiap respons Messages API menyertakan field stop_reason yang memberi tahu Anda mengapa Claude berhenti menghasilkan output. Periksa field ini untuk memutuskan apakah akan menggunakan respons apa adanya, melanjutkan percakapan, mencoba ulang, atau beralih ke model lain sebagai fallback.

Untuk skema respons lengkap, lihat referensi Messages API.

Referensi cepat

NilaiKapan terjadiApa yang harus dilakukan
end_turnClaude menyelesaikan responsnya secara alami.Gunakan respons tersebut.
max_tokensRespons mencapai batas max_tokens Anda.Naikkan max_tokens atau lanjutkan respons.
stop_sequenceClaude menghasilkan salah satu stop_sequences Anda.Baca stop_sequence untuk melihat mana yang terpicu.
tool_useClaude memanggil sebuah alat.Jalankan alat tersebut dan kembalikan hasilnya. Panggilan alat server yang belum memiliki blok hasil akan diselesaikan dalam respons berikutnya.
pause_turnLoop alat server mencapai batas iterasinya.Kirim kembali konten asisten untuk melanjutkan.
refusalClaude menolak untuk merespons.Baca stop_details dan coba ulang pada model fallback.
model_context_window_exceededRespons memenuhi jendela konteks model.Perlakukan respons sebagai terpotong.

Field stop_reason

Field stop_reason adalah bagian dari setiap respons Messages API yang berhasil. Berbeda dengan error, yang menunjukkan kegagalan dalam memproses permintaan Anda, stop_reason memberi tahu Anda mengapa Claude menyelesaikan pembuatan responsnya.

Example response
{
  "id": "msg_01234",
  "type": "message",
  "role": "assistant",
  "content": [
    {
      "type": "text",
      "text": "Here's the answer to your question..."
    }
  ],
  "stop_reason": "end_turn",
  "stop_sequence": null,
  "stop_details": null,
  "usage": {
    "input_tokens": 100,
    "output_tokens": 50
  }
}

Nilai-nilai stop reason

end_turn

Alasan berhenti yang paling umum. Menunjukkan bahwa Claude menyelesaikan responsnya secara alami.

client = anthropic.Anthropic()

response = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello!"}],
)
if response.stop_reason == "end_turn":
    # Proses respons lengkap
    print(response.content[0].text)

max_tokens

Claude berhenti karena mencapai batas max_tokens yang ditentukan dalam permintaan Anda.

client = anthropic.Anthropic()
# Permintaan dengan token terbatas
response = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=10,
    messages=[{"role": "user", "content": "Explain quantum physics"}],
)

if response.stop_reason == "max_tokens":
    # Respons terpotong
    print("Response was cut off at token limit")
    # Pertimbangkan untuk membuat permintaan lain untuk melanjutkan

stop_sequence

Claude menemukan salah satu stop sequence kustom Anda.

client = anthropic.Anthropic()
response = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=1024,
    stop_sequences=["END", "STOP"],
    messages=[{"role": "user", "content": "Generate text until you say END"}],
)

if response.stop_reason == "stop_sequence":
    print(f"Stopped at sequence: {response.stop_sequence}")

tool_use

Claude memanggil sebuah alat dan mengharapkan Anda untuk mengeksekusinya.



Untuk sebagian besar implementasi penggunaan alat, gunakan tool runner, yang secara otomatis menangani eksekusi alat, pemformatan hasil, dan manajemen percakapan.

client = anthropic.Anthropic()
weather_tool = {
    "name": "get_weather",
    "description": "Get the current weather in a given location",
    "input_schema": {
        "type": "object",
        "properties": {
            "location": {"type": "string", "description": "City and state"},
        },
        "required": ["location"],
    },
}


def execute_tool(name, tool_input):
    """Execute a tool and return the result."""
    return f"Weather in {tool_input.get('location', 'unknown')}: 72°F"


response = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=1024,
    tools=[weather_tool],
    messages=[{"role": "user", "content": "What is the weather in San Francisco?"}],
)

if response.stop_reason == "tool_use":
    # Ekstrak dan jalankan alat
    for block in response.content:
        if block.type == "tool_use":
            result = execute_tool(block.name, block.input)
            # Kembalikan hasil ke Claude untuk respons akhir

Respons tool_use juga dapat berisi blok server_tool_use yang id-nya tidak memiliki blok hasil yang cocok. Panggilan alat server tersebut belum selesai, dan respons ini tidak membawa hasilnya. Dalam kasus umum, Claude memanggil sebuah alat server dan salah satu alat klien Anda dalam kelompok panggilan alat paralel yang sama: API mengembalikan respons tanpa menjalankan alat server sehingga Anda dapat menjalankan alat klien terlebih dahulu. Tidak ada penanda lain untuk keadaan ini; deteksi dengan memeriksa id setiap blok server_tool_use atau mcp_tool_use untuk mencari blok hasil yang cocok.



Dengan programmatic tool calling, bentuk respons yang sama memiliki arti yang berbeda. Blok tool_use klien berasal dari kode yang berjalan di alat code_execution alih-alih dari Claude secara langsung, dan field caller-nya menyebutkan blok code_execution yang memanggilnya. Kode tersebut sudah mulai berjalan: ia dijeda menunggu blok tool_result Anda, dan mengirimkannya akan melanjutkan eksekusi alih-alih memulai alat yang ditangguhkan. Blok hasil milik blok code_execution itu sendiri akan tiba setelah kode selesai, yang dapat memerlukan lebih dari satu putaran hasil alat. Pesan pengguna lanjutan itu sendiri sama dalam kedua kasus; dengan programmatic tool calling, sertakan juga kembali id dari field container respons, seperti yang ditunjukkan pada halaman tersebut.

A mixed tool_use response
{
  "stop_reason": "tool_use",
  "content": [
    {
      "type": "server_tool_use",
      "id": "srvtoolu_01HxbWnMRmbWyMfUtJKC45rA",
      "name": "web_fetch",
      "input": { "url": "https://example.com/article" }
    },
    {
      "type": "tool_use",
      "id": "toolu_01PjgRJLbXrXEMZwDNYLnBqk",
      "name": "run_command",
      "input": { "command": "uname -a" }
    }
  ]
}

Lanjutannya adalah pesan pengguna berisi blok tool_result, satu untuk setiap blok tool_use dalam respons (lihat Menangani panggilan alat), dengan dua aturan tambahan: pesan tersebut tidak boleh berisi apa pun selain blok tool_result, dan permintaan harus mempertahankan array tools yang sama. Permintaan lanjutan yang tidak lagi mendefinisikan alat server yang sedang menunggu akan gagal dengan error 400 yang pesannya diakhiri dengan but no `web_fetch` tool was provided. API melampirkan hasil Anda ke giliran asisten yang masih terbuka, menjalankan alat server yang ditangguhkan (untuk eksekusi kode yang dijeda, melanjutkannya), dan melanjutkan giliran tersebut. Untuk alat server yang dipanggil Claude secara langsung, content respons berikutnya dimulai dengan blok hasil yang menjawab id server_tool_use dari respons sebelumnya.

The follow-up user message
{
  "role": "user",
  "content": [
    {
      "type": "tool_result",
      "tool_use_id": "toolu_01PjgRJLbXrXEMZwDNYLnBqk",
      "content": "Linux demo-host 6.8.0-52-generic x86_64 GNU/Linux"
    }
  ]
}

Menambahkan apa pun setelah blok tool_result dalam pesan pengguna tersebut, seperti teks, akan mengakhiri giliran asisten; untuk alat server yang dipanggil Claude secara langsung, permintaan kemudian gagal dengan invalid_request_error 400 yang menyebutkan alat server yang belum terselesaikan:

`web_fetch` tool use with id `srvtoolu_01HxbWnMRmbWyMfUtJKC45rA` was found without a corresponding `web_fetch_tool_result` block

Menghilangkan sebuah tool_result, atau menempatkannya setelah konten lain, akan gagal lebih awal dengan error standar tool_use ids were found without tool_result blocks immediately after. Untuk memberikan Claude input tambahan, kirimkan sebagai pesan pengguna terpisah setelah giliran selesai.

pause_turn

Dikembalikan ketika loop sampling sisi server mencapai batas iterasinya saat mengeksekusi alat server seperti web search atau web fetch. Batas default adalah 10 iterasi per permintaan.

Ketika ini terjadi, respons mungkin berisi blok server_tool_use tanpa blok hasil yang sesuai. Untuk membiarkan Claude menyelesaikan pemrosesan, lanjutkan percakapan dengan mengirim kembali respons apa adanya. Respons yang meninggalkan blok tool_use klien menunggu Anda tidak pernah memiliki stop_reason berupa pause_turn: ketika Claude berhenti untuk memanggil alat Anda, stop_reason adalah tool_use, dan Anda melanjutkannya dengan mengirim blok tool_result klien alih-alih respons itu sendiri.

response = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=4096,
    tools=[{"type": "web_search_20250305", "name": "web_search"}],
    messages=[{"role": "user", "content": "Search for latest AI news"}],
)

if response.stop_reason == "pause_turn":
    # Lanjutkan percakapan dengan mengirim kembali respons tersebut
    messages = [
        {"role": "user", "content": "Search for latest AI news"},
        {"role": "assistant", "content": response.content},
    ]
    continuation = client.messages.create(
        model="claude-opus-4-8",
        max_tokens=4096,
        messages=messages,
        tools=[{"type": "web_search_20250305", "name": "web_search"}],
    )


Aplikasi Anda harus menangani pause_turn dalam setiap loop agen yang menggunakan alat server. Tambahkan respons asisten ke array pesan Anda dan buat permintaan API lain untuk membiarkan Claude melanjutkan.

refusal

Claude menolak untuk menghasilkan respons. Pada Claude Fable 5, pengklasifikasi keamanan mengembalikan alasan berhenti ini sebagai respons HTTP 200 normal, bukan error.

client = anthropic.Anthropic()
response = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=1024,
    messages=[{"role": "user", "content": "[Unsafe request]"}],
)

if response.stop_reason == "refusal":
    # Claude menolak untuk merespons
    print("Claude was unable to process this request")
    # Pertimbangkan untuk menyusun ulang atau memodifikasi permintaan


Jika Anda sering menemukan alasan berhenti refusal saat menggunakan Claude Sonnet 4.5 atau Opus 4.1 (tidak digunakan lagi), Anda dapat mencoba memperbarui panggilan API Anda untuk menggunakan Haiku 4.5 (claude-haiku-4-5-20251001), yang memiliki batasan penggunaan yang berbeda. Pelajari lebih lanjut tentang memahami filter keamanan API Sonnet 4.5.

Pada penolakan, objek stop_details mengidentifikasi kategori kebijakan yang memicunya. Kategori-kategori dan bentuk respons penolakan lengkap dibahas di Penolakan dan fallback. stop_details bernilai null untuk semua alasan berhenti selain refusal.

Permintaan yang ditolak pada Claude Fable 5 biasanya dapat dilayani dengan mencoba ulang pada model Claude lain, dan Penolakan dan fallback menunjukkan cara menyiapkan percobaan ulang tersebut, di sisi server atau di klien Anda. Kredit fallback membahas cara menghindari membayar biaya cache prompt dua kali ketika Anda membangun percobaan ulang sendiri.

model_context_window_exceeded

Claude berhenti karena mencapai batas jendela konteks model. Ini memungkinkan Anda meminta token maksimum yang mungkin tanpa mengetahui ukuran input yang tepat.



Alasan berhenti ini saat ini hanya diketik dalam namespace beta SDK, sehingga contoh berikut memanggil client.beta.messages dan menggunakan tipe dengan prefiks Beta. Pada Sonnet 4.5 dan model yang lebih baru, API mengembalikan nilai ini tanpa header beta. Untuk model sebelumnya, tambahkan header beta model-context-window-exceeded-2025-08-26 untuk mengaktifkannya.

# Permintaan dengan token maksimum untuk mendapatkan sebanyak mungkin
response = client.beta.messages.create(
    model="claude-opus-4-8",
    max_tokens=20000,  # Python SDK requires streaming for max_tokens above ~21k (Opus 4.8 supports 128k with streaming)
    messages=[
        {"role": "user", "content": "Large input that uses most of context window..."}
    ],
)

if response.stop_reason == "model_context_window_exceeded":
    # Respons mencapai batas jendela konteks sebelum max_tokens
    print("Response reached model's context window limit")
    # Respons tetap valid tetapi dibatasi oleh jendela konteks

Praktik terbaik untuk menangani alasan berhenti

Selalu periksa stop_reason

Biasakan untuk memeriksa stop_reason dalam logika penanganan respons Anda:

def handle_response(response):
    if response.stop_reason == "tool_use":
        return handle_tool_use(response)
    elif response.stop_reason == "max_tokens":
        return handle_truncation(response)
    elif response.stop_reason == "model_context_window_exceeded":
        return handle_context_limit(response)
    elif response.stop_reason == "pause_turn":
        return handle_pause(response)
    elif response.stop_reason == "refusal":
        return handle_refusal(response)
    else:
        # Tangani end_turn dan kasus lainnya
        return response.content[0].text

Tangani respons terpotong dengan baik

Ketika respons terpotong karena batas token atau jendela konteks, tambahkan pemberitahuan agar pembaca tahu bahwa output tidak lengkap. Untuk melanjutkan pembuatan dari tempat respons terhenti, lihat Memastikan respons lengkap.

def handle_truncated_response(response):
    if response.stop_reason in ["max_tokens", "model_context_window_exceeded"]:
        if response.stop_reason == "max_tokens":
            note = "[Response truncated due to max_tokens limit]"
        else:
            note = "[Response truncated due to context window limit]"
        return f"{response.content[0].text}\n\n{note}"
    return response.content[0].text

Implementasikan logika percobaan ulang untuk pause_turn

Saat menggunakan alat server, API dapat mengembalikan pause_turn jika loop sampling sisi server mencapai batas iterasinya (default 10). Tangani ini dengan melanjutkan percakapan:

def handle_server_tool_conversation(client, user_query, tools, max_continuations=5):
    """
    Handle server tool conversations that may require multiple continuations.

    The server runs a sampling loop when executing server tools. If the loop
    reaches its iteration limit, the API returns pause_turn. Continue the
    conversation by sending the response back to let Claude finish.
    """
    messages = [{"role": "user", "content": user_query}]

    for _ in range(max_continuations):
        response = client.messages.create(
            model="claude-opus-4-8", max_tokens=4096, messages=messages, tools=tools
        )

        if response.stop_reason != "pause_turn":
            # Claude selesai memproses - kembalikan respons akhir
            return response

        # pause_turn: ganti seluruh daftar pesan untuk mempertahankan peran yang berselang-seling
        messages = [
            {"role": "user", "content": user_query},
            {"role": "assistant", "content": response.content},
        ]

    # Mencapai batas maksimum kelanjutan - kembalikan respons terakhir
    return response

Alasan berhenti vs. error

Penting untuk membedakan antara nilai stop_reason dan error yang sebenarnya:

Alasan berhenti (respons berhasil)

  • Bagian dari body respons
  • Menunjukkan mengapa pembuatan berhenti secara normal
  • Respons berisi konten yang valid

Error (permintaan gagal)

  • Kode status HTTP 4xx atau 5xx
  • Menunjukkan kegagalan pemrosesan permintaan
  • Respons berisi detail error
client = anthropic.Anthropic()

try:
    response = client.messages.create(
        model="claude-opus-4-8",
        max_tokens=1024,
        messages=[{"role": "user", "content": "Hello!"}],
    )

    # Tangani respons yang berhasil dengan stop_reason
    if response.stop_reason == "max_tokens":
        print("Response was truncated")

except anthropic.APIStatusError as e:
    # Tangani error yang sebenarnya
    if e.status_code == 429:
        print("Rate limit exceeded")
    elif e.status_code == 500:
        print("Server error")

Pertimbangan streaming

Saat menggunakan streaming, stop_reason adalah:

  • null dalam event message_start awal
  • Disediakan dalam event message_delta
  • Tidak disediakan dalam event lainnya
client = anthropic.Anthropic()

with client.messages.stream(
    model="claude-opus-4-8",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello!"}],
) as stream:
    for event in stream:
        if event.type == "message_delta":
            stop_reason = event.delta.stop_reason
            if stop_reason:
                print(f"Stream ended with: {stop_reason}")

Pola umum

Menangani alur kerja penggunaan alat



Lebih sederhana dengan tool runner: Contoh berikut menunjukkan penanganan alat secara manual. Untuk sebagian besar kasus penggunaan, tool runner secara otomatis menangani eksekusi alat dengan kode yang jauh lebih sedikit.

def complete_tool_workflow(client, user_query, tools):
    messages = [{"role": "user", "content": user_query}]

    while True:
        response = client.messages.create(
            model="claude-opus-4-8", max_tokens=1024, messages=messages, tools=tools
        )

        if response.stop_reason == "tool_use":
            # Jalankan alat dan lanjutkan
            tool_results = execute_tools(response.content)
            messages.append({"role": "assistant", "content": response.content})
            messages.append({"role": "user", "content": tool_results})
        else:
            # Respons akhir
            return response

Memastikan respons lengkap

def get_complete_response(client, prompt, max_attempts=3):
    messages = [{"role": "user", "content": prompt}]
    full_response = ""

    for _ in range(max_attempts):
        response = client.messages.create(
            model="claude-opus-4-8", messages=messages, max_tokens=4096
        )

        full_response += response.content[0].text

        if response.stop_reason != "max_tokens":
            break

        # Lanjutkan dari titik terakhir berhenti
        messages = [
            {"role": "user", "content": prompt},
            {"role": "assistant", "content": full_response},
            {"role": "user", "content": "Please continue from where you left off."},
        ]

    return full_response

Mendapatkan token maksimum tanpa mengetahui ukuran input

Dengan alasan berhenti model_context_window_exceeded, Anda dapat meminta token maksimum yang mungkin tanpa menghitung ukuran input:

def get_max_possible_tokens(client, prompt):
    """
    Get as many tokens as possible within the model's context window
    without needing to calculate input token count
    """
    response = client.beta.messages.create(
        model="claude-opus-4-8",
        messages=[{"role": "user", "content": prompt}],
        max_tokens=20000,  # Python SDK requires streaming for max_tokens above ~21k
    )

    if response.stop_reason == "model_context_window_exceeded":
        # Mendapatkan token maksimum yang mungkin berdasarkan ukuran input
        print(
            f"Generated {response.usage.output_tokens} tokens (context limit reached)"
        )
    elif response.stop_reason == "max_tokens":
        # Mendapatkan persis jumlah token yang diminta
        print(f"Generated {response.usage.output_tokens} tokens (max_tokens reached)")
    else:
        # Penyelesaian alami
        print(f"Generated {response.usage.output_tokens} tokens (natural completion)")

    return response.content[0].text

Langkah selanjutnya

Penolakan dan fallback

Coba ulang permintaan yang ditolak pada model fallback, di sisi server atau di klien Anda.


Tool Runner (SDK)

Biarkan SDK mengelola loop tool_use, pemformatan hasil, dan percobaan ulang untuk Anda.


Streaming pesan

Baca stop_reason dari event message_delta saat melakukan streaming.


Error

Tangani error HTTP 4xx dan 5xx, yang berbeda dari alasan berhenti.

Was this page helpful?

  • Referensi cepat
  • Field stop_reason
  • Nilai-nilai stop reason
  • end_turn
  • max_tokens
  • stop_sequence
  • tool_use
  • pause_turn
  • refusal
  • model_context_window_exceeded
  • Praktik terbaik untuk menangani alasan berhenti
  • Selalu periksa stop_reason
  • Tangani respons terpotong dengan baik
  • Implementasikan logika percobaan ulang untuk pause_turn
  • Alasan berhenti vs. error
  • Alasan berhenti (respons berhasil)
  • Error (permintaan gagal)
  • Pertimbangan streaming
  • Pola umum
  • Menangani alur kerja penggunaan alat
  • Memastikan respons lengkap
  • Mendapatkan token maksimum tanpa mengetahui ukuran input
  • Langkah selanjutnya