Aller au contenu principal
MyTrainingApp

Programme détaillé

Bootcamp agents IA : LangChain, LangGraph, RAG & MCP

8 modules · 32 leçons · 40 h · quiz auto-corrigés, labs guidés, livrables et projet final. La première leçon de chaque module est lisible ci-dessous sans inscription.

IntermédiaireIntelligence artificielle40 hGratuit
Voir la fiche complète

Ce que vous saurez faire

  • Expliquer ce qu'un modèle de langage fait réellement (prochain jeton, fenêtre de contexte, hallucinations)
  • Maîtriser la couche « messages » : invites système, formats de conversation, sorties structurées et appel
  • Écrire une boucle d'agent à la main, la casser volontairement trois fois et réparer chaque échec.
  • Construire un assistant complet avec LangChain et `create_agent` : outils typés, middleware, barrière
  • Dessiner des graphes LangGraph avec état typé, arêtes conditionnelles, cycle d'outils et réduveurs.
  • Ajouter mémoire, points de contrôle, persistance, reprise, humain dans la boucle et plafonds de coût.
  • Construire une chaîne RAG complète : chargement, découpage, plongements, index, récupérateur, ancrage,
  • Instrumenter un système avec LangSmith : traces, jeux de données, évaluateurs, évaluations hors ligne et en
  • Orchestrer une équipe multi-agents (AutoGen, CrewAI, LangFlow) et un agent profond de recherche.
  • Servir un service RAG via FastAPI, Postgres et Docker, puis livrer une capstone complète.

Prérequis : Un ordinateur avec 8 Go de RAM minimum (16 Go recommandé pour les labs Docker et le modèle local). · Python 3.11+, Git, un éditeur de code (VS Code recommandé), un compte GitHub. · Un **modèle local gratuit** servi par Ollama (`ollama pull qwen3:8b`) : tout le cours tourne sans clé d'API. · Une clé de modèle hébergé (compatible OpenAI) est **optionnelle** et s'active par variable d'environnement. · Pour les labs 6 à 10 : Docker et Docker Compose (Postgres/pgvector, serveur de développement LangGraph).

Module 1

Agents IA et fondations des modèles

3 leçons · 0 min · quiz 6 questions (seuil 5/6) · lab 8 étapes

Leçons

  1. Leçon 1 — Qu'est-ce qu'un agent IA, et pourquoi ce bootcamp0 min
  2. Leçon 2 — Un environnement reproductible et sans clé0 min
  3. Leçon 3 — Ce qu'un modèle de langage fait réellement0 min
Lire l'aperçu gratuit : leçon 1 — Qu'est-ce qu'un agent IA, et pourquoi ce bootcamp

Durée conseillée : 40 min

Le contexte

Vous avez déjà vu des démonstrations d'agents qui impressionnent, et des produits lancés qui déçoivent. L'écart entre les deux n'est presque jamais une question de modèle : c'est une question d'ingénierie autour du modèle. Avant d'écrire la moindre ligne de code d'agent, il faut donc une image mentale juste de ce qu'est un agent, à quoi il sert, et comment ce cours va vous y conduire.

Idée centrale

Un agent IA est un modèle de langage en boucle, avec des outils et un arrêt. Le modèle lit la situation et propose l'étape suivante ; un outil l'exécute ; le résultat revient ; le modèle décide à nouveau ; et la boucle s'arrête quand le travail est fait, quand un plafond est atteint, ou quand une personne doit dire « oui » avant une action irréversible. Si vous retenez cette phrase, vous comprenez déjà mieux les agents que la majorité de ce qui s'écrit à leur sujet. Tout le reste du cours sert à rendre cette boucle assez fiable pour qu'une entreprise accepte qu'elle touche des clients, des comptes et de l'argent.

Développement 1 — La phrase-clé : un modèle en boucle, des outils, un arrêt

Décomposons la phrase en quatre mots. Le modèle lit les messages et propose soit une réponse, soit un appel d'outil. Les outils sont des fonctions dotées d'un nom et d'une description que le modèle peut demander. La boucle est le code qui appelle le modèle, exécute l'outil demandé, ajoute le résultat et rappelle le modèle. L'arrêt est la condition qui termine la boucle : le modèle a répondu en mots, un plafond de tours a été atteint, ou une règle a exigé l'accord d'un humain.

Un simple appel de modèle répond à une question. Il ne peut pas réinitialiser un mot de passe, car cela demande d'abord un appel à une fonction, puis une phrase qui explique ce qui s'est passé — deux tours avec le monde réel entre les deux. La boucle, elle, permet au modèle de faire quelque chose, de voir le résultat et de décider de la suite. Un ticket qui exige une recherche puis une réinitialisation représente trois tours de boucle, et le modèle décide à chaque tour à partir de ce qu'il a déjà vu.

L'arrêt est la partie que l'on oublie jusqu'à ce qu'elle fasse mal. Une boucle sans arrêt est un modèle qui appelle des outils jusqu'à épuisement de l'argent ou de la patience. Un bon agent s'arrête pour trois raisons : il a produit une réponse finale sans appel d'outil, un plafond de tours a été atteint, ou une règle a décidé que cette étape exige une personne. La troisième raison s'appelle la barrière humaine.

Développement 2 — Les trois mondes : TechCorp, Dataflow et TalentFlow

