Vai al contenuto principale

Documentation Index

Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt

Use this file to discover all available pages before exploring further.

I subagenti sono istanze di agente separate che il tuo agente principale può generare per gestire sottoattività mirate. Utilizza i subagenti per isolare il contesto per sottoattività mirate, eseguire più analisi in parallelo e applicare istruzioni specializzate senza appesantire il prompt dell’agente principale. Questa guida spiega come definire e utilizzare i subagenti nell’SDK utilizzando il parametro agents.

Panoramica

Puoi creare subagenti in tre modi:
  • A livello di programmazione: utilizza il parametro agents nelle tue opzioni query() (TypeScript, Python)
  • Basato su file system: definisci gli agenti come file markdown nelle directory .claude/agents/ (vedi definizione di subagenti come file)
  • Generale integrato: Claude può richiamare il subagente general-purpose integrato in qualsiasi momento tramite lo strumento Agent senza che tu debba definire nulla
Questa guida si concentra sull’approccio programmatico, che è consigliato per le applicazioni SDK. Quando definisci i subagenti, Claude determina se richiamarli in base al campo description di ogni subagente. Scrivi descrizioni chiare che spieghino quando il subagente dovrebbe essere utilizzato, e Claude delegherà automaticamente i compiti appropriati. Puoi anche richiedere esplicitamente un subagente per nome nel tuo prompt (ad esempio, “Usa l’agente code-reviewer per…”).

Vantaggi dell’utilizzo dei subagenti

Isolamento del contesto

Ogni subagente viene eseguito nella propria conversazione nuova. Le chiamate agli strumenti intermedi e i risultati rimangono all’interno del subagente; solo il suo messaggio finale ritorna al genitore. Vedi Cosa ereditano i subagenti per sapere esattamente cosa c’è nel contesto del subagente. Esempio: un subagente research-assistant può esplorare dozzine di file senza che nessuno di questi contenuti si accumuli nella conversazione principale. Il genitore riceve un riassunto conciso, non ogni file che il subagente ha letto.

Parallelizzazione

Più subagenti possono essere eseguiti contemporaneamente, accelerando drasticamente i flussi di lavoro complessi. Esempio: durante una revisione del codice, puoi eseguire i subagenti style-checker, security-scanner e test-coverage simultaneamente, riducendo il tempo di revisione da minuti a secondi.

Istruzioni e conoscenze specializzate

Ogni subagente può avere prompt di sistema personalizzati con competenze specifiche, best practice e vincoli. Esempio: un subagente database-migration può avere conoscenze dettagliate sulle best practice SQL, strategie di rollback e controlli di integrità dei dati che sarebbero rumore inutile nelle istruzioni dell’agente principale.

Restrizioni degli strumenti

I subagenti possono essere limitati a strumenti specifici, riducendo il rischio di azioni indesiderate. Esempio: un subagente doc-reviewer potrebbe avere accesso solo agli strumenti Read e Grep, assicurando che possa analizzare ma non modifichi mai accidentalmente i tuoi file di documentazione.

Creazione di subagenti

Definizione programmatica (consigliata)

Definisci i subagenti direttamente nel tuo codice utilizzando il parametro agents. Questo esempio crea due subagenti: un revisore di codice con accesso in sola lettura e un esecutore di test che può eseguire comandi. Lo strumento Agent deve essere incluso in allowedTools poiché Claude richiama i subagenti tramite lo strumento Agent.
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, AgentDefinition


async def main():
    async for message in query(
        prompt="Review the authentication module for security issues",
        options=ClaudeAgentOptions(
            # Agent tool is required for subagent invocation
            allowed_tools=["Read", "Grep", "Glob", "Agent"],
            agents={
                "code-reviewer": AgentDefinition(
                    # description tells Claude when to use this subagent
                    description="Expert code review specialist. Use for quality, security, and maintainability reviews.",
                    # prompt defines the subagent's behavior and expertise
                    prompt="""You are a code review specialist with expertise in security, performance, and best practices.

When reviewing code:
- Identify security vulnerabilities
- Check for performance issues
- Verify adherence to coding standards
- Suggest specific improvements

Be thorough but concise in your feedback.""",
                    # tools restricts what the subagent can do (read-only here)
                    tools=["Read", "Grep", "Glob"],
                    # model overrides the default model for this subagent
                    model="sonnet",
                ),
                "test-runner": AgentDefinition(
                    description="Runs and analyzes test suites. Use for test execution and coverage analysis.",
                    prompt="""You are a test execution specialist. Run tests and provide clear analysis of results.

Focus on:
- Running test commands
- Analyzing test output
- Identifying failing tests
- Suggesting fixes for failures""",
                    # Bash access lets this subagent run test commands
                    tools=["Bash", "Read", "Grep"],
                ),
            },
        ),
    ):
        if hasattr(message, "result"):
            print(message.result)


