Skill Mini Graphe de Contexte
L'Idée Centrale
Le RAG standard redécouvre les connaissances à partir de zéro à chaque requête. Ce skill est différent :
- Couche wiki — L'LLM écrit et maintient des pages markdown persistantes (résumés, pages d'entités, synthèses thématiques). Les renvois croisés sont déjà présents. Le wiki s'enrichit à chaque ingestion.
- Couche graphe — Les entités et relations sont extraites une fois et stockées comme un graphe de connaissances navigable. La traversée BFS répond aux requêtes structurelles sans relire les sources.
- Couche source brute — Les documents originaux sont stockés immuablement avec des chunks. Les liens de provenance relient chaque nœud et arête du graphe au texte exact qui les justifie.
L'LLM écrit ; les outils Python gèrent toute la comptabilité.
Trois Couches
| Couche | Où | Ce que fait l'LLM | Ce que fait Python |
|---|---|---|---|
| Sources Brutes | data/documents.json |
Lit (ne modifie jamais) | Stocke les chunks + métadonnées |
| Wiki | wiki/ (markdown) |
Écrit/met à jour les pages | Gère index.md + log.md |
| Graphe | data/graph.json |
Extrait entités + relations | Persiste, déduplique, traverse |
⚡ Démarrage Rapide pour les Agents
from scripts.contextgraph import ContextGraphSkill
from scripts.tools import wiki_store
skill = ContextGraphSkill()
# ===== INGESTION AVEC RAG COMPLET + WIKI =====
# 1. Lisez d'abord references/ingestion.md et references/ontology.md
# 2. Extrayez entités et relations (étape de raisonnement LLM)
entities = [
{"name": "memory leak", "type": "issue", "supporting_text": "memory leaks cause crashes"},
{"name": "system crash", "type": "issue", "supporting_text": "system crashes due to memory leaks"},
]
relations = [
{"source": "memory leak", "target": "system crash", "type": "causes",
"confidence": 1.0, "supporting_text": "System crashes due to memory leaks."},
]
result = skill.ingest_with_content(
doc_id="doc_001",
title="System Crash Analysis",
source="/docs/incident_report.pdf",
raw_content="System crashes due to memory leaks. Memory leaks occur when objects are not released.",
entities=entities,
relations=relations,
)
# result = {"doc_id": "doc_001", "chunk_count": 1, "nodes_added": 2, "edges_added": 1}
# 3. Écrivez une page de résumé wiki pour ce document
wiki_store.write_page(
category="summary",
title="System Crash Analysis Summary",
content="""---
title: System Crash Analysis
source_document: doc_001
tags: [summary, incident]
---
# System Crash Analysis
**Source:** incident_report.pdf
## Key Claims
- [[memory-leak]] causes [[system-crash]] (confidence: 1.0)
## Entities
- [[memory-leak]] (issue)
- [[system-crash]] (issue)
""",
summary="Incident report: memory leaks cause system crashes.",
)
# ===== REQUÊTE AVEC PREUVES =====
result = skill.query_with_evidence("Why does the system crash?")
# Returns: {"query": ..., "subgraph": ..., "supporting_documents": [...], "evidence_chain": ...}
# ===== RECHERCHE WIKI (lire le wiki avant de répondre) =====
pages = wiki_store.search_wiki("memory leak")
# Returns: [{slug, category, path, snippet}, ...]
Opérations
Ingestion
Quand un utilisateur fournit un nouveau document :
- Lisez
references/ingestion.md— règles d'extraction d'entités/relations. - Lisez
references/ontology.md— règles de normalisation des types. - Extrayez les entités et relations via votre raisonnement LLM.
- Appelez
skill.ingest_with_content(...)— stocke le contenu brut + chunks + nœuds de graphe + provenance. - Écrivez une page de résumé wiki avec
wiki_store.write_page(category="summary", ...). - Mettez à jour les pages d'entités — pour chaque entité nouvelle/mise à jour, écrivez ou mettez à jour
wiki_store.write_page(category="entity", ...). - Mettez à jour les pages thématiques si le document touche un sujet de synthèse existant.
- Une ingestion de document unique touchera généralement 3–10 pages wiki.
Requête
Quand un utilisateur pose une question :
- Vérifiez d'abord le wiki —
wiki_store.search_wiki(query)pour trouver les pages pertinentes. Lisez-les. - Si le wiki a une bonne réponse, synthétisez à partir des pages wiki (chemin rapide).
- Si une traversée de graphe plus profonde est nécessaire, appelez
skill.query_with_evidence(query). - Retournez la réponse avec des citations de preuves provenant de
supporting_documents. - Si la réponse est précieuse, renvoyez-la comme une nouvelle page de sujet wiki.
Lint
Vérifiez périodiquement la santé du wiki :
from scripts.tools import wiki_store
issues = wiki_store.lint_wiki()
# Returns: {orphan_pages, missing_pages, broken_wikilinks, isolated_pages}
Demandez à l'LLM d'examiner et corriger : liens cassés, pages orphelines, affirmations obsolètes, renvois croisés manquants. Voir references/lint.md pour le workflow lint complet.
Contraintes d'Ingestion
- ❌ Ne HALLUCINEZ PAS d'entités absentes du texte
- ❌ N'AJOUTEZ PAS de relations sans preuve textuelle explicite
- ❌ N'AJOUTEZ PAS d'arêtes avec confiance < 0,6
- ✅ Fournissez
supporting_textpour chaque entité et relation — cela active la provenance - ✅ Écrivez une page de résumé wiki pour chaque document ingéré
- ✅ Mettez à jour les pages d'entités existantes quand de nouvelles infos arrivent
- ✅ Signalez les contradictions dans les pages wiki quand les nouvelles données contredisent les anciennes affirmations
Contraintes de Récupération
- 🔒 La profondeur de traversée NE DOIT PAS dépasser 2 (config: MAX_GRAPH_DEPTH)
- 🔒 Uniquement les arêtes avec confiance ≥ 0,6 (config: MIN_CONFIDENCE)
- 🔒 Maximum 50 nœuds retournés (config: MAX_NODES)
- ❌ Ne FABRIQUEZ PAS de nœuds ou arêtes absents du graphe
Référence API Python Complète
| Méthode | Objectif | Quand l'Utiliser |
|---|---|---|
skill.ingest_with_content(doc_id, title, source, raw_content, entities, relations) |
Ingestion RAG complète : docs bruts + graphe + provenance | Chaque nouveau document |
skill.add_node(name, node_type) |
Ajouter une entité unique (pas de provenance) | Ajouts rapides sans document source |
skill.add_edge(source_name, target_name, relation, confidence) |
Ajouter une relation unique | Ajouts rapides sans document source |
skill.query(query) |
Récupération graphe uniquement → sous-graphe | Requêtes structurelles |
skill.query_with_evidence(query) |
Graphe + provenance → sous-graphe + chunks source | Requêtes nécessitant des citations |
wiki_store.write_page(category, title, content, summary) |
Écrire/mettre à jour une page wiki | Après chaque ingestion ; après répondre aux requêtes |
wiki_store.read_page(category, title) |
Lire une page wiki | Avant de répondre ; pour les renvois croisés |
wiki_store.search_wiki(query) |
Recherche par mots-clés dans le wiki | Chemin rapide avant traversée de graphe |
wiki_store.list_pages(category) |
Lister toutes les pages wiki | Obtenir une vue d'ensemble |
wiki_store.get_log(last_n) |
Lire les opérations récentes | Comprendre l'historique du wiki |
wiki_store.lint_wiki() |
Vérification santé | Maintenance périodique |
documents_store.list_documents() |
Lister toutes les sources brutes ingérées | Audit / vérification de provenance |
documents_store.search_chunks(query) |
Recherche au niveau des chunks | Trouver des preuves spécifiques |
Philosophie de Conception
« Le wiki est un artefact persistant et composé. Les renvois croisés sont déjà là. La synthèse reflète déjà tout ce que vous avez lu. » — Karpathy
| Couche | Ce qui se Passe | Qui en est Responsable |
|---|---|---|
| Raisonnement LLM | Extraction, synthèse, écriture des pages wiki | Agent (fichiers de guidance .md) |
| Persistance Wiki | Index, log, I/O fichier | wiki_store.py |
| Persistance Graphe | Dédup, index, traversée BFS | graph_store.py, retrieval_engine.py |
| Stockage Source Brut | Docs immuables + chunks + provenance | documents_store.py |
L'humain curate les sources et pose les questions. L'LLM écrit le wiki, extrait le graphe, et répond avec des citations. Python gère toute la comptabilité.