Cambiar tema

Desarrollo práctico de agentes de IA: diseño de arquitectura e implementación

Easton editorial illustration: agent rollout and rollback rail

Un agente ReAct corrió veinte minutos en bucle invocando la misma herramienta: faltaba maxIterations. Trampas: bucles ReAct, multiagente sin convergencia, Plan-and-Execute rígido.

Tres niveles: modelo directo; agente + herramientas; multiagente con cautela. Azure: ≤3 en group chat.

Dos años de lecciones: patrones, orquestación, frameworks y agente con Claude Agent SDK.

1. Tres niveles de arquitectura

Principio clave: si una solución simple basta, no añadas complejidad.

Azure divide la arquitectura en tres niveles; clasificación muy práctica:

1.1 Llamada directa al modelo

Nivel más simple: envías la tarea y obtienes respuesta.

// Invocación básica
const response = await anthropic.messages.create({
  model: 'claude-sonnet-4-20250514',
  max_tokens: 1024,
  messages: [{ role: 'user', content: 'Resume este texto...' }]
});

Escenarios: un paso, determinista, sin herramientas (resumen, traducción, autocompletado).

Ventajas: simple, barato. Desventajas: sin razonamiento multipaso ni herramientas.

1.2 Agente único + herramientas

Opción por defecto empresarial. Invoca herramientas y tareas multipaso.

// Ejemplo LangChain
import { ChatAnthropic } from '@langchain/anthropic';
import { AgentExecutor, createToolCallingAgent } from 'langchain/agents';
import { tool } from '@langchain/core/tools';
import { z } from 'zod';

// Herramienta clima
const weatherTool = tool(
  async ({ city }) => {
    // Simular API
    return `${city} soleado hoy, 22 °C`;
  },
  {
    name: 'get_weather',
    description: 'Clima de una ciudad',
    schema: z.object({
      city: z.string().describe('Ciudad'),
    }),
  }
);

const model = new ChatAnthropic({
  model: 'claude-sonnet-4-20250514',
  temperature: 0,
});

const agent = await createToolCallingAgent({
  llm: model,
  tools: [weatherTool],
  prompt: 'Eres un asistente útil.',
});

const executor = AgentExecutor.fromAgentAndTools({
  agent,
  tools: [weatherTool],
});

// Run
const result = await executor.invoke({
  input: '¿Tiempo en Pekín hoy?',
});

Escenarios: herramientas, tareas descomponibles, análisis, APIs.

1.3 Orquestación multiagente

Nivel más complejo: agentes especializados colaboran.

Menos escenarios reales de los que parece; costo de coordinación y depuración exponencial.

Escenarios: tareas transversales, pipelines de desarrollo, decisiones complejas.

1.4 Tabla de decisión

EscenarioNivelMotivo
Q&A simpleModelo directoSin sobreingeniería
BD/APIAgente + toolsEstable
Pasos inciertosReActAuto-planifica
Varios rolesMultiagenteCon cautela

Resumen: empieza simple.

2. Tres patrones de arquitectura

Tras el nivel, elige patrón; a menudo se combinan.

2.1 ReAct

ReAct: razonar mientras actúa.

Flujo:

Entrada → Pensamiento → Acción → Observación → Bucle/fin

Ejemplo: deporte al aire libre mañana en Pekín:

  1. Pensamiento: consultar clima de mañana en Pekín
  2. Acción: invocar get_weather con city: "Pekín"
  3. Observación: nublado, 18-25 °C, 10% lluvia
  4. Pensamiento: temperatura moderada, apto para deporte
  5. Respuesta: apto; chaqueta ligera

Implementación (LangChain):

import { ChatAnthropic } from '@langchain/anthropic';
import { AgentExecutor, createReactAgent } from 'langchain/agents';
import { pull } from 'langchain/hub';

// Plantilla ReAct
const prompt = await pull('hwchase17/react');

const agent = await createReactAgent({
  llm: model,
  tools: [weatherTool, searchTool], // Herramientas
  prompt,
});

// Limitar iteraciones
const executor = AgentExecutor.fromAgentAndTools({
  agent,
  tools: [weatherTool, searchTool],
  maxIterations: 10, // Evitar bucles
  verbose: true, // Log de razonamiento
});

Pros y contras:

