agent-sdk/agent-loop.md +395 −0 created
1> ## Documentation Index
2> Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt
3> Use this file to discover all available pages before exploring further.
4
5# Cómo funciona el bucle del agente
6
7> Comprenda el ciclo de vida de los mensajes, la ejecución de herramientas, la ventana de contexto y la arquitectura que potencia sus agentes SDK.
8
9El Agent SDK le permite incrustar el bucle de agente autónomo de Claude Code en sus propias aplicaciones. El SDK es un paquete independiente que le proporciona control programático sobre herramientas, permisos, límites de costos y salida. No necesita tener instalado el CLI de Claude Code para usarlo.
10
11Cuando inicia un agente, el SDK ejecuta el mismo [bucle de ejecución que potencia Claude Code](/es/how-claude-code-works#the-agentic-loop): Claude evalúa su prompt, llama a herramientas para tomar acciones, recibe los resultados y repite hasta que la tarea se complete. Esta página explica qué sucede dentro de ese bucle para que pueda construir, depurar y optimizar sus agentes de manera efectiva.
12
13## El bucle de un vistazo
14
15Cada sesión de agente sigue el mismo ciclo:
16
17<img src="https://mintcdn.com/claude-code/gvy2DIUELtNA8qD3/images/agent-loop-diagram.svg?fit=max&auto=format&n=gvy2DIUELtNA8qD3&q=85&s=192e1bd6c8a2950a16e5ee0b94e27e26" alt="Bucle del agente: el prompt entra, Claude evalúa, se ramifica a llamadas de herramientas o respuesta final" width="680" height="150" data-path="images/agent-loop-diagram.svg" />
18
191. **Recibir prompt.** Claude recibe su prompt, junto con el prompt del sistema, las definiciones de herramientas e historial de conversación. El SDK produce un [`SystemMessage`](#message-types) con subtipo `"init"` que contiene metadatos de sesión.
202. **Evaluar y responder.** Claude evalúa el estado actual y determina cómo proceder. Puede responder con texto, solicitar una o más llamadas de herramientas, o ambas. El SDK produce un [`AssistantMessage`](#message-types) que contiene el texto y cualquier solicitud de llamada de herramienta.
213. **Ejecutar herramientas.** El SDK ejecuta cada herramienta solicitada y recopila los resultados. Cada conjunto de resultados de herramientas se devuelve a Claude para la siguiente decisión. Puede usar [hooks](/es/agent-sdk/hooks) para interceptar, modificar o bloquear llamadas de herramientas antes de que se ejecuten.
224. **Repetir.** Los pasos 2 y 3 se repiten como un ciclo. Cada ciclo completo es un turno. Claude continúa llamando a herramientas y procesando resultados hasta que produce una respuesta sin llamadas de herramientas.
235. **Devolver resultado.** El SDK produce un [`AssistantMessage`](#message-types) final con la respuesta de texto (sin llamadas de herramientas), seguido de un [`ResultMessage`](#message-types) con el texto final, uso de tokens, costo e ID de sesión.
24
25Una pregunta rápida ("¿qué archivos hay aquí?") podría tomar uno o dos turnos llamando a `Glob` y respondiendo con los resultados. Una tarea compleja ("refactorizar el módulo de autenticación y actualizar las pruebas") puede encadenar docenas de llamadas de herramientas en muchos turnos, leyendo archivos, editando código y ejecutando pruebas, con Claude ajustando su enfoque basado en cada resultado.
26
27## Turnos y mensajes
28
29Un turno es un viaje de ida y vuelta dentro del bucle: Claude produce una salida que incluye llamadas de herramientas, el SDK ejecuta esas herramientas y los resultados se devuelven a Claude automáticamente. Esto sucede sin ceder el control a su código. Los turnos continúan hasta que Claude produce una salida sin llamadas de herramientas, momento en el cual el bucle termina y se entrega el resultado final.
30
31Considere cómo podría verse una sesión completa para el prompt "Arregla las pruebas fallidas en auth.ts".
32
33Primero, el SDK envía su prompt a Claude y produce un [`SystemMessage`](#message-types) con los metadatos de sesión. Luego comienza el bucle:
34
351. **Turno 1:** Claude llama a `Bash` para ejecutar `npm test`. El SDK produce un [`AssistantMessage`](#message-types) con la llamada de herramienta, ejecuta el comando, luego produce un [`UserMessage`](#message-types) con la salida (tres fallos).
362. **Turno 2:** Claude llama a `Read` en `auth.ts` y `auth.test.ts`. El SDK devuelve el contenido del archivo y produce un `AssistantMessage`.
373. **Turno 3:** Claude llama a `Edit` para arreglar `auth.ts`, luego llama a `Bash` para volver a ejecutar `npm test`. Las tres pruebas pasan. El SDK produce un `AssistantMessage`.
384. **Turno final:** Claude produce una respuesta solo de texto sin llamadas de herramientas: "Arreglé el error de autenticación, las tres pruebas pasan ahora." El SDK produce un `AssistantMessage` final con este texto, luego un [`ResultMessage`](#message-types) con el mismo texto más costo y uso.
39
40Eso fueron cuatro turnos: tres con llamadas de herramientas, uno con respuesta final solo de texto.
41
42Puede limitar el bucle con `max_turns` / `maxTurns`, que cuenta solo los turnos de uso de herramientas. Por ejemplo, `max_turns=2` en el bucle anterior se habría detenido antes del paso de edición. También puede usar `max_budget_usd` / `maxBudgetUsd` para limitar los turnos basándose en un umbral de gasto.
43
44Sin límites, el bucle se ejecuta hasta que Claude termine por su cuenta, lo cual está bien para tareas bien delimitadas pero puede ejecutarse durante mucho tiempo en prompts abiertos ("mejora esta base de código"). Establecer un presupuesto es un buen valor predeterminado para agentes de producción. Vea [Turnos y presupuesto](#turns-and-budget) a continuación para la referencia de opciones.
45
46## Tipos de mensajes
47
48A medida que se ejecuta el bucle, el SDK produce un flujo de mensajes. Cada mensaje lleva un tipo que le indica en qué etapa del bucle se originó. Los cinco tipos principales son:
49
50* **`SystemMessage`:** eventos del ciclo de vida de la sesión. El campo `subtype` los distingue: `"init"` es el primer mensaje (metadatos de sesión), y `"compact_boundary"` se dispara después de [compactación](#automatic-compaction). En TypeScript, el límite de compactación es su propio tipo [`SDKCompactBoundaryMessage`](/es/agent-sdk/typescript#sdkcompactboundarymessage) en lugar de un subtipo de `SDKSystemMessage`.
51* **`AssistantMessage`:** emitido después de cada respuesta de Claude, incluida la final solo de texto. Contiene bloques de contenido de texto y bloques de llamadas de herramientas de ese turno.
52* **`UserMessage`:** emitido después de cada ejecución de herramienta con el contenido del resultado de la herramienta enviado de vuelta a Claude. También se emite para cualquier entrada de usuario que transmita a mitad del bucle.
53* **`StreamEvent`:** solo se emite cuando los mensajes parciales están habilitados. Contiene eventos de transmisión de API sin procesar (deltas de texto, fragmentos de entrada de herramientas). Vea [Respuestas de transmisión](/es/agent-sdk/streaming-output).
54* **`ResultMessage`:** marca el final del bucle del agente. Contiene el resultado de texto final, uso de tokens, costo e ID de sesión. Verifique el campo `subtype` para determinar si la tarea tuvo éxito o alcanzó un límite. Un pequeño número de eventos del sistema finales, como `prompt_suggestion`, pueden llegar después, así que itere el flujo hasta completarse en lugar de romper en el resultado. Vea [Manejar el resultado](#handle-the-result).
55
56Estos cinco tipos cubren el ciclo de vida completo del bucle del agente en ambos SDK. El SDK de TypeScript también produce eventos de observabilidad adicionales (eventos de hooks, progreso de herramientas, límites de velocidad, notificaciones de tareas) que proporcionan detalles adicionales pero no son necesarios para impulsar el bucle. Vea la [referencia de tipos de mensajes de Python](/es/agent-sdk/python#message-types) y la [referencia de tipos de mensajes de TypeScript](/es/agent-sdk/typescript#message-types) para las listas completas.
57
58### Manejar mensajes
59
60Qué mensajes maneja depende de lo que esté construyendo:
61
62* **Solo resultados finales:** maneje `ResultMessage` para obtener la salida, el costo y si la tarea tuvo éxito o alcanzó un límite.
63* **Actualizaciones de progreso:** maneje `AssistantMessage` para ver qué está haciendo Claude en cada turno, incluidas las herramientas que llamó.
64* **Transmisión en vivo:** habilite mensajes parciales (`include_partial_messages` en Python, `includePartialMessages` en TypeScript) para obtener mensajes `StreamEvent` en tiempo real. Vea [Respuestas de transmisión en tiempo real](/es/agent-sdk/streaming-output).
65
66Cómo verifica los tipos de mensajes depende del SDK:
67
68* **Python:** verifique los tipos de mensajes con `isinstance()` contra clases importadas de `claude_agent_sdk` (por ejemplo, `isinstance(message, ResultMessage)`).
69* **TypeScript:** verifique el campo de cadena `type` (por ejemplo, `message.type === "result"`). `AssistantMessage` y `UserMessage` envuelven el mensaje de API sin procesar en un campo `.message`, por lo que los bloques de contenido están en `message.message.content`, no en `message.content`.
70
71<Accordion title="Ejemplo: Verificar tipos de mensajes y manejar resultados">
72 <CodeGroup>
73 ```python Python theme={null}
74 from claude_agent_sdk import query, AssistantMessage, ResultMessage
75
76 async for message in query(prompt="Summarize this project"):
77 if isinstance(message, AssistantMessage):
78 print(f"Turn completed: {len(message.content)} content blocks")
79 if isinstance(message, ResultMessage):
80 if message.subtype == "success":
81 print(message.result)
82 else:
83 print(f"Stopped: {message.subtype}")
84 ```
85
86 ```typescript TypeScript theme={null}
87 import { query } from "@anthropic-ai/claude-agent-sdk";
88
89 for await (const message of query({ prompt: "Summarize this project" })) {
90 if (message.type === "assistant") {
91 console.log(`Turn completed: ${message.message.content.length} content blocks`);
92 }
93 if (message.type === "result") {
94 if (message.subtype === "success") {
95 console.log(message.result);
96 } else {
97 console.log(`Stopped: ${message.subtype}`);
98 }
99 }
100 }
101 ```
102 </CodeGroup>
103</Accordion>
104
105## Ejecución de herramientas
106
107Las herramientas dan a su agente la capacidad de tomar acciones. Sin herramientas, Claude solo puede responder con texto. Con herramientas, Claude puede leer archivos, ejecutar comandos, buscar código e interactuar con servicios externos.
108
109### Herramientas integradas
110
111El SDK incluye las mismas herramientas que potencian Claude Code:
112
113| Categoría | Herramientas | Qué hacen |
114| :------------------------- | :----------------------------------------------- | :------------------------------------------------------------------------------------- |
115| **Operaciones de archivo** | `Read`, `Edit`, `Write` | Leer, modificar y crear archivos |
116| **Búsqueda** | `Glob`, `Grep` | Encontrar archivos por patrón, buscar contenido con regex |
117| **Ejecución** | `Bash` | Ejecutar comandos de shell, scripts, operaciones de git |
118| **Web** | `WebSearch`, `WebFetch` | Buscar en la web, obtener y analizar páginas |
119| **Descubrimiento** | `ToolSearch` | Encontrar y cargar herramientas dinámicamente bajo demanda en lugar de precargar todas |
120| **Orquestación** | `Agent`, `Skill`, `AskUserQuestion`, `TodoWrite` | Generar subagentes, invocar skills, preguntar al usuario, rastrear tareas |
121
122Más allá de las herramientas integradas, puede:
123
124* **Conectar servicios externos** con [servidores MCP](/es/agent-sdk/mcp) (bases de datos, navegadores, APIs)
125* **Definir herramientas personalizadas** con [manejadores de herramientas personalizadas](/es/agent-sdk/custom-tools)
126* **Cargar skills del proyecto** a través de [fuentes de configuración](/es/agent-sdk/claude-code-features) para flujos de trabajo reutilizables
127
128### Permisos de herramientas
129
130Claude determina qué herramientas llamar basándose en la tarea, pero usted controla si esas llamadas pueden ejecutarse. Puede aprobar automáticamente herramientas específicas, bloquear otras completamente o requerir aprobación para todo. Tres opciones funcionan juntas para determinar qué se ejecuta:
131
132* **`allowed_tools` / `allowedTools`** aprueba automáticamente las herramientas listadas. Un agente de solo lectura con `["Read", "Glob", "Grep"]` en su lista de herramientas permitidas ejecuta esas herramientas sin solicitar. Las herramientas no listadas aún están disponibles pero requieren permiso.
133* **`disallowed_tools` / `disallowedTools`** bloquea las herramientas listadas, independientemente de otras configuraciones. Vea [Permisos](/es/agent-sdk/permissions) para el orden en que se verifican las reglas antes de que se ejecute una herramienta.
134* **`permission_mode` / `permissionMode`** controla qué sucede con las herramientas que no están cubiertas por reglas de permitir o denegar. Vea [Modo de permiso](#permission-mode) para los modos disponibles.
135
136También puede limitar herramientas individuales con reglas como `"Bash(npm *)"` para permitir solo comandos específicos. Vea [Permisos](/es/agent-sdk/permissions) para la sintaxis completa de reglas.
137
138Cuando se deniega una herramienta, Claude recibe un mensaje de rechazo como resultado de la herramienta e intenta típicamente un enfoque diferente o reporta que no pudo proceder.
139
140### Ejecución paralela de herramientas
141
142Cuando Claude solicita múltiples llamadas de herramientas en un solo turno, ambos SDK pueden ejecutarlas concurrentemente o secuencialmente dependiendo de la herramienta. Las herramientas de solo lectura (como `Read`, `Glob`, `Grep` y herramientas MCP marcadas como de solo lectura) pueden ejecutarse concurrentemente. Las herramientas que modifican estado (como `Edit`, `Write` y `Bash`) se ejecutan secuencialmente para evitar conflictos.
143
144Las herramientas personalizadas tienen ejecución secuencial de forma predeterminada. Para habilitar la ejecución paralela para una herramienta personalizada, establezca `readOnlyHint` en sus anotaciones. Ambos SDK de [TypeScript](/es/agent-sdk/typescript#tool) y [Python](/es/agent-sdk/python#tool) usan este nombre de campo del SDK de MCP.
145
146## Controlar cómo se ejecuta el bucle
147
148Puede limitar cuántos turnos toma el bucle, cuánto cuesta, cuán profundamente razona Claude y si las herramientas requieren aprobación antes de ejecutarse. Todos estos son campos en [`ClaudeAgentOptions`](/es/agent-sdk/python#claudeagentoptions) (Python) / [`Options`](/es/agent-sdk/typescript#options) (TypeScript).
149
150### Turnos y presupuesto
151
152| Opción | Qué controla | Predeterminado |
153| :----------------------------------------------------- | :------------------------------------------------------ | :------------- |
154| Máximo de turnos (`max_turns` / `maxTurns`) | Máximo de viajes de ida y vuelta de uso de herramientas | Sin límite |
155| Presupuesto máximo (`max_budget_usd` / `maxBudgetUsd`) | Costo máximo antes de detener | Sin límite |
156
157Cuando se alcanza cualquiera de los límites, el SDK devuelve un `ResultMessage` con un subtipo de error correspondiente (`error_max_turns` o `error_max_budget_usd`). Vea [Manejar el resultado](#handle-the-result) para cómo verificar estos subtipos y [`ClaudeAgentOptions`](/es/agent-sdk/python#claudeagentoptions) / [`Options`](/es/agent-sdk/typescript#options) para la sintaxis.
158
159### Nivel de esfuerzo
160
161La opción `effort` controla cuánto razonamiento aplica Claude. Los niveles de esfuerzo más bajos usan menos tokens por turno y reducen el costo. No todos los modelos soportan el parámetro de esfuerzo. Vea [Esfuerzo](https://platform.claude.com/docs/en/build-with-claude/effort) para qué modelos lo soportan.
162
163| Nivel | Comportamiento | Bueno para |
164| :--------- | :-------------------------------------- | :----------------------------------------------------------- |
165| `"low"` | Razonamiento mínimo, respuestas rápidas | Búsquedas de archivos, listado de directorios |
166| `"medium"` | Razonamiento equilibrado | Ediciones rutinarias, tareas estándar |
167| `"high"` | Análisis exhaustivo | Refactorizaciones, depuración |
168| `"xhigh"` | Profundidad de razonamiento extendida | Tareas de codificación y agentes; recomendado en Opus 4.7 |
169| `"max"` | Profundidad de razonamiento máxima | Problemas de múltiples pasos que requieren análisis profundo |
170
171Si no establece `effort`, el SDK de Python deja el parámetro sin establecer y se remite al comportamiento predeterminado del modelo. El SDK de TypeScript tiene como predeterminado `"high"`.
172
173<Note>
174 `effort` intercambia latencia y costo de token por profundidad de razonamiento dentro de cada respuesta. [Extended thinking](https://platform.claude.com/docs/en/build-with-claude/extended-thinking) es una característica separada que produce bloques de cadena de pensamiento visibles en la salida. Son independientes: puede establecer `effort: "low"` con extended thinking habilitado, o `effort: "max"` sin él.
175</Note>
176
177Use esfuerzo más bajo para agentes que realizan tareas simples y bien delimitadas (como listar archivos o ejecutar un único grep) para reducir costo y latencia. Establezca `effort` en las opciones de nivel superior `query()` para toda la sesión, o por subagente con el campo `effort` en [`AgentDefinition`](/es/agent-sdk/subagents#agentdefinition-configuration) para anular el nivel de sesión.
178
179### Modo de permiso
180
181La opción de modo de permiso (`permission_mode` en Python, `permissionMode` en TypeScript) controla si el agente solicita aprobación antes de usar herramientas:
182
183| Modo | Comportamiento |
184| :------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
185| `"default"` | Las herramientas no cubiertas por reglas de permitir activan su devolución de llamada de aprobación; sin devolución de llamada significa denegar |
186| `"acceptEdits"` | Aprueba automáticamente ediciones de archivo y comandos comunes del sistema de archivos (`mkdir`, `touch`, `mv`, `cp`, etc.); otros comandos de Bash siguen reglas predeterminadas |
187| `"plan"` | Las herramientas de solo lectura se ejecutan; Claude explora y produce un plan sin editar sus archivos fuente |
188| `"dontAsk"` | Nunca solicita. Las herramientas preaprobadas por [reglas de permiso](/es/settings#permission-settings) se ejecutan, todo lo demás se deniega |
189| `"auto"` (solo TypeScript) | Usa un clasificador de modelo para aprobar o denegar cada llamada de herramienta. Vea [Modo automático](/es/permission-modes#eliminate-prompts-with-auto-mode) para disponibilidad y comportamiento |
190| `"bypassPermissions"` | Ejecuta todas las herramientas permitidas sin preguntar. No se puede usar cuando se ejecuta como root en Unix. Use solo en entornos aislados donde las acciones del agente no pueden afectar sistemas que le importan |
191
192Para aplicaciones interactivas, use `"default"` con una devolución de llamada de aprobación de herramienta para mostrar solicitudes de aprobación. Para agentes autónomos en una máquina de desarrollo, `"acceptEdits"` aprueba automáticamente ediciones de archivo y comandos comunes del sistema de archivos (`mkdir`, `touch`, `mv`, `cp`, etc.) mientras aún controla otros comandos de `Bash` detrás de reglas de permitir. Reserve `"bypassPermissions"` para CI, contenedores u otros entornos aislados. Vea [Permisos](/es/agent-sdk/permissions) para detalles completos.
193
194### Modelo
195
196Si no establece `model`, el SDK usa el predeterminado de Claude Code, que depende de su método de autenticación y suscripción. Establézcalo explícitamente (por ejemplo, `model="claude-sonnet-4-6"`) para fijar un modelo específico o para usar un modelo más pequeño para agentes más rápidos y económicos. Vea [modelos](https://platform.claude.com/docs/en/about-claude/models) para IDs disponibles.
197
198## La ventana de contexto
199
200La ventana de contexto es la cantidad total de información disponible para Claude durante una sesión. No se reinicia entre turnos dentro de una sesión. Todo se acumula: el prompt del sistema, definiciones de herramientas, historial de conversación, entradas de herramientas y salidas de herramientas. El contenido que permanece igual en todos los turnos (prompt del sistema, definiciones de herramientas, CLAUDE.md) se [almacena automáticamente en caché de prompt](https://platform.claude.com/docs/en/build-with-claude/prompt-caching), lo que reduce el costo y la latencia para prefijos repetidos.
201
202### Qué consume contexto
203
204Aquí está cómo cada componente afecta el contexto en el SDK:
205
206| Fuente | Cuándo se carga | Impacto |
207| :------------------------------- | :----------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
208| **Prompt del sistema** | Cada solicitud | Costo fijo pequeño, siempre presente |
209| **Archivos CLAUDE.md** | Inicio de sesión, a través de [`settingSources`](/es/agent-sdk/claude-code-features) | Contenido completo en cada solicitud (pero almacenado en caché de prompt, así que solo la primera solicitud paga el costo completo) |
210| **Definiciones de herramientas** | Cada solicitud | Cada herramienta agrega su esquema; use [búsqueda de herramientas MCP](/es/agent-sdk/mcp#mcp-tool-search) para cargar herramientas bajo demanda en lugar de todas a la vez |
211| **Historial de conversación** | Se acumula en turnos | Crece con cada turno: prompts, respuestas, entradas de herramientas, salidas de herramientas |
212| **Descripciones de skills** | Inicio de sesión, a través de fuentes de configuración | Resúmenes cortos; el contenido completo se carga solo cuando se invoca |
213
214Las salidas de herramientas grandes consumen contexto significativo. Leer un archivo grande o ejecutar un comando con salida detallada puede usar miles de tokens en un solo turno. El contexto se acumula en turnos, así que sesiones más largas con muchas llamadas de herramientas acumulan significativamente más contexto que las cortas.
215
216### Compactación automática
217
218Cuando la ventana de contexto se acerca a su límite, el SDK compacta automáticamente la conversación: resume el historial anterior para liberar espacio, manteniendo intactos sus intercambios más recientes y decisiones clave. El SDK emite un mensaje con `type: "system"` y `subtype: "compact_boundary"` en el flujo cuando esto sucede (en Python esto es un `SystemMessage`; en TypeScript es un tipo separado `SDKCompactBoundaryMessage`).
219
220La compactación reemplaza mensajes anteriores con un resumen, así que instrucciones específicas del inicio de la conversación pueden no preservarse. Las reglas persistentes pertenecen a CLAUDE.md (cargado a través de [`settingSources`](/es/agent-sdk/claude-code-features)) en lugar de en el prompt inicial, porque el contenido de CLAUDE.md se reinyecta en cada solicitud.
221
222Puede personalizar el comportamiento de compactación de varias maneras:
223
224* **Instrucciones de resumen en CLAUDE.md:** El compactador lee su CLAUDE.md como cualquier otro contexto, así que puede incluir una sección diciéndole qué preservar al resumir. El encabezado de la sección es de forma libre (no una cadena mágica); el compactador coincide en intención.
225* **Hook `PreCompact`:** Ejecute lógica personalizada antes de que ocurra la compactación, por ejemplo para archivar la transcripción completa. El hook recibe un campo `trigger` (`manual` o `auto`). Vea [hooks](/es/agent-sdk/hooks).
226* **Compactación manual:** Envíe `/compact` como una cadena de prompt para activar la compactación bajo demanda. (Los slash commands enviados de esta manera son entradas de SDK, no atajos solo de CLI. Vea [slash commands en el SDK](/es/agent-sdk/slash-commands).)
227
228<Accordion title="Ejemplo: Instrucciones de resumen en CLAUDE.md">
229 Agregue una sección al CLAUDE.md de su proyecto diciéndole al compactador qué preservar. El nombre del encabezado no es especial; use cualquier etiqueta clara.
230
231 ```markdown CLAUDE.md theme={null}
232 # Summary instructions
233
234 When summarizing this conversation, always preserve:
235 - The current task objective and acceptance criteria
236 - File paths that have been read or modified
237 - Test results and error messages
238 - Decisions made and the reasoning behind them
239 ```
240</Accordion>
241
242### Mantener el contexto eficiente
243
244Algunas estrategias para agentes de larga duración:
245
246* **Use subagentes para subtareas.** Cada subagente comienza con una conversación nueva (sin historial de mensajes anterior, aunque carga su propio prompt del sistema y contexto a nivel de proyecto como CLAUDE.md). No ve los turnos del padre, y solo su respuesta final regresa al padre como resultado de herramienta. El contexto del agente principal crece por ese resumen, no por la transcripción completa de subtarea. Vea [Qué heredan los subagentes](/es/agent-sdk/subagents#what-subagents-inherit) para detalles.
247* **Sea selectivo con herramientas.** Cada definición de herramienta toma espacio de contexto. Use el campo `tools` en [`AgentDefinition`](/es/agent-sdk/subagents#agentdefinition-configuration) para limitar subagentes al conjunto mínimo que necesitan, y use [búsqueda de herramientas MCP](/es/agent-sdk/mcp#mcp-tool-search) para cargar herramientas bajo demanda en lugar de precargarlas todas.
248* **Observe costos de servidor MCP.** Cada servidor MCP agrega todos sus esquemas de herramientas a cada solicitud. Algunos servidores con muchas herramientas pueden consumir contexto significativo antes de que el agente haga ningún trabajo. La herramienta `ToolSearch` puede ayudar cargando herramientas bajo demanda en lugar de precargarlas todas. Vea [búsqueda de herramientas MCP](/es/agent-sdk/mcp#mcp-tool-search) para configuración.
249* **Use esfuerzo más bajo para tareas rutinarias.** Establezca [esfuerzo](#effort-level) a `"low"` para agentes que solo necesitan leer archivos o listar directorios. Esto reduce el uso de tokens y el costo.
250
251Para un desglose detallado de costos de contexto por característica, vea [Entender costos de contexto](/es/features-overview#understand-context-costs).
252
253## Sesiones y continuidad
254
255Cada interacción con el SDK crea o continúa una sesión. Capture el ID de sesión de `ResultMessage.session_id` (disponible en ambos SDK) para reanudar más tarde. El SDK de TypeScript también lo expone como un campo directo en el `SystemMessage` de init; en Python está anidado en `SystemMessage.data`.
256
257Cuando reanuda, el contexto completo de turnos anteriores se restaura: archivos que fueron leídos, análisis que fue realizado y acciones que fueron tomadas. También puede bifurcar una sesión para ramificarse en un enfoque diferente sin modificar el original.
258
259Vea [Gestión de sesiones](/es/agent-sdk/sessions) para la guía completa en patrones de reanudar, continuar y bifurcar.
260
261<Note>
262 En Python, `ClaudeSDKClient` maneja IDs de sesión automáticamente en múltiples llamadas. Vea la [referencia del SDK de Python](/es/agent-sdk/python#choosing-between-query-and-claudesdkclient) para detalles.
263</Note>
264
265## Manejar el resultado
266
267Cuando el bucle termina, el `ResultMessage` le dice qué sucedió y le proporciona la salida. El campo `subtype` (disponible en ambos SDK) es la forma principal de verificar el estado de terminación.
268
269| Subtipo de resultado | Qué sucedió | ¿Campo `result` disponible? |
270| :------------------------------------ | :-------------------------------------------------------------------------------------- | :-------------------------: |
271| `success` | Claude terminó la tarea normalmente | Sí |
272| `error_max_turns` | Alcanzó el límite de `maxTurns` antes de terminar | No |
273| `error_max_budget_usd` | Alcanzó el límite de `maxBudgetUsd` antes de terminar | No |
274| `error_during_execution` | Un error interrumpió el bucle (por ejemplo, una falla de API o solicitud cancelada) | No |
275| `error_max_structured_output_retries` | La validación de salida estructurada falló después del límite de reintentos configurado | No |
276
277El campo `result` (la salida de texto final) solo está presente en la variante `success`, así que siempre verifique el subtipo antes de leerlo. Todos los subtipos de resultado llevan `total_cost_usd`, `usage`, `num_turns` e `session_id` para que pueda rastrear el costo y reanudar incluso después de errores. En Python, `total_cost_usd` y `usage` se escriben como opcionales y pueden ser `None` en algunas rutas de error, así que proteja antes de formatearlos. Vea [Rastrear costos y uso](/es/agent-sdk/cost-tracking) para detalles sobre la interpretación de los campos `usage`.
278
279El resultado también incluye un campo `stop_reason` (`string | null` en TypeScript, `str | None` en Python) indicando por qué el modelo dejó de generar en su turno final. Los valores comunes son `end_turn` (modelo terminó normalmente), `max_tokens` (alcanzó el límite de token de salida) y `refusal` (el modelo rechazó la solicitud). En subtipos de resultado de error, `stop_reason` lleva el valor de la última respuesta de asistente antes de que el bucle terminara. Para detectar rechazos, verifique `stop_reason === "refusal"` (TypeScript) o `stop_reason == "refusal"` (Python). Vea [`SDKResultMessage`](/es/agent-sdk/typescript#sdkresultmessage) (TypeScript) o [`ResultMessage`](/es/agent-sdk/python#resultmessage) (Python) para el tipo completo.
280
281## Hooks
282
283[Hooks](/es/agent-sdk/hooks) son devoluciones de llamada que se disparan en puntos específicos del bucle: antes de que se ejecute una herramienta, después de que regresa, cuando el agente termina, y así sucesivamente. Algunos hooks comúnmente usados son:
284
285| Hook | Cuándo se dispara | Usos comunes |
286| :------------------------------- | :------------------------------------------ | :------------------------------------------------ |
287| `PreToolUse` | Antes de que se ejecute una herramienta | Validar entradas, bloquear comandos peligrosos |
288| `PostToolUse` | Después de que regresa una herramienta | Auditar salidas, activar efectos secundarios |
289| `UserPromptSubmit` | Cuando se envía un prompt | Inyectar contexto adicional en prompts |
290| `Stop` | Cuando el agente termina | Validar el resultado, guardar estado de sesión |
291| `SubagentStart` / `SubagentStop` | Cuando se genera un subagente o se completa | Rastrear y agregar resultados de tareas paralelas |
292| `PreCompact` | Antes de la compactación de contexto | Archivar transcripción completa antes de resumir |
293
294Los hooks se ejecutan en su proceso de aplicación, no dentro de la ventana de contexto del agente, así que no consumen contexto. Los hooks también pueden cortocircuitar el bucle: un hook `PreToolUse` que rechaza una llamada de herramienta evita que se ejecute, y Claude recibe el mensaje de rechazo en su lugar.
295
296Ambos SDK soportan todos los eventos anteriores. El SDK de TypeScript incluye eventos adicionales que Python aún no soporta. Vea [Controlar ejecución con hooks](/es/agent-sdk/hooks) para la lista completa de eventos, disponibilidad por SDK y la API de devolución de llamada completa.
297
298## Ponerlo todo junto
299
300Este ejemplo combina los conceptos clave de esta página en un único agente que arregla pruebas fallidas. Configura el agente con herramientas permitidas (aprobadas automáticamente para que el agente se ejecute autónomamente), configuración del proyecto y límites de seguridad en turnos y esfuerzo de razonamiento. A medida que se ejecuta el bucle, captura el ID de sesión para posible reanudación, maneja el resultado final e imprime el costo total.
301
302<CodeGroup>
303 ```python Python theme={null}
304 import asyncio
305 from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage
306
307
308 async def run_agent():
309 session_id = None
310
311 async for message in query(
312 prompt="Find and fix the bug causing test failures in the auth module",
313 options=ClaudeAgentOptions(
314 allowed_tools=[
315 "Read",
316 "Edit",
317 "Bash",
318 "Glob",
319 "Grep",
320 ], # Listing tools here auto-approves them (no prompting)
321 setting_sources=[
322 "project"
323 ], # Load CLAUDE.md, skills, hooks from current directory
324 max_turns=30, # Prevent runaway sessions
325 effort="high", # Thorough reasoning for complex debugging
326 ),
327 ):
328 # Handle the final result
329 if isinstance(message, ResultMessage):
330 session_id = message.session_id # Save for potential resumption
331
332 if message.subtype == "success":
333 print(f"Done: {message.result}")
334 elif message.subtype == "error_max_turns":
335 # Agent ran out of turns. Resume with a higher limit.
336 print(f"Hit turn limit. Resume session {session_id} to continue.")
337 elif message.subtype == "error_max_budget_usd":
338 print("Hit budget limit.")
339 else:
340 print(f"Stopped: {message.subtype}")
341 if message.total_cost_usd is not None:
342 print(f"Cost: ${message.total_cost_usd:.4f}")
343
344
345 asyncio.run(run_agent())
346 ```
347
348 ```typescript TypeScript theme={null}
349 import { query } from "@anthropic-ai/claude-agent-sdk";
350
351 let sessionId: string | undefined;
352
353 for await (const message of query({
354 prompt: "Find and fix the bug causing test failures in the auth module",
355 options: {
356 allowedTools: ["Read", "Edit", "Bash", "Glob", "Grep"], // Listing tools here auto-approves them (no prompting)
357 settingSources: ["project"], // Load CLAUDE.md, skills, hooks from current directory
358 maxTurns: 30, // Prevent runaway sessions
359 effort: "high" // Thorough reasoning for complex debugging
360 }
361 })) {
362 // Save the session ID to resume later if needed
363 if (message.type === "system" && message.subtype === "init") {
364 sessionId = message.session_id;
365 }
366
367 // Handle the final result
368 if (message.type === "result") {
369 if (message.subtype === "success") {
370 console.log(`Done: ${message.result}`);
371 } else if (message.subtype === "error_max_turns") {
372 // Agent ran out of turns. Resume with a higher limit.
373 console.log(`Hit turn limit. Resume session ${sessionId} to continue.`);
374 } else if (message.subtype === "error_max_budget_usd") {
375 console.log("Hit budget limit.");
376 } else {
377 console.log(`Stopped: ${message.subtype}`);
378 }
379 console.log(`Cost: $${message.total_cost_usd.toFixed(4)}`);
380 }
381 }
382 ```
383</CodeGroup>
384
385## Próximos pasos
386
387Ahora que entiende el bucle, aquí está dónde ir dependiendo de lo que esté construyendo:
388
389* **¿Aún no ha ejecutado un agente?** Comience con el [inicio rápido](/es/agent-sdk/quickstart) para obtener el SDK instalado y ver un ejemplo completo ejecutándose de principio a fin.
390* **¿Listo para conectarse a su proyecto?** [Cargue CLAUDE.md, skills y hooks del sistema de archivos](/es/agent-sdk/claude-code-features) para que el agente siga automáticamente las convenciones de su proyecto.
391* **¿Construyendo una interfaz de usuario interactiva?** Habilite [transmisión](/es/agent-sdk/streaming-output) para mostrar texto en vivo y llamadas de herramientas a medida que se ejecuta el bucle.
392* **¿Necesita control más ajustado sobre lo que el agente puede hacer?** Bloquee el acceso a herramientas con [permisos](/es/agent-sdk/permissions) y use [hooks](/es/agent-sdk/hooks) para auditar, bloquear o transformar llamadas de herramientas antes de que se ejecuten.
393* **¿Ejecutando tareas largas o costosas?** Descargue trabajo aislado a [subagentes](/es/agent-sdk/subagents) para mantener su contexto principal delgado.
394
395Para la imagen conceptual más amplia del bucle agente (no específica del SDK), vea [Cómo funciona Claude Code](/es/how-claude-code-works).