Chaque lab du bootcamp travaille sur l'une de trois petites entreprises qui vivent dans le dépôt sous forme de données réelles : fichiers, tables et tickets, pas trois phrases qui prétendent être une base de connaissances. Elles sont assez petites pour être lues intégralement et assez riches pour casser des choses.

MondeMétierDonnéesForme d'agent apprise
TechCorpDesk informatique interne12 tickets employés, annuaire, outils de recherche, réinitialisation et attribution d'accèsBoucle simple avec un droit protégé (type create_agent)
DataflowDesk de support client50 commandes, 30 tickets, base de 20 fichiers, wiki des politiques de retour et d'expéditionGraphe dessiné avec branches, mémoire, remboursement parqué, récupérateur
TalentFlowÉquipe de recrutementPile de CV de longueurs et de qualités diverses, fiche de poste, trois modèles d'e-mailDiffusion parallèle (fan-out) puis map-reduce

TechCorp est le monde où l'on apprend à brancher un modèle sur des outils. Dataflow est le monde où l'on apprend le contrôle et la récupération ; c'est la colonne vertébrale du cours. TalentFlow est le monde où l'on apprend à diffuser en parallèle sur une multitude d'éléments. Trois mondes, trois dépôts dans votre portfolio, trois formes d'agent différentes : un seul monde ne peut pas enseigner trois formes.

Pourquoi trois entreprises plutôt qu'une ? Parce qu'apprendre les trois formes sur une seule entreprise les brouillerait. Apprendre chaque forme sur l'entreprise qui la porte naturellement rend la forme évidente. Et parce que les données sont honnêtes : la base de connaissances de Dataflow contient un manuel employé à côté d'une politique de retour client, et une recherche naïve répond à une question de retour avec la règle d'équipement du manuel. Ce n'est pas un piège planté, c'est ce qu'une vraie pile de documents fait à une recherche naïve.

Le monde porteur enseigne aussi la bonne forme. Un desk informatique est une seule boucle avec un droit protégé : la forme create_agent. Un desk de support est un flux de travail avec des branches, de la mémoire, un remboursement parqué et un récupérateur : la forme du graphe dessiné. Une pile de CV est une opération map sur de nombreux éléments avec une seule réduction : la forme de la diffusion parallèle.

Développement 3 — Comment fonctionne le bootcamp

Chaque section du cours a la même forme, si bien qu'après la première vous savez toujours ce qui arrive. Une leçon de concept explique une idée : ce qu'elle est, pourquoi elle existe, comment elle fonctionne sur le desk, en quoi elle aide à livrer, et quand ne pas l'utiliser. Puis un lab vous fait taper le code, l'exécuter, le casser et le réparer. Puis le concept suivant. La section se termine par un court quiz, et certaines par un exercice de code vérifié par un test.

En une phrase : on explique avant de taper, on tape avant de faire confiance, et on casse avant de livrer. Il n'y a qu'un seul dépôt d'élève pour tout le cours. Vous le clonez au premier lab, et chaque lab suivant est un fichier dedans, nommé labs/<numéro de section>/<numéro de lab>_<nom>. Chaque fichier de lab possède un jumeau notebook, généré automatiquement, que vous n'éditez jamais à la main.

La clé de correction, c'est le dépôt lui-même : le code terminé de chaque lab est committé sur la branche du cours. Quand vous êtes bloqué, vous pouvez lire le fichier. Quand vous ne l'êtes pas, tapez-le quand même, car c'est en tapant que l'on apprend. Chaque lab demande quatre choses : ouvrir le fichier nommé par la leçon et suivre l'ordre, lire la sortie réelle et la comparer avec ce que la leçon annonçait, faire l'étape « casser exprès » puis remettre la correction, et terminer par un « dire à voix haute » : un paragraphe que vous expliquez avec vos propres mots, car ce que vous savez expliquer, vous le maîtrisez.

Tout le cours tourne sur un modèle local gratuit, servi par Ollama, appelé à travers un seul fichier de configuration. Le coût d'exécution du cours est donc nul et rien ne quitte votre machine. Si vous possédez une clé de modèle hébergé, la configuration l'utilisera dès que vous définirez une variable — et la leçon 2 montre les deux chemins. Les sorties montrées dans les leçons ont été capturées sur ce même modèle local, erreurs comprises, car ce sont les erreurs qui enseignent.

Deux rythmes honnêtes sont possibles : une section à la fois, dans l'ordre, au rythme que votre semaine permet ; ou le sprint de 24 jours, environ deux sections par jour, intense mais faisable si vous avez le temps. Dans les deux cas, ne sautez pas les fondations sur les modèles, et ne sautez pas le bloc LangGraph, car c'est là que le desk devient un produit. Pour demander de l'aide, indiquez le nom du lab, collez la sortie obtenue, la sortie attendue par la leçon et le modèle utilisé : la plupart des problèmes sont soit une installation manquante, soit un modèle non lancé, soit un chemin de fichier incorrect.

Exemple concret / mise en pratique

Voici la boucle d'agent en dix lignes, sans aucune bibliothèque. Elle illustre exactement la phrase-clé : un modèle qui propose, un code qui exécute, un arrêt qui ferme la boucle.

