Créer des Skills

Guide pas à pas pour ajouter de nouvelles expertises à ton projet Arc OS.


Avant d'écrire un nouveau skill — vérifie la bibliothèque globale

Arc OS est livré avec 40+ skills génériques dans skills/ couvrant les rôles courants. Avant d'en rédiger un nouveau, regarde si l'existant couvre ton besoin :

Domaine Skills disponibles
Engineering commit-discipline, tdd-flow, react-best-practices, postgres-patterns, mcp-builder
Frontend / Design frontend-design-principles, svg-graphics, slide-deck-html, service-design, scss-modular-architecture, responsive-mobile-first
Startup ops market-analysis, gtm-strategy, financial-modeling, pitch-deck, customer-development, fundraising, founder-brand, metrics-dashboard, legal-startup
Marketing seo-foundations, founder-brand
Process standup-aggregator, commit-discipline
Database postgres-patterns

Liste complète : GET /api/crm/skills?category=<X> ou bun -e "console.log(JSON.stringify(require('./skills/_registry.json').skills.map(s=>s.name),null,2))".

Skill = déclenché par triggers, pas toujours actif

Un skill s'auto-injecte dans le prompt du worker quand le message correspond à ses triggers (dans _registry.json). Le champ description est de la logique de déclenchement ("quand l'utiliser"), pas un résumé. Le Context Router choisit les 5 meilleures correspondances par message.


Qu'est-ce qu'un Skill

Un skill est un ensemble d'instructions portable qui enseigne à ton bot IA une capacité spécifique. Les skills vivent dans le répertoire skills/ et se composent de :

skills/
├── _registry.json              ← Central registry
├── my-new-skill/
│   ├── skill.md                ← What the AI should do
│   ├── my-new-skill.evals.json ← How to validate the output
│   └── references/             ← Context documents
└── library/
    └── domain-expert.md        ← Simple single-file skills

Étape 1 : Rédiger skill.md

C'est l'instruction centrale. Claude lit ce fichier lorsque le skill est activé.

Template

# Skill Name

## Purpose
What this skill accomplishes in one sentence.

## When to Use
- Trigger condition 1
- Trigger condition 2

## Protocol
1. First action
2. Second action
3. Third action

## Output Format
What the response should look like.

## Constraints
- What NOT to do
- Safety boundaries

Bonnes pratiques

Exemple : Odoo Expert

# Odoo Expert

## Purpose
Odoo ERP module development: models, views, security, QWeb templates.

## When to Use
- Building or modifying Odoo modules
- Writing QWeb templates
- Configuring access rules and record rules
- Working with the ORM (create, write, search, browse)

## Protocol
1. Check if modifying an existing module or creating new
2. Follow Odoo 17 conventions (manifest, models/, views/, security/)
3. Use self.env['model.name'] for ORM operations
4. Always use _t() or t-call for translatable strings
5. Test with --test-tags after changes

## Constraints
- Never use cr.execute() for direct SQL — use ORM
- Never use sudo() unless security context explicitly requires it
- No inline JavaScript in QWeb templates

Étape 2 : Rédiger les evals (règles de qualité)

Les evals sont des règles déclaratives qui valident automatiquement chaque réponse. Elles s'exécutent après que Claude génère sa sortie et ajoutent des notes de bas de page si des règles échouent.

Nommage du fichier

skills/<name>/<name>.evals.json

Schéma

{
  "version": 1,
  "skill": "my-new-skill",
  "rules": [
    {
      "id": "ms-001",
      "name": "Human-readable rule description",
      "type": "rule_type",
      "value": "for string/length types",
      "pattern": "for regex types",
      "severity": "warning"
    }
  ]
}

Types de règles disponibles

Type Ce qu'il vérifie Champ utilisé
string_contains La réponse contient un texte littéral value (string)
string_not_contains La réponse ne contient PAS le texte value (string)
regex_match La réponse correspond à la regex pattern (string)
regex_not_match La réponse ne correspond PAS à la regex pattern (string)
max_length Longueur de la réponse <= N caractères value (number)
min_length Longueur de la réponse >= N caractères value (number)

