Le problème de tout répéter

Avez-vous déjà dû expliquer la même chose à quelqu’un vingt fois ? Eh bien imaginez ça, mais avec un robot qui en plus perd la mémoire toutes les quelques heures.

“Non, Claude, le commit doit passer les tests d’abord.” “Claude, je t’ai déjà dit d’utiliser le format type: description.” “N’ajoute pas d’emojis, bon sang !”

C’était mon quotidien jusqu’à ce que je découvre les Skills. Dit en termes clairs : ce sont des instructions que vous écrivez une fois et que Claude suit pour toujours. Comme dresser un chien, mais sans les croquettes.

Ce que sont les Skills

Depuis la version 2.1.3, Claude Code a fusionné les anciens slash commands avec quelque chose de plus puissant : les Skills. Ce sont des fichiers Markdown avec des instructions que Claude peut exécuter de deux façons :

  1. Manuellement : quand vous écrivez /mon-skill
  2. Automatiquement : quand Claude détecte qu’il devrait l’utiliser

Ce deuxième point, c’est la magie. Vous n’avez plus besoin de vous rappeler d’invoquer la commande. Si vous avez un skill qui dit “utiliser quand l’utilisateur termine une tâche et qu’il y a des changements non commités”, Claude le fera tout seul.

C’est comme avoir un majordome qui sait quand débarrasser la table sans qu’on le lui demande.

Où ils vivent

~/.claude/skills/          # Personnels (tous vos projets)
.claude/skills/            # Du projet (partagés avec l'équipe)
~/.claude/commands/        # Legacy, fonctionne encore
.claude/commands/          # Legacy, fonctionne encore

Si vous voulez que seul vous utilisiez le skill, vous le mettez dans votre home. Si vous voulez que toute l’équipe l’ait, vous le commitez au repo. Aussi simple que ça.

Anatomie d’un Skill

Un skill est un fichier Markdown avec un frontmatter YAML et ensuite le contenu :

1
2
3
4
5
6
7
8
---
name: mon-skill
description: Brève description de ce qu'il fait
---

# Instructions

Ce que Claude doit faire quand ce skill est invoqué.

C’est le minimum. Mais le frontmatter a pas mal d’autres options qui valent la peine d’être connues.

Champs obligatoires

name

L’identifiant du skill. Seulement minuscules, chiffres et tirets (max. 64 caractères). Doit correspondre au nom du fichier ou répertoire.

1
2
name: check-types      # ✓ valide
name: Check_Types      # ✗ invalide (majuscules et underscore)

description

C’est le champ le plus important. Claude l’utilise pour deux choses :

  1. Décider quand auto-invoquer le skill
  2. Comprendre ce qu’il doit faire

Maximum 1024 caractères. Incluez des mots-clés que l’utilisateur dirait naturellement.

1
2
3
4
5
6
7
8
# Mauvais - trop vague
description: Fait des trucs avec les commits

# Bien - spécifique et avec des triggers
description: >
  Crée des commits git en vérifiant type-check, lint et tests.
  Utiliser quand l'utilisateur dit "commit", "commite", ou termine une tâche
  avec des changements en attente.

Champs optionnels

model

Force un modèle spécifique pour ce skill. Utile pour des tâches qui nécessitent plus de capacité.

1
2
3
model: opus    # Pour audits de sécurité, refactoring complexe
model: sonnet  # Équilibre entre capacité et coût
model: haiku   # Pour tâches simples et rapides

Si vous ne le spécifiez pas, il utilise le modèle de la conversation actuelle.

allowed-tools

Restreint les outils que Claude peut utiliser. Critique pour les skills en lecture seule ou sécurisés.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Peut seulement lire, pas modifier
allowed-tools:
  - Read
  - Grep
  - Glob

# Peut seulement exécuter des commandes spécifiques
allowed-tools:
  - Bash(git:*)      # Seulement commandes git
  - Bash(uv:*)       # Seulement commandes uv
  - Read

Exemple pratique : un skill d’analyse qui ne doit rien toucher :