# La phrase-clé du module, réduite à une fonction exécutable.
def agent_loop(model, tools, ticket, max_turns=8):
    """Le modèle propose, le code exécute, la boucle s'arrête."""
    messages = [{"role": "user", "content": ticket}]
    for _ in range(max_turns):
        reply = model(messages, tools)               # le modèle propose
        if reply.get("tool_calls"):
            for call in reply["tool_calls"]:         # le code exécute
                result = tools[call["name"]](**call["arguments"])
                messages.append(
                    {"role": "tool", "content": result, "id": call["id"]}
                )
        else:
            return reply["content"]                  # arrêt : réponse finale
    return "Le desk n’a pas pu terminer dans le budget de tours."

La fonction ci-dessus ne fait rien d'autre que la description en prose. Le modèle ne lance jamais l'outil ; il demande un nom et des arguments. Votre code exécute, décide, et arrête. Le schéma suivant fixe cette boucle une fois pour toutes.

        ┌───────────────────────────┐
        │  messages (le contexte)    │
        └─────────────┬─────────────┘
                      ▼
               ┌────────────┐   propose un appel d'outil
               │   MODÈLE   │───────────────┐
               └────────────┘               │
                      ▲                      ▼
                      │              ┌────────────┐
                      │  résultat    │   OUTILS   │
                      └──────────────└────────────┘
                      │
                      ▼   arrêt : réponse finale, plafond, ou « non » d'un humain

Exercice guidé (10–15 min)

La suite (leçons 2 à 3, quiz, lab et livrable) est accessible après une inscription gratuite.

Module 2

Invites, messages, outils et sorties structurées

4 leçons · 0 min · quiz 6 questions (seuil 5/6) · lab 8 étapes

Leçons

  1. Leçon 1 — Messages, rôles et invite système0 min
  2. Leçon 2 — Sorties structurées : une forme, pas un paragraphe0 min
  3. Leçon 3 — L'appel d'outils au niveau de l'API0 min
  4. Leçon 4 — La boucle d'agent à la main0 min
Lire l'aperçu gratuit : leçon 1 — Messages, rôles et invite système

Durée conseillée : 50 min

Le contexte

Quand vous appelez un modèle de conversation, vous n'envoyez pas une chaîne. Vous envoyez une liste de messages, chacun portant un rôle. Le modèle relit la liste entière à chaque appel et ne conserve rien entre deux appels : c'est votre code qui tient la mémoire.

Idée centrale

Une conversation est une liste de messages. Le modèle n'a pas de mémoire ; la liste est la mémoire, et vous êtes celui qui la porte. Quatre rôles décrivent tout échange : system (les règles), user (l'entrée), assistant (la réponse ou la demande d'outil), tool (le résultat).

Développement 1 — Les quatre rôles

RôleCe qu'il porteÉcrit parRôle dans l'agent
systemLes règles, le rôle, le périmètreVousCadre relu à chaque tour
userLa question, le ticketLe clientL'entrée à traiter
assistantLa réponse, ou une demande d'outilLe modèleParle ou agit
toolLe résultat d'un appel, avec son identifiantVotre codeRend l'action observable

Un message tool porte un identifiant qui doit correspondre à celui de la demande précédente, sinon le modèle ne sait pas quelle question la réponse traite. L'invite système est une instruction, le message utilisateur est une donnée ; les confondre ouvre la porte à l'injection d'invite.

Développement 2 — L'invite système et ce qu'elle ne garantit pas

L'invite système est le premier message, relu à chaque appel. Écrivez-la comme la description de poste d'une nouvelle recrue, en cinq bandes serrées : « rôle » (une phrase), « périmètre » (ce qui est traité), « règles d'outils » (chercher l'utilisateur avant de réinitialiser), « refus » (forme fixe hors périmètre), « sortie » (longueur, ton, éléments obligatoires).

Elle a la plus forte influence par mot écrit, mais elle est du texte : elle oriente, elle ne garantit pas. Ce qui doit tenir à coup sûr — barrière humaine avant un remboursement, plafond d'appels, résultat typé quand un utilisateur est absent — vit dans le code. Si une règle doit toujours tenir, elle est du code ; si elle doit généralement tenir, elle est de l'invite. N'y mettez jamais un secret ni une identité.

Exemple concret / mise en pratique

Le script ci-dessous envoie une liste de messages au modèle local et lit la réponse, la raison de fin (finish reason) et l'usage. stop signifie que le modèle a fini ; length signifie que vous l'avez coupé.

"""Construire une liste de messages et lire la réponse d'un modèle local."""
from openai import OpenAI

client = OpenAI(base_url="http://localhost:11434/v1", api_key="placeholder")

SYSTEM_PROMPT = (
    "Tu es le desk support Dataflow. Réponds aux questions sur les commandes "
    "et les retours à partir des outils et de la politique. "
    "Si tu ne disposes pas de l'information, dis-le au lieu de deviner."
)

messages = [
    {"role": "system", "content": SYSTEM_PROMPT},
    {"role": "user", "content": "Où en est ma commande 41-77 ?"},
]

reply = client.chat.completions.create(
    model="qwen3:8b", messages=messages, max_tokens=200
)
choice = reply.choices[0]
print("contenu :", choice.message.content)
print("raison de fin :", choice.finish_reason)
print("jetons :", reply.usage.prompt_tokens, reply.usage.completion_tokens)

