- Início
- Documentation
- Ferramentas de execução
- Descoberta e Seleção de Agentes de Tarefa
Descoberta e Seleção de Agentes de Tarefa
Este documento descreve como o subsistema de tarefas descobre definições de agentes, mescla múltiplas fontes e resolve um agente solicitado no momento da execução.
Ele abrange o comportamento em tempo de execução conforme implementado atualmente, incluindo precedência, tratamento de definições inválidas e restrições de spawn/profundidade que podem tornar um agente efetivamente indisponível.
Arquivos de implementação
Seção intitulada “Arquivos de implementação”src/task/discovery.tssrc/task/agents.tssrc/task/types.tssrc/task/index.tssrc/task/commands.tssrc/prompts/agents/task.mdsrc/prompts/tools/task.mdsrc/discovery/helpers.tssrc/config.tssrc/task/executor.ts
Formato de definição de agente
Seção intitulada “Formato de definição de agente”Os agentes de tarefa são normalizados para AgentDefinition (src/task/types.ts):
name,description,systemPrompt(obrigatórios para um agente carregado válido)tools,spawns,model,thinkingLevel,output(opcionais)source:"bundled" | "user" | "project"filePath(opcional)
A análise vem do frontmatter via parseAgentFields() (src/discovery/helpers.ts):
nameoudescriptionausentes => inválido (null), o chamador trata como falha de análisetoolsaceita CSV ou array; se fornecido,submit_resulté adicionado automaticamentespawnsaceita*, CSV ou array- comportamento de compatibilidade retroativa: se
spawnsestiver ausente mastoolsincluirtask,spawnspassa a ser* outputé repassado como dados de esquema opacos
Agentes embutidos
Seção intitulada “Agentes embutidos”Os agentes embutidos são incorporados no momento da compilação (src/task/agents.ts) usando importações de texto.
EMBEDDED_AGENT_DEFS define:
explore,plan,designer,reviewera partir de arquivos de prompttaskequick_taska partir do corpo compartilhadotask.mdmais frontmatter injetado
Caminho de carregamento:
loadBundledAgents()analisa o markdown incorporado comparseAgent(..., "bundled", "fatal")- os resultados são armazenados em cache na memória (
bundledAgentsCache) clearBundledAgentsCache()é uma redefinição de cache exclusiva para testes
Como a análise dos agentes embutidos usa level: "fatal", frontmatter malformado lança uma exceção e pode causar falha na descoberta inteiramente.
Descoberta no sistema de arquivos e em plugins
Seção intitulada “Descoberta no sistema de arquivos e em plugins”discoverAgents(cwd, home) (src/task/discovery.ts) mescla agentes de múltiplos locais antes de acrescentar as definições embutidas.
Entradas de descoberta
Seção intitulada “Entradas de descoberta”- Diretórios de agentes da configuração do usuário obtidos via
getConfigDirs("agents", { project: false }) - Diretórios de agentes do projeto mais próximo obtidos via
findAllNearestProjectConfigDirs("agents", cwd) - Raízes de plugins Claude (
listClaudePluginRoots(home)) com subdiretóriosagents/ - Agentes embutidos (
loadBundledAgents())
Ordem real das fontes
Seção intitulada “Ordem real das fontes”A ordem das famílias de fontes vem de getConfigDirs("", { project: false }), derivada de priorityList em src/config.ts:
.xcsh.claude.codex.gemini
Para cada família de fontes, a ordem de descoberta é:
- diretório do projeto mais próximo para aquela fonte (se encontrado)
- diretório do usuário para aquela fonte
Após todos os diretórios de famílias de fontes, os diretórios agents/ de plugins são acrescentados (plugins de escopo de projeto primeiro, depois de escopo de usuário).
Os agentes embutidos são acrescentados por último.
Ressalva importante: comentários desatualizados vs. código atual
Seção intitulada “Ressalva importante: comentários desatualizados vs. código atual”Os comentários de cabeçalho em discovery.ts ainda mencionam .pi e não mencionam .codex/.gemini. A ordem em tempo de execução real é determinada por src/config.ts e atualmente utiliza .xcsh, .claude, .codex, .gemini.
Regras de mesclagem e colisão
Seção intitulada “Regras de mesclagem e colisão”A descoberta usa deduplicação por nome exato com política de primeiro a chegar:
- Um
Set<string>rastreia os nomes já vistos. - Os agentes carregados são achatados na ordem dos diretórios e mantidos apenas se o nome ainda não foi visto.
- Os agentes embutidos são filtrados em relação ao mesmo conjunto e adicionados apenas se ainda não foram vistos.
Implicações:
- O projeto substitui o usuário para a mesma família de fontes.
- Famílias de fontes de maior prioridade substituem as de menor prioridade (
.xcshantes de.claude, etc.). - Agentes não embutidos substituem agentes embutidos com o mesmo nome.
- A correspondência de nomes é sensível a maiúsculas e minúsculas (
Tasketasksão distintos). - Dentro de um mesmo diretório, os arquivos markdown são lidos em ordem lexicográfica de nome de arquivo antes da deduplicação.
Comportamento com arquivos de agente inválidos ou ausentes
Seção intitulada “Comportamento com arquivos de agente inválidos ou ausentes”Por diretório (loadAgentsFromDir):
- diretório ilegível ou ausente: tratado como vazio (
readdir(...).catch(() => [])) - falha de leitura ou análise de arquivo: aviso registrado, arquivo ignorado
- o caminho de análise usa
parseAgent(..., level: "warn")
O comportamento de falha do frontmatter vem de parseFrontmatter:
- erro de análise no nível
warnregistra aviso - o analisador retorna a um parser simples de linha
key: value - se os campos obrigatórios ainda estiverem ausentes,
parseAgentFieldsfalha, entãoAgentParsingErroré lançado e capturado pelo chamador (arquivo ignorado)
Efeito líquido: um arquivo de agente personalizado inválido não aborta a descoberta dos demais arquivos.
Pesquisa e seleção de agente
Seção intitulada “Pesquisa e seleção de agente”A pesquisa é uma busca linear por nome exato:
getAgent(agents, name)=>agents.find(a => a.name === name)
Na execução de tarefas (TaskTool.execute):
- os agentes são redescobertos no momento da chamada (
discoverAgents(this.session.cwd)) - o
params.agentsolicitado é resolvido viagetAgent - agente ausente retorna resposta imediata da ferramenta:
Unknown agent "...". Available: ...- nenhum subprocesso é executado
Descoberta na descrição vs. no momento da execução
Seção intitulada “Descoberta na descrição vs. no momento da execução”TaskTool.create() constrói a descrição da ferramenta a partir dos resultados de descoberta no momento da inicialização (buildDescription).
execute() redescobre os agentes novamente. Portanto, o conjunto em tempo de execução pode diferir do que foi listado na descrição anterior da ferramenta se os arquivos de agente foram alterados durante a sessão.
Proteções de saída estruturada e precedência de esquema
Seção intitulada “Proteções de saída estruturada e precedência de esquema”Precedência do esquema de saída em tempo de execução em TaskTool.execute:
outputdo frontmatter do agenteparams.schemada chamada de tarefaoutputSchemada sessão pai
(effectiveOutputSchema = effectiveAgent.output ?? outputSchema ?? this.session.outputSchema)
O texto de proteção em tempo de prompt em src/prompts/tools/task.md averte sobre o comportamento de incompatibilidade para agentes de saída estruturada (explore, reviewer): instruções de formato de saída em prosa podem conflitar com o esquema embutido e produzir saídas null.
Isso é uma orientação, não lógica de validação em tempo de execução em discoverAgents.
Interação com a descoberta de comandos
Seção intitulada “Interação com a descoberta de comandos”src/task/commands.ts é uma infraestrutura paralela para comandos de fluxo de trabalho (não definições de agente), mas segue o mesmo padrão geral:
- descobrir a partir dos provedores de capacidade primeiro
- deduplicar por nome com política de primeiro a chegar
- acrescentar comandos embutidos se ainda não vistos
- pesquisa por nome exato via
getCommand
Em src/task/index.ts, os auxiliares de comando são reexportados junto com os auxiliares de descoberta de agentes. A descoberta de agentes em si não depende da descoberta de comandos em tempo de execução.
Restrições de disponibilidade além da descoberta
Seção intitulada “Restrições de disponibilidade além da descoberta”Um agente pode ser detectável, mas ainda assim indisponível para execução devido a proteções de execução.
Política de spawn do pai
Seção intitulada “Política de spawn do pai”TaskTool.execute verifica session.getSessionSpawns():
"*"=> permitir qualquer um""=> negar todos- lista CSV => permitir apenas os nomes listados
Se negado: resposta imediata Cannot spawn '...'. Allowed: ....
Proteção de ambiente contra autorrecursão bloqueada
Seção intitulada “Proteção de ambiente contra autorrecursão bloqueada”PI_BLOCKED_AGENT é lido na construção da ferramenta. Se a solicitação corresponder, a execução é rejeitada com uma mensagem de prevenção de recursão.
Limitação de profundidade de recursão (disponibilidade da ferramenta de tarefa em sessões filhas)
Seção intitulada “Limitação de profundidade de recursão (disponibilidade da ferramenta de tarefa em sessões filhas)”Em runSubprocess (src/task/executor.ts):
- a profundidade é calculada a partir de
taskDepth task.maxRecursionDepthcontrola o limite- ao atingir a profundidade máxima:
- a ferramenta
taské removida da lista de ferramentas da sessão filha spawnsdo ambiente filho é definido como vazio
- a ferramenta
Portanto, níveis mais profundos não podem gerar mais tarefas mesmo que a definição do agente inclua spawns.
Ressalva sobre o modo de plano (implementação atual)
Seção intitulada “Ressalva sobre o modo de plano (implementação atual)”TaskTool.execute calcula um effectiveAgent para o modo de plano (adiciona o prompt do modo de plano ao início, força um subconjunto de ferramentas somente leitura, limpa spawns), mas runSubprocess é chamado com agent em vez de effectiveAgent.
Efeito atual:
- a substituição de modelo / nível de raciocínio / esquema de saída são derivados de
effectiveAgent - o prompt do sistema e as restrições de ferramenta/spawn de
effectiveAgentnão são repassados neste caminho de chamada
Esta é uma ressalva de implementação importante ao analisar as expectativas de comportamento do modo de plano.