asyncio.run(main())

Configurazione di AgentDefinition

CampoTipoObbligatorioDescrizione
descriptionstringDescrizione in linguaggio naturale di quando utilizzare questo agente
promptstringIl prompt di sistema dell’agente che definisce il suo ruolo e comportamento
toolsstring[]NoArray di nomi di strumenti consentiti. Se omesso, eredita tutti gli strumenti
disallowedToolsstring[]NoArray di nomi di strumenti da rimuovere dal set di strumenti dell’agente
modelstringNoOverride del modello per questo agente. Accetta un alias come 'sonnet', 'opus', 'haiku', 'inherit', o un ID modello completo. Predefinito al modello principale se omesso
skillsstring[]NoElenco di nomi di skill da precaricare nel contesto dell’agente all’avvio. Le skill non elencate rimangono invocabili tramite lo strumento Skill
memory'user' | 'project' | 'local'NoFonte di memoria per questo agente
mcpServers(string | object)[]NoServer MCP disponibili per questo agente, per nome o configurazione inline
maxTurnsnumberNoNumero massimo di turni agentici prima che l’agente si fermi
backgroundbooleanNoEsegui questo agente come attività di background non bloccante quando richiamato
effort'low' | 'medium' | 'high' | 'xhigh' | 'max' | numberNoLivello di sforzo di ragionamento per questo agente
permissionModePermissionModeNoModalità di autorizzazione per l’esecuzione dello strumento all’interno di questo agente
Nell’SDK Python, questi nomi di campo utilizzano camelCase per corrispondere al formato wire. Vedi il riferimento AgentDefinition per i dettagli.
I subagenti non possono generare i propri subagenti. Non includere Agent nell’array tools di un subagente.

Definizione basata su file system (alternativa)

Puoi anche definire i subagenti come file markdown nelle directory .claude/agents/. Vedi la documentazione dei subagenti Claude Code per i dettagli su questo approccio. Gli agenti definiti a livello di programmazione hanno la precedenza sugli agenti basati su file system con lo stesso nome.
Anche senza definire subagenti personalizzati, Claude può generare il subagente general-purpose integrato quando Agent è nei tuoi allowedTools. Questo è utile per delegare attività di ricerca o esplorazione senza creare agenti specializzati.

Cosa ereditano i subagenti

La finestra di contesto di un subagente inizia da zero (nessuna conversazione genitore) ma non è vuota. L’unico canale dal genitore al subagente è la stringa di prompt dello strumento Agent, quindi includi direttamente nel prompt qualsiasi percorso di file, messaggio di errore o decisione di cui il subagente ha bisogno.
Il subagente riceveIl subagente non riceve
Il suo prompt di sistema (AgentDefinition.prompt) e il prompt dello strumento AgentLa cronologia della conversazione del genitore o i risultati degli strumenti
CLAUDE.md del progetto (caricato tramite settingSources)Contenuto di skill precaricato, a meno che non sia elencato in AgentDefinition.skills
Definizioni degli strumenti (ereditate dal genitore, o il sottoinsieme in tools)Il prompt di sistema del genitore
Il genitore riceve il messaggio finale del subagente verbatim come risultato dello strumento Agent, ma potrebbe riassumerlo nella sua risposta. Per preservare l’output del subagente verbatim nella risposta rivolta all’utente, includi un’istruzione per farlo nel prompt o nell’opzione systemPrompt che passi alla chiamata principale query().

Richiamo dei subagenti

Richiamo automatico

Claude decide automaticamente quando richiamare i subagenti in base al compito e alla description di ogni subagente. Ad esempio, se definisci un subagente performance-optimizer con la descrizione “Performance optimization specialist for query tuning”, Claude lo richiamerà quando il tuo prompt menziona l’ottimizzazione delle query. Scrivi descrizioni chiare e specifiche in modo che Claude possa abbinare i compiti al subagente giusto.

Richiamo esplicito

Per garantire che Claude utilizzi un subagente specifico, menzionalo per nome nel tuo prompt:
"Use the code-reviewer agent to check the authentication module"
Questo bypassa l’abbinamento automatico e richiama direttamente il subagente denominato.

Configurazione dinamica dell’agente

Puoi creare definizioni di agente dinamicamente in base alle condizioni di runtime. Questo esempio crea un revisore di sicurezza con diversi livelli di rigore, utilizzando un modello più potente per revisioni rigorose.
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, AgentDefinition


