El campo stop_reason en los mensajes de resultado te indica por qué el modelo dejó de generar. Esta es la forma recomendada de detectar rechazos, límites de tokens máximos y otras condiciones de terminación (no se requiere análisis de flujo).
stop_reason está disponible en cada ResultMessage, independientemente de si el streaming está habilitado. No necesitas establecer include_partial_messages (Python) o includePartialMessages (TypeScript).
El campo stop_reason está presente tanto en mensajes de resultado exitosos como en mensajes de error. Verifica después de iterar a través del flujo de mensajes:
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())| Razón de parada | Significado |
|---|---|
end_turn | El modelo terminó de generar su respuesta normalmente. |
max_tokens | La respuesta alcanzó el límite máximo de tokens de salida. |
stop_sequence | El modelo generó una secuencia de parada configurada. |
refusal | El modelo rechazó cumplir con la solicitud. |
tool_use | La salida final del modelo fue una llamada de herramienta. Esto es poco común en resultados de SDK porque las llamadas de herramienta normalmente se ejecutan antes de que se devuelva el resultado. |
null | No se recibió respuesta de la API; por ejemplo, ocurrió un error antes de la primera solicitud, o el resultado se reprodujo desde una sesión en caché. |
Los resultados de error (como error_max_turns o error_during_execution) también llevan stop_reason. El valor refleja el último mensaje del asistente recibido antes de que ocurriera el error:
| Variante de resultado | valor de stop_reason |
|---|---|
success | La razón de parada del mensaje final del asistente. |
error_max_turns | La razón de parada del último mensaje del asistente antes de que se alcanzara el límite de turnos. |
error_max_budget_usd | La razón de parada del último mensaje del asistente antes de que se excediera el presupuesto. |
error_max_structured_output_retries | La razón de parada del último mensaje del asistente antes de que se alcanzara el límite de reintentos. |
error_during_execution | La última razón de parada vista, o null si el error ocurrió antes de cualquier respuesta de la 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" es la forma más simple de detectar cuándo el modelo rechaza una solicitud. Anteriormente, detectar rechazos requería habilitar el streaming de mensajes parciales y escanear manualmente los mensajes StreamEvent para eventos message_delta. Con stop_reason en el mensaje de resultado, puedes verificar directamente:
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 a medida que lleganWas this page helpful?