Avec un budget minuscule (max_tokens=5), la réponse revient vide et la raison de fin devient length : un budget doit laisser de la place aux jetons invisibles.

Exercice guidé (10–15 min)

La suite (leçons 2 à 4, quiz, lab et livrable) est accessible après une inscription gratuite.

Module 3

LangChain, contexte, outils et assistants robustes

4 leçons · 0 min · quiz 6 questions (seuil 5/6) · lab 8 étapes

Leçons

  1. Leçon 1 — Maîtriser le contexte : fichiers d'instructions, compaction, notes structurées0 min
  2. Leçon 2 — La mémoire des agents : fil, profil, similarité0 min
  3. Leçon 3 — LangChain et les outils : messages, outils typés, échecs0 min
  4. Leçon 4 — Un assistant robuste avec create_agent0 min
Lire l'aperçu gratuit : leçon 1 — Maîtriser le contexte : fichiers d'instructions, compaction, notes structurées

Durée conseillée : 45 min

Le contexte

Votre guichet fonctionne. À chaque ticket, il lit l'historique, appelle des outils, répond. Puis un ticket arrive avec une règle cachée au milieu : « les remboursements pour ce compte ne doivent jamais dépasser 40 € ». Le modèle la respecte au quatrième tour et répond correctement à un sondage au dernier tour. Mais entre les deux, le contexte a grandi. Est-ce que la règle tient encore ? La réponse honnête est : personne ne le sait, sauf si on mesure.

Cette leçon commence par regarder les chiffres d'une exécution longue, puis propose trois techniques complémentaires pour reprendre la main : un fichier d'instructions court, la compaction des vieux tours et des notes structurées.

Idée centrale

Le contexte n'est ni gratuit ni cumulatif. Chaque appel repaie pour tout ce que le modèle voit, et une règle enterrée dans un contexte trop long finit par échapper à l'attention. Maîtriser le contexte, c'est décider ce qui entre : des instructions courtes qui pointent vers des ressources, un résumé qui plie les vieux tours, et des notes qui gardent les faits importants hors du fil. La règle de sécurité qui compte est celle-ci : toute règle qui doit s'appliquer à chaque réponse appartient aux instructions permanentes, jamais derrière un simple pointeur.

Développement 1 — Mesurer la croissance du contexte

On ne décide pas sans mesure. Le laboratoire associé construit un fil long : quatre tours d'introduction, une phrase de contrainte (« les remboursements pour ce compte ne dépassent pas 40 € »), puis plusieurs dizaines de tours de conversation ordinaire, et enfin un sondage qui demande un remboursement au-dessus du plafond. Un juge écrit en code, pas un second modèle, vérifie que la réponse finale reprend bien le plafond de 40 €. On relève le nombre de jetons à deux endroits : au tour où la règle est énoncée et au tour où elle est nécessaire.

Moment de la mesureJetons (bibliothèque)Jetons (serveur)
Tour 4 — règle énoncéeenviron 150un peu moins de 200
Tour 45 — règle requiseenviron 1 250plus de 1 500

Le contexte a crû d'un facteur huit autour d'une seule phrase, et aucun contrôle du fil ne vérifie que la règle est encore appliquée, sinon la sonde que vous avez écrite. Sur cette exécution, le modèle local a tenu la contrainte jusqu'au tour 45. C'est une bonne nouvelle pour ce modèle, à cette longueur, et cela ne dit rien de l'exécution du mois prochain à 300 tours. La dégradation du contexte (context rot) se définit simplement : une règle encore présente dans la fenêtre mais qui n'est plus dans la réponse.

Développement 2 — Un résultat qui ne fait aucun bruit

Le piège de la dégradation du contexte est qu'elle est silencieuse. Une exécution qui meurt de contexte dégradé ne lève aucune exception : elle répond avec aplomb, sans la règle. Le seul moyen de le savoir est une sonde jugée par du code, par exemple « la réponse contient-elle le nombre 40 et ne promet-elle pas le montant plein ? ». Le laboratoire enregistre la trace dans un fichier, parce que la leçon suivante relit ces deux comptes côte à côte. La leçon pratique : sur un contexte long, ce n'est pas le modèle qu'on interroge pour savoir s'il a oublié, c'est un test qu'on écrit.

Développement 3 —Le fichier d'instructions est une table des matières

Toute équipe qui construit un guichet finit par écrire un fichier d'instructions. Il commence à cinq lignes, puis un ticket se passe mal et on ajoute un paragraphe, puis la conformité veut une règle, puis le tableau des engagements de service (SLA), puis la procédure de remboursement, puis le guide de ton. Six mois plus tard, le fichier fait neuf pages, il est envoyé à chaque appel de modèle, et personne ne sait quelle ligne a corrigé quel ticket.

Un tel fichier est une encyclopédie. Il devrait être une table des matières : assez courte pour être relue à chaque appel, disant au modèle ce qui existe et où chercher, sans recopier tout ce qui existe. Les instructions permanentes contiennent le rôle, la portée, les règles d'outils, la forme du refus, puis une carte : les noms des documents, des outils et des notes que le modèle peut aller chercher, chacun avec une ligne disant quand.