1
2
3
4
5
6
7
8
---
name: analyze-deps
description: Analyse les dépendances du projet sans rien modifier
allowed-tools:
  - Read
  - Grep
  - Bash(uv pip list:*)
---

context: fork

Exécute le skill dans un sous-agent isolé avec son propre contexte. L’historique de la conversation principale n’est pas contaminé.

1
context: fork

Utile pour des opérations complexes en plusieurs étapes où vous ne voulez pas encombrer le chat de bruit.

agent

Fonctionne seulement avec context: fork. Définit quel type d’agent exécute le skill.

1
2
3
context: fork
agent: Explore    # Agent d'exploration rapide
agent: Plan       # Agent de planification

user-invocable

Contrôle s’il apparaît dans le menu des / (slash commands). Par défaut c’est true.

1
user-invocable: false  # Caché du menu, mais Claude peut l'utiliser

Utile pour des skills internes qui devraient seulement s’activer automatiquement.

disable-model-invocation

Empêche Claude d’invoquer le skill par lui-même. Seul vous pouvez l’activer avec /nom.

1
disable-model-invocation: true

Utile pour des opérations destructives ou coûteuses qui nécessitent une décision humaine explicite.

hooks

Définit des hooks qui s’exécutent pendant le cycle de vie du skill. Supporte PreToolUse, PostToolUse et Stop.

1
2
3
4
5
6
7
hooks:
  PreToolUse:
    - matcher: "Bash"
      hooks:
        - type: command
          command: "./scripts/validate-input.sh $TOOL_INPUT"
          once: true

Variables de substitution

Dans le contenu du skill vous pouvez utiliser :

VariableCe qu’elle contient
$ARGUMENTSLes arguments passés en invoquant /skill arg1 arg2
${CLAUDE_SESSION_ID}ID de la session actuelle (utile pour les logs)

Tableau récapitulatif

ChampObligatoireBut
nameIdentifiant du skill
descriptionQuand et pourquoi l’utiliser
modelForcer un modèle spécifique
allowed-toolsRestreindre les outils
contextfork pour sous-agent isolé
agentType d’agent (avec context: fork)
user-invocableMontrer/cacher dans le menu /
disable-model-invocationBloquer l’auto-invocation
hooksHooks du cycle de vie

Exemple complet

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
---
name: security-audit
description: >
  Audit de sécurité OWASP. Utiliser quand l'utilisateur demande de réviser
  la sécurité, chercher des vulnérabilités, ou avant de déployer en production.
model: opus
allowed-tools:
  - Read
  - Grep
  - Glob
user-invocable: true
disable-model-invocation: true  # Seulement manuel, c'est coûteux
---

# Audit de Sécurité

[instructions...]

Pour la référence complète, consultez la documentation officielle des Agent Skills.

Texte libre ou code déterministe ?

C’est la question à un million : si les skills sont en Markdown, est-ce que ça veut dire que Claude “interprète” toujours ce que vous écrivez ? Puis-je faire quelque chose de vraiment prévisible ?

La réponse courte : les skills sont aussi déterministes que vous les écrivez.

Pensez à un spectre :

Vague/Flexible ──────────────────────────► Déterministe
"révise le code"        "exécute ces 3 commandes dans l'ordre"

Skill flexible (Claude décide)

1
2
3
4
5
6
---
name: review
description: Révise le code à la recherche de problèmes
---

Analyse le code et suggère des améliorations.

Ici Claude a toute liberté. Il peut regarder ce qu’il veut, suggérer ce qui lui semble bien. Utile pour l’exploration, dangereux pour les processus critiques.

Skill déterministe (script déguisé)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
---
name: check
description: Vérifications de qualité obligatoires
allowed-tools:
  - Bash
---

Exécuter **exactement** ces commandes dans l'ordre :

1. `uv run basedpyright src/`
2. `uv run ruff check src/`
3. `uv run pytest -x`

## Règles

- **NE PAS interpréter** les erreurs de manière créative
- **NE PAS continuer** si l'une échoue
- **NE PAS suggérer** de corrections automatiquement
- Rapporter seulement : ✓ réussi / ✗ échoué avec output