Niveaux de sévérité

Exemple

{
  "version": 1,
  "skill": "odoo-expert",
  "rules": [
    {
      "id": "oe-001",
      "name": "Must use ORM, not raw SQL",
      "type": "string_not_contains",
      "value": "cr.execute",
      "severity": "warning"
    },
    {
      "id": "oe-002",
      "name": "Must use translation helpers",
      "type": "regex_match",
      "pattern": "_t\\(|t-call|t-esc",
      "severity": "warning"
    },
    {
      "id": "oe-003",
      "name": "Response under 5000 chars",
      "type": "max_length",
      "value": 5000,
      "severity": "info"
    }
  ]
}

Conseils


Étape 3 : Enregistrer dans _registry.json

Le registre informe le Context Router de l'existence de ton skill afin qu'il puisse être recommandé pour les messages pertinents.

Ajouter une entrée

{
  "name": "my-new-skill",
  "description": "One sentence (shown in SKILLS_HINT, max 80 chars).",
  "triggers": ["direct-command", "explicit-request", "пряма команда"],
  "keywords": ["broader", "semantic", "related-term"],
  "agents": ["rick"],
  "category": ["complex"],
  "phase": "21.5"
}

Triggers vs Keywords

Triggers (2 points chacun) : Signaux d'invocation directe. L'utilisateur demande explicitement ce skill.

Keywords (1 point chacun) : Termes plus larges qui suggèrent une pertinence sans être des commandes.

Bonnes pratiques


Étape 4 : Skills de bibliothèque (format simplifié)

Pour une expertise métier qui ne nécessite ni evals ni répertoire dédié, utilise skills/library/ :

skills/library/
├── docker-ops.md
├── postgres-pro.md
└── react-patterns.md

Ce sont des fichiers .md simples. Pas de répertoire, pas d'evals, pas de references. Idéal pour les skills riches en connaissances et pauvres en validation.


Checklist


Ce qui se passe à l'exécution

1. Bot starts → loadRegistry() reads _registry.json
                 loadEvals() reads all .evals.json files
                 loadLearnings() reads learnings.md

2. Message arrives → routeContext() scores skills → SKILLS_HINT injected
                     formatForPrompt() adds LEARNINGS block

3. Claude responds → checkOutput() runs eval rules
                     formatEvalWarnings() appends footnotes

4. Fix It / thumbs-down → addLearning() writes to learnings.md
                          qualityTracker logs feedback

5. Nightly → findUnderperformingSkills() checks metrics
             Proposals sent to CEO for approval

Seeder les skills dans la DB globale

Les skills en DB (table skills_global) sont le SSOT du Context Router. Le fichier sur disque est la source de vérité pour le contenu ; la DB est l'index rapide pour le matching + l'auto-injection. Ils se synchronisent via des scripts de seed.

Seeder générique par catégorie

# Reads skills/_registry.json, filters by category, upserts skills_global rows.
# Idempotent + drift-aware (skip if no change, update on content drift).
bun scripts/seed-skill-category.ts --category engineering
bun scripts/seed-skill-category.ts --category frontend
bun scripts/seed-skill-category.ts --category marketing

Fonctionne pour n'importe quelle catégorie présente dans _registry.json. Prend la première catégorie du tableau comme valeur de colonne DB.

Seeders spécifiques

Quand les lancer

Vérification

sqlite3 data/citadel.db "SELECT name, category, owner_project FROM skills_global ORDER BY id"

owner_project = NULL → global (visible par tous les projets). owner_project = 'my-project' → réservé au projet (seul ce projet le voit).


Skills project-only vs globaux

Type de skill owner_project Cas d'usage
Global (template) NULL Méthodologie générique (TDD, Conventional Commits, AARRR) — utile à n'importe quel projet
Project-only '<project-name>' Documents propres à NOTRE codebase (p. ex. crm-api-reference ne vit que dans arc-v2)

Passer un skill existant en project-only :

sqlite3 data/citadel.db "UPDATE skills_global SET owner_project='my-project' WHERE name='internal-api-docs'"

Le filtre listForProject gère la visibilité : les autres projets ne verront pas un skill project-only.