Trois coûts justifient la carte courte. Le coût en jetons : le fichier est relu à chaque appel, et un agent fait plusieurs appels par ticket ; neuf pages, c'est plusieurs milliers de jetons multipliés par les appels et par les tickets, payés même quand le ticket ne touche aucune de ces pages. Le coût en attention : plus la fenêtre contient de texte, moins chaque ligne reçoit d'attention ; une règle enterrée en page 6 sous un tableau est une règle que le modèle ne trouve que parfois. Le coût de maintenance : un fichier de neuf pages change chaque semaine et n'est jamais testé, alors qu'une carte de douze lignes change rarement et que chaque ligne pointe vers un fichier ou un outil testable seul.

Deux règles de conception pour la carte. Chaque ligne est un pointeur avec un déclencheur : « quand ceci, lire cela ». Une liste de noms sans « quand » est une liste que le modèle ignore. Et la carte ne nomme que ce qui est réellement accessible : un fichier qu'une lecture juste-à-temps peut ouvrir, un outil qui existe, une note que l'agent a écrite. Un pointeur vers rien est pire qu'aucun pointeur.

Développement 4 — La compaction : plier les vieux tours

Un fil de conversation croît d'un message humain, d'un message assistant et parfois d'un appel d'outils et de son résultat à chaque tour. Au bout de vingt tours, le contexte porte des dizaines de messages dont la plupart n'ont plus d'utilité immédiate, mais dont chacun est repayé à chaque appel. La compaction consiste à plier les vieux tours : on demande au modèle de résumer la conversation ancienne, on remplace les messages d'origine par ce résumé, et l'on garde intacts les derniers tours ainsi que les messages système. Le résultat est un contexte plus court ; le coût en jetons cesse de croître linéairement.

Fil sans compaction :  [sys][H][A][H][A][H][A][H][A]...  ->  jetons en hausse continue
Fil avec compaction :  [sys][ RESUME ][A][H][A][H]      ->  plateau apres le pli

La compaction a une contrepartie, et c'est exactement la leçon des notes structurées : un résumé perd des détails. Si un fait doit survivre à toutes les compactions — un identifiant, une préférence, un plafond —, il ne doit pas vivre dans le texte résumé : il doit vivre dans un fichier de notes à part, relu explicitement quand il faut. Le fil raconte ce qui a été dit ; les notes disent ce qui est vrai.

Développement 5 — Ce qui doit survivre : les notes structurées

On distingue donc trois étages : les instructions permanentes (courtes, rechargées à chaque appel), le fil de conversation (qui peut être plié), et les notes (des faits datés, sourcés, avec une échéance). Une note utile porte quatre champs : quoi, quand, source, expiration. Le plafond de remboursement d'un compte est une note, pas une phrase éphémère au milieu d'un fil : il a une valeur, il vient d'une politique écrite, il a une date, et il expirera quand la politique changera.

Exemple concret / mise en pratique

TechniqueCe qu'elle protègeCe qu'elle sacrifie
Fichier d'instructions courtLe coût et l'attention sur les règles permanentesRien, si la carte pointe vers de vrais fichiers
Compaction des vieux toursLe plafond de coût du filLes détails des tours anciens
Notes structuréesLes faits critiques (montants, identifiants, préférences)Le détail narratif (assumé)

Exercice guidé (10–15 min)

La suite (leçons 2 à 4, quiz, lab et livrable) est accessible après une inscription gratuite.

Module 4

LangGraph : graphes et états

4 leçons · 0 min · quiz 6 questions (seuil 5/6) · lab 12 étapes

Leçons

  1. Leçon 1 — LangGraph expliqué simplement : nœuds, arêtes, état0 min
  2. Leçon 2 — Arêtes conditionnelles et aiguillage0 min
  3. Leçon 3 — Le cycle d'outils dans un graphe0 min
  4. Leçon 4 — État typé et réduveurs d'état0 min
Lire l'aperçu gratuit : leçon 1 — LangGraph expliqué simplement : nœuds, arêtes, état

Durée conseillée : 50 min

Le contexte

LangGraph a une réputation intimidante, entretenue par une documentation dense et un vocabulaire de théorie des graphes. La réalité est plus simple, et la version en langage courant mérite d'être donnée avant la version officielle. Si vous savez dessiner un organigramme avec des flèches, vous savez déjà lire un graphe LangGraph.

Idée centrale

Un graphe LangGraph, c'est une boîte de départ, des boîtes de travail, des flèches entre elles, et un bloc-notes qui voyage de boîte en boîte. La boîte de départ est le point d'entrée ; les boîtes de travail sont des fonctions (un nœud = une fonction) ; les flèches décident qui s'exécute ensuite ; le bloc-notes est l'état (state), l'ensemble des valeurs que les nœuds lisent et écrivent. Là où une boucle cache son contrôle dans du code, le graphe le rend visible dans un dessin.

Développement 1 — Nœuds, arêtes, état

Un nœud reçoit l'état, fait un travail, et renvoie une mise à jour de l'état. Une arête relie deux nœuds ; une arête spéciale part du point d'entrée et une autre mène à la fin. L'état est partagé : chaque nœud voit ce que les précédents ont écrit. Cette séparation est ce qui rend le système testable : on peut appeler un nœud seul, avec un état fabriqué à la main, sans lancer tout le graphe.

Développement 2 — Le premier graphe : trier un ticket

Le desk Dataflow reçoit des tickets clients. Le premier graphe ne fait qu'une chose : classer un ticket par catégorie et écrire le résultat dans l'état.

