Recipes · agents
Agentic Loop
System prompt y loop de ejecución para un agente con herramientas. Incluye instrucciones de transparencia, manejo de errores y condición de parada.
claude-opus-4-5agenttool-uselooptypescriptActualizado 2026-04-23
System Prompt
You are an autonomous agent. You have access to a set of tools to accomplish
tasks. Follow these operating principles:
## Planning
Before taking any action on a complex task, think through the steps required.
Use a <thinking> block to reason before calling tools:
<thinking>
What do I need to do? What tool should I call first? What could go wrong?
</thinking>
## Tool use
- Use the minimum number of tool calls needed.
- Prefer read-only operations before write operations.
- If a tool call fails, diagnose why before retrying. Do not retry more than
twice with the same arguments.
## Progress
- After completing a significant step, briefly summarize what you did and what
remains.
- If you reach a point where you cannot proceed without more information,
stop and ask the user one clear question.
## Completion
- When the task is fully done, produce a concise final summary.
- Do not call any more tools after the task is complete.
- End your final message with: [TASK COMPLETE]
Loop de ejecución (TypeScript)
typescript
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
async function runAgent(
task: string,
tools: Anthropic.Tool[],
executeTool: (name: string, input: unknown) => Promise<string>,
maxIterations = 20,
): Promise<string> {
const messages: Anthropic.MessageParam[] = [
{ role: "user", content: task },
];
for (let i = 0; i < maxIterations; i++) {
const response = await client.messages.create({
model: "claude-opus-4-5",
max_tokens: 8096,
system: AGENTIC_LOOP_SYSTEM_PROMPT,
tools,
messages,
});
// Append assistant turn
messages.push({ role: "assistant", content: response.content });
// Check for natural end
if (response.stop_reason === "end_turn") {
const lastText = response.content
.filter((b): b is Anthropic.TextBlock => b.type === "text")
.map((b) => b.text)
.join("\n");
return lastText;
}
// Execute tool calls
if (response.stop_reason === "tool_use") {
const toolResults: Anthropic.ToolResultBlockParam[] = [];
for (const block of response.content) {
if (block.type !== "tool_use") continue;
let content: string;
try {
content = await executeTool(block.name, block.input);
} catch (err) {
content = `ERROR: ${err instanceof Error ? err.message : String(err)}`;
}
toolResults.push({
type: "tool_result",
tool_use_id: block.id,
content,
});
}
messages.push({ role: "user", content: toolResults });
}
}
throw new Error(`Agent exceeded max iterations (${maxIterations})`);
}Cuándo usar esta receta
Úsala para tareas que requieren múltiples pasos y herramientas: análisis de repositorios, pipelines de datos, automatización de flujos de trabajo. No es adecuada para tareas simples de pregunta/respuesta.
Variables a personalizar
| Variable | Descripción |
|---|---|
maxIterations | Limita el costo en caso de bucles inesperados |
max_tokens | Aumenta para tareas que requieren razonamiento largo |
System prompt ## Planning | Elimina si usas un modelo que razona nativamente (extended thinking) |
Manejo de errores
Siempre envuelve executeTool en try/catch y devuelve el error como string al modelo. Si devuelves una excepción sin capturar, el loop se rompe y el agente no puede recuperarse.
Seguridad
Para agentes en producción con acceso a herramientas destructivas (write, delete, deploy), añade una etapa de confirmación humana antes de ejecutar cualquier tool con efectos secundarios:
typescript
if (DESTRUCTIVE_TOOLS.includes(block.name)) {
const confirmed = await askUserConfirmation(block.name, block.input);
if (!confirmed) {
content = "Tool call cancelled by user.";
}
}