Skip to content

Overview de agentes

Ongrid es un sistema ReAct multi-agente. El usuario siempre habla con el coordinator — la persona de nivel superior en la superficie de chat. Cuando una tarea encaja en un dominio especializado (investigación profunda de causa raíz, revisión de una acción mutadora, análisis profundo de red), el coordinator despacha a un sub-agente (un "worker") vía AgentTool. Cada worker ejecuta el mismo graph kernel contra un toolbag filtrado y devuelve una respuesta final que el coordinator teje en su respuesta.

Esta página es el mapa. Las páginas por persona explican cada agente en detalle.

Personas, no hilos de chat

Una persona es un archivo en disco que describe lo que hace un agente. El layout canónico — misma forma que el formato de agente de Claude Code con keys snake_case:

yaml
---
name: specialist-disk
description: 文件系统 / 磁盘容量专家 — du / find / stat / inode / 挂载 / 大文件
when_to_use: |
  When the task is about disk / filesystem health:
    - Disk full / utilization climbing
    - Hunt for large files / large directories
    - inode exhaustion / mount point inspection
tools:
  - query_knowledge
  - host_find_large_files
  - host_du_summary
  - host_stat_file
  - host_bash
  - query_promql
  - get_host_load
permission_mode: read-only
max_turns: 15
---
[markdown body — this becomes the system prompt]

El cuerpo debajo del frontmatter es el SystemPrompt. Dos archivos de persona con el mismo name colisionan y el loader emite un warning. Ver referencia de formato de persona para cada campo.

Las personas viven bajo ./agents/ en la imagen del manager (/app/agents/ dentro del contenedor). Ongrid trae personas integradas en la imagen y también lee personas escritas por el usuario desde un directorio montado — ver Agentes custom.

Coordinator vs worker

AspectoCoordinatorWorker
Quién habla con el usuarioSí (vía superficie de chat o IM)Nunca — la salida del worker va al coordinator
ToolbagAmplio: query_*, AgentTool, redirect stubsEstrecho: whitelist tools: de la persona
Nombre de personadefault (o override por organización)specialist-*, incident-investigator, reviewer
Lo lanzaRuntime (uno por sesión de chat)AgentTool o decorator review_gate
Puede lanzarSí (workers)No (los workers no anidan por diseño)
SesiónLarga vida, persistidaNueva sesión por spawn, alcance de un turno

El trabajo del coordinator es dispatch + triage + síntesis. Las herramientas de deep-dive viven en los workers. El coordinator lleva slots de RedirectStub para tools que el LLM tiende a alucinar (host_bash, get_host_load, …); llamar a uno de ellos devuelve un mensaje de redirect que empuja al modelo a re-invocar vía AgentTool.

AgentTool

La primitiva de dispatch del coordinator. Nombre del wire AgentTool (PascalCase para alinearse con el catálogo de tools de Claude Code). Schema visible para el LLM:

json
{
  "type": "object",
  "properties": {
    "description":   {"type": "string"},
    "subagent_type": {"type": "string"},
    "prompt":        {"type": "string"}
  },
  "required": ["description", "subagent_type", "prompt"]
}
  • description — resumen de tarea de 1 línea que usa el tile de la SPA.
  • subagent_typename de la persona. El catálogo inyectado en el system prompt del coordinator lista los valores válidos (el registry de personas, menos reviewer y default).
  • prompt — brief de tarea completo. El worker no puede ver el contexto del coordinator — empaqueta todo detalle necesario (incident_id, device_id, redacción exacta).

La llamada es síncrona desde la perspectiva del coordinator. Bloquea hasta que el worker llega a completed / failed / killed. Una revisión anterior tenía un flag asíncrono background: true; los modelos débiles lo aceptaban, respondían al usuario con el task_id pendiente y nunca daban seguimiento. El flag ya no existe hoy (ver agent_tool.go para el comentario del post-mortem). La única ruta async es el reviewer — y eso lo conduce el decorator, no el LLM.

El dedupe viene incorporado

Un LRU de 120s con key sha256(subagent_type + canonical(prompt)) cortocircuita la segunda de dos llamadas idénticas a AgentTool. El LLM ve el resultado previo con un hint explícito de "ya despachaste esto". Recorta loops del coordinator (la eval E2E D1 vio 122 tool calls en 240s sin dedupe).

