
Crea un agente autónomo con Claude Sonnet 5: tool use, el loop agéntico y autoverificación
Claude Sonnet 5 (id claude-sonnet-5) es el Sonnet más agéntico hasta hoy: planea, usa herramientas y revisa su propia salida. Define tus tools como JSON Schema, corre un loop agéntico (de tool_use a tool_result hasta stop_reason end_turn), usa adaptive thinking con effort, agrega un paso de autoverificación y cachea el prefijo system+tools. Con el precio intro de $2/$10 hasta el 31 ago 2026, correr agentes reales sale barato.
Acaba de salir Claude Sonnet 5 — y viene hecho para agentes
Hoy, 30 de junio de 2026, Anthropic lanzó Claude Sonnet 5. Ya está vivo en todas las apps de Claude y en la Claude Platform/API, y según el anuncio es desde hoy el modelo por defecto en Free y Pro, además de estar disponible para Max, Team y Enterprise.
La frase oficial de Anthropic es directa: “the best combination of speed and intelligence” y “the most agentic Sonnet yet”. En corto: planea, usa herramientas (navegadores, terminales) y corre de forma autónoma a un nivel que hace unos meses exigía modelos mucho más grandes y caros. Es un salto sólido sobre Sonnet 4.6 en razonamiento, tool use, código y trabajo de conocimiento, con un rendimiento cercano a Opus 4.8 a un precio más bajo.
El id del modelo es claude-sonnet-5 — un id sin fecha, formato pinned-snapshot, que sirve tanto como id de API como de alias. No le agregues sufijo de fecha. En Bedrock es anthropic.claude-sonnet-5 y en Google Cloud claude-sonnet-5.
Pero este post no es cobertura de día de lanzamiento. Es un build. Vamos a armar un agente autónomo de verdad — que usa herramientas y revisa su propia salida — sobre la Messages API. Si todavía no tienes claro el concepto, lee primero qué es un agente de IA. Las fuentes oficiales: Anthropic — Introducing Claude Sonnet 5 y Models overview.
Por qué Sonnet 5 cambia las cuentas de los agentes
Mi opinión, etiquetada como tal: el titular para builders es COSTO × AGENCIA. Puedes correr agentes autónomos, que usan herramientas y se autoverifican, a precio de Sonnet.
Los números, como están al lanzamiento (confirma el precio vigente antes de presupuestar): el precio estándar es $3 por MTok de input y $15 por MTok de output. Hay un precio introductorio de $2 / $10 por MTok hasta el 31 de agosto de 2026, y después regresa a $3/$15. A precio estándar, eso es alrededor de 60% más barato por token que Opus 4.8 ($5/$25).
Ahora, seamos honestos con la brecha frente a Opus. En una evaluación de coding agéntico, Sonnet 5 anda en ~63.2% contra ~69.2% de Opus 4.8 y ~58.1% de Sonnet 4.6. Son cifras reportadas por Anthropic — revisa el anuncio para los nombres exactos de los evals. La lectura: Sonnet 5 cierra la mayor parte de la distancia a Opus 4.8 a una fracción del costo, pero Opus 4.8 sigue mandando en el coding agéntico más difícil.
Mi veredicto operativo: elige Sonnet 5 para cargas agénticas a escala; Opus 4.8 cuando necesites lo absolutamente top; y Haiku 4.5 ($1/$5) para las llamadas simples más baratas y rápidas. Sonnet 5 es el punto dulce de la gama de valor, no la frontera absoluta.
Specs que importan para agentes: contexto de 1M de tokens, 128k de output máximo (hasta 300k en la Batch API con el beta header output-300k-2026-03-24), knowledge cutoff confiable de enero de 2026 y latencia “Fast”. Para más fundamentos, /es/agentes-de-ia/.
Cómo funciona de verdad el loop agéntico
Antes de tocar código, quitemos la magia. El contrato es este: llega una tarea del usuario → Sonnet 5 planea → emite un bloque tool_use (con un nombre de herramienta, un input y un id único de tool_use) → tu código corre la herramienta real → tú agregas un bloque tool_result que referencia ese mismo tool_use_id → mandas todo de regreso → y el loop se repite.
La señal que vigilas es stop_reason. Mientras valga "tool_use", sigues iterando. Cuando cambie a "end_turn", el modelo ya tiene su respuesta final y te detienes.
Detalle clave de seguridad y control: el modelo nunca corre tus herramientas, solo las pide. Tú eres el runtime. Esa separación es toda la historia de control — tú decides qué se ejecuta, con qué permisos y con qué validación.
La diferencia con un prompt de una sola pasada: ahí obtienes una respuesta y ya. En el loop agéntico el modelo planea → usa herramientas → verifica → termina. Eso cuesta varias llamadas, y justo por eso el precio bajo de Sonnet 5 importa: hace que correr el loop multi-paso repetidamente salga barato. Y como esta superficie trae adaptive thinking, el razonamiento se intercala con la planeación entre llamadas a herramientas.
Por qué la jugada cambia con el precio
Prompt de una pasada
- Una sola llamada, una respuesta
- Sin herramientas reales ni verificación
- Barato pero limitado a lo que ya sabe el modelo
- Bien para Q&A simple
Loop agéntico
- Planea → usa herramientas → verifica → termina
- Varias llamadas por tarea (más tokens)
- Acciones reales: datos, búsquedas, escrituras
- Viable a escala por el intro de $2/$10 (al lanzamiento)
Define tus herramientas (JSON Schema con descripciones prescriptivas)
Cada herramienta necesita tres cosas: un name, una descripción prescriptiva (arranca con “Llama a esta herramienta cuando…” — la descripción es tu volante de dirección) y un input_schema en JSON Schema con propiedades tipadas y campos required.
La calidad de la descripción importa más que el schema. Dile al modelo la situación exacta que debe disparar la llamada y para qué no usarla.
import anthropic
client = anthropic.Anthropic()
# Las tools y el system se mantienen ESTABLES entre turnos.
# Más adelante cacheamos este prefijo para abaratar el loop.
tools = [
{
"name": "get_exchange_rate",
"description": (
"Llama a esta herramienta cuando el usuario pida convertir "
"un monto entre dos monedas o pregunte el tipo de cambio actual. "
"NO la uses para precios históricos ni para criptomonedas."
),
"input_schema": {
"type": "object",
"properties": {
"from_currency": {
"type": "string",
"description": "Código ISO 4217 de origen, ej. 'USD'.",
},
"to_currency": {
"type": "string",
"description": "Código ISO 4217 destino, ej. 'MXN'.",
},
"amount": {
"type": "number",
"description": "Monto a convertir en la moneda de origen.",
},
},
"required": ["from_currency", "to_currency", "amount"],
},
},
{
"name": "lookup_invoice",
"description": (
"Llama a esta herramienta cuando el usuario referencie una "
"factura por folio para consultar su estatus o total. "
"NO la uses para crear ni modificar facturas."
),
"input_schema": {
"type": "object",
"properties": {
"folio": {
"type": "string",
"description": "Folio de la factura, ej. 'F-2026-0042'.",
}
},
"required": ["folio"],
},
},
]
Si quieres que estas herramientas hablen con sistemas reales (tu base de datos, tu ERP, un proveedor de pagos), el camino limpio es MCP: conecta tu agente a tus datos vía MCP. Y fija el modelo explícito: model="claude-sonnet-5".
Escribe el loop: entra tool_use, sale tool_result
Aquí está el corazón. El loop manual completo, ejecutable, con el contrato de ids al frente: el tool_use_id de tu tool_result tiene que coincidir con el id del bloque tool_use que emitió el modelo, o la API lo rechaza.
import json
def run_tool(name, tool_input):
# Despacha por nombre a tu handler real.
# Hazlos IDEMPOTENTES: un re-plan o reintento puede llamar dos veces.
if name == "get_exchange_rate":
# ...llamada real a tu fuente de tipo de cambio...
return {"rate": 17.05, "result": tool_input["amount"] * 17.05}
if name == "lookup_invoice":
return {"folio": tool_input["folio"], "status": "pagada", "total": 4200.0}
return {"error": f"herramienta desconocida: {name}"}
messages = [
{"role": "user", "content": "¿Cuánto son 250 USD en MXN hoy?"}
]
MAX_ITERS = 8 # guarda anti-loop-infinito
for _ in range(MAX_ITERS):
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=2048,
system="Eres un agente operativo. Verifica tu resultado antes de terminar.",
tools=tools,
messages=messages,
thinking={"type": "adaptive"}, # adaptive only; NO budget_tokens
output_config={"effort": "medium"}, # default es "high"; bájalo si es simple
# SIN temperature / top_p / top_k: no se usan en esta superficie.
)
# Maneja pause_turn: el modelo pausó una operación larga; reanuda.
if response.stop_reason == "pause_turn":
messages.append({"role": "assistant", "content": response.content})
continue
# Para el resto de finales, agrega el turno del assistant
# (incluye los bloques tool_use). La rama pause_turn ya hizo su append y salió.
messages.append({"role": "assistant", "content": response.content})
if response.stop_reason != "tool_use":
# end_turn (u otro final): el agente terminó.
final_text = "".join(
b.text for b in response.content if b.type == "text"
)
print(final_text)
break
# Ejecuta cada tool_use y construye los tool_result con el id que coincide.
tool_results = []
for block in response.content:
if block.type == "tool_use":
output = run_tool(block.name, block.input)
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id, # <- DEBE coincidir
"content": json.dumps(output, ensure_ascii=False), # JSON válido
})
# El turno del usuario lleva los tool_result; el orden y los ids deben cuadrar.
# (content también acepta una lista de bloques de contenido, no solo string.)
messages.append({"role": "user", "content": tool_results})
else:
print("Se alcanzó MAX_ITERS sin end_turn — revisa el agente.")
Tres cosas que no debes saltarte. Una: la guarda de max-iterations, para que un agente que se porta mal no itere para siempre. Dos: idempotencia en los handlers con efectos secundarios — usa dedup keys o check-before-write, porque tus herramientas pueden llamarse más veces de las que esperas (reintentos, re-planes). Tres: effort arranca en "high" por defecto en la Claude API y en Claude Code; bájalo a medium/low para despacho de herramientas más barato y rápido cuando la tarea es simple. Si vienes armando esto desde cero, mi guía base es cómo construir un agente de IA con Python.
- Define tus toolsname + descripción 'llama a esta cuando…' + input_schema (JSON Schema)
- Escribe el loopmessages.create con tools[], thinking adaptive, effort explícito
- Ejecuta y devuelvecorre cada tool_use; tool_result con tool_use_id que coincide
- Deja que se autoverifiqueque revise su salida contra los criterios de éxito antes de cerrar
- Detente en end_turnloop mientras stop_reason sea tool_use; guarda de max-iters
Deja que revise su propio trabajo (autoverificación)
Los partners de acceso temprano reportan que Sonnet 5 termina tareas donde Sonnets anteriores se quedaban cortos, y que revisa su propia salida sin que se lo pidas. Hagamos de eso una feature, no suerte.
Agrega un paso explícito de autoverificación: antes de aceptar end_turn, haz que el modelo (o una herramienta dedicada) revalide su resultado contra los criterios de éxito de la tarea y o confirme o vuelva a iterar para corregir.
Hay dos patrones. Uno: una instrucción en el system prompt que le ordene verificar antes de terminar (es lo que puse arriba). Dos: una herramienta verify_result que el agente debe llamar y que regresa pass/fail con razones.
verify_tool = {
"name": "verify_result",
"description": (
"Llama a esta herramienta SIEMPRE antes de dar tu respuesta final. "
"Revisa tu resultado contra los criterios de éxito de la tarea. "
"Devuelve pass/fail con las razones."
),
"input_schema": {
"type": "object",
"properties": {
"claim": {"type": "string", "description": "El resultado a verificar."},
"criteria_met": {"type": "boolean"},
"reasons": {"type": "string"},
},
"required": ["claim", "criteria_met", "reasons"],
},
}
Y como doble seguro, usa structured outputs con output_config.format para que la respuesta final regrese en un schema que valides en tu código, no solo en la cabeza del modelo. effort y format viven como llaves hermanas dentro de output_config:
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=1024,
messages=messages,
output_config={
"effort": "medium",
"format": {
"type": "json_schema",
"schema": {
"type": "object",
"properties": {
"amount_mxn": {"type": "number"},
"rate_used": {"type": "number"},
"verified": {"type": "boolean"},
},
"required": ["amount_mxn", "rate_used", "verified"],
},
},
},
)
La advertencia honesta: la autoverificación reduce errores, no los elimina. Mantén tus propias aserciones sobre cualquier acción con efectos secundarios.
El tool runner del SDK vs el loop manual — cuál usar
Hay dos caminos y conviene elegir a propósito.
El tool runner del SDK es el camino fácil: registras tus funciones de herramienta y el SDK maneja el loop tool_use → tool_result por ti. Menos código, más rápido para salir a producción. Es un helper en beta: en Python usas client.beta.messages.tool_runner junto con el decorador @beta_tool (el equivalente en el SDK de TypeScript se llama toolRunner).
El loop manual es para control: lógica custom de reintentos/idempotencia, observabilidad y logging en cada llamada a herramienta, aprobaciones human-in-the-loop, o despacho no estándar.
Mi take: arranca con el tool runner del SDK para prototipar, y baja al loop manual cuando necesites instrumentar o poner compuertas en el loop. De cualquier forma el contrato de abajo es idéntico — stop_reason, tool_use_id que coincide, end_turn — así que lo que aprendiste aquí se transfiere.
La palanca de costo aplica a ambos: prompt caching con cache_control sobre el prefijo estable de system + tools. El array tools[] y el system prompt se repiten en cada turno del loop; cachéalos para no pagar input completo en cada iteración. En corridas multi-paso largas el ahorro es real, además del intro de $2/$10. Tengo una guía dedicada: cachea el prefijo system+tools para bajar costos.
Migrar un agente que ya tienes en Sonnet 4.6
Si ya corres un agente, la migración es corta:
- Cambia el string del modelo a
claude-sonnet-5. - Si usabas extended thinking con
budget_tokens, cámbiate a adaptive thinking:thinking={"type": "adaptive"}.budget_tokensno está soportado. - Re-afina
effort: Sonnet 5 trae"high"por defecto, que puede costar más o correr más lento de lo que quieres para despacho simple de herramientas. Ponlo explícito. - Quita cualquier
temperature/top_p/top_k: no se usan en esta superficie. - Confirma los breaking changes exactos contra la guía de migración de Anthropic antes de ir a producción — no confíes en esta lista a ciegas.
Preguntas frecuentes
¿Cuál es el id exacto del modelo? claude-sonnet-5 — pinned snapshot sin fecha, usado como id de API y como alias. Sin sufijo de fecha.
¿Cuánto cuesta? Estándar $3/$15 por MTok; intro $2/$10 hasta el 31 de agosto de 2026, luego regresa a $3/$15. Confirma el precio vigente al momento, ya que esto está recién salido.
¿Puedo fijar un budget de thinking? No — solo adaptive thinking (thinking={"type": "adaptive"}). Controlas la profundidad con output_config.effort, no con budget_tokens.
¿Es tan bueno como Opus 4.8? Cerca en tareas agénticas (~63.2% vs ~69.2% en un eval de coding agéntico — cifras reportadas por Anthropic; revisa el anuncio para los nombres exactos), pero Opus 4.8 sigue liderando en el coding agéntico más difícil. Sonnet 5 es la gama de valor.
¿Cómo evito que el loop corra para siempre? Pon una guarda de max-iterations y detente en stop_reason == "end_turn".
¿Qué tan grande es el contexto / output? Contexto de 1M de tokens y 128k de output máximo (hasta 300k en la Batch API con el beta header output-300k-2026-03-24).
A producción
La receta entera de un jalón: modelo claude-sonnet-5, tools[] con JSON Schema y descripciones “llama a esta cuando…”, loop sobre stop_reason igual a tool_use, adaptive thinking más effort, un paso de autoverificación, y cachea el prefijo system + tools.
Sonnet 5 hace que correr agentes autónomos que se autorrevisan salga barato — especialmente durante la ventana intro de $2/$10 hasta el 31 de agosto de 2026. Confirma siempre los ids de modelo, los precios y los campos de API contra la documentación de precios de Anthropic antes de mandar a producción. Esto está recién salido y se mueve rápido.