"""Premier graphe LangGraph : classer un ticket Dataflow."""
from typing import TypedDict
from langgraph.graph import StateGraph, START, END
from langchain_core.messages import HumanMessage
from config import build_chat_model


class TriageState(TypedDict):
    ticket: str
    categorie: str


def classer(state: TriageState) -> dict:
    """Nœud : demande au modèle une catégorie, écrit la mise à jour d'état."""
    model = build_chat_model()
    prompt = f"Classe ce ticket parmi facturation, livraison, technique, autre :\n{state['ticket']}"
    categorie = model.invoke([HumanMessage(prompt)]).content.strip().lower()
    return {"categorie": categorie}


builder = StateGraph(TriageState)
builder.add_node("classer", classer)
builder.add_edge(START, "classer")
builder.add_edge("classer", END)
graph = builder.compile()

print(graph.get_graph().draw_ascii())        # prouve que le graphe compile
result = graph.invoke({"ticket": "Ma facture est fausse, je suis prélevé deux fois."})
print(result["categorie"])

Développement 3 — Compiler, puis exécuter

On construit le graphe avec StateGraph, on ajoute les nœuds et les arêtes, puis on compile : la compilation transforme le dessin en objet exécutable et vérifie sa cohérence. Une bonne habitude est d'afficher le graphe compilé (draw_ascii) : si le dessin correspond à l'intention, la moitié du travail de débogage est faite. Les nœuds s'exécutent dans l'ordre des arêtes ; l'état est transmis et enrichi à chaque étape.

Exemple concret / mise en pratique

ÉlémentDans la boucle à la mainDans un graphe LangGraph
Le travailDes lignes de code dans le whileUn nœud = une fonction
Le contrôleDes if imbriqués difficiles à lireDes arêtes, visibles dans un dessin
Les données partagéesDes variables localesUn état typé, transmis de nœud en nœud
Le testDifficile à isolerUn nœud se teste seul avec un état fabriqué

Exercice guidé (10–15 min)

La suite (leçons 2 à 4, quiz, lab et livrable) est accessible après une inscription gratuite.

Module 5

LangGraph : cycle d'outils, mémoire, persistance et conformité

4 leçons · 0 min · quiz 6 questions (seuil 5/6) · lab 8 étapes

Leçons

  1. Leçon 1 — Mémoire d'un agent : fil, profil, notes notées0 min
  2. Leçon 2 — Persistance : points de contrôle, reprise, retour dans le temps0 min
  3. Leçon 3 — L'humain dans la boucle : parquer une action irréversible0 min
  4. Leçon 4 — Plafonds, journalisation et conformité0 min
Lire l'aperçu gratuit : leçon 1 — Mémoire d'un agent : fil, profil, notes notées

Durée conseillée : 50 min

Le contexte

Un desk qui répond deux fois avec deux réponses différentes au même client n'est pas un desk : c'est un générateur de réponses. La mémoire est ce qui fait qu'un agent « reconnaît » un client qui revient et n'oublie pas une règle énoncée plus tôt. Mais la mémoire n'est pas une propriété du modèle (module 1) : c'est un objet construit autour de lui. Ce module montre comment la câbler dans le graphe.

Idée centrale

La mémoire se range dans deux tiroirs et suit trois natures (module 3, leçon 10). Côté graphe, cela se traduit par deux mécanismes : le fil de conversation (la clé messages, accumulée par add_messages) et le magasin de faits nommés (un objet clé-valeur hors du fil, relu quand on connaît la clé). Le fil vit dans l'exécution courante ; le magasin survit d'un fil à l'autre. Un desk utile a besoin des deux.

Développement 1 — Le fil de conversation dans le graphe

Le fil de conversation est la clé messages de l'état, avec le réduveur add_messages. Au premier tour, l'état contient un message humain ; le nœud agent ajoute la réponse ; au tour suivant, la liste a grandi. Pour garder plusieurs conversations distinctes, on associe un identifiant de fil (thread id) à chaque exécution : c'est cet identifiant qui, avec un gestionnaire de points de contrôle (leçon 18), permet de retrouver l'historique.

Développement 2 — Le magasin de faits nommés

Le second tiroir est un magasin clé-valeur. On y écrit un fait sous une entité et une clé, et on le relit plus tard, éventuellement sur un autre fil. Un profil client typique porte : préférence de contact, formule, région, plafond de remboursement. La relecture se fait sans passer par le modèle : c'est le code qui lit le magasin et l'injecte dans l'invite au bon moment.

"""Magasin de faits nommés : ecrire sur un fil, relire sur un autre."""
from langgraph.store.memory import InMemoryStore

store = InMemoryStore()

# Ecriture : le client prefere l'e-mail (namespace = client, cle = preference)
store.put(("client", "C-2048"), "contact_pref", {"valeur": "email", "source": "ticket #118"})

# Relecture, plus tard, dans un autre fil :
fait = store.get(("client", "C-2048"), "contact_pref")
print(fait.value)   # {'valeur': 'email', 'source': 'ticket #118'}

Développement 3 — Retrouver une note par similarité

Le magasin accepte aussi une recherche par similarité : au lieu de connaître la clé exacte, on cherche les faits ou les notes les plus proches d'une requête, avec un score et un plancher. Le plancher est la garantie de qualité : sous un certain score, on ne renvoie rien, plutôt que de renvoyer un fait hors sujet.

