Поле stop_reason в результирующих сообщениях сообщает вам, почему модель прекратила генерацию. Это рекомендуемый способ обнаружения отказов, ограничений по максимальному количеству токенов и других условий завершения (не требуется анализ потока).
stop_reason доступен на каждом ResultMessage, независимо от того, включена ли потоковая передача. Вам не нужно устанавливать include_partial_messages (Python) или includePartialMessages (TypeScript).
Поле stop_reason присутствует как в успешных, так и в ошибочных результирующих сообщениях. Проверьте его после итерации по потоку сообщений:
from claude_agent_sdk import query, ResultMessage
import asyncio
async def check_stop_reason():
async for message in query(prompt="Write a poem about the ocean"):
if isinstance(message, ResultMessage):
print(f"Stop reason: {message.stop_reason}")
if message.stop_reason == "refusal":
print("The model declined this request.")
asyncio.run(check_stop_reason())| Причина остановки | Значение |
|---|---|
end_turn | Модель завершила генерацию своего ответа нормально. |
max_tokens | Ответ достиг максимального ограничения выходных токенов. |
stop_sequence | Модель сгенерировала настроенную последовательность остановки. |
refusal | Модель отказалась выполнить запрос. |
tool_use | Финальный результат модели был вызовом инструмента. Это редко встречается в результатах SDK, потому что вызовы инструментов обычно выполняются до возврата результата. |
null | Ответ API не был получен; например, произошла ошибка до первого запроса, или результат был воспроизведен из кэшированной сессии. |
Результаты ошибок (такие как error_max_turns или error_during_execution) также содержат stop_reason. Значение отражает последнее сообщение ассистента, полученное до возникновения ошибки:
| Вариант результата | Значение stop_reason |
|---|---|
success | Причина остановки из финального сообщения ассистента. |
error_max_turns | Причина остановки из последнего сообщения ассистента перед достижением ограничения по количеству ходов. |
error_max_budget_usd | Причина остановки из последнего сообщения ассистента перед превышением бюджета. |
error_max_structured_output_retries | Причина остановки из последнего сообщения ассистента перед достижением ограничения по количеству повторных попыток. |
error_during_execution | Последняя наблюдаемая причина остановки или null, если ошибка произошла до получения какого-либо ответа API. |
from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage
import asyncio
async def handle_max_turns():
options = ClaudeAgentOptions(max_turns=3)
async for message in query(prompt="Refactor this module", options=options):
if isinstance(message, ResultMessage):
if message.subtype == "error_max_turns":
print(f"Hit turn limit. Last stop reason: {message.stop_reason}")
# stop_reason might be "end_turn" or "tool_use"
# depending on what the model was doing when the limit hit
asyncio.run(handle_max_turns())stop_reason === "refusal" — это самый простой способ обнаружить, когда модель отклоняет запрос. Ранее обнаружение отказов требовало включения потоковой передачи частичных сообщений и ручного сканирования сообщений StreamEvent на предмет событий message_delta. С stop_reason в результирующем сообщении вы можете проверить напрямую:
from claude_agent_sdk import query, ResultMessage
import asyncio
async def safe_query(prompt: str):
async for message in query(prompt=prompt):
if isinstance(message, ResultMessage):
if message.stop_reason == "refusal":
print("Request was declined. Please revise your prompt.")
return None
return message.result
return None
asyncio.run(safe_query("Summarize this article"))message_delta по мере их поступленияWas this page helpful?