C’est essentiellement un script de 3 lignes. Claude n’a pas de marge pour être créatif. Exécute, rapporte, point.

Skill avec logique conditionnelle

1
2
3
4
5
6
7
8
9
---
name: release
description: Prépare le release du projet
---

## Étape 1 : Vérifier la branche

```bash
git branch --show-current
  • Si ce n’est PAS mainABANDONNER avec “Seulement depuis main”

Étape 2 : État propre

1
git status --porcelain
  • S’il y a un output → ABANDONNER avec “Changements non commités”

Étape 3 : Bump + push

1
2
uv run bump2version patch
git push && git push --tags

Il y a de la logique de branches ici, mais ça reste déterministe : les conditions sont explicites.

### Skill qui invoque un script réel

Si vous avez besoin de vraie logique complexe (boucles, parsing, APIs), mettez le code dans un script et que le skill ne fasse que l'exécuter :

.claude/skills/deploy/ ├── SKILL.md └── deploy.sh


**SKILL.md :**
```markdown
---
name: deploy
description: Déploie en production
---

Exécuter :

```bash
bash .claude/skills/deploy/deploy.sh

Rapporter le résultat. NE PAS modifier le script.


**deploy.sh :**
```bash
#!/bin/bash
set -e
uv run pytest || exit 1
hugo --minify
rsync -avz public/ user@server:/var/www/

Le meilleur des deux mondes : la logique complexe vit en Bash/Python où elle appartient, et le skill est juste le déclencheur.

Quand utiliser chaque approche

BesoinApproche
Commandes fixes, toujours identiquesSkill déterministe
Logique complexe avec beaucoup de branchesScript externe
Analyse qui nécessite du jugementSkill flexible avec garde-fous
Opérations dangereusesallowed-tools restrictif

Exemple réel : le skill de commit

C’est celui que j’utilise le plus. Avant je devais me rappeler : “ok, exécute les tests, puis le linter, puis le type-check, et seulement alors commite”. Maintenant je dis simplement “commite” et Claude fait tout seul.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
---
name: commit
description: Crée des commits git avec vérification obligatoire de qualité.
  Exécute type-check, lint et tests avant de commiter.
---

# Commit

## Quand Utiliser (Automatique)

Appliquer quand :
- L'utilisateur dit "commit", "commite", "sauvegarde les changements"
- L'utilisateur termine une tâche et il y a des changements non commités

## Interdit

- Commiter sans exécuter les vérifications
- Demander confirmation (fais-le simplement)
- Ajouter Co-Authored-By
- Utiliser des emojis dans les messages de commit

## Processus

### Phase 1 : Détecter les changements

```bash
git diff --name-only HEAD

Phase 2 : Vérifications OBLIGATOIRES

1
2
3
uv run basedpyright src/
uv run ruff check src/
uv run pytest

Si l’une échoue, NE PAS continuer.

Phase 3 : Créer le commit

  1. git add -A
  2. Analyser les changements
  3. Générer le message : type: description
  4. git commit

Vous voyez la section "Quand Utiliser" ? C'est ce qui permet l'auto-invocation. Claude lit ça et pense : "ah, l'utilisateur vient de dire 'c'est fini', il y a des changements en attente, je devrais utiliser ce skill".

## Autre exemple : archivage de tâches

Si vous utilisez un fichier `TASKS.md` pour tracker ce que vous faites (je le faisais avant Beads), ce skill vous nettoie les tâches terminées automatiquement :

```markdown
---
name: archive-tasks
description: Archive les tâches terminées de TASKS.md vers TASKS-DONE.md.
  Utiliser automatiquement quand TASKS.md a beaucoup de tâches terminées
  ou dépasse les 20K tokens.
---

# Archive Tasks

## Quand Utiliser (Automatique)

- TASKS.md a plus de 50 tâches terminées `[x]`
- TASKS.md dépasse les 20'000 tokens
- L'utilisateur mentionne que TASKS.md est très gros

## Processus

1. Lire `docs/llm/TASKS.md`
2. Identifier les tâches terminées (`[x]`)
3. Déplacer vers `docs/llm/TASKS-DONE.md` avec date
4. Supprimer de TASKS.md
5. Rapporter combien ont été archivées