Exemple concret / mise en pratique

Le desk Dataflow lit le profil d'un client avant de traiter son ticket, et écrit un fait seulement s'il est durable.

InformationTiroirÉcritureRelecture
Message du ticketFil (messages)Ajout automatiqueAu tour suivant
Préférence de contactMagasin de faitsSi exprimée explicitementAvant chaque réponse
Règle énoncée « pas plus de 40 € »Note (fait nommé)Avec source et expirationAvant tout remboursement
Historique brut de la semaineAucun (minimisation)JamaisJamais

Exercice guidé (10–15 min)

La suite (leçons 2 à 4, quiz, lab et livrable) est accessible après une inscription gratuite.

Module 6

RAG : de la source à la réponse ancrée

4 leçons · 0 min · quiz 6 questions (seuil 5/6) · lab 8 étapes

Leçons

  1. Leçon 1 — Charger, découper : de la source aux segments0 min
  2. Leçon 2 — Plongements, index et base vectorielle0 min
  3. Leçon 3 — Du récupérateur à la réponse : route, retrieve, grade, rewrite0 min
  4. Leçon 4 — Ancrage, citations, refus et évaluation0 min
Lire l'aperçu gratuit : leçon 1 — Charger, découper : de la source aux segments

Durée conseillée : 50 min

Le contexte