VentajasDesventajas
FlexibleRiesgo de bucle
TransparenteMayor costo
Sin pasos fijosPlanificación limitada

Aviso: define maxIterations; mi primer ReAct corrió toda la noche.

2.2 Plan-and-Execute

ReAct va paso a paso; Plan-and-Execute planifica primero.

Flujo:

Entrada → Plan → Ejecución → Resultado

Implementación (LangGraph):

import { ChatAnthropic } from '@langchain/anthropic';
import { StateGraph, END } from '@langchain/langgraph';

// Estado
interface AgentState {
  input: string;
  plan: string[];
  pastSteps: string[];
  response: string;
}

// Planificación
async function planNode(state: AgentState): Promise<AgentState> {
  const plannerPrompt = `Objetivo: ${state.input}
Plan detallado en JSON array.`;

  const response = await model.invoke(plannerPrompt);
  const plan = JSON.parse(response.content as string);
  return { ...state, plan };
}

// Ejecutar paso
async function executeNode(state: AgentState): Promise<AgentState> {
  const currentStep = state.plan[0];
  const result = await executor.invoke({ input: currentStep });

  return {
    ...state,
    plan: state.plan.slice(1), // Quitar paso
    pastSteps: [...state.pastSteps, `${currentStep}: ${result.output}`],
  };
}

// Grafo
const workflow = new StateGraph<AgentState>({
  channels: {
    input: { value: null },
    plan: { value: null },
    pastSteps: { value: null, default: () => [] },
    response: { value: null },
  },
});

workflow.addNode('planner', planNode);
workflow.addNode('executor', executeNode);

// Tras planificar
workflow.addEdge('planner', 'executor');

// ¿Quedan pasos?
workflow.addConditionalEdges('executor', (state) => {
  return state.plan.length > 0 ? 'executor' : END;
});

Pros y contras:

VentajasDesventajas
EstablePlan rígido
DeterministaPoco adaptable
MonitorizableDepende del planner

Experiencia: ideal para pasos previsibles; ReAct si la estrategia cambia.

2.3 Multi-Agent

Cuando un agente no alcanza, multiagente.

Idea: un dominio por agente.

Code Implementation (Claude Agent SDK style):

import { ClaudeAgent } from '@anthropic-ai/claude-agent-sdk';

// Agentes
const researchAgent = new ClaudeAgent({
  name: 'researcher',
  model: 'claude-sonnet-4-20250514',
  systemPrompt: 'Experto en investigación.',
  tools: ['WebSearch', 'WebFetch'],
});

const writerAgent = new ClaudeAgent({
  name: 'writer',
  model: 'claude-sonnet-4-20250514',
  systemPrompt: 'Experto en contenido.',
  tools: ['Read', 'Write', 'Edit'],
});

const reviewerAgent = new ClaudeAgent({
  name: 'reviewer',
  model: 'claude-sonnet-4-20250514',
  systemPrompt: 'Experto en calidad.',
  tools: ['Read'],
});

// Colaboración
async function collaborativeWriting(topic: string) {
  // Step 1: Research
  const research = await researchAgent.run(`Tema: ${topic}`);

  // Step 2: Writing
  const draft = await writerAgent.run(
    `Redacta con esta investigación:\n${research}`
  );

  // Step 3: Review
  const review = await reviewerAgent.run(
    `Revisa y sugiere:\n${draft}`
  );

  // Step 4: Revision
  const final = await writerAgent.run(
    `Corrige según revisión:\nOriginal: ${draft}\nComentarios: ${review}`
  );

  return final;
}

Cuándo usar multiagente:

  • Varias especialidades (código, diseño, copy)
  • Ventana de contexto insuficiente
  • División clara del trabajo

Advertencia: depuración exponencial; no fuerces multiagente si uno basta.

3. Cinco modos de orquestación

Si necesitas multiagente, elige modo de orquestación; Azure resume cinco patrones.

3.1 Sequential

Salida de A es entrada de B, como pipeline.

[Agent A] → [Agent B] → [Agent C] → Resultado

Escenarios: documentos (investigación → borrador → revisión), código.

Code Example:

// Secuencial
async function sequentialPipeline(input: string) {
  const step1 = await researchAgent.run(input);
  const step2 = await writerAgent.run(step1.output);
  const step3 = await editorAgent.run(step2.output);
  return step3.output;
}

Nota: acuerda formato de salida por paso.

