Conception de graphes d’agents IA résilients : tentatives répétées, solutions de secours et GraphRAG
Apprenez à créer des workflows d’agents IA résistants aux pannes en utilisant des branches de défaillance explicites, une logique de tentative répétée, LangGraph, ainsi que les cas où GraphRAG surpasse le RAG classique ou les boucles d’agent.
Lorsque des pannes surviennent : planifier des itinéraires alternatifs
Prenant là où la discussion précédente s’était arrêtée, imaginez que l’agent de recherche financière soit à présent nettement plus sophistiqué.
Rappelons la question type qu’un gérant de portefeuille pourrait poser, du genre pourquoi une action particulière a chuté après sa publication de résultats financiers, et quels risques méritent d’être surveillés à l’avenir. Le système est capable d’analyser ce type de question, de récupérer des données provenant de multiples sources, d’effectuer des analyses sur les résultats, de rédiger une réponse, de la vérifier, et de la transmettre à un évaluateur humain si nécessaire — en somme, un schéma de collaboration homme-machine.
Cependant, il y a un aspect que nous n’avons pas encore abordé : que se passe-t-il lorsque l’une des étapes de ce processus échoue ?
Imaginez que le système atteigne la branche responsable des données de marché.
Il envoie une demande concernant les variations de prix et le volume des transactions, mais le fournisseur de données ne répond pas.
Dans ce cas, il n’est pas possible de passer directement à l’étape Analyser comme si de rien n’était.
En même temps, arrêter complètement l’exécution est généralement une mesure trop extrême, car les systèmes de niveau production nécessitent une forme de comportement de secours.
C’est précisément pourquoi l’échec doit être traité comme une branche à part entière au sein du diagramme, et non comme une considération ultérieure.
Le flux initial et simple ressemble à ceci :
Search Market Data
↓
Analyze
Nous pouvons plutôt le restructurer de cette manière :
Search Market Data
/ \
↓ ↓
Success Failure
↓ ↓
Analyze Retry (how to handle this!?)
Avec cette structure, le diagramme indique clairement quoi faire en cas d’échec d’une demande.
Gestion de la logique de tentative
Si la tentative réussit, le flux de travail reprend normalement.
Cependant, si cela échoue à nouveau, il pourrait être plus judicieux de passer à une autre source de données ou d’escalader la demande à un examen humain plutôt que de répéter indéfiniment la même requête.
Voici une version plus détaillée de cette logique de branchement :
Search Market Data
/ \
↓ ↓
Success Failure
↓ ↓
Analyze Retry
↓
┌──────┴──────┐
↓ ↓
Success Failure
↓ ↓
Analyze Alternative
Source
Ce qui importe ici n’est pas le nombre de tentatives autorisées — c’est le fait que la gestion des échecs est intégrée dès la conception du graphe. Comme le montre le diagramme, différents types d’échecs peuvent mener à des chemins distincts.
Supposons que l’API de données boursières simple se time out. Réessayer est raisonnable, car le problème est probablement temporaire.
Mais supposons que la requête soit traitée correctement sans retourner d’informations utiles pour la période concernée. Répéter exactement cette même requête ne servira à rien.
Dans ce cas, il vaut mieux interroger une source de données alternative et approuvée.
Et si cela reste sans résultat, il est probablement judicieux de faire monter l’affaire à un éditeur humain. Ce sont ce genre de détails qui distinguent un flux de travail fragile d’un flux de travail fiable.
La fonction de routage qui gère cela pourrait ressembler à ceci :
def route_after_market_search(state):
if state["market_data"]:
return "analyze"
if state["retry_count"] < 2:
return "retry"
return "human_review"
Ces conditions définissent clairement les limites du graphe : il est possible de réessayer, mais pas indéfiniment.
Le même principe s’applique au reste du graphe, car de nombreuses choses peuvent mal se passer en cours de route :
- Une étape de récupération peut échouer
- Une appel à l’LLM peut échouer
- Une source donnée peut devenir temporairement inaccessible
- Une réponse générée peut échouer à un contrôle de validation
Au lieu d’envelopper toute l’application dans un seul et vaste gestionnaire d’erreurs, vous pouvez décider, nœud par nœud, de ce qui doit se passer au moment précis où quelque chose tombe en panne.
C’est là l’une des raisons pour lesquelles modéliser un flux de travail sous forme de graphe est attrayant. Lorsqu’une erreur se produit, on n’est pas obligé de se poser une question vague du type « pourquoi l’agent a-t-il échoué ? »
Au lieu de cela, on peut suivre le chemin exact emprunté par l’exécution et identifier précisément où les choses ont mal tourné :
Understand
↓
Search Filings ✓
↓
Search Earnings ✓
↓
Search Market Data ✗
↓
Retry ✓
↓
Analyze
↓
Write
↓
Check
Cela vous donne quelque chose de concret à analyser plutôt qu’une boîte noire.
Naturellement, à mesure que le graphe s’agrandit, gérer tout cela manuellement devient très laborieux — et c’est une préoccupation légitime.
À ce stade, il faut gérer la logique d’exécution, la gestion de l’état, le routage conditionnel, la gestion des tentatives répétées, la persistance des données, ainsi qu’un moyen d’examiner ce qui s’est réellement passé lors d’une exécution donnée.
C’est précisément dans ce genre de situation qu’un framework vous permet d’éviter de réinventer constamment les mêmes mécanismes d’orchestration pour chaque projet.
C’est là la lacune que LangGraph a été conçu pour combler.
LangGraph
Avec un cadre en place, votre flux de travail peut être divisé en tâches de recherche distinctes, ces résultats peuvent ensuite être fusionnés, les étapes échouées peuvent être réessayées, une pause peut être prise pour permettre à un humain d’intervenir, et l’état du système peut être suivi au fur et à mesure que l’exécution passe d’une étape à l’autre.
Bien sûr, définir ce graphe et le faire fonctionner réellement nécessite encore du travail.
LangGraph a été conçu pour gérer précisément cette couche.
LangGraph est un cadre conçu pour créer des flux de travail d’agents basés sur des graphes et ayant un état. Au lieu de considérer un agent comme une boucle unique qui demande constamment à un modèle de langage ce qu’il doit faire ensuite, vous définez explicitement les nœuds, les transitions entre eux, l’état partagé ainsi que le flux d’exécution global.
En revenant à l’agent de recherche NVIDIA mentionné précédemment, sa structure pourrait être esquissée comme ceci :
Question
↓
Understand
↓
┌──────────┼──────────┐
↓ ↓ ↓
Filings Earnings Market
↓ ↓ ↓
└──────────┼──────────┘
↓
Analyze
↓
Write
↓
Check
↙ ↓ ↘
Search Rewrite Human
↓ ↓ Review
└───────┴───────┘
↓
Send
Ce qui est notable, c’est que la structure du graphe et la logique d’application réelle peuvent coexister dans la même base de code.
from langgraph.graph import StateGraph, END
builder = StateGraph(ResearchState)
builder.add_node("understand", understand)
builder.add_node("search_filings", search_filings)
builder.add_node("search_earnings", search_earnings)
builder.add_node("search_market", search_market)
builder.add_node("analyze", analyze)
builder.add_node("write", write)
builder.add_node("check", check)
builder.set_entry_point("understand")
builder.add_edge("understand", "search_filings")
builder.add_edge("understand", "search_earnings")
builder.add_edge("understand", "search_market")
builder.add_edge("analyze", "write")
builder.add_edge("write", "check")
Le fragment ci-dessus est intentionnellement minimal afin que vous puissiez vous concentrer sur le modèle mental sous-jacent — celui qui relie les nœuds, les arêtes et les concepts de statut présentés précédemment dans cette série.
- Chaque nœud gère une unité de travail
- Le graphe définit la manière dont ces unités se connectent entre elles
- Le statut est ce qui transmet des informations d’un nœud à l’autre
C’est vraiment tout. Ce modèle mental est bien plus facile à comprendre que de tenter d’intégrer tout cela dans un seul prompt d’agent très complexe.
Vous pouvez examiner le graphique lui-même pour comprendre ce que le flux de travail est censé faire, avant même d’analyser comment chaque nœud individuel est implémenté.
Supposons que vous souhaitiez insérer une étape d’approbation humaine avant que la réponse finale ne soit envoyée — vous devriez modifier directement la structure du flux de travail :
Check
↓
Human Review
↓
Send
Il n’est pas nécessaire de cacher ce type de décision quelque part dans un prompt. La structure elle-même la rend explicite et facile à suivre pour votre équipe.
Pourquoi choisir LangGraph plutôt qu’un simple cycle d’agent ?
Un cycle d’agent conventionnel suit généralement cette structure :
Think
↓
Choose Tool
↓
Use Tool
↓
Think Again
↓
Choose Tool
↓
...
Dans ce cadre, le modèle dispose d’une grande marge de manœuvre pour décider de la suite des opérations. Cette flexibilité est véritablement précieuse lorsque la tâche en question est de nature ouverte.
Mais un flux de travail de recherche financière comme celui décrit ici comprend plusieurs points de décision que vous souhaiterez probablement contrôler plus strictement. C’est là l’essence du problème.
Tous les flux de travail n’exigent pas un boucle d’agent.
Examinons quelques exemples :
- Vous pourriez avoir besoin que le système collecte des preuves spécifiques avant de pouvoir produire une réponse.
- Vous pourriez vouloir que les données de marché et les documents officiels soient obtenus de manière indépendante l’un de l’autre.
- Vous pourriez exiger une étape de vérification avant que quoi que ce soit ne soit transmis à un examinateur humain.
- Vous pourriez vouloir que le processus s’arrête automatiquement après un certain nombre de tentatives.
Ce ne sont pas des choix que vous souhaitez nécessairement laisser à l’improvisation du modèle à chaque exécution. À l’intérieur d’une boucle, il n’y a aucun moyen de garantir que le modèle effectuera toujours la même action.
C’est là la différence clé à retenir. L’objectif n’est pas d’éliminer la capacité de raisonnement de l’agent — c’est plutôt de décider délibérément où ce raisonnement doit avoir lieu et où une orchestration déterministe est plus adaptée.
Pendant que vous continuez à développer des flux de travail qui traitent des données financières structurées, une nouvelle question se pose.
Actuellement, notre agent récupère des documents et des chiffres provenant de diverses sources. Mais que se passe-t-il lorsque les informations sous-jacentes présentent des liens qui ont réellement de l’importance ?
- Les entreprises emploient des dirigeants
- Ces dirigeants siègent souvent au conseil d’administration
- Une entreprise peut acquérir une autre
Jusqu’à présent, nous avons traité chaque élément de données de manière isolée. Cependant, les liens présentés ci-dessus sont difficiles à représenter si votre base de connaissances n’est rien de plus qu’une pile de documents indépendants.
Cela nous amène à un autre concept fondamental : GraphRAG.
GraphRAG
Jusqu’à maintenant, nous avons utilisé les graphes principalement pour régir le comportement de l’agent. Mais les graphes peuvent également servir un deuxième but :
organiser les connaissances elles-mêmes.
Dans notre exemple concret, une configuration RAG classique pourrait récupérer des documents mentionnant les résultats financiers de NVIDIA, ses prévisions, ses chiffres de revenus, ses marges et la réaction du marché.
Cette approche fonctionne bien lorsque la réponse se trouve principalement dans un petit nombre de documents pertinents. Mais les questions financières ne sont pas toujours aussi bien encadrées.
Une réponse pertinente dépend souvent de la mise en relation des informations dispersées dans plusieurs documents distincts.
Imaginons maintenant que l’on souhaite comprendre non seulement ce que NVIDIA a rapporté, mais aussi comment les différents éléments de ce rapport sont liés entre eux (ce qui correspond exactement à la situation que nous rencontrons).
C’est précisément là qu’un graphe de connaissances devient utile.
Au lieu de stocker les connaissances uniquement sous forme d’extraits de texte, nous pouvons modéliser les entités importantes ainsi que les relations qui les relient :
NVIDIA ──→ produces ──→ GPUs
│
├──→ reports ──→ Earnings
│
├──→ depends on ──→ Suppliers
│
├──→ competes with ──→ AMD
│
└──→ operates in ──→ AI Infrastructure
Le graphe permet désormais de capturer des liens qui ne seraient jamais apparus en lisant un seul document isolément.
RAG comparé à GraphRAG
Le RAG standard fonctionne généralement en récupérant des extraits pertinents et en les fournissant au modèle en tant que contexte. Voici une vue simplifiée de ce flux :
Question
↓
Retrieve relevant chunks
↓
LLM
↓
Answer
GraphRAG introduit une couche supplémentaire. Le système peut s’appuyer sur les relations entre entités pour déterminer quelles informations sont réellement importantes :
Question
↓
Identify entities
↓
Traverse relationships
↓
Retrieve relevant information
↓
LLM
↓
Answer
Pour notre agent de recherche financière, cela devient précieux chaque fois qu’une question nécessite de relier plusieurs entités ou documents en même temps.
Supposons que le gérant de portefeuille demande : quels risques pourraient affecter NVIDIA si la demande d’infrastructures IA diminue ?
Pour y répondre correctement, il peut être nécessaire de relier NVIDIA à ses produits, ses clients, ses fournisseurs, ses concurrents, les conditions du marché plus larges, ainsi qu’aux risques déjà mentionnés dans ses déclarations antérieures.
Un graphe fournit au système de récupération une voie structurée pour explorer toutes ces connexions.
NVIDIA
/ | \
/ | \
Products Suppliers Competitors
| | |
↓ ↓ ↓
AI GPUs Supply Risk AMD
|
↓
AI Infrastructure
|
↓
Demand
À partir de là, le modèle peut raisonner sur tout ce qui a été extrait de ces entités liées.
Cela ne signifie pas pour autant que GraphRAG est toujours supérieur à RAG classique. La structure supplémentaire s’avère particulièrement utile lorsque les relations entre les différentes informations sont au cœur de la question posée.
Si la réponse se trouve clairement à l’intérieur d’un seul rapport de résultats financiers, un pipeline de récupération conventionnel suffit probablement.
Si répondre à la question implique de rassembler des informations dispersées sur de nombreuses entités et sources, une architecture basée sur des graphes devient beaucoup plus attractive.
Il existe une autre distinction importante à bien comprendre : votre graphique de flux de travail et votre graphe de connaissances sont deux choses complètement différentes.
Le graphique de flux de travail répond à la question de savoir ce que l’agent doit faire ensuite. Le graphique de connaissances répond à la question de savoir ce qui est relié à quoi au sein des données sur lesquelles on travaille.
Dans notre système, ces deux éléments peuvent coexister côte à côte :
WORKFLOW GRAPH:
Question
↓
Retrieve
↓
Analyze
↓
Write
↓
Check
alors que, en sous-main, la couche de récupération fonctionne sur :
KNOWLEDGE GRAPH:
NVIDIA
├── Products
├── Suppliers
├── Competitors
├── Executives
├── Filings
└── Industry
Remarquez la séparation des responsabilités : une structure gère l’exécution, tandis que l’autre organise les connaissances et les relations qui s’y trouvent.
Dès que ces deux concepts commencent à se renforcer mutuellement, l’agent de recherche financière devient considérablement plus performant.
- Le flux de travail détermine comment la recherche est menée.
- Le graphique de connaissances détermine quelles informations sont reliées.
Naturellement, cela soulève une question subsidiaire : si les graphes offrent un tel niveau de contrôle, devrait-on construire chaque flux de travail sous cette forme ?
Pas nécessairement.
Dans de nombreux cas, un simple cycle d’agent suffit pour résoudre le problème.
Au lieu de convertir systématiquement chaque flux de travail d’IA en graphes, il est utile de comparer directement les deux approches afin de déterminer quand la complexité supplémentaire liée à l’ingénierie des graphes en vaut réellement la peine.
Il convient de se rappeler que les graphes vous donnent plus de contrôle, mais ce contrôle s’accompagne d’un travail supplémentaire : vous devez désormais concevoir et maintenir cette structure vous-même.
Si la tâche de base est vraiment simple, l’envelopper dans un graphes peut en fait rendre le système plus difficile à suivre sans vous apporter beaucoup en retour.
Revenons à l’exemple de l’agent de recherche financière. Supposons que l’utilisateur demande quelque chose comme : résumer le dernier rapport de résultats d’NVIDIA.
C’est une demande précise et autonome.
On peut la gérer en récupérant le rapport pertinent et en le transmettant au modèle pour qu’il en produise un résumé :
Question
↓
Retrieve Report
↓
Summarize
↓
Answer
Il n’y a pas de véritables branches ni de logique complexe à gérer. Un pipeline RAG simple ou une boucle d’agent de base suffiront amplement.
Comparons maintenant cela à une demande plus large, où l’utilisateur souhaite comprendre ce qui a provoqué la baisse du cours de l’action après les résultats, veut que ces résultats soient comparés aux prévisions des analystes, souhaite obtenir une liste des risques à surveiller à l’avenir, et veut pouvoir valider les conclusions avant qu’elles ne soient intégrées dans un rapport de portefeuille.
C’est un type de problème complètement différent.
Cette version implique plusieurs types de recherches, s’appuie sur différentes sources, nécessite une validation, peut exiger plusieurs tentatives et comprend une étape d’examen par un humain.
Le flux de travail ressemble désormais davantage à ceci :
Question
↓
Understand
↓
┌──────────┼──────────┐
↓ ↓ ↓
Filings Earnings Market
↓ ↓ ↓
└──────────┼──────────┘
↓
Analyze
↓
Write
↓
Check
↙ ↓ ↘
Search Rewrite Human
↓ ↓ Review
└───────┴──────┘
↓
Send
À ce niveau de complexité, décrire explicitement le flux de travail commence à porter ses fruits.
Alors, quand un cycle d’agent suffit-il ?
liberté pour choisir l’outil à utiliser ensuite.
Par exemple :
Question
↓
LLM decides what to do
↓
Tool
↓
LLM decides what to do next
↓
Tool
↓
Answer
Lorsque la tâche est explicative et que l’on ne peut pas prédire à l’avance le nombre d’étapes, cette flexibilité est véritablement précieuse.
L’agent pourrait décider qu’il doit vérifier un extrait des revenus, puis extraire une métrique spécifique, avant de chercher plus de contexte. Vous n’avez pas besoin de planifier à l’avance chaque chemin possible.
Quand un graphe devient-il plus compréhensible ?
le flux de travail dispose de règles qui ont réellement de l’importance.
Pour le système de recherche financière, ces règles pourraient ressembler à ceci :
Retrieve evidence
↓
Run analysis
↓
Generate draft
↓
Verify claims
↓
Human review
↓
Publish
Il s’agit de contraintes au niveau du flux de travail, et un graphe vous permet de les encoder directement plutôt que d’espérer que le modèle les déduira automatiquement.
L’équilibre à trouver
Vous devez maintenant réfléchir à :
- la manière dont l’état est structuré
- la logique de routage
- ce qui se passe en cas d’échec
- le comportement de tentative répétée
- la persistance
Rien de tout cela n’est intrinsèquement négatif — cela signifie simplement que le graphe doit justifier la charge supplémentaire qu’il introduit.
Pour l’agent de recherche NVIDIA, il n’aurait aucun sens de construire l’intégralité du graphe dès le départ simplement parce que les graphes sont intéressants.
Au lieu de cela, la structure supplémentaire ne devrait être introduite que lorsque le flux de travail l’exige réellement :
- Commencez par quelque chose de simple.
- Ajoutez des branches dès que c’est vraiment nécessaire.
- Ajoutez l’exécution en parallèle lorsque les tâches peuvent réellement s’exécuter indépendamment les unes des autres.
- Ajoutez des points de contrôle lorsque le flux de travail doit être suspendu ou se remettre d’une interruption.
- Ajoutez une étape de révision par un humain lorsque les enjeux justifient cette friction supplémentaire.
- Intégrez GraphRAG lorsque les relations au sein des connaissances elles-mêmes commencent à être importantes.
Ainsi, le graphe existe parce que le problème l’exige, et non parce qu’il est disponible.
Pensées finales
C’est probablement la leçon principale tirée de cette réflexion sur la conception.
Un graphe n’a pas pour but de donner l’impression à un système d’intelligence artificielle qu’il est sophistiqué. Il existe pour faciliter la compréhension et le contrôle du flux de travail.
L’agent de recherche financière développé au cours de cette discussion peut désormais prendre des chemins alternatifs, réessayer, faire une pause, intégrer un examinateur humain, et même s’appuyer sur les relations entre les différents éléments de connaissance lorsque c’est utile.
Néanmoins, rien de tout cela ne signifie que chaque système a besoin d’un graphe. Parfois, un simple pipeline RAG constitue l’équipement adéquat. D’autres fois, une boucle d’agent couvre tout ce que le problème exige.
La véritable compétence réside dans la capacité à identifier le moment où un problème devient suffisamment complexe pour que l’utilisation d’un graphique en vaille la peine.