# Factory function that returns an AgentDefinition
# This pattern lets you customize agents based on runtime conditions
def create_security_agent(security_level: str) -> AgentDefinition:
    is_strict = security_level == "strict"
    return AgentDefinition(
        description="Security code reviewer",
        # Customize the prompt based on strictness level
        prompt=f"You are a {'strict' if is_strict else 'balanced'} security reviewer...",
        tools=["Read", "Grep", "Glob"],
        # Key insight: use a more capable model for high-stakes reviews
        model="opus" if is_strict else "sonnet",
    )


async def main():
    # The agent is created at query time, so each request can use different settings
    async for message in query(
        prompt="Review this PR for security issues",
        options=ClaudeAgentOptions(
            allowed_tools=["Read", "Grep", "Glob", "Agent"],
            agents={
                # Call the factory with your desired configuration
                "security-reviewer": create_security_agent("strict")
            },
        ),
    ):
        if hasattr(message, "result"):
            print(message.result)


asyncio.run(main())

Rilevamento dell’invocazione del subagente

I subagenti vengono richiamati tramite lo strumento Agent. Per rilevare quando un subagente viene richiamato, controlla i blocchi tool_use dove name è "Agent". I messaggi provenienti dal contesto di un subagente includono un campo parent_tool_use_id.
Il nome dello strumento è stato rinominato da "Task" a "Agent" in Claude Code v2.1.63. Le versioni attuali dell’SDK emettono "Agent" nei blocchi tool_use ma utilizzano ancora "Task" nell’elenco degli strumenti system:init e in result.permission_denials[].tool_name. Controllare entrambi i valori in block.name garantisce la compatibilità tra le versioni dell’SDK.
Questo esempio itera attraverso i messaggi trasmessi, registrando quando un subagente viene richiamato e quando i messaggi successivi provengono dal contesto di esecuzione di quel subagente.
La struttura del messaggio differisce tra gli SDK. In Python, i blocchi di contenuto sono accessibili direttamente tramite message.content. In TypeScript, SDKAssistantMessage avvolge il messaggio dell’API Claude, quindi il contenuto è accessibile tramite message.message.content.
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, AgentDefinition


async def main():
    async for message in query(
        prompt="Use the code-reviewer agent to review this codebase",
        options=ClaudeAgentOptions(
            allowed_tools=["Read", "Glob", "Grep", "Agent"],
            agents={
                "code-reviewer": AgentDefinition(
                    description="Expert code reviewer.",
                    prompt="Analyze code quality and suggest improvements.",
                    tools=["Read", "Glob", "Grep"],
                )
            },
        ),
    ):
        # Check for subagent invocation. Match both names: older SDK
        # versions emitted "Task", current versions emit "Agent".
        if hasattr(message, "content") and message.content:
            for block in message.content:
                if getattr(block, "type", None) == "tool_use" and block.name in (
                    "Task",
                    "Agent",
                ):
                    print(f"Subagent invoked: {block.input.get('subagent_type')}")

        # Check if this message is from within a subagent's context
        if hasattr(message, "parent_tool_use_id") and message.parent_tool_use_id:
            print("  (running inside subagent)")

        if hasattr(message, "result"):
            print(message.result)


asyncio.run(main())

Ripresa dei subagenti

I subagenti possono essere ripresi per continuare da dove si erano fermati. I subagenti ripresi mantengono la loro cronologia di conversazione completa, incluse tutte le chiamate agli strumenti precedenti, i risultati e il ragionamento. Il subagente riprende esattamente da dove si era fermato piuttosto che iniziare da zero. Quando un subagente si completa, Claude riceve il suo ID agente nel risultato dello strumento Agent. Per riprendere un subagente a livello di programmazione:
  1. Cattura l’ID della sessione: Estrai session_id dai messaggi durante la prima query
  2. Estrai l’ID dell’agente: Analizza agentId dal contenuto del messaggio
  3. Riprendi la sessione: Passa resume: sessionId nelle opzioni della seconda query e includi l’ID dell’agente nel tuo prompt
Devi riprendere la stessa sessione per accedere alla trascrizione del subagente. Ogni chiamata query() avvia una nuova sessione per impostazione predefinita, quindi passa resume: sessionId per continuare nella stessa sessione.Se stai utilizzando un agente personalizzato (non uno integrato), devi anche passare la stessa definizione di agente nel parametro agents per entrambe le query.
L’esempio seguente dimostra questo flusso: la prima query esegue un subagente e cattura l’ID della sessione e l’ID dell’agente, quindi la seconda query riprende la sessione per porre una domanda di follow-up che richiede il contesto della prima analisi.
import { query, type SDKMessage } from "@anthropic-ai/claude-agent-sdk";