3.2 Concurrent

Varios agentes en paralelo, luego agregación.

           → [Agent A] →
[Input]  →  → [Agent B] →  → [Agregador] → Resultado
           → [Agent C] →

Escenarios: análisis multiperspectiva, acciones, revisión de código.

Code Example:

// Concurrente
async function concurrentAnalysis(code: string) {
  const [security, performance, style] = await Promise.all([
    securityAgent.run(`Seguridad:\n${code}`),
    performanceAgent.run(`Rendimiento:\n${code}`),
    styleAgent.run(`Estilo:\n${code}`),
  ]);

  // Agregar
  return {
    security: security.output,
    performance: performance.output,
    style: style.output,
  };
}

Nota: define arbitraje ante conflictos.

3.3 Group Chat

Debate hasta consenso o timeout.

[Agent A] ⇄ [Agent B] ⇄ [Agent C]
     ↑           ↓
   [Moderator]

Escenarios: brainstorming, validación, decisiones por discusión.

Azure: máximo 3 agentes.

Code Example:

// Group chat (seudocódigo)
interface ChatMessage {
  sender: string;
  content: string;
}

async function groupChatDiscussion(
  topic: string,
  agents: ClaudeAgent[],
  maxRounds: number = 5
) {
  const history: ChatMessage[] = [];

  for (let round = 0; round < maxRounds; round++) {
    for (const agent of agents) {
      const response = await agent.run(
        `Tema: ${topic}\nHistorial: ${JSON.stringify(history)}\nTu punto de vista:`
      );
      history.push({ sender: agent.name, content: response.output });

      // ¿Consenso?
      if (checkConsensus(history)) {
        return summarizeConsensus(history);
      }
    }
  }

  return 'Timeout sin consenso';
}

Trampa: maxRounds y moderador.

3.4 Handoff

Un agente transfiere al siguiente.

[Agent A] necesita B → traslado a [Agent B] → Continue processing

Escenarios: soporte (ventas → técnico → posventa), diagnóstico.

Code Example:

// Handoff
const supportAgent = new ClaudeAgent({
  name: 'support',
  systemPrompt: `Soporte: técnico → "HANDOFF:tech".
Posventa → "HANDOFF:after_sales".`,
});

const techAgent = new ClaudeAgent({
  name: 'tech',
  systemPrompt: 'Experto soporte técnico.',
});

async function handleWithHandoff(userInput: string) {
  let currentAgent = supportAgent;
  let response = await currentAgent.run(userInput);

  // Señal HANDOFF
  while (response.output.includes('HANDOFF:')) {
    const targetAgent = response.output.match(/HANDOFF:(\w+)/)?.[1];

    if (targetAgent === 'tech') currentAgent = techAgent;
    else if (targetAgent === 'after_sales') currentAgent = afterSalesAgent;

    response = await currentAgent.run(userInput);
  }

  return response.output;
}

Nota: evita traslados circulares.

3.5 Magentic

El planificador elige el agente más adecuado.

[Cola] → [Planificador] → Selección por tarea [Agent A/B/C]

Escenarios: tareas diversas, scheduling dinámico.

Implementation Approach:

// Magentic
interface Task {
  type: string;
  priority: number;
  content: string;
}

async function magenticScheduling(task: Task) {
  // Mejor agente
  const agentScores = await Promise.all(
    agents.map(async (agent) => {
      const score = await evaluateAgentFit(agent, task);
      return { agent, score };
    })
  );

  // Mayor puntuación
  const bestAgent = agentScores.sort((a, b) => b.score - a.score)[0].agent;
  return bestAgent.run(task.content);
}

Nota: evalúa ajuste tarea-agente.

3.6 Tabla rápida

ModoEscenarioComplejidadRiesgo
SequentialPipelineBajaBloqueos
ConcurrentParaleloMediaConflictos
Group ChatDebateAltaSin convergencia
HandoffDinámicoMediaCiclo
MagenticDiversoAltaScheduling

4. Frameworks

Tras patrones, ¿qué framework? LangChain, AutoGen, CrewAI, Claude Agent SDK.

No hay mejor framework, solo el más adecuado.

4.1 Posicionamiento

