• Pesan
  • 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 PesanPemrosesan batchHasil pencarianStreaming penolakanDukungan multibahasaEmbeddings
Alat
IkhtisarCara kerja penggunaan alatTutorial: Membangun agen yang menggunakan alatMendefinisikan alatMenangani panggilan alatPenggunaan alat paralelTool Runner (SDK)Penggunaan alat ketatPenggunaan alat dengan caching promptAlat serverPemecahan masalahAlat pencarian webAlat pengambilan webAlat eksekusi kodeAlat penasihatAlat memoriAlat BashAlat penggunaan komputerAlat editor teks
Infrastruktur alat
Referensi alatMengelola konteks alatKombinasi alatPencarian alatPemanggilan 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 PDFGambar dan visi
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 AWSMicrosoft FoundryVertex AI
Log in
Alasan berhenti dan fallback
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...

Solutions

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

Partners

  • Amazon Bedrock
  • Google Cloud's Vertex AI

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
Pesan/Membangun dengan Claude

Stop reason dan fallback

Field stop_reason, arti setiap nilainya, dan di mana menangani penolakan dan fallback.

Saat Anda membuat permintaan ke Messages API, respons Claude menyertakan field stop_reason yang menunjukkan mengapa model berhenti menghasilkan responsnya. Memahami nilai-nilai ini sangat penting untuk membangun aplikasi yang tangguh yang menangani berbagai jenis respons dengan tepat.

Untuk detail tentang stop_reason dalam respons API, lihat referensi Messages API.

Field stop_reason

Field stop_reason adalah bagian dari setiap respons Messages API yang berhasil. Tidak seperti 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,
  "usage": {
    "input_tokens": 100,
    "output_tokens": 50
  }
}

Nilai stop reason

end_turn

Stop reason yang paling umum. Menunjukkan bahwa Claude menyelesaikan responsnya secara alami.

Python
from anthropic import Anthropic

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

Respons kosong dengan end_turn

Terkadang Claude mengembalikan respons kosong (tepat 2-3 token tanpa konten) dengan stop_reason: "end_turn". Ini biasanya terjadi ketika Claude menafsirkan bahwa giliran asisten sudah selesai, terutama setelah hasil alat.

Penyebab umum:

  • Menambahkan blok teks langsung setelah hasil alat (Claude belajar untuk mengharapkan pengguna selalu menyisipkan teks setelah hasil alat, sehingga Claude mengakhiri gilirannya untuk mengikuti pola tersebut)
  • Mengirim kembali respons Claude yang sudah selesai tanpa menambahkan apa pun (Claude sudah memutuskan bahwa ia selesai, jadi ia akan tetap selesai)

Cara mencegah respons kosong:

# SALAH: Menambahkan teks langsung setelah tool_result
messages = [
    {"role": "user", "content": "Calculate the sum of 1234 and 5678"},
    {
        "role": "assistant",
        "content": [
            {
                "type": "tool_use",
                "id": "toolu_123",
                "name": "calculator",
                "input": {"operation": "add", "a": 1234, "b": 5678},
            }
        ],
    },
    {
        "role": "user",
        "content": [
            {"type": "tool_result", "tool_use_id": "toolu_123", "content": "6912"},
            {
                "type": "text",
                "text": "Here's the result",  # Don't add text after tool_result
            },
        ],
    },
]

# BENAR: Kirim hasil alat secara langsung tanpa teks tambahan
messages = [
    {"role": "user", "content": "Calculate the sum of 1234 and 5678"},
    {
        "role": "assistant",
        "content": [
            {
                "type": "tool_use",
                "id": "toolu_123",
                "name": "calculator",
                "input": {"operation": "add", "a": 1234, "b": 5678},
            }
        ],
    },
    {
        "role": "user",
        "content": [
            {"type": "tool_result", "tool_use_id": "toolu_123", "content": "6912"}
        ],
    },  # Just the tool_result, no additional text
]


# Jika Anda masih mendapatkan respons kosong setelah memperbaiki struktur pesan:
def handle_empty_response(client, messages):
    response = client.messages.create(
        model="claude-opus-4-8", max_tokens=1024, messages=messages
    )

    # Periksa apakah respons kosong
    if response.stop_reason == "end_turn" and not response.content:
        # SALAH: Jangan hanya mencoba ulang dengan respons kosong tersebut
        # Ini tidak akan berhasil karena Claude sudah memutuskan bahwa ia selesai

        # BENAR: Tambahkan prompt lanjutan dalam pesan user yang BARU
        messages.append({"role": "user", "content": "Please continue"})

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

    return response

Praktik terbaik:

  1. Jangan pernah menambahkan blok teks langsung setelah hasil alat - Ini mengajarkan Claude untuk mengharapkan input pengguna setelah setiap penggunaan alat
  2. Jangan mencoba ulang respons kosong tanpa modifikasi - Sekadar mengirim kembali respons kosong tidak akan membantu
  3. Gunakan prompt lanjutan sebagai upaya terakhir - Hanya jika perbaikan di atas tidak menyelesaikan masalah

max_tokens

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

Python
# 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

Blok tool use yang tidak lengkap

