Skip to content

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

markdown
---
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

ChampTypeRequisDescription
namestringouiIdentifiant d'agent utilisé au moment du spawn (/v1/agents/{name}).
descriptionstringouiChaîne de listing humaine affichée dans le picker d'agent.
when_to_usestringouiHint de décision de spawn du coordinator. Le coordinator lit ceci en décidant quel specialist invoquer.
toolsstring[]nonWhitelist explicite d'outils. Vide = hérite de la politique (chaque outil que le rôle de l'utilisateur peut voir).
disallowed_toolsstring[]nonBlacklist appliquée après la whitelist. Le noir l'emporte sur le blanc.
permission_modeenumnon (défaut read-only)read-only, mutating-with-confirm, dual-sign-required. Gate quelles classes d'outils peuvent tourner sans confirmation.
max_turnsintnonPlafonne la boucle ReAct interne du worker. Le défaut du coordinator s'applique si zéro.
modelstringnonIdentifiant LLM (anthropic/claude-sonnet-4-6, openai/gpt-5.4, zhipu/glm-4.7, etc.). Vide = hérite du défaut du coordinator.
critical_reminderstringnonBloc system-reminder injecté à chaque tour. Mécanisme anti-dérive.
initial_promptstringnonPréfixé au premier message utilisateur au spawn. Supporte la syntaxe template Go sur le contexte de spawn ({{.incident_id}}, {{.device_id}}).
backgroundboolnontrue force l'exécution asynchrone (workers longue durée).
omit_claude_mdboolnonSaute l'héritage du contexte système global. Utilisé pour les agents reviewer strictement scopés.
metadataobjectnonGate 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 :

ValeurSignification
builtinlivré dans le binaire (Add programmatique). Lecture seule dans l'UI.
diskchargé depuis agents/*.md à côté du binaire ou sous un répertoire externe. Lecture seule dans l'UI.
usercréé 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.

ModeClasses autoriséesConfirmation requise
read-onlyread (alias safe)jamais
mutating-with-confirmread + writeune fois par appel write
dual-sign-requiredread + write + destructiveSOP 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 :

  1. Prendre le set d'outils global que le rôle de l'utilisateur peut voir.
  2. Intersecter avec tools si non vide.
  3. Retirer tout ce qui est dans disallowed_tools.
  4. Pour chaque outil restant, vérifier permission_mode contre sa class.

Flux d'enregistrement

text
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) :

http
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

markdown
---
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)

markdown
---
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