FrameworkPosiciónFortalezasEscenarios
LangChainGeneralHerramientas, ReActPrototipos y producción
AutoGenMultiagenteConversación, HITLSistemas complejos
CrewAIRolesAPI limpiaEquipos
Claude Agent SDKClaude nativoCódigo, archivosEcosistema Claude

4.2 Detalle

LangChain: ecosistema maduro.

  • Soporte completo en TypeScript y Python
  • Herramientas e integraciones integradas de forma extensa
  • Implementaciones listas de ReAct y Plan-and-Execute
  • ¿Contras? La API cambia con frecuencia y la documentación a veces no alcanza a seguir el ritmo

AutoGen: Microsoft, multiagente.

  • El concepto central es la “conversación”: los agents colaboran mediante mensajes
  • Soporta human-in-the-loop
  • Adecuado para escenarios con varias rondas de discusión y decisión
  • ¿Contras? Curva de aprendizaje pronunciada; depurar sistemas multiagente es doloroso

CrewAI: simple y directo.

  • Modela con conceptos de “roles”, “tareas” y “equipos”, muy intuitivo
  • API limpia y arranque rápido
  • Ideal para prototipos multiagente en poco tiempo
  • ¿Contras? El ecosistema y la integración de herramientas no son tan ricos como en LangChain

Claude Agent SDK: oficial Anthropic 2026.

  • Integración profunda con modelos Claude
  • Lectura/escritura de archivos, edición de código y ejecución de comandos integradas
  • Soporta permissionMode para controlar permisos de operación
  • Si tu modelo principal es Claude, esta es la primera opción

4.3 Guía de selección

Pregúntate:

  1. ¿Cuál es tu modelo principal?

    • Claude → Prioriza Claude Agent SDK
    • OpenAI → El ecosistema LangChain es más maduro
    • Multi-modelo → LangChain o AutoGen
  2. ¿Qué tan compleja es la tarea?

    • Un agent + herramientas → LangChain basta
    • Colaboración multiagente → AutoGen o CrewAI
    • Tareas de código → Claude Agent SDK
  3. ¿Cuál es el stack de tu equipo?

    • Principalmente Python → Todos los frameworks están soportados
    • Principalmente TypeScript → LangChain y Claude Agent SDK tienen mejor soporte
  4. ¿Necesitas colaboración humano-máquina?

    • Sí → El human-in-the-loop de AutoGen está bien diseñado
    • No → Cualquier otro framework funciona

4.4 Recomendación

En la mayoría de escenarios, LangChain basta. Su integración de herramientas y la implementación de ReAct son maduras, con buen soporte de la comunidad.

Si estás seguro de que necesitas multiagente y la tarea es lo bastante compleja como para requerir varios agents especializados, AutoGen merece la pena. Pero recuerda: depurar multiagente cuesta caro; no lo uses solo por “avance técnico”.

Si eres usuario intensivo de Claude, Claude Agent SDK es hoy la mejor opción: es oficial y encaja mejor con los modelos Claude.

5. Práctica con Claude Agent SDK

Dicho esto, vamos a la práctica: usa Claude Agent SDK para escribir un agent de refactorización de código que funcione de verdad.

5.1 Entorno

# Instalar
npm install @anthropic-ai/claude-agent-sdk

# API Key
export ANTHROPIC_API_KEY=your_api_key_here

5.2 Básico

import { ClaudeAgent } from '@anthropic-ai/claude-agent-sdk';

// Agente refactor
const refactorAgent = new ClaudeAgent({
  model: 'claude-sonnet-4-20250514',
  tools: ['Read', 'Write', 'Edit', 'Bash'],
  permissionMode: 'acceptEdits', // Aceptar ediciones
  workingDirectory: './src', // Directorio
});

// Ejecutar
async function refactorCode(task: string) {
  const result = await refactorAgent.run(task);
  console.log('Resultado:', result);
  return result;
}

// Ejemplo de uso
refactorCode('Refactorizar auth.ts a async/await');

5.3 Configuración

permissionMode:

  • 'acceptEdits': Acepta automáticamente operaciones de edición de archivos
  • 'interactive': Cada operación requiere confirmación manual
  • 'planOnly': Solo genera el plan, no ejecuta

tools:

  • Read: Leer archivos
  • Write: Crear archivos nuevos
  • Edit: Editar archivos existentes
  • Bash: Ejecutar comandos de terminal
  • Glob: Coincidencia de patrones de archivos
  • Grep: Búsqueda de contenido