La base documentaire du desk Dataflow est une pile réaliste : une vingtaine de fichiers, répartis en plusieurs dossiers et plusieurs formats (pages clients, données d'entreprise, procédures internes, pages légales, wiki). Avant de chercher quoi que ce soit, il faut lire ces fichiers et les mettre dans une forme que le reste de la chaîne comprend. Et cette forme a une propriété détestable : si le découpage est mauvais, le nom du fait auquel appartient un passage risque de se perdre.

Idée centrale

Deux étapes précèdent toute recherche : le chargement (loaders) et le découpage en segments (chunking). Le chargement lit les fichiers et en extrait du texte avec des métadonnées (nom, source). Le découpage coupe ce texte en morceaux assez petits pour être cherchés et plongés. Le piège est que le nom du fait (« politique de retour », « procédure d'expédition ») vit souvent dans un titre, pas dans le corps : un découpage naïf peut le laisser derrière lui.

Développement 1 — Le chargement et les formats

Une base réaliste est hétérogène. Il faut un chargeur par famille de formats : texte brut et Markdown pour les pages, CSV/JSON pour les données structurées, PDF pour les documents légaux. Chaque chargeur produit un document portant un texte et des métadonnées (source, titre, section). Normaliser tôt (même structure de document) évite de traiter des cas particuliers à chaque étape suivante.

"""Chargement de la base Dataflow en documents normalises."""
from langchain_community.document_loaders import TextLoader, JSONLoader

dossiers = {
    "clients": "data/dataflow/clients",
    "entreprise": "data/dataflow/business",
    "operations": "data/dataflow/ops",
    "legal": "data/dataflow/legal",
}

documents = []
for section, chemin in dossiers.items():
    for fichier in Path(chemin).glob("*"):
        loader = TextLoader(str(fichier), encoding="utf-8")
        for doc in loader.load():
            doc.metadata["section"] = section        # tracabilite de la source
            documents.append(doc)

print(f"{len(documents)} documents charges")   # ordre de grandeur : ~20 fichiers

Développement 2 — Le découpage en segments

Un document est trop gros pour être présenté en entier au modèle et trop gros pour être plongé comme un seul point. On le coupe en segments avec un chevauchement (overlap) pour ne pas perdre le contexte aux jointures. Le paramètre chunk_size arbitre entre précision (petits segments) et contexte (grands segments).

"""Decoupage en segments avec chevauchement."""
from langchain_text_splitters import RecursiveCharacterTextSplitter

splitter = RecursiveCharacterTextSplitter(
    chunk_size=800,
    chunk_overlap=120,           # on garde un peu de contexte aux jointures
    separators=["\n\n", "\n", ". ", " "],
)
segments = splitter.split_documents(documents)
print(f"{len(segments)} segments")   # ordre de grandeur : plusieurs centaines

Développement 3 — Garder le nom du fait

Le piège central du découpage : des segments qui portent le contenu d'une règle sans son nom. Un remède efficace est de préfixer chaque segment par le titre de sa section (ou d'utiliser un découpage par structure, section par section). Ainsi, un segment contient à la fois le fait et le nom du fait, ce qui améliore la récupération et rend la citation possible.

"""Prefixer chaque segment par sa section : garder le nom du fait."""
for seg in segments:
    titre = seg.metadata.get("titre", seg.metadata["section"])
    seg.page_content = f"[{titre}] {seg.page_content}"

Exercice guidé (10–15 min)

La suite (leçons 2 à 4, quiz, lab et livrable) est accessible après une inscription gratuite.

Module 7

Évaluation, observabilité et fiabilité avec LangSmith

5 leçons · 0 min · quiz 6 questions (seuil 5/6) · lab 8 étapes

Leçons

  1. Leçon 1 — Tracer et explorer les runs dans LangSmith0 min
  2. Leçon 2 — Jeux de données et évaluateurs de base0 min
  3. Leçon 3 — Jeux de données et évaluateurs de base0 min
  4. Leçon 4 — Évaluation offline et en ligne0 min
  5. Leçon 5 — Prompts versionnés, annotations et LangSmith Studio0 min
Lire l'aperçu gratuit : leçon 1 — Tracer et explorer les runs dans LangSmith

Durée conseillée : 50 min

Le contexte

Tout agent IA produit des données. Un appel de modèle produit du texte, du coût et du temps. Un outil produit des résultats ou lève une exception. Un noeud du graphe choisit une branche ou une autre. Sans traces, ces données disparaissent dans la mer. Avec les traces, on peut ouvrir une exécution et voir précisément ce qui s'est passé, ligne par ligne, appel par appel.

LangSmith fournit une plateforme centralisée pour collecter, stocker et explorer ces traces. Elle répond à trois questions : qu'est-ce qui s'est passé ? pourquoi ? et est-ce que cela coûte trop cher ?

Idée centrale

La trace est une ligne de vie de l'exécution d'un agent. Elle est organisée en trois niveaux :

  • Projet : un conteneur logique, type "support-dataflow", qui regroupe toutes les traces pour un usage donné.
  • Run : un appel unique à l'agent (une invocation de la boucle principale).
  • Span : un appel imbriqué (un modèle, un outil, un noeud de graphe).

Développement 1 — Activation du tracer

Chaque module de l'agent construit un objet de configuration qui retourne des callbacks LangSmith. Le module 4 a démontré l'extraction d'un modèle depuis un fichier de configuration. Le module 7 ajoute la couche d'observabilité.

\"\"\"Configurer LangSmith pour le bureau support-dataflow.\"\"\"
from langsmith import Client

client = Client()

def config():
    return {
        'callbacks': [LangSmithCallbackHandler(
            project_name='support-dataflow',
            sync=False
        )],
        'metadata': {
            'domain': 'support',
            'team': 'dataflow',
            'version': '0.1.0',
        },
    }

Développement 2 — Explorer une trace

Dans LangSmith Studio, on cherche un run par le modèle de requête, l'horodatage ou la charge utile. La vue d'ensemble affiche un graphe de la trace : le nœud generate avec ses entrées et sorties, le nœud chercher_politique et ses résultats, l'arête qui a guidé l'exécution.

L'état de la trace donne accès à :

  • Les arguments de l'appel (la question, le contexte)
  • Les sorties (la réponse, les sources)
  • Les métriques (coût, tokens émis, durée, latence)
  • Les erreurs (exceptions levées, classes de nerveuse)
\"\"\"Exemple d'exécution avec résultat dans LangSmith.\"\"\"
from langchain_core.messages import HumanMessage

reponse = agent.invoke(
    {'question': 'Quel est le délai de retour pour un article ?'},
    config=config()
)

print(reponse['answer'][:80])
# "Le délai de retour est de 30 jours pour les articles en bon état."

Exercice guidé (10-15 min)

Synthèse

  • Un projet regroupe les traces par usage.
  • Un run est un appel de l'agent avec toutes ses spans.
  • Une span est un appel imbriqué (modèle, outil, nœud).
  • Les métriques clés : coût, tokens, latence, erreurs.

La suite (leçons 2 à 5, quiz, lab et livrable) est accessible après une inscription gratuite.

Module 8

Frameworks Multi-Agents et Gestion de l Équipe

4 leçons · 0 min · quiz 6 questions (seuil 5/6) · lab 8 étapes

Leçons

  1. Leçon 1 — LangFlow : les workflows visuels0 min
  2. Leçon 2 — Multi-agent systems : la théorie0 min
  3. Leçon 3 — AutoGen : le framework Microsoft0 min
  4. Leçon 4 — Projet AutoGen portfolio0 min
Lire l'aperçu gratuit : leçon 1 — LangFlow : les workflows visuels

Durée conseillée : 50 min

Le contexte

LangFlow est une interface de dessin de workflows. Contrairement aux modules précédents où vous avez écrit du code, ici vous arrangez des blocs graphiques qui représentent les étapes d un pipeline. LangFlow est construit sur LangChain et utilise les mêmes composants sous jacents.

Idée centrale

Un workflow LangFlow est un graphe orienté. Les nœuds sont des composants (modèle, outil, chargeur, etc.) et les arêtes représentent les données qui circulent entre eux.

Développement 1 — Créer un workflow

  1. Ouvrez LangFlow et créez un nouveau projet.
  2. Ajoutez un nœud ChatInput pour recevoir la question.
  3. Connectez-le au nœud ChatModel.
  4. Ajoutez un nœud ChatOutput pour afficher la réponse.
  5. Lancez l exécution.
ChatInput --> ChatModel --> ChatOutput

Développement 2 — Ajouter un outil

Pour ajouter un outil, placez un nœud Tool et connectez le au ChatModel. Vous pouvez configurer les paramètres de l outil directement dans l interface.

Exercice guidé (10-15 min)

Synthèse

  • LangFlow est un outil visuel pour construire des workflows.
  • Les nœuds sont reliés par des arêtes.
  • Le workflow est un graphe orienté.

La suite (leçons 2 à 4, quiz, lab et livrable) est accessible après une inscription gratuite.

Prêt à valider le parcours ?

Inscription gratuite, progression enregistrée, quiz corrigés automatiquement et certificat vérifiable une fois le projet final validé.