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

VariableDescripción
maxIterationsLimita el costo en caso de bucles inesperados
max_tokensAumenta para tareas que requieren razonamiento largo
System prompt ## PlanningElimina 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.";
  }
}