## Règles

- **NE PAS supprimer** les tâches en attente `[ ]`
- **PRÉSERVER** le contexte (section parent)
- **AJOUTER** la date d'archivage

Le beau c’est que vous n’avez pas besoin de vous en souvenir. Claude voit que TASKS.md est énorme et agit.

Conseils pour écrire de bons skills

1. Descriptions spécifiques

1
2
3
4
5
6
# Mauvais
description: Fait des trucs avec les commits

# Bien
description: Crée des commits git en vérifiant type-check, lint et tests.
  Bloque s'il y a des erreurs.

2. Définissez quand appliquer

1
2
3
4
5
6
## Quand Utiliser Ce Skill (Automatique)

Appliquer automatiquement quand :
- L'utilisateur dit "commit" ou "sauvegarde les changements"
- Il y a des changements staged prêts
- L'utilisateur termine une tâche

3. Soyez explicite avec les interdictions

Claude a tendance à vouloir être poli et demander confirmation. Si vous ne voulez pas ça, dites-le clairement :

1
2
3
4
5
## Interdit

- Demander confirmation (JAMAIS)
- Ajouter Co-Authored-By
- Utiliser des emojis

4. Utilisez model: opus pour l’important

Si le skill fait quelque chose de critique (audit de sécurité, refactoring complexe), forcez le modèle le plus capable :

1
2
3
4
5
---
name: owasp
description: Audit de sécurité OWASP
model: opus
---

5. Restreignez les outils si nécessaire

Parfois vous voulez un skill qui ne fait que lire, sans rien modifier :

1
2
3
4
5
6
7
8
---
name: readonly-analysis
description: Analyse le code sans le modifier
allowed-tools:
  - Glob
  - Grep
  - Read
---

Skills simples vs complexes

Un skill simple est un seul fichier :

.claude/skills/review.md

Un skill complexe est un répertoire avec des ressources :

.claude/skills/deploy/
├── SKILL.md                 # Instructions
├── templates/
│   └── k8s-deployment.yaml
└── scripts/
    └── healthcheck.sh

Claude peut lire les fichiers du répertoire comme contexte additionnel.

Ce que j’utilise

SkillPour quoiAuto-invocation
commitCommit avec vérificationsQuand je dis “commit” ou termine quelque chose
check-diagnosticsVérifier types et lintAvant les commits
owaspAudit de sécuritéManuel (c’est coûteux)
archive-tasksNettoyer TASKS.mdQuand c’est très gros

La différence avec les commands legacy

AspectSkillsCommands
Auto-invocationOuiNon
StructureRépertoire ou fichierSeulement fichier
RecommandationUtiliser pour tout nouveauLegacy

Les commands fonctionnent encore, mais les skills sont strictement meilleurs. Si vous avez de vieux commands, pas besoin de les migrer, mais pour du nouveau utilisez les skills.

Conclusion

Les skills sont essentiellement de la programmation, mais en langage naturel. Vous définissez ce que vous voulez qu’il se passe, quand, et avec quelles restrictions. Claude fait le reste.

Le mieux c’est qu’ils sont versionnés avec votre code. Si vous travaillez en équipe, tout le monde a les mêmes skills. Si vous changez quelque chose, ça reste dans l’historique git.

Est-ce que ça vaut l’effort de les écrire ? Si vous répétez la même chose plus de trois fois, absolument. Chaque skill que vous écrivez est une conversation que vous n’aurez plus jamais à avoir.

Maintenant si vous m’excusez, je dois aller apprendre à Claude que “refactoriser” ne veut pas dire “réécrire tout depuis zéro”.


TL;DR : Les skills sont des instructions en Markdown que Claude Code exécute manuellement ou automatiquement. Ils peuvent être aussi flexibles ou déterministes que vous en avez besoin : de “analyse ça” jusqu’à des scripts déguisés en prose. Si vous avez besoin de logique complexe, invoquez des scripts externes. Ils vivent dans .claude/skills/ et sont versionnés avec votre code.