← Volver al listado de tecnologías

Capítulo 7: Subagentes

Por: Artiko
claudeagent-sdksubagentesdelegacion

Capítulo 7: Subagentes

¿Qué son los Subagentes?

Los subagentes son agentes especializados que el agente principal puede invocar para tareas específicas.

flowchart TB
    subgraph Principal["AGENTE PRINCIPAL"]
        Tarea["Analiza este proyecto<br/>y mejora el código"]
        Tarea --> TaskTool["TASK TOOL"]
        TaskTool --> CR["Code Reviewer"]
        TaskTool --> TW["Test Writer"]
        TaskTool --> DW["Docs Writer"]
        CR --> R1["5 issues"]
        TW --> R2["3 tests"]
        DW --> R3["README.md"]
    end

Ventajas de Subagentes

VentajaDescripción
EspecializaciónCada agente tiene un propósito específico
Contexto aisladoNo contaminan el contexto del principal
ParalelizaciónPueden ejecutarse en paralelo
ReusabilidadDefinir una vez, usar muchas veces

Definir Subagentes

from claude_agent_sdk import query, ClaudeAgentOptions, AgentDefinition

options = ClaudeAgentOptions(
    allowed_tools=["Read", "Glob", "Grep", "Task"],  # Task es necesario
    agents={
        "code-reviewer": AgentDefinition(
            description="Revisor experto de código para calidad y seguridad",
            prompt="Analiza el código y reporta problemas de calidad",
            tools=["Read", "Glob", "Grep"]
        ),
        "test-writer": AgentDefinition(
            description="Escritor de tests unitarios",
            prompt="Escribe tests usando pytest con alta cobertura",
            tools=["Read", "Write", "Glob"]
        ),
        "doc-writer": AgentDefinition(
            description="Escritor de documentación técnica",
            prompt="Genera documentación clara y concisa",
            tools=["Read", "Write", "Glob"]
        )
    }
)

Usar Subagentes

async for msg in query(
    prompt="Usa el agente code-reviewer para revisar src/",
    options=options
):
    print(msg)

El agente principal invocará automáticamente al subagente cuando sea necesario.

TypeScript

import { query, AgentDefinition } from "@anthropic-ai/claude-agent-sdk";

for await (const message of query({
  prompt: "Usa el code-reviewer para revisar este proyecto",
  options: {
    allowedTools: ["Read", "Glob", "Grep", "Task"],
    agents: {
      "code-reviewer": {
        description: "Revisor experto de código",
        prompt: "Analiza calidad y sugiere mejoras",
        tools: ["Read", "Glob", "Grep"]
      }
    }
  }
})) {
  console.log(message);
}

Ejemplo: Pipeline de Desarrollo

options = ClaudeAgentOptions(
    allowed_tools=["Read", "Write", "Edit", "Bash", "Glob", "Grep", "Task"],
    permission_mode="acceptEdits",
    agents={
        "analista": AgentDefinition(
            description="Analiza requisitos y diseña soluciones",
            prompt="Analiza el problema y propone una arquitectura",
            tools=["Read", "Glob", "Grep"]
        ),
        "desarrollador": AgentDefinition(
            description="Implementa código siguiendo especificaciones",
            prompt="Implementa el código limpio y bien estructurado",
            tools=["Read", "Write", "Edit", "Glob"]
        ),
        "tester": AgentDefinition(
            description="Escribe y ejecuta tests",
            prompt="Escribe tests completos y ejecútalos",
            tools=["Read", "Write", "Bash", "Glob"]
        ),
        "revisor": AgentDefinition(
            description="Revisa código y sugiere mejoras",
            prompt="Revisa el código buscando bugs y mejoras",
            tools=["Read", "Glob", "Grep"]
        )
    }
)

async for msg in query(
    prompt="""Implementa un validador de emails:
    1. Usa el analista para diseñar
    2. Usa el desarrollador para implementar
    3. Usa el tester para probar
    4. Usa el revisor para revisar""",
    options=options
):
    print(msg)

Identificar Mensajes de Subagentes

async for msg in query(prompt="...", options=options):
    if hasattr(msg, 'parent_tool_use_id'):
        # Este mensaje viene de un subagente
        print(f"[Subagente] {msg}")
    else:
        # Este mensaje es del agente principal
        print(f"[Principal] {msg}")

Ejemplo: Agente de Investigación

options = ClaudeAgentOptions(
    allowed_tools=["Read", "Glob", "Grep", "WebSearch", "WebFetch", "Task"],
    agents={
        "buscador": AgentDefinition(
            description="Busca información en la web",
            prompt="Busca información relevante y resume los hallazgos",
            tools=["WebSearch", "WebFetch"]
        ),
        "lector": AgentDefinition(
            description="Lee y extrae información de documentos",
            prompt="Lee los documentos y extrae la información clave",
            tools=["Read", "Glob", "Grep"]
        ),
        "sintetizador": AgentDefinition(
            description="Sintetiza información de múltiples fuentes",
            prompt="Combina la información en un resumen coherente",
            tools=["Read"]
        )
    }
)

async for msg in query(
    prompt="""Investiga sobre FastAPI:
    1. Usa el buscador para encontrar documentación
    2. Usa el lector para analizar archivos locales
    3. Usa el sintetizador para crear un resumen""",
    options=options
):
    print(msg)

Ejemplo: Refactor Masivo

options = ClaudeAgentOptions(
    allowed_tools=["Read", "Write", "Edit", "Bash", "Glob", "Grep", "Task"],
    permission_mode="acceptEdits",
    agents={
        "identificador": AgentDefinition(
            description="Identifica archivos que necesitan cambios",
            prompt="Encuentra todos los archivos que usan el patrón antiguo",
            tools=["Glob", "Grep"]
        ),
        "migrador": AgentDefinition(
            description="Migra código al nuevo patrón",
            prompt="Actualiza el código al nuevo patrón manteniendo funcionalidad",
            tools=["Read", "Edit"]
        ),
        "verificador": AgentDefinition(
            description="Verifica que los cambios funcionen",
            prompt="Ejecuta tests y verifica que no hay regresiones",
            tools=["Bash", "Read"]
        )
    }
)

async for msg in query(
    prompt="""Migra de 'print()' a 'logging':
    1. Usa el identificador para encontrar todos los print()
    2. Usa el migrador para cambiarlos a logging
    3. Usa el verificador para confirmar que funciona""",
    options=options
):
    print(msg)

Buenas Prácticas

1. Especialización clara

# BIEN: Propósito específico
AgentDefinition(
    description="Escribe tests unitarios con pytest",
    prompt="Crea tests unitarios completos con mocks",
    tools=["Read", "Write"]
)

# MAL: Demasiado general
AgentDefinition(
    description="Hace cosas de testing",
    prompt="Testea",
    tools=["Read", "Write", "Edit", "Bash"]
)

2. Herramientas mínimas

# BIEN: Solo lo necesario
agents={
    "lector": AgentDefinition(tools=["Read", "Glob"]),
    "escritor": AgentDefinition(tools=["Write", "Edit"])
}

# MAL: Todas las herramientas
agents={
    "lector": AgentDefinition(tools=["Read", "Write", "Edit", "Bash", "Glob"])
}

3. Prompts específicos

AgentDefinition(
    prompt="""Analiza el código Python buscando:
    - Funciones sin docstrings
    - Variables sin tipo
    - Código duplicado
    Reporta en formato markdown."""
)

Resumen