5.4 Con restricciones

const cautiousAgent = new ClaudeAgent({
  model: 'claude-sonnet-4-20250514',
  tools: ['Read', 'Write', 'Edit', 'Bash'],
  permissionMode: 'interactive', // Cauteloso
  maxIterations: 20, // Límite
  timeout: 300000, // 5 min

  // systemPrompt límites
  systemPrompt: `Experto en refactorización.
Reglas:
1. No borrar tests
2. No tocar package.json
3. Backup antes de editar
4. Tests tras cambios`,
});

async function safeRefactor(filePath: string) {
  try {
    const result = await cautiousAgent.run(
      `Refactoriza ${filePath}, optimiza estructura y legibilidad.`
    );
    return result;
  } catch (error) {
    console.error('Falló:', error);
    // Lógica de rollback...
  }
}

5.5 Buenas prácticas

  1. Iteraciones: evitar bucles infinitos
  2. Timeout: tareas largas con límite de tiempo
  3. Permisos: modo interactive para operaciones sensibles
  4. Backup: respaldar archivos importantes antes de editar
  5. Tests: ejecutar pruebas tras los cambios

5.6 Depuración

// Log detallado
const debugAgent = new ClaudeAgent({
  model: 'claude-sonnet-4-20250514',
  tools: ['Read', 'Write', 'Edit'],
  verbose: true, // Proceso
});

// Eventos
debugAgent.on('toolCall', (tool, args) => {
  console.log(`Herramienta: ${tool}, parámetros: ${JSON.stringify(args)}`);
});

debugAgent.on('thinking', (thought) => {
  console.log(`Pensamiento: ${thought}`);
});

Cierre

Tras todo esto, la idea central al elegir arquitectura de agent se resume en una frase: Empieza simple, añade lo necesario.

Complejidad:

  • Un paso → modelo
  • Herramientas → agente
  • Varios roles → multiagente

Patrón:

  • Dinámico → ReAct
  • Previsible → Plan-and-Execute
  • Especialización → Multi-Agent

Framework:

  • Claude → SDK
  • Multi-modelo → LangChain
  • Multiagente → AutoGen/CrewAI

Practica en un proyecto pequeño; los fallos enseñan.

Artículos relacionados: MCP Server e invocación de herramientas — trilogía coherente.

Construir agente con Claude Agent SDK

Del entorno al primer agente

⏱️ Estimated time: 30 min

  1. 1

    Step 1: Instalar dependencias

    Ejecuta los comandos:

    ```bash
    npm install @anthropic-ai/claude-agent-sdk
    export ANTHROPIC_API_KEY=your_api_key_here
    ```

    API Key desde Anthropic; usar variables de entorno.
  2. 2

    Step 2: Crear instancia básica

    Tres parámetros al crear el agente:

    ```typescript
    const agent = new ClaudeAgent({
    model: 'claude-sonnet-4-20250514',
    tools: ['Read', 'Write', 'Edit', 'Bash'],
    permissionMode: 'acceptEdits'
    });
    ```

    • model: versión Claude
    • tools: herramientas
    • permissionMode: permisos
  3. 3

    Step 3: Ejecutar tarea

    Invoca run:

    ```typescript
    const result = await agent.run('Refactorizar auth.ts');
    ```

    Añade errores y logs.
  4. 4

    Step 4: Protecciones

    En producción:

    • maxIterations: ~20
    • timeout: ~5 min
    • systemPrompt: límites
    • permissionMode: 'interactive' en sensibles

FAQ

¿ReAct, Plan-and-Execute o Multi-Agent?
ReAct: pasos inciertos; Plan-and-Execute: flujos estables; Multi-Agent: varias especialidades.
¿Por qué Azure limita group chat a 3?
Convergencia difícil y depuración costosa; 3 agentes suelen bastar.
¿LangChain o AutoGen/CrewAI?
LangChain en la mayoría; AutoGen/CrewAI solo para multiagente real.
¿Claude Agent SDK?
Oficial Anthropic: Claude, código y permissionMode.
¿Evitar bucles infinitos?
maxIterations, timeout y parada en systemPrompt.

10 min de lectura · Publicado el: 21 mar 2026 · Actualizado el: 21 ago 2026

Comentarios

Inicia sesión con GitHub para dejar un comentario

Easton BlogEaston Blog