Communitygithub.com

vima-tech/Innate

Couche de connaissance procédurale auto-croissante pour les agents IA. Serveur MCP Rust + CLI — rappel des connaissances pertinentes avant les tâches, enregistrement des résultats après, distillation de l'expérience en informations réutilisables. Fonctionne avec Claude Code, Codex, opencode.

Qu'est-ce que Innate ?

Innate est une couche de connaissance procédurale auxiliaire pour les agents IA, conçue pour améliorer la qualité et la pertinence des décisions prises par l'agent. Elle fonctionne comme un serveur MCP (Model Context Protocol) en Rust, avec une interface en ligne de commande. Son principal rôle est de rappeler, au début d'une tâche, les connaissances pertinentes acquises lors de sessions précédentes, et d'enregistrer, après la tâche, les leçons apprises sous forme de résumés structurés et généralisables. L'agent doit suivre un protocole strict pour la formulation des requêtes (utilisation d'une 'intention canonique'), l'enregistrement des résultats (avec verdict par chunk et résumé structuré), et la sauvegarde des insights. La plateforme utilise un système de feedback pour faire remonter les bonnes connaissances (chunks 'used+helped') et archiver les mauvaises (chunks 'used+misled'). Il est principalement utilisé avec Claude Code, Codex et opencode, mais l'architecture MCP le rend potentiellement compatible avec d'autres clients. L'accent est mis sur la généralisation des leçons apprises pour les rendre utiles dans d'autres projets, en évitant les détails spécifiques à un projet ou un fichier.

Compatible avec✓Claude Code✓Codex CLI~Cursor✓OpenCode
npx skills add vima-tech/Innate

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Rôle de la couche

Innate est auxiliaire — elle ne doit jamais bloquer la tâche principale. Toutes les opérations d'Innate sont au mieux. En cas d'erreur d'outil : réessayez une fois avec un appel corrigé, puis abandonnez et continuez.

Quand rappeler

Rappelez au début d'une tâche uniquement si la tâche :

  • Est dans un domaine avec des motifs récurrents connus (par exemple, une base de code, un framework ou un protocole spécifique)
  • Consiste à déboguer ou corriger quelque chose qui a peut-être déjà été rencontré
  • Est architecturale / conception — les décisions antérieures sont importantes

Ne pas rappeler pour : les requêtes rapides, les questions avec des réponses claires, les tâches que l'utilisateur a définies comme un territoire entièrement nouveau sans contexte préalable.

Formulation de la requête

Utilisez l'intention canonique, pas les mots littéraux de l'utilisateur. Gardez les requêtes cohérentes entre les sessions — la même classe de problème doit toujours utiliser la même forme canonique, car Innate accumule des statistiques de contexte par motif de requête.

L'utilisateur ditBonne requêteMauvaise requête
"pourquoi ça plante au démarrage ?"plantage démarrage sqlite initpourquoi ça plante au démarrage
"refactorise le flux d'auth"flux auth gestion jeton sessionrefactorise flux auth
"ajoute une limitation de débit à l'API"motif middleware limitation débitajoute limitation débit
"débogue le test instable"test instable condition course timingdébogue test instable

Appelez : innate_recall(query=<intention_canonique>, budget=4000, source="mcp")

Injectez les extraits rappelés dans votre contexte de travail. Mentionnez à l'utilisateur (une phrase suffit) si des connaissances antérieures pertinentes ont été trouvées.

Accroche de rappel automatique

Quand Innate est installé avec des hooks, un hook UserPromptSubmit peut automatiquement injecter un bloc <innate-recall> dans la conversation — il a déjà exécuté un rappel filtré par pertinence pour l'invite et porte un trace_id. Lorsque vous voyez ce bloc :

  • Réutilisez son trace_id pour l'appel final innate_record — n'appelez pas innate_recall à nouveau pour la même tâche (cela créerait une trace dupliquée et orpheline).
  • Traitez ses extraits exactement comme ceux que vous auriez rappelés vous-même : appliquez ce qui aide, puis concluez avec un verdict par extrait (voir ci-dessous).
  • Si le bloc est absent et que la tâche le justifie, rappelez manuellement comme ci-dessus.

Le hook est filtré par pertinence, donc son silence signifie "rien n'a atteint le seuil de pertinence" — pas "aucune connaissance n'existe". Rappelez manuellement si vous soupçonnez une connaissance antérieure pertinente que le filtre a manquée.

Quand enregistrer

Enregistrez après une tâche qui a produit un résultat réel (succès ou échec). Ne pas enregistrer pour :

  • Des allers-retours exploratoires sans résultat définitif
  • Des tâches où l'utilisateur a interrompu avant l'achèvement
  • De la simple récupération d'information (l'utilisateur a seulement posé une question, rien n'a été construit ou modifié)

Règles de résultat

Situationrésultat
Tâche terminée, utilisateur a confirmé ou accepté le résultatok
Tâche échouée, approche erronée, utilisateur a dû corriger le capfail
Session interrompue, résultat incertainunknown

Verdict par extrait — Obligatoire

C'est le contrat le plus important d'Innate : le classement par confiance n'est aussi bon que la précision de ce que vous rapportez ici. Chaque rappel qui a fait remonter des extraits (manuel ou injecté par hook) doit être conclu par un verdict par extrait. Pour chaque extrait qui vous a été présenté, il tombe dans exactement un des trois seaux :

VerdictCe que ça signifieOù ça va
Utilisé + A aidéVous l'avez appliqué et cela a fait gagner du temps / évité une erreurused=[id] et feedback_up=[id]
Utilisé + A induit en erreurVous l'avez appliqué mais c'était faux ou vous a envoyé sur la mauvaise voieused=[id] et feedback_down=[id]
Non utiliséRappelé mais vous ne l'avez jamais appliquéOmettre entièrement (ne pas lister dans used)

Règles pour garder le signal propre :

  • used liste uniquement les extraits que vous avez activement référencés dans votre raisonnement ou votre sortie — généralement un à trois. Ne le gonflez jamais avec des extraits simplement rappelés.
  • Si vous n'avez appliqué rien, c'est un signal réel et précieux : définissez used=[] explicitement (connu comme aucun). Ne sautez pas l'enregistrement — le silence n'est pas la même chose que "rien n'a aidé".
  • Un extrait que vous avez utilisé devrait presque toujours aussi porter un signal positif ou négatif. Un extrait utilisé sans verdict gaspille la plus forte entrée de classement que vous puissiez donner.
  • Soyez honnête à propos de feedback_down. Un extrait erroné que vous marquez négativement sera révisé et archivé ; un extrait erroné que vous laissez non marqué continuera d'induire en erreur les sessions futures.

Résumé de sortie — Format structuré

Rédigez une phrase autonome qu'un agent futur peut utiliser à froid. Utilisez cette structure :

<ce qui a été fait ou appris> — <contrainte ou méthode clé> — <quand cela s'applique>

Exemples positifs :

  • Corrigé la détection du mode WAL SQLite en vérifiant la réponse PRAGMA journal_mode plutôt qu'en supposant WAL — se déclenche sur toute nouvelle connexion db dans des configurations multi-processus
  • Résolu le test d'auth instable en injectant un mock d'horloge — le temps système réel crée une condition de course dans la vérification d'expiration du jeton
  • La limitation de débit doit être appliquée avant le middleware d'auth, pas après — sinon les requêtes non authentifiées contournent le limiteur

Exemples négatifs (trop vagues pour être réutilisés) :

  • Corrigé le bogue
  • J'ai aidé l'utilisateur avec l'auth
  • Le problème était le timing

L'output_summary devient l'extrait de connaissance réutilisable. S'il se lit comme une histoire, réécrivez-le comme un principe. Privilégiez la forme générale et transférable — supprimez les noms de dépôt/fichier/fonction et les identifiants uniques, et reformulez la leçon pour qu'elle aide aussi sur le prochain projet ; conservez les détails spécifiques au projet uniquement lorsque la leçon ne peut pas être généralisée sans perdre son sens. Si vous ne pouvez pas rédiger un résumé utile, définissez output="unknown" et ne procédez pas à l'enregistrement.

Appelez : innate_record(trace_id=<id>, outcome=<ok|fail|unknown>, used=[<chunk_ids>], output_summary=<phrase>)

Feedback explicite — Pourquoi c'est important

Les listes feedback_up / feedback_down du tableau de verdict ci-dessus sont le signal le plus rapide pour la qualité des connaissances, et elles pilotent directement le classement et le cycle de vie : deux signaux négatifs sur le même extrait déclenchent une révision de gouvernance ; cinq déclenchent un archivage automatique. À l'inverse, une répétition used + feedback_up est ce qui promeut un extrait pending à active. Retenir le feedback fige la base de connaissances ; le donner est la façon dont les bonnes connaissances montent et les mauvaises tombent.

Nomination — Rare, Explicite

Utilisez le champ nomination uniquement pour des leçons vraiment généralisables — des motifs qui feront gagner beaucoup de temps la prochaine fois que ce type de problème apparaîtra. Rare. Pas pour chaque tâche.

Format pour la nomination (principe autonome) :

<principe> — <quand cela s'applique> — <ce qu'il faut éviter>

Exemple :

innate_record(..., nomination="L'index UNIQUE SQLite sur une clause WHERE partielle nécessite une correspondance WHERE exacte dans ON CONFLICT — s'applique à tous les motifs upsert ; un ON CONFLICT nu sans WHERE sautera silencieusement l'upsert")

Référence des outils MCP

OutilUtilisationNotes
innate_recallDébut de tâche (quand pertinent)Utiliser la forme de requête canonique — le phrasé cohérent accumule des statistiques de contexte
innate_recordFin de tâche (quand un résultat réel existe)output_summary structuré + IDs utilisés précis
innate_addCapturer un insight confirméToujours source="mcp" ; va en pending, attend révision
innate_sparkIdée rapide pour plus tardForme brève distillée ; aucune révision nécessaire
innate_evolveFin de sessiontrigger="manual" ; distille les logs + conserve la base de connaissances
innate_inspectVérification d'étatcomptes d'extraits, ratio de dette, file d'attente de reconstruction
innate_appraiseVérification intuitive avant une étape risquéeSignal de référence uniquement — intuition, PAS une réponse précise. Considérez-le comme une entrée ; ne le laissez jamais supplanter votre propre analyse. abstained=true signifie aucun point d'appui — c'est correct, pas un échec

Ne jamais appeler sans demande explicite de l'utilisateur : innate_approve, innate_archive, innate_invalidate, innate_restore, innate_mature_spark, innate_promote_spark, innate_drop_spark.

Décision de réécriture

Avant de terminer une longue session, parcourez silencieusement cette liste de contrôle :

  1. Une solution non évidente a-t-elle été trouvée ? (solution de contournement, contrainte cachée, motif de bogue subtil)
  2. Une compétence, méthode ou technique générale et transférable a-t-elle été dégagée ? (privilégiez celles-ci — abstraire les leçons spécifiques au projet en forme réutilisable ; ne conservez une règle spécifique au projet que lorsqu'elle ne peut vraiment pas être généralisée)
  3. L'utilisateur a-t-il corrigé une hypothèse erronée que je risquais de répéter ?
  4. Un insight durement gagné a-t-il été atteint après plusieurs tentatives infructueuses ?
  5. Un extrait rappelé a-t-il activement aidé ? (enregistrer feedback_up)
  6. Un extrait rappelé a-t-il induit en erreur ? (enregistrer feedback_down)

Si l'un des 1 à 4 → proposez à l'utilisateur :

"Cette session a mis en lumière [description en une ligne]. Voulez-vous que je l'enregistre dans Innate ?"

N'appelez innate_spark ou innate_add qu'après confirmation de l'utilisateur. N'écrivez jamais en silence.

Règle anti-verbatim

Le texte brut de la conversation ne doit jamais être stocké. Distillez-le toujours dans la forme de principe réutilisable :

<principe> — <contexte déclencheur> — <ce qu'il faut éviter>

❌ Verbatim✅ Distillé
"L'utilisateur m'a dit d'utiliser le mode WAL et je l'ai corrigé en changeant le pragma""Le mode WAL SQLite doit être vérifié via la réponse PRAGMA, pas supposé — se déclenche sur toute ouverture de db dans des configurations multi-processus à forte écriture"
"Nous avons passé 2 heures à déboguer l'auth à cause du décalage d'horloge""La validation JWT doit prendre en compte la tolérance de décalage d'horloge (≥30s) — se déclenche sur l'auth distribuée entre services avec des horloges système indépendantes"

Privilégier le général au spécifique au projet

Innate est biaisée vers les compétences, méthodes et techniques générales et transférables — des connaissances qui portent leurs fruits sur plusieurs projets, pas seulement sur la base de code actuelle. Lorsqu'une leçon est spécifique au projet :

  1. Essayez de l'abstraire — supprimez les noms de dépôt/fichier/fonction/chemin et les identifiants uniques, et reformulez-la comme un principe que le prochain projet pourrait réutiliser.
  2. Enregistrez la forme abstraite. Ne conservez les détails concrets spécifiques au projet que lorsque la leçon ne peut vraiment pas être généralisée sans perdre son sens.
❌ Lié au projet✅ Généralisé
"Dans ce dépôt, record() doit s'exécuter à l'intérieur de BEGIN IMMEDIATE""Les mutations d'état en plusieurs étapes qui doivent être atomiques appartiennent à une seule transaction exclusive, pas à des commits par étape — s'applique à tout writer SQLite avec des processus concurrents"
"Définissez recall.budget=4000 dans la table meta""Exposez le budget de récupération comme un paramètre ajustable au lieu de le coder en dur — permet au rappel de s'adapter à la fenêtre de contexte sans modifications de code"

Sparks vs. Notes

Utilisez innate_sparkUtilisez innate_add
Idée rapide, intuition à moitié forméePrincipe réutilisable confirmé
Pas encore validéeValidé dans cette session
L'utilisateur dit "note ceci pour plus tard"L'utilisateur dit "souviens-toi de cette règle"

Solution de secours CLI (si MCP non configuré)

# Rappel
innate recall "<intention_canonique>" --top 5 --format json --source cli

# Enregistrement avec résumé structuré
innate record <trace_id> --outcome ok \
  --used <id1>,<id2> \
  --output-summary "Corrigé X en faisant Y — s'applique quand Z" \
  --feedback up  # ou down

# Capturer un insight
innate add "<principe> — <déclencheur> — <ce qu'il faut éviter>" \
  --trigger "<contexte de 2 à 5 mots>" \
  --source agent

# Spark rapide
innate spark "<idée distillée en 1-2 phrases>"

# Fin de session
innate evolve --trigger manual
innate inspect

Commandes

Les commandes slash ci-dessous sont automatiquement installées dans ~/.claude/commands/ par innate install et mises à jour à chaque ré-exécution de innate install. Chaque bloc command définit une commande : métadonnées avant ---, corps (l'invite de l'agent) après ---.

name: innate-recall
description: Rappeler les connaissances innées antérieures pour le contexte de la tâche en cours
---
Exécutez innate_recall pour le contexte de la tâche en cours et injectez le résultat dans cette conversation.

Si l'utilisateur a fourni une requête après la commande, utilisez-la exactement comme requête de rappel.
Si aucune requête n'est fournie ($ARGUMENTS est vide), déduisez la requête du message utilisateur le plus récent
ou de l'intention de la tâche en cours — utilisez **l'intention canonique** (par exemple `sqlite wal mode init`,
pas `pourquoi ça plante`). Gardez la forme de la requête cohérente avec la façon dont vous formuleriez la même classe
de problème à l'avenir.

Étapes :
1. Formulez la chaîne de requête canonique (à partir de $ARGUMENTS ou de l'intention déduite).
2. Appelez `innate_recall` avec `query=<requête>`, `budget=4000`, `source="mcp"`.
3. Si la connaissance est renvoyée : résumez en une phrase ce qui a été trouvé, puis injectez les
   extraits pertinents dans le contexte.
4. Si vide : dites "Aucune connaissance antérieure trouvée pour : <requête>" — n'inventez pas.
5. Sauvegardez le `trace_id` pour une utilisation ultérieure dans `/innate-record`.
name: innate-record
description: Fermer la trace innée actuelle avec un résultat et un résumé structuré
---
Fermez la trace innée actuelle avec un résultat et un résumé.

Analysez $ARGUMENTS pour :
- outcome : un de `ok`, `fail`, `unknown` (par défaut : `ok` si non spécifié)
- Tout texte restant devient l'output_summary de remplacement

Étapes :
1. Identifiez le trace_id actif de l'appel le plus récent de `innate_recall` de cette session.
   Si aucun trace_id n'est disponible, dites "Aucune trace active — exécutez d'abord /innate-recall."
2. Déterminez quels IDs d'extraits rappelés ont été **réellement utilisés** dans la réponse finale (pas
   seulement les candidats rappelés). Soyez précis — les extraits rappelés non utilisés ne doivent PAS être listés.
3. Rédigez un output_summary structuré pour un agent futur lisant à froid :
   Format : `<ce qui a été fait> — <contrainte/méthode clé> — <quand cela s'applique>`
   Si l'utilisateur a fourni un texte de résumé dans $ARGUMENTS, utilisez-le.
4. Évaluez le feedback :
   - Si un extrait a été directement utile → incluez `feedback_up=[chunk_id]`
   - Si un extrait était erroné/induisant en erreur → incluez `feedback_down=[chunk_id]`
5. Appelez `innate_record` avec `trace_id`, `outcome`, `used=[<chunk_ids>]`, `output_summary`, et le feedback si applicable.
6. Confirmez : "Trace <trace_id> enregistrée comme <outcome>."
name: innate-save
description: Sauvegarder un insight confirmé dans Innate comme un extrait de connaissance en attente
---
Sauvegardez un insight confirmé dans Innate comme un extrait de connaissance en attente.

$ARGUMENTS est le texte de l'insight à sauvegarder (requis). Si vide, demandez : "Quel insight
souhaitez-vous sauvegarder ?"

Étapes :
1. Analysez $ARGUMENTS comme le contenu de l'insight.
2. Di...

[...tronqué pour la traduction]

Skills associés