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

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

Apa itu stop_reason?

Bidang 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 berhasil menyelesaikan pembuatan responsnya.

Contoh respons
{
  "id": "msg_01234",
  "type": "message",
  "role": "assistant",
  "content": [
    {
      "type": "text",
      "text": "Berikut jawaban untuk pertanyaan Anda..."
    }
  ],
  "stop_reason": "end_turn",
  "stop_sequence": null,
  "usage": {
    "input_tokens": 100,
    "output_tokens": 50
  }
}

Nilai-nilai stop reason

end_turn

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

if response.stop_reason == "end_turn":
    # Proses respons lengkap
    print(response.content[0].text)

max_tokens

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

# Permintaan dengan token terbatas
response = client.messages.create(
    model="claude-3-7-sonnet-20250219",
    max_tokens=10,
    messages=[{"role": "user", "content": "Jelaskan fisika kuantum"}]
)

if response.stop_reason == "max_tokens":
    # Respons terpotong
    print("Respons terpotong pada batas token")
    # Pertimbangkan untuk membuat permintaan lain untuk melanjutkan

stop_sequence

Claude menemukan salah satu urutan berhenti kustom Anda.

response = client.messages.create(
    model="claude-3-7-sonnet-20250219",
    max_tokens=1024,
    stop_sequences=["END", "STOP"],
    messages=[{"role": "user", "content": "Hasilkan teks sampai Anda mengatakan END"}]
)

if response.stop_reason == "stop_sequence":
    print(f"Berhenti pada urutan: {response.stop_sequence}")

tool_use

Claude memanggil alat dan mengharapkan Anda untuk mengeksekusinya.

response = client.messages.create(
    model="claude-3-7-sonnet-20250219",
    max_tokens=1024,
    tools=[weather_tool],
    messages=[{"role": "user", "content": "Bagaimana cuacanya?"}]
)

if response.stop_reason == "tool_use":
    # Ekstrak dan eksekusi 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

Digunakan dengan alat server seperti pencarian web ketika Claude perlu menjeda operasi yang berjalan lama.

response = client.messages.create(
    model="claude-3-7-sonnet-20250219",
    max_tokens=1024,
    tools=[{"type": "web_search_20250305", "name": "web_search"}],
    messages=[{"role": "user", "content": "Cari berita AI terbaru"}]
)

if response.stop_reason == "pause_turn":
    # Lanjutkan percakapan
    messages = [
        {"role": "user", "content": original_query},
        {"role": "assistant", "content": response.content}
    ]
    continuation = client.messages.create(
        model="claude-3-7-sonnet-20250219",
        messages=messages,
        tools=[{"type": "web_search_20250305", "name": "web_search"}]
    )

Praktik terbaik untuk menangani stop reasons

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 == "pause_turn":
        return handle_pause(response)
    else:
        # Tangani end_turn dan kasus lainnya
        return response.content[0].text

2. Tangani max_tokens dengan baik

Ketika respons terpotong karena batas token:

def handle_truncated_response(response):
    if response.stop_reason == "max_tokens":
        # Opsi 1: Peringatkan pengguna
        return f"{response.content[0].text}\n\n[Respons terpotong karena panjangnya]"
        
        # Opsi 2: Lanjutkan pembuatan
        messages = [
            {"role": "user", "content": original_prompt},
            {"role": "assistant", "content": response.content[0].text}
        ]
        continuation = client.messages.create(
            model="claude-3-7-sonnet-20250219",
            max_tokens=1024,
            messages=messages + [{"role": "user", "content": "Silakan lanjutkan"}]
        )
        return response.content[0].text + continuation.content[0].text

3. Implementasikan logika percobaan ulang untuk pause_turn

Untuk alat server yang mungkin dijeda:

def handle_paused_conversation(initial_response, max_retries=3):
    response = initial_response
    messages = [{"role": "user", "content": original_query}]
    
    for attempt in range(max_retries):
        if response.stop_reason != "pause_turn":
            break
            
        messages.append({"role": "assistant", "content": response.content})
        response = client.messages.create(
            model="claude-3-7-sonnet-20250219",
            messages=messages,
            tools=original_tools
        )
    
    return response

Stop reasons vs. errors

Penting untuk membedakan antara nilai stop_reason dan error sebenarnya:

Stop reasons (respons berhasil)

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

Errors (permintaan gagal)

  • Kode status HTTP 4xx atau 5xx
  • Menunjukkan kegagalan pemrosesan permintaan
  • Respons berisi detail error
try:
    response = client.messages.create(...)
    
    # Tangani respons berhasil dengan stop_reason
    if response.stop_reason == "max_tokens":
        print("Respons terpotong")
    
except anthropic.APIError as e:
    # Tangani error sebenarnya
    if e.status_code == 429:
        print("Batas rate terlampaui")
    elif e.status_code == 500:
        print("Error server")

Pertimbangan streaming

Ketika menggunakan streaming, stop_reason adalah:

  • null dalam event message_start awal
  • Disediakan dalam event message_delta
  • Non-null dalam semua event lainnya
with client.messages.stream(...) as stream:
    for event in stream:
        if event.type == "message_delta":
            stop_reason = event.delta.stop_reason
            if stop_reason:
                print(f"Stream berakhir dengan: {stop_reason}")

Pola umum

Menangani alur kerja penggunaan alat

def complete_tool_workflow(client, user_query, tools):
    messages = [{"role": "user", "content": user_query}]
    
    while True:
        response = client.messages.create(
            model="claude-3-7-sonnet-20250219",
            messages=messages,
            tools=tools
        )
        
        if response.stop_reason == "tool_use":
            # Eksekusi 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-3-7-sonnet-20250219",
            messages=messages,
            max_tokens=4096
        )
        
        full_response += response.content[0].text
        
        if response.stop_reason != "max_tokens":
            break
            
        # Lanjutkan dari tempat terakhir berhenti
        messages = [
            {"role": "user", "content": prompt},
            {"role": "assistant", "content": full_response},
            {"role": "user", "content": "Silakan lanjutkan dari tempat Anda berhenti."}
        ]
    
    return full_response

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