Cómo se compone un system prompt

ComposeSystemPrompt ensambla el prompt que recibe el LLM, en orden:

  1. basePrompt — el preámbulo universal del runtime. Puede estar vacío.
  2. agentProfile.SystemPrompt — el cuerpo Markdown de la persona. El coordinator puede llevar uno (la mayoría lo hace); los workers siempre lo llevan.
  3. agentProfile.CriticalReminder — envuelto en <critical-reminder>...</critical-reminder>. Esta es la constante a nivel de persona; la capa de grafo también la re-inyecta por turno como un <system-reminder> para que sobreviva la deriva de atención en sesiones largas.
  4. Por cada skill activo: un header [能力: <name>] + el PromptBody del skill.

El coordinator recibe un bloque extra antes de la lista de skills: el catálogo de agentes (buildAgentCatalog) — una lista de bullets en Markdown de "specialists disponibles" con la description y la primera línea de when_to_use. El catálogo excluye deliberadamente reviewer (solo el decorator ReviewGate puede lanzarlo) y default (la persona virtual top-level — listarlo como sub-agente lanzable dejaría que el coordinator se autoinstanciara recursivamente).

El agent registry

El AgentRegistry mantiene las personas parseadas en memoria. Carga una vez al arranque; Reload() bajo un único swap de sync.RWMutex para que un turno del coordinator en vuelo nunca observe un registry a medio cargar.

MétodoCuándo
Load(root)Arranque. Recorre <root>/**/*.md recursivamente.
Reload(root, ...)Install/uninstall de marketplace. Swap atómico.
ByName(name)Lookup al spawn. Devuelve (nil, false) si no está.
Replace(ag)Edición de user-agent. Upsert in place — registry vivo, sin reinicio.
Remove(name)Borrado de user-agent.

Los errores de parse por archivo aterrizan como warnings en vez de abortar el walk (misma política que el registry de skills). Las raíces de agentes inexistentes no son un error — obtienes un registry vacío, no un fallo de arranque.

Reviewer y el review gate

El reviewer es especial: el coordinator no puede lanzarlo. Está gated por el decorator ReviewGate, que intercepta cualquier tool cuya Class sea "write" o "destructive". El decorator:

  1. Construye un payload de propuesta (action, target, reason, blast_radius, operator).
  2. Lanza el worker reviewer (síncrono desde la perspectiva del tool interior) con su propio timeout de 60s, independiente de los 15s del tool interior.
  3. Si el reviewer devuelve Decision: approve, la llamada cae al tool interior. En caso contrario, el decorator devuelve ErrReviewRejected envolviendo la razón del reviewer.

Por eso el catálogo de agentes omite reviewer: solo el decorator puede invocarlo. Ponerlo en el catálogo dejaría que el coordinator despachara "reviews" ad-hoc que no gatean nada.

Ver Reviewer para la máquina de estados completa.

Ciclo de vida del worker

Máquina de estados de Runtime.SpawnWorker:

text
pending  → running  → completed
                   ↘ failed
                   ↘ killed     (StopWorker called while running)
  • Una fila chat_sessions se crea por adelantado para que las queries de audit + árbol parent → worker resuelvan incluso mientras el worker está corriendo.
  • Los spawns en background derivan del contexto de larga vida del runtime para que un request HTTP que termine no pueda tirar abajo al worker en medio de la ejecución; los spawns síncronos heredan el ctx del caller.
  • La fila de sesión se cierra (closed_at establecido) en cada ruta terminal, incluidos pánicos — sin esto, las filas huérfanas se acumulan (el entorno de test llegó a 161 antes de que aterrizara el fix).

Los workers no pueden lanzar workers. SpawnWorker solo está expuesto en el Runtime, y el filtro disabledForWorker elimina AgentTool del toolbag de cualquier worker. Un coordinator, N workers paralelos, sin anidamiento más profundo.

Qué sigue

  • Coordinator — la persona por defecto, sus tres tools de control y cuándo despachar vs responder directamente.
  • Incident investigator — causa raíz hasta el "patient zero", el presupuesto de 18 tools y la eval F1.
  • Specialists — compute / disk / network / ops / sre, qué posee cada uno, cómo elige el coordinator.
  • Reviewer — el gate SOP de doble firma sobre tools mutadores.
  • Agentes custom — escribe tu propia persona, hot-reload, debug.