Le RAG hybride excelle à retrouver des passages pertinents. Mais posez-lui une question relationnelle — « quels clients touchés par l’incident X ont une commande sous garantie ? » — et il échoue : la réponse n’est dans aucun passage unique. Elle se construit en suivant des relations à travers plusieurs documents. C’est l’angle mort de la récupération par similarité.

Le GraphRAG y répond en récupérant non par ressemblance mais par traversée d’un graphe de connaissances. Sur AWS, ce graphe vit dans Amazon Neptune.

Fig.01 · Récupération par traversal
Client Cmd Produit Garantie Facture Incident entité de départ contexte connecté
À partir d'une entité de départ, on suit les relations du graphe (multi-sauts) pour rassembler un contexte connecté — ce qu'aucune recherche par similarité ne capture.

Un graphe de connaissances, c’est quoi

Un graphe de connaissances modélise le domaine en entités (nœuds : Client, Commande, Produit, Incident…) reliées par des relations typées (A_COMMANDÉ, CONCERNE, COUVERT_PAR). Là où un index vectoriel ne connaît que des points proches dans un espace, le graphe connaît des chemins — et c’est en les parcourant qu’on répond aux questions relationnelles.

Étape 1 — Construire le graphe (extraction)

On extrait entités et relations des documents avec un LLM, en sortie structurée — un travail d’ingestion, à faire une fois (et à maintenir).

from pydantic import BaseModel, Field
from langchain_aws import ChatBedrockConverse

class Triplet(BaseModel):
    sujet: str = Field(description="Entité source")
    relation: str = Field(description="Type de relation, en MAJUSCULES")
    objet: str = Field(description="Entité cible")

class Extraction(BaseModel):
    triplets: list[Triplet]

modele = ChatBedrockConverse(model="eu.anthropic.claude-sonnet-4-5-20250929-v1:0",
                             region_name="eu-west-1")

def extraire(document: str) -> list[Triplet]:
    """Extrait les (entité, relation, entité) d'un document."""
    res = modele.with_structured_output(Extraction).invoke(
        f"Extrais les entités et leurs relations de ce texte sous forme de triplets "
        f"(sujet, RELATION, objet) :\n{document}"
    )
    return res.triplets

Étape 2 — Charger dans Neptune

Amazon Neptune est la base de graphes managée d’AWS. Deux saveurs : Neptune Database (transactionnel, requêtes openCypher/Gremlin/SPARQL) et Neptune Analytics (analyse de graphes en mémoire, algorithmes, et index vectoriel intégré — utile pour l’hybride graphe + vecteur). On insère les triplets via openCypher.

def charger(graphe, triplets: list[Triplet]):
    for t in triplets:
        graphe.query(
            "MERGE (s:Entite {nom: $sujet}) "
            "MERGE (o:Entite {nom: $objet}) "
            "MERGE (s)-[r:REL {type: $relation}]->(o)",
            params={"sujet": t.sujet, "objet": t.objet, "relation": t.relation},
        )

Étape 3 — Récupérer par traversal

Deux stratégies de récupération GraphRAG, complémentaires :

  • Locale — on identifie l’entité de départ dans la question, puis on traverse ses voisins sur quelques sauts pour bâtir le contexte. Idéal pour les questions pointues sur une entité.
  • Globale — on pré-calcule des résumés de communautés (clusters d’entités très liées) ; une question globale interroge ces résumés. Idéal pour les questions de synthèse sur tout le corpus.

Pour la récupération locale, on génère la requête de graphe à partir de la question. LangChain fournit des chaînes question→openCypher pour Neptune ; on peut aussi l’exposer plus simplement.

def recuperer_graphe(graphe, entite: str, sauts: int = 2) -> str:
    """Traverse le voisinage d'une entité et renvoie les relations trouvées."""
    chemins = graphe.query(
        f"MATCH p = (s:Entite {{nom: $entite}})-[*1..{sauts}]-(v) "
        "RETURN p LIMIT 50", params={"entite": entite},
    )
    return formater_chemins(chemins)        # « Client -A_COMMANDÉ-> Cmd -CONCERNE-> Produit »

Étape 4 — Brancher à un agent LangGraph

On expose la récupération par graphe comme un outil, aux côtés (souvent) du RAG hybride : l’agent choisit la bonne arme selon la question.

from langchain_core.tools import tool
from langgraph.prebuilt import create_react_agent

@tool
def interroger_graphe(question: str) -> str:
    """Récupère par TRAVERSÉE du graphe de connaissances. À utiliser pour les
    questions relationnelles ou multi-sauts (qui, lié à quoi, via quoi)."""
    entite = identifier_entite(question)          # extraction de l'entité de départ
    return recuperer_graphe(graphe, entite)

@tool
def base_vectorielle(requete: str) -> str:
    """Recherche hybride (sémantique + mots-clés). Pour les questions factuelles."""
    ...

agent = create_react_agent(modele, [interroger_graphe, base_vectorielle])

Le coût de la richesse

Le GraphRAG est puissant mais exigeant : il faut construire et maintenir le graphe (l’extraction se rejoue quand les données changent), opérer Neptune, et la récupération est plus complexe à régler. Ne l’introduisez que si vos questions le justifient — et mesurez le gain, comme toujours, sur un dataset d’évaluation.

Bonnes pratiques & pièges

Bonnes pratiques
  • Réservez le GraphRAG aux questions multi-sauts, relationnelles ou globales.
  • Définissez une ontologie légère (entités/relations attendues) avant d'extraire.
  • Donnez à l'agent les DEUX outils — graphe et vectoriel — et laissez-le choisir.
  • Neptune Analytics pour combiner traversée et index vectoriel (hybride graphe+vecteur).
  • Pré-calculez des résumés de communautés pour les questions globales.
  • Mesurez le gain du GraphRAG sur un dataset : il a un coût, il doit le justifier.
Pièges à éviter
  • Dégainer le GraphRAG pour des questions factuelles locales : le hybride suffit, en plus simple.
  • Extraire sans schéma : un graphe incohérent est intraversable.
  • Oublier la maintenance : un graphe figé diverge des données qui évoluent.
  • Sous-estimer l'exploitation de Neptune et le réglage de la traversée.
  • Opposer graphe et vectoriel au lieu de les combiner.

Ce qu’il faut retenir

  • Le GraphRAG récupère par traversée de relations, pas par similarité — il répond aux questions multi-sauts et relationnelles.
  • On extrait un graphe de connaissances (entités + relations) qu’on héberge sur Amazon Neptune (Database ou Analytics).
  • Récupération locale (voisinage d’une entité) et globale (résumés de communautés) sont complémentaires.
  • On l’expose comme outil d’un agent LangGraph, aux côtés du RAG hybride — l’agent choisit.
  • Puissant mais coûteux à construire et maintenir : à justifier par les questions et à mesurer.

Vous avez maintenant tout l’arsenal de récupération AWS — hybride, managé, par graphe. Assemblons-le dans un système complet : le cas pratique 100 % AWS.

#aws#graphrag#neptune#knowledge-graph#rag