Coordinator
O coordinator é a persona com quem o usuário de fato conversa. Toda sessão de chat (web UI, Slack, Telegram, Feishu) pertence a uma instância de coordinator. Ele não é um worker — é o loop ReAct de longa duração que conduz a conversa, decide quando responder diretamente, e decide quando despachar para um specialist via AgentTool.
Identidade
| Campo | Valor |
|---|---|
| Nome da persona | default |
| Pode virar worker? | Não — o catálogo de agents exclui default |
| Modelo de sessão | Uma linha de longa duração em chat_sessions por (usuário, thread de chat) |
| Tool bag | Ampla: query_*, AgentTool, SendMessage, TaskStop, redirect stubs |
| Corpo da persona | Embarcada na imagem do manager; override por organização via arquivo montado |
Se você quiser mudar o comportamento do coordinator em toda a frota, monte um default.md customizado sobre o built-in (veja Agents customizados). A costura AgentRegistry.Replace é o que sustenta a UI de edição de user-agent; um arquivo de override usa o mesmo caminho de código no startup.
O que ele pode fazer diretamente
A tool bag do coordinator inclui todas as ferramentas query somente-leitura que operam no escopo do manager:
query_promql,query_logql,query_traceql— telemetria. Stubbed no coordinator (redirecionam para incident-investigator) para casos conhecidos de alucinação — veja abaixo.query_knowledge— RAG sobre o vault + uploads.query_incidents,get_incident_detail,query_alert_rules,query_devices— alerta / inventário.query_change_events— mutações recentes de config / regra / device.expand_topology,find_topology_node— grafo de serviços.get_active_incidents— alertas abertos no momento.- BC handler tools — qualquer coisa que um admin de org/usuário faria pela UI.
Ele deliberadamente não carrega ferramentas de shell de host nem de inspeção por host. Essas vivem nos specialists.
O trio de control-tools
Três ferramentas especiais existem apenas no coordinator. Elas controlam orquestração multi-agente; não consultam nada.
AgentTool
Despacha um worker. Síncrono. O schema completo, o comportamento de dedupe, e a regra "não delegue trivialidades" estão documentados em Visão geral dos agents. O formato:
{
"description": "Find which process is OOM-ing on node-01",
"subagent_type": "specialist-compute",
"prompt": "On device_id=7 we saw mem_used_pct=98 at 14:02. Find the top RSS processes and check dmesg for oom-killer hits. The user originally asked: 'who's eating memory on node-01?'"
}O system reminder injeta o catálogo de personas para que o LLM saiba os valores válidos de subagent_type. O reminder é por turno — mesmo após attention drift em sessões longas, o LLM nunca esquece quais specialists existem.
SendMessage
Envia uma mensagem intermediária ao usuário sem encerrar o turno. Usada quando o coordinator quer dizer "Estou despachando para specialist-network — me dê um minuto" antes do dispatch concluir. Workers não carregam essa ferramenta — só o coordinator fala com o usuário.
A ponte IM usa isso para atualizar a mensagem placeholder no chat (chat.update no Slack, editMessageText no Telegram, PUT /messages no Feishu). A web UI usa para fazer stream de texto intermediário no transcript antes da resposta final.
TaskStop
Cancela educadamente um worker em execução. O coordinator emite TaskStop quando, por exemplo, o usuário muda de assunto no meio de um dispatch e a resposta do worker em execução não é mais relevante.
Internamente ele chama Runtime.StopWorker, que dispara o context.CancelFunc do worker. O worker observa ctx.Done() na próxima chamada de tool e define Status = killed.
Quando despachar vs responder direto
O prompt de persona do coordinator codifica a regra:
AgentTool não é a opção padrão. Se você consegue responder em 1-2 passos com ferramentas locais, responda você mesmo. Investigação profunda (precisa de 5+ passos / cross-host / cross-signal) é que deve ser despachada.
Em outras palavras: despache apenas quando a tarefa
- precisa de iteração profunda (5+ chamadas de tool para inspeção focada),
- precisa de ferramentas no host (
host_bash,host_probe_*,host_du_summary), ou - se beneficia de uma tool bag específica de domínio que o coordinator não carrega.
Para "qual a carga do node-01?" o coordinator responde direto com um get_host_load (bem — com um stub-mediado redirect para AgentTool(specialist-compute); o princípio é o mesmo). Para "por que o serviço de pedidos está retornando 502 e o que devo fazer?" o coordinator despacha para incident-investigator.
Redirect stubs (anti-alucinação)
A bag do coordinator carrega entradas RedirectStub para nomes de tool que o LLM tende a alucinar (host_bash, host_du_summary, host_restart_service, get_host_load, correlate_incident, …). Quando o LLM escolhe um nome com stub, o stub retorna:
{
"status": "redirect",
"hint": "This tool is not available in coordinator scope. Re-invoke via AgentTool to dispatch to specialist-disk.",
"reason": "目录占用分析",
"suggested_call": "AgentTool(description=\"…\", subagent_type=\"specialist-disk\", prompt=\"<self-contained task>\", background=true)",
"why_stub_exists": "Coordinator's job is dispatch + triage. Deep-dive tools live on specialist workers; calling them inline is the wrong pattern."
}Sem esses stubs, o runtime de grafo do eino abortaria com [NodeRunError] tool X not found in toolsNode indexes e desperdiçaria o turno. Com eles, o LLM aprende com o resultado e tenta de novo com a chamada AgentTool correta na próxima iteração. A lista de stubs vive em CoordinatorRedirectStubs; é puro dado — acrescente conforme novas alucinações aparecem.
Não sombreie a bag inteira do specialist
Cada stub consome um slot na lista de schemas apresentada ao LLM. Stubs em excesso inflam o budget de prompt; o LLM pode começar a tratar stubs como opções válidas a considerar. Apenas ferramentas observadas alucinando em evals ganham um stub.
O que o usuário vê
A cada turno o coordinator pode:
- Fazer stream de tokens diretamente — a resposta é curta e auto-contida.
- Chamar ferramentas de query somente-leitura inline —
query_incidents,expand_topology,query_knowledge. - Despachar um worker via AgentTool — o SPA renderiza um "Agent tile" com o nome da persona + a descrição de 1 linha enquanto o worker roda. O resultado final do worker aparece como filho do tile.
- Enviar mensagem intermediária via SendMessage — geralmente antes que um dispatch lento conclua ("Investigando; subindo specialist-network").
- Parar um worker via TaskStop — raro, geralmente só quando o usuário redireciona no meio do dispatch.
O usuário nunca vê o transcript bruto do worker. O coordinator sintetiza o Result do worker em sua própria resposta.
Sessão e auditoria
- A sessão do coordinator vive em
chat_sessionscomagent_id = "default"eparent_session_id = NULL. - Sessões de worker recebem
parent_session_idapontando para a linha do coordinator. A UI de auditoria percorre essa árvore para renderizar runs pai → filho. - Cada chamada de tool gera uma linha em
audit_logscom a visão do LLM dos args e o resultado truncado (veja self-observabilidade).
Customizando o coordinator
Você pode sobrescrever o arquivo de persona do coordinator. Coisas que tipicamente você quer mudar:
- A orientação de dispatch (sua equipe tem uma política de "quando delegar" diferente).
- O idioma / tom da saída (use default_locale no canal; ou fixe via corpo da persona).
- A lista de ferramentas somente-leitura inline que o coordinator deve usar antes de despachar.
Coisas que você não deve mudar:
- O bloco do catálogo de agents — é gerado por máquina. Editá-lo não tem efeito; o próximo reload regenera.
- A semântica do redirect-stub — são código, não persona.
- O
namedefault— o runtime localiza o coordinator por nome.
Veja Agents customizados para a história de hot-reload.