Jika respons Claude terpotong karena mencapai batas max_tokens, dan respons yang terpotong tersebut berisi blok tool use yang tidak lengkap, Anda perlu mencoba ulang permintaan dengan nilai max_tokens yang lebih tinggi untuk mendapatkan tool use yang lengkap.

# Periksa apakah respons terpotong selama penggunaan alat
if response.stop_reason == "max_tokens":
    # Periksa apakah blok konten terakhir adalah tool_use yang tidak lengkap
    last_block = response.content[-1]
    if last_block.type == "tool_use":
        # Kirim permintaan dengan max_tokens yang lebih tinggi
        response = client.messages.create(
            model="claude-opus-4-8",
            max_tokens=4096,  # Increased limit
            messages=messages,
            tools=tools,
        )

stop_sequence

Claude menemukan salah satu stop sequence kustom Anda.

Python
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.

Python
from anthropic import Anthropic

client = 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-sonnet-4-20250514",
    max_tokens=1024,
    tools=[weather_tool],
    messages=[{"role": "user", "content": "What's the weather?"}],
)

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

pause_turn

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

Ketika ini terjadi, respons mungkin berisi blok server_tool_use tanpa server_tool_result yang sesuai. Untuk membiarkan Claude menyelesaikan pemrosesan, lanjutkan percakapan dengan mengirim kembali respons apa adanya.

Python
response = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=1024,
    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": original_query},
        {"role": "assistant", "content": response.content},
    ]
    continuation = client.messages.create(
        model="claude-opus-4-8",
        max_tokens=1024,
        messages=messages,
        tools=[{"type": "web_search_20250305", "name": "web_search"}],
    )

Aplikasi Anda harus menangani pause_turn dalam setiap loop agen yang menggunakan server tools. Cukup tambahkan respons asisten ke array messages Anda dan buat permintaan API lain untuk membiarkan Claude melanjutkan.

refusal

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

Python
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 stop reason 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 tersebut dan bentuk lengkap respons penolakan dibahas di Penolakan dan fallback. stop_details bernilai null untuk semua stop reason 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, baik di sisi server maupun di klien Anda. Kredit fallback membahas cara menghindari pembayaran 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.

Python
# Permintaan dengan token maksimum untuk mendapatkan sebanyak mungkin
response = client.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

Stop reason ini tersedia secara default di Sonnet 4.5 dan model yang lebih baru. Untuk model sebelumnya, gunakan beta header model-context-window-exceeded-2025-08-26 untuk mengaktifkan perilaku ini.

Praktik terbaik untuk menangani stop reason

1. 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

2. Tangani respons yang terpotong dengan baik

Ketika respons terpotong karena batas token atau jendela konteks:

def handle_truncated_response(response):
    if response.stop_reason in ["max_tokens", "model_context_window_exceeded"]:
        # Opsi 1: Peringatkan pengguna tentang batas spesifik tersebut
        if response.stop_reason == "max_tokens":
            message = "[Response truncated due to max_tokens limit]"
        else:
            message = "[Response truncated due to context window limit]"
        return f"{response.content[0].text}\n\n{message}"

        # Opsi 2: Lanjutkan proses generasi
        messages = [
            {"role": "user", "content": original_prompt},
            {"role": "assistant", "content": response.content[0].text},
        ]
        continuation = client.messages.create(
            model="claude-opus-4-8",
            max_tokens=1024,
            messages=messages + [{"role": "user", "content": "Please continue"}],
        )
        return response.content[0].text + continuation.content[0].text

3. Terapkan logika percobaan ulang untuk pause_turn

Saat menggunakan server tools, API mungkin 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=1024, 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 bergantian
        messages = [
            {"role": "user", "content": user_query},
            {"role": "assistant", "content": response.content},
        ]

    # Mencapai batas maksimum kelanjutan - kembalikan respons terakhir
    return response

Stop reason vs. error

Penting untuk membedakan antara nilai stop_reason dan error yang sebenarnya:

Stop reason (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
Python
import anthropic
from anthropic import Anthropic

client = Anthropic()

try:
    response = client.messages.create(
        model="claude-sonnet-4-20250514",
        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
Python
from anthropic import Anthropic

client = Anthropic()

with client.messages.stream(
    model="claude-sonnet-4-20250514",
    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 yang 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 stop reason 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.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

Dengan menangani nilai stop_reason dengan benar, Anda dapat membangun aplikasi yang lebih tangguh yang menangani berbagai skenario respons dengan baik dan memberikan pengalaman pengguna yang lebih baik.

Was this page helpful?

  • Field stop_reason
  • Nilai stop reason
  • end_turn
  • max_tokens
  • stop_sequence
  • tool_use
  • pause_turn
  • refusal
  • model_context_window_exceeded
  • Praktik terbaik untuk menangani stop reason
  • 1. Selalu periksa stop_reason
  • 2. Tangani respons yang terpotong dengan baik
  • 3. Terapkan logika percobaan ulang untuk pause_turn
  • Stop reason vs. error
  • Stop reason (respons berhasil)
  • Error (permintaan gagal)
  • Pertimbangan streaming
  • Pola umum
  • Menangani alur kerja penggunaan alat
  • Memastikan respons yang lengkap
  • Mendapatkan token maksimum tanpa mengetahui ukuran input