Format de persona d'agent
Une persona d'agent est un fichier markdown décrivant comment un agent — un coordinator, un incident investigator, un specialist — se comporte : quels outils il peut appeler, sur quel modèle il tourne, combien de tours ReAct il obtient, et quel system prompt il porte.
Source de vérité : Agent dans internal/manager/biz/aiops/chatruntime/types.go.
Forme sur disque
---
name: incident_investigator
description: Walk an incident from symptom to root cause, calling host + observability tools.
when_to_use: When the user asks why an alert is firing, or shares an incident link.
tools:
- expand_topology
- find_topology_node
- query_promql
- search_logs
- query_traceql
- host_probe
- bash
disallowed_tools: []
permission_mode: read-only
max_turns: 24
model: anthropic/claude-sonnet-4-6
critical_reminder: |
Always show your evidence. Cite the PromQL / LogQL / file path. Never speculate
beyond what the tools returned.
initial_prompt: |
You are investigating incident {{ '{{' }}.incident_id{{ '}}' }} on device {{ '{{' }}.device_id{{ '}}' }}.
Start by reading the incident summary.
background: false
omit_claude_md: false
metadata:
os: [linux, darwin]
requires:
bins: []
config: []
ongrid:
scope: manager
---
# Incident investigator
You are an SRE-grade incident investigator. Given an incident, your job is to:
1. Pull the alert detail and any attached evidence (alert summary, snapshot).
2. Expand the device's topology to understand the blast radius.
3. Query the relevant signal (metric / log / trace) to confirm the symptom.
4. Walk upstream services / underlying resources until you find the root cause.
5. Return an evidence-backed answer in plain language.
When the user asks a follow-up, stay grounded in tool output. If you cannot
verify a claim with a tool call, say so explicitly and stop.Le frontmatter est du YAML. Le corps (après ---) est le system prompt que le worker LLM voit. Les espaces et le formatage markdown dans le corps sont préservés verbatim.
Champs du frontmatter
| Champ | Type | Requis | Description |
|---|---|---|---|
name | string | oui | Identifiant d'agent utilisé au moment du spawn (/v1/agents/{name}). |
description | string | oui | Chaîne de listing humaine affichée dans le picker d'agent. |
when_to_use | string | oui | Hint de décision de spawn du coordinator. Le coordinator lit ceci en décidant quel specialist invoquer. |
tools | string[] | non | Whitelist explicite d'outils. Vide = hérite de la politique (chaque outil que le rôle de l'utilisateur peut voir). |
disallowed_tools | string[] | non | Blacklist appliquée après la whitelist. Le noir l'emporte sur le blanc. |
permission_mode | enum | non (défaut read-only) | read-only, mutating-with-confirm, dual-sign-required. Gate quelles classes d'outils peuvent tourner sans confirmation. |
max_turns | int | non | Plafonne la boucle ReAct interne du worker. Le défaut du coordinator s'applique si zéro. |
model | string | non | Identifiant LLM (anthropic/claude-sonnet-4-6, openai/gpt-5.4, zhipu/glm-4.7, etc.). Vide = hérite du défaut du coordinator. |
critical_reminder | string | non | Bloc system-reminder injecté à chaque tour. Mécanisme anti-dérive. |
initial_prompt | string | non | Préfixé au premier message utilisateur au spawn. Supporte la syntaxe template Go sur le contexte de spawn ({{.incident_id}}, {{.device_id}}). |
background | bool | non | true force l'exécution asynchrone (workers longue durée). |
omit_claude_md | bool | non | Saute l'héritage du contexte système global. Utilisé pour les agents reviewer strictement scopés. |
metadata | object | non | Gate d'OS, binaires / clés de config requis, extensions ongrid (scope, edge_runtime, edge_capabilities). |
Les clés de frontmatter inconnues sont préservées (le parser les stocke sous UnknownFields) pour que les champs futurs d'openclaw / claude-code ne cassent pas le loader.
Champ Source
Quand la SPA relit un agent, l'API inclut aussi un champ source qui n'est pas partie du frontmatter sur disque :
| Valeur | Signification |
|---|---|
builtin | livré dans le binaire (Add programmatique). Lecture seule dans l'UI. |
disk | chargé depuis agents/*.md à côté du binaire ou sous un répertoire externe. Lecture seule dans l'UI. |
user | créé par l'utilisateur via POST /v1/agents/custom. Éditable et supprimable depuis l'UI. |
Modes de permission
Le champ permission_mode gate quelles classes d'outils la persona peut exécuter.
| Mode | Classes autorisées | Confirmation requise |
|---|---|---|
read-only | read (alias safe) | jamais |
mutating-with-confirm | read + write | une fois par appel write |
dual-sign-required | read + write + destructive | SOP en deux étapes pour destructive ; une fois pour write |
Une persona peut contraindre plus loin via tools (whitelist) et disallowed_tools (blacklist). Le runtime les applique dans cet ordre :
- Prendre le set d'outils global que le rôle de l'utilisateur peut voir.
- Intersecter avec
toolssi non vide. - Retirer tout ce qui est dans
disallowed_tools. - Pour chaque outil restant, vérifier
permission_modecontre saclass.
Flux d'enregistrement
Built-in personas
↳ programmatic Add() in cmd/ongrid/main.go at startup. Cannot be deleted.
On-disk personas
↳ ./agents/*.md (relative to manager working dir) scanned at boot.
↳ ONGRID_AGENTS_EXTERNAL_DIRS adds more.
↳ The loader walks every .md, parses frontmatter via skill_parser.go / agent_parser.go.
↳ Each agent is registered with Source="disk".
↳ Cannot be edited or deleted via the UI; remove the file and restart.
User personas
↳ POST /v1/agents/custom with the frontmatter as a JSON body.
↳ Stored in agents table (DB), not on disk.
↳ Source="user"; fully editable via PATCH /v1/agents/custom/{name}.L'ordre de merge au démarrage est builtin → disk → user. Une persona user avec le même name qu'une persona built-in ou disk la shadow.
Spawner un agent
Le coordinator choisit un specialist en matchant la requête de l'utilisateur contre le when_to_use de chaque persona. Pour spawner programmatiquement (API chat) :
POST /api/v1/chat/sessions/{id}/messages
Content-Type: application/json
Authorization: Bearer ...
{
"content": "Investigate incident 4217.",
"agent": "incident_investigator",
"context": { "incident_id": 4217, "device_id": 102 }
}Si agent est omis, le coordinator choisit. context est templaté dans le initial_prompt de la persona.
Critical reminders
Le bloc critical_reminder est injecté comme message system-reminder au sommet de chaque tour, pas juste le premier. C'est le mécanisme anti-dérive standard de claude-code — quand le modèle dérive mid-conversation (par ex. arrête de citer des preuves après le tour 8), le rappel le ramène.
Utilisez-le avec parcimonie. Un court paragraphe par persona suffit. Le kernel d'agent injecte déjà des rappels au niveau framework (locale, nom de modèle, outils disponibles) ; votre critical_reminder devrait ajouter seulement du comportement spécifique à la persona.
Exemples
Specialist minimal
---
name: disk_specialist
description: Diagnose disk pressure issues — usage, IO, mount points.
when_to_use: When the user asks about disk-full, slow IO, or mount errors.
tools: [host_probe, bash, query_promql]
permission_mode: read-only
model: zhipu/glm-4.7
---
# Disk specialist
Focus exclusively on disk-related questions. ...Reviewer (omet le contexte global)
---
name: change_reviewer
description: Review a proposed config change for blast radius.
when_to_use: When the user wants a second opinion on a destructive action.
tools: [expand_topology, read_repo, search_knowledge]
permission_mode: read-only
omit_claude_md: true
max_turns: 8
model: anthropic/claude-opus-4-7
critical_reminder: |
Be a skeptic. Default to "do not proceed" unless evidence is overwhelming.
---
# Change reviewer
You are reviewing a proposed change. Your job is to find reasons the change
should NOT proceed. Approve only when you cannot find a reason to block.Voir aussi
- Agents → Aperçu — tour côté opérateur des personas intégrées.
- Capacités → Skills — le catalogue d'outils parmi lequel une persona choisit.
- Manifeste de skill — définir de nouveaux outils qu'une persona peut appeler.
- API REST → aiops — endpoints pour gérer les personas au runtime.