// Helper to extract agentId from message content
// Stringify to avoid traversing different block types (TextBlock, ToolResultBlock, etc.)
function extractAgentId(message: SDKMessage): string | undefined {
  if (!("message" in message)) return undefined;
  // Stringify the content so we can search it without traversing nested blocks
  const content = JSON.stringify(message.message.content);
  const match = content.match(/agentId:\s*([a-f0-9-]+)/);
  return match?.[1];
}

let agentId: string | undefined;
let sessionId: string | undefined;

// First invocation - use the Explore agent to find API endpoints
for await (const message of query({
  prompt: "Use the Explore agent to find all API endpoints in this codebase",
  options: { allowedTools: ["Read", "Grep", "Glob", "Agent"] }
})) {
  // Capture session_id from ResultMessage (needed to resume this session)
  if ("session_id" in message) sessionId = message.session_id;
  // Search message content for the agentId (appears in Agent tool results)
  const extractedId = extractAgentId(message);
  if (extractedId) agentId = extractedId;
  // Print the final result
  if ("result" in message) console.log(message.result);
}

// Second invocation - resume and ask follow-up
if (agentId && sessionId) {
  for await (const message of query({
    prompt: `Resume agent ${agentId} and list the top 3 most complex endpoints`,
    options: { allowedTools: ["Read", "Grep", "Glob", "Agent"], resume: sessionId }
  })) {
    if ("result" in message) console.log(message.result);
  }
}
Le trascrizioni dei subagenti persistono indipendentemente dalla conversazione principale:
  • Compattazione della conversazione principale: Quando la conversazione principale si compatta, le trascrizioni dei subagenti non sono interessate. Sono archiviate in file separati.
  • Persistenza della sessione: Le trascrizioni dei subagenti persistono all’interno della loro sessione. Puoi riprendere un subagente dopo il riavvio di Claude Code riprendendo la stessa sessione.
  • Pulizia automatica: Le trascrizioni vengono pulite in base all’impostazione cleanupPeriodDays (predefinito: 30 giorni).

Restrizioni degli strumenti

I subagenti possono avere accesso agli strumenti limitato tramite il campo tools:
  • Ometti il campo: l’agente eredita tutti gli strumenti disponibili (predefinito)
  • Specifica gli strumenti: l’agente può utilizzare solo gli strumenti elencati
Questo esempio crea un agente di analisi in sola lettura che può esaminare il codice ma non può modificare file o eseguire comandi.
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, AgentDefinition


async def main():
    async for message in query(
        prompt="Analyze the architecture of this codebase",
        options=ClaudeAgentOptions(
            allowed_tools=["Read", "Grep", "Glob", "Agent"],
            agents={
                "code-analyzer": AgentDefinition(
                    description="Static code analysis and architecture review",
                    prompt="""You are a code architecture analyst. Analyze code structure,
identify patterns, and suggest improvements without making changes.""",
                    # Read-only tools: no Edit, Write, or Bash access
                    tools=["Read", "Grep", "Glob"],
                )
            },
        ),
    ):
        if hasattr(message, "result"):
            print(message.result)


asyncio.run(main())

Combinazioni di strumenti comuni

Caso d’usoStrumentiDescrizione
Analisi in sola letturaRead, Grep, GlobPuò esaminare il codice ma non modificare o eseguire
Esecuzione di testBash, Read, GrepPuò eseguire comandi e analizzare l’output
Modifica del codiceRead, Edit, Write, Grep, GlobAccesso completo in lettura/scrittura senza esecuzione di comandi
Accesso completoTutti gli strumentiEredita tutti gli strumenti dal genitore (ometti il campo tools)

Risoluzione dei problemi

Claude non delega ai subagenti

Se Claude completa i compiti direttamente invece di delegare al tuo subagente:
  1. Includi lo strumento Agent: i subagenti vengono richiamati tramite lo strumento Agent, quindi deve essere in allowedTools
  2. Usa prompt espliciti: menziona il subagente per nome nel tuo prompt (ad esempio, “Usa l’agente code-reviewer per…”)
  3. Scrivi una descrizione chiara: spiega esattamente quando il subagente dovrebbe essere utilizzato in modo che Claude possa abbinare i compiti in modo appropriato

Agenti basati su file system non caricati

Gli agenti definiti in .claude/agents/ vengono caricati solo all’avvio. Se crei un nuovo file di agente mentre Claude Code è in esecuzione, riavvia la sessione per caricarlo.

Windows: errori di prompt lungo

Su Windows, i subagenti con prompt molto lunghi potrebbero non riuscire a causa dei limiti di lunghezza della riga di comando (8191 caratteri). Mantieni i prompt concisi o utilizza agenti basati su file system per istruzioni complesse.

Documentazione correlata