working-with-skills

Par posthog · skills

Bonnes pratiques pour les agents gérant des skills PostHog via les outils MCP `llma-skill-*` — comment découvrir, lire, créer, mettre à jour et refactoriser des skills efficacement, en particulier les skills volumineuses regroupant de nombreux fichiers. À utiliser dès que vous êtes sur le point d'appeler un outil `llma-skill-*`, qu'on vous demande de créer ou modifier une skill partagée, ou que vous cherchez pourquoi une écriture de skill a été rejetée. Complète `skills-store` (qui couvre la surface brute des outils) en ajoutant des conseils sur l'arbre de décision, l'efficacité et les pièges à éviter.

npx skills add https://github.com/posthog/skills --skill working-with-skills

Travailler avec les skills PostHog

Cette skill enseigne aux agents comment utiliser les outils MCP llma-skill-* efficacement — contexte minimal, allers-retours minimes, erreurs minimales. Si vous ne connaissez pas encore la surface de l'outil elle-même, lisez d'abord la skill skills-store pour le catalogue. Ce document parle de comment choisir entre les outils et comment faire évoluer le workflow quand les skills deviennent volumineux.

Principes de fonctionnement

  1. La divulgation progressive est non-négociable. Les listes retournent des descriptions, get retourne body + manifest, file-get retourne un fichier. Ne préchargez jamais de fichiers bundlés « juste au cas où » — chaque script préchargé gaspille du contexte pour la tâche réelle.
  2. Choisissez la plus petite primitive d'écriture qui fait le travail. Un edits ou file_edits ciblé est moins cher, plus sûr et plus clair dans l'historique des versions qu'un remplacement complet du body ou du bundle.
  3. Les lectures sont bon marché ; les écritures concurrentes ne le sont pas. Ayez toujours une version récente depuis llma-skill-get (ou depuis la réponse de l'écriture précédente) avant d'appeler un outil d'écriture, et transmettez-la en tant que base_version.
  4. La création suit la spécification Agent Skills. Gardez name en kebab-case, descriptions riches en déclencheurs, body court, matériel volumineux dans les fichiers bundlés.

Arbre de décision : quel outil appeler ?

Besoin de savoir ce qui est disponible ?
  └─► llma-skill-list                    (noms + descriptions uniquement)

Besoin d'utiliser / inspecter une skill spécifique ?
  └─► llma-skill-get                     (body + manifest de fichiers, PAS de contenu de fichiers)
        └─► llma-skill-file-get          (un fichier, à la demande, uniquement selon référence)

Créer une toute nouvelle skill ?
  └─► llma-skill-create                  (body + tous les fichiers initiaux en un seul appel)

Éditer une skill existante ?
  ├─ Changement du body ?
  │    ├─ Réécriture substantielle ......... update(body=...)
  │    └─ Ajustement chirurgical ........... update(edits=[{old, new}, ...])
  ├─ Changement du contenu des fichiers bundlés ?
  │    └─ update(file_edits=[{path, edits:[...]}, ...])
  ├─ Ajouter / supprimer / renommer un fichier ?
  │    ├─ Ajouter .......................... llma-skill-file-create
  │    ├─ Supprimer ........................ llma-skill-file-delete
  │    └─ Renommer ......................... llma-skill-file-rename
  └─ Réinitialisation en gros du bundle (rare!) ... update(files=[...])  # remplace TOUS les fichiers

Voulez-vous un fork comme point de départ ?
  └─► llma-skill-duplicate               (puis mettre à jour la copie)

Si vous vous surprenez à utiliser update(body=...) plus un files=[...] étendu pour changer un paragraphe et un script, arrêtez — ce sont deux appels plus étroits (update(edits=[...]) plus update(file_edits=[...])) ou même un seul update portant à la fois edits et file_edits.

Découvrez avant de récupérer

posthog:llma-skill-list
{ "search": "fractal" }

llma-skill-list est le bon outil pour « trouver une skill » — il retourne les noms et descriptions uniquement. Lire les descriptions est tout l'intérêt : choisissez la bonne skill avant de tirer un body. Si search ne réduit pas assez, listez sans et scannez, mais ne commencez pas à récupérer aveuglément les bodies candidats.

llma-skill-get doit être appelé une fois par skill par tâche, pas par question. Mettez en cache le body dans votre mémoire de travail ; refetch uniquement si vous suspectez que la skill a changé sous vous (par ex. un 409 lors de l'écriture — voir « Concurrence » ci-dessous).

Lire une grande skill efficacement

Les grandes skills (long body, nombreux fichiers bundlés) sont le cas où le lazy loading importe le plus.

  1. llma-skill-get(skill_name=...) — lire body + manifest files[].
  2. Scannez la table des matières / les titres du body. Le body devrait déjà vous dire quel fichier correspond à quelle tâche — c'est pourquoi les bodies restent courts et référencent les fichiers par chemin.
  3. Pour chaque fichier que le body pointe explicitement pour la tâche actuelle, appelez llma-skill-file-get(file_path=...). Ignorez tout le reste.
  4. Si le body référence « voir scripts/X pour le cas rare Y » et vous n'êtes pas dans le cas Y, ne récupérez pas scripts/X.

En cas de doute, moins de fichiers. Vous pouvez toujours en récupérer un de plus au prochain tour.

Créer une nouvelle skill

Utilisez un seul appel llma-skill-create avec body et fichiers initiaux — la skill atterrit à version: 1 complète. Ne créez pas la skill vide puis ne faites N appels llma-skill-file-create de suivi ; c'est N versions supplémentaires et N allers-retours supplémentaires pour aucun bénéfice.

posthog:llma-skill-create
{
  "name": "my-skill",
  "description": "Ce qu'elle fait ET quand l'utiliser. Incluez les mots-clés déclencheurs.",
  "body": "# my-skill\n\n## Quand l'utiliser\n...\n## Workflow\n...",
  "license": "MIT",
  "compatibility": "Requires Python 3.10+",
  "allowed_tools": ["Bash", "Write"],
  "metadata": { "author": "me", "category": "..." },
  "files": [
    { "path": "scripts/foo.py", "content": "...", "content_type": "text/x-python" },
    { "path": "references/primer.md", "content": "...", "content_type": "text/markdown" }
  ]
}

Règles empiriques de création

  • description est la surface de découverte. C'est la seule chose que llma-skill-list retourne. Rendez-la riche en déclencheurs (ce que l'utilisateur pourrait dire) et honnête quant à la portée (ce que la skill fait et ne fait pas).
  • name — kebab-case, max 64 caractères, pas de tirets au début/fin/consécutifs. Le validateur spec rejette tout le reste.
  • Body ≤ ~500 lignes. Les longs préambules, SQL exhaustif, payloads d'exemple complètes et code exécutable appartiennent à references/, assets/, ou scripts/. Le body devrait router vers ces fichiers, pas les inliner.
  • Convention de disposition des fichiersscripts/ pour le code exécutable, references/ pour les documents en prose et exemples, assets/ pour les modèles / données. Les agents peuvent s'y fier pour l'orientation quand ils n'ont que le manifest.
  • allowed_tools liste les outils MCP / intégrés que la skill s'attend à être appelable. Soyez honnête — sous-déclarer cause des silences d'échec, sur-déclarer sent la sécurité.

Mettre à jour une skill existante

L'erreur unique la plus courante est d'utiliser update(body=..., files=[...]) pour une petite modification. Ça marche, mais ça fait un aller-retour de toute la skill, rend le diff illisible dans l'historique des versions et risque de perdre des fichiers si files était incomplet. Utilisez plutôt la plus petite primitive.

Toujours lire d'abord, capturer version

posthog:llma-skill-get
{ "skill_name": "my-skill" }

Notez la version retournée — transmettez-la en tant que base_version à chaque écriture. Après une écriture réussie, la réponse contient la nouvelle version ; chaînez les autres écritures avec celle-ci.

Body : remplacement complet vs édits incrémentiels

Remplacement complet quand vous restructurez le body :

posthog:llma-skill-update
{ "skill_name": "my-skill", "body": "# my-skill\n\nNew body...", "base_version": 7 }

Édits incrémentiels quand vous ajustez quelques lignes (préféré pour les petites modifications — plus facile à examiner, surface d'erreur plus réduite) :

posthog:llma-skill-update
{
  "skill_name": "my-skill",
  "edits": [
    { "old": "Use Pillow for rendering.", "new": "Use Pillow ≥10.0 for rendering." },
    { "old": "## Old section title", "new": "## New section title" }
  ],
  "base_version": 7
}

Chaque edits[].old doit correspondre exactement une fois dans le body actuel, et body et edits s'excluent mutuellement en un seul appel.

Édits du contenu des fichiers bundlés

file_edits corrige un ou plusieurs fichiers existants sur place — les fichiers non ciblés sont reportés inchangés. C'est la bonne primitive quand vous ajustez la logique du script ou corriger une typo dans un document de référence :

posthog:llma-skill-update
{
  "skill_name": "my-skill",
  "file_edits": [
    {
      "path": "scripts/foo.py",
      "edits": [{ "old": "ITERATIONS = 100", "new": "ITERATIONS = 250" }]
    },
    {
      "path": "references/primer.md",
      "edits": [{ "old": "## Outdated header", "new": "## Updated header" }]
    }
  ],
  "base_version": 7
}

file_edits ne peut pas ajouter, supprimer ou renommer des fichiers — seulement corriger les existants. Pour les changements structurels, utilisez les outils par fichier.

Combiner les édits en un seul appel

Vous pouvez combiner edits (body) et file_edits (fichiers existants) en un seul appel llma-skill-update pour publier une version cohérente unique quand un changement s'étend sur les deux :

posthog:llma-skill-update
{
  "skill_name": "my-skill",
  "edits": [{ "old": "## Configuration", "new": "## Setup" }],
  "file_edits": [
    { "path": "scripts/run.py", "edits": [{ "old": "DEBUG = False", "new": "DEBUG = True" }] }
  ],
  "base_version": 7
}

Ajouter, supprimer, renommer des fichiers

Chacun est son propre appel, chacun publie une nouvelle version :

posthog:llma-skill-file-create
{ "skill_name": "my-skill", "path": "scripts/julia.py", "content": "...", "base_version": 7 }
posthog:llma-skill-file-delete
{ "skill_name": "my-skill", "file_path": "scripts/old.py", "base_version": 8 }
posthog:llma-skill-file-rename
{ "skill_name": "my-skill", "old_path": "scripts/julia.py", "new_path": "scripts/julia_set.py", "base_version": 9 }

llma-skill-file-rename est un vrai déplacement — il reporte le contenu existant sans le renvoyer. Préférez-le toujours à la suppression + création quand le contenu est inchangé.

Quand utiliser update(files=[...]) (rare)

Passer files à llma-skill-update remplace l'ensemble du bundle — tout ce qui ne figure pas dans le tableau est supprimé. C'est le bon outil uniquement quand vous essuyez intentionnellement et resemez le bundle (par ex. importer un arbre SKILL.md local frais). Pour presque tous les autres cas, préférez file_edits plus CRUD par fichier.

Travailler avec les grandes skills multi-fichiers

Les skills avec de nombreux fichiers (10+) exigent une discipline supplémentaire :

  • Traitez le manifest comme l'index. Le files[] de llma-skill-get est votre carte. Faites correspondre chaque étape de tâche à un fichier et récupérez uniquement celui-ci.
  • Groupez les changements structurels en séquence, pas en fork. Si vous renommez trois fichiers, faites-le séquentiellement : rename → rename → rename, chacun chaîné via la version de la réponse précédente. Cela vous donne trois petites versions examinables au lieu d'un énorme blob update(files=[...]).
  • Gardez les édits localisés. Un seul llma-skill-update avec file_edits ciblant cinq fichiers c'est bien. Un seul update(files=[...]) portant dix corps de fichier complets est presque toujours un signe que vous auriez dû utiliser file_edits.
  • Refactorisez d'abord le body lui-même. Si le body a grandi au-delà d'~500 lignes, la prochaine étape appropriée est généralement de scinder le contenu en nouveaux fichiers bundlés avant d'ajouter plus de matériel.

Concurrence : base_version

Chaque outil d'écriture accepte base_version. Transmettez-le toujours.

  • Le serveur compare base_version à la version la plus récente actuelle. S'ils correspondent, l'écriture réussit et la nouvelle version est base_version + 1.
  • S'ils diffèrent, l'écriture est rejetée (quelqu'un d'autre a mis à jour la skill). Réexécutez llma-skill-get, réconciliez vos changements avec le nouveau body, et réessayez avec la version fraîche.
  • Après une écriture réussie, la réponse inclut la nouvelle version. Chaînez les autres édits avec celle-ci — ne faites pas de nouveau get entre des écritures dos-à-dos que vous contrôlez.

Ignorer base_version ne n'accélère pas les choses — cela transforme juste une erreur propre « quelqu'un d'autre a gagné la course » en une écrasement silencieux de son travail.

Pièges courants

  • Appeler llma-skill-list sans recherche puis récupérer tous les bodies — défait la divulgation progressive. Lisez d'abord les descriptions.
  • Pré-récupérer chaque fichier bundlé après llma-skill-get — même erreur au niveau interne. Récupérez à la demande selon les directives du body.
  • Utiliser update(body=..., files=[...]) pour une correction d'une ligne — fait un aller-retour de toute la skill, rend les diffs illisibles et risque de perdre des fichiers. Utilisez edits / file_edits.
  • Utiliser update(files=[...]) quand vous vouliez ajouter un fichier — supprime tous les fichiers que vous n'avez pas inclus. Utilisez llma-skill-file-create à la place.
  • Supprimer + créer au lieu de renommer — perd l'historique du contenu et coûte un bump de version supplémentaire.
  • base_version obsolète après les écritures chaînées — lisez la version de la réponse de l'écriture précédente, pas de votre get initial.
  • Laisser base_version de côté — accepte un écrasement silencieux. Incluez-le toujours une fois que vous avez fait un get.
  • Description vide / vague — la skill devient effectivement non-découvrable via la recherche llma-skill-list. Traitez la description comme le contrat de déclencheur.
  • Long body + aucun fichier bundlé — quand un body dépasse ~500 lignes, refactorisez en references/ et scripts/ plutôt que de laisser croître.
  • Mélanger body et edits en un seul appel update — ils s'excluent mutuellement. Choisissez-en un.

Porter un arbre SKILL.md local dans PostHog

En migrant un dossier de skill local (par ex. my-skill/SKILL.md plus scripts/, references/, assets/) :

  1. Lisez le SKILL.md local. Son frontmatter mappe vers name, description, license, compatibility, allowed_tools, metadata. Le body après le frontmatter devient body.
  2. Parcourez les sous-répertoires bundlés et rassemblez chaque fichier en tant que { path, content, content_type }.
  3. Appelez posthog:llma-skill-create une fois avec tout — la skill atterrit à version: 1 complète. Ne divisez pas cela en un appel create + N file-create.

Après la création, la skill est en direct pour tout le monde via llma-skill-get.

Quand une skill est la mauvaise réponse

Pas tous les prompts persistants appartiennent au skills store :

  • Les instructions de tâche ponctuelles appartiennent à la conversation, pas à une skill.
  • Les brouillons personnels appartiennent à la mémoire de l'agent ou aux fichiers locaux.
  • Le code n'est pas une skill — si c'est quelque chose qu'un service exécute, cela appartient au repo.

Une bonne skill est réutilisable, découvrable par description, et vaut le coût de la maintenir correcte au fil du temps.

Skills similaires