Aller au contenu principal

Module 1 — Ce que LangChain apporte et ce qu'il complique

Un premier curl vers l'API d'un fournisseur de LLM tient en trois lignes. Un assistant qui lit des documents, se souvient de la conversation, appelle des outils et bascule entre deux modèles selon le coût dépasse le millier de lignes — et l'essentiel n'est plus l'appel réseau mais la plomberie autour. LangChain propose des abstractions communes pour cette plomberie. Ce module explique ce qu'elles apportent, ce qu'elles coûtent, et à quel moment il vaut mieux écrire l'appel à la main.

Le fil rouge et pourquoi il justifie une bibliothèque

Notre assistant de notes de frais doit, au module 10, faire coopérer six briques : appeler un modèle chat, valider une sortie structurée en pydantic, chercher dans une centaine de justificatifs, retrouver la politique de remboursement, se souvenir du contexte utilisateur et déclencher un outil qui écrit une ligne dans un tableur. Sans bibliothèque, chacune de ces briques réinvente sa propre interface. Le jour où l'on remplace OpenAI par Ollama (cours 29) pour tester en local, il faut réécrire les six.

L'apport de LangChain tient en une phrase : des interfaces qui survivent au changement de fournisseur. Un modèle chat expose .invoke(), .stream(), .batch() que l'implémentation soit ChatOpenAI, ChatAnthropic ou ChatOllama. Un Retriever expose .invoke(query) que le vecteur vive dans Chroma, FAISS ou Pinecone. Vous ne réécrivez pas l'assistant quand le contexte technique change ; vous changez une ligne d'import.

L'écosystème en trois couches

Il faut distinguer trois paquets qui ne se confondent pas et qu'un lecteur pressé mélange :

PaquetRôle
langchain-coreInterfaces stables : Runnable, ChatModel, Retriever, messages, gabarits. Peu de dépendances, très stable.
langchainCha\u00eenes prêtes, agents historiques, utilitaires. Historiquement instable, décomposé au fil des versions.
langchain-<fournisseur>Adaptateurs par fournisseur : langchain-openai, langchain-anthropic, langchain-chroma. Un par intégration.
langgraphMachine à états pour agents et flux complexes (module 8). Autonome de langchain.

La règle pratique : dépendre de langchain-core et d'un ou deux adaptateurs, éviter d'importer depuis langchain.chains ou langchain.agents. Ces sous-modules ont beaucoup bougé et servent surtout de compatibilité descendante.

LCEL en une minute

Le LangChain Expression Language (LCEL) est l'opérateur | de Python appliqué à des Runnable. Une chaîne s'y lit comme un pipeline shell :

from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

modele = ChatOpenAI(model="gpt-4o-mini", temperature=0)
consigne = ChatPromptTemplate.from_messages([
("system", "Vous répondez aux questions sur la politique de notes de frais."),
("human", "{question}"),
])
chaine = consigne | modele | StrOutputParser()

print(chaine.invoke({"question": "Le taxi vers un aéroport est-il remboursable ?"}))

Trois Runnable composés en cinq lignes : gabarit, modèle, analyseur. La chaîne obtenue expose gratuitement .stream() (flux jeton par jeton), .batch() (plusieurs entrées en parallèle) et l'exécution asynchrone. Un module ne remplace pas cet apport par un for avec openai.chat.completions.create.

Le coût de l'abstraction

Une abstraction n'est jamais gratuite ; il faut la nommer.

Une couche de plus à déboguer. Un TypeError dans RunnableSequence.invoke est plus long à lire qu'un appel direct. Le module 9 sur le traçage n'est pas un luxe, c'est le contrepoids de cette couche.

Une surface qui bouge. langchain-core est stable depuis la version 0.3, mais les cha\u00eenes prêtes et les agents ont changé trois fois d'interface en deux ans. Épingler les versions dans requirements.txt n'est pas optionnel.

La tentation de tout envelopper. Un simple résumez ce texte ne mérite pas trois Runnable. La règle : dès qu'on a une seconde entrée à passer, une sortie structurée à parser, ou un fournisseur à pouvoir changer, LCEL gagne. En dessous, client.chat.completions.create() reste plus lisible.

Quand écrire l'appel à la main

Trois situations où LangChain n'aide pas :

  • Un seul appel, une seule sortie, un seul fournisseur assumé. Un script d'annotation de tickets qui tourne une fois par jour ne mérite pas une chaîne.
  • Latence critique. L'orchestrateur ajoute des microsecondes de dispatch par nœud. Sur un service qui vise la milliseconde, httpx direct reste préférable.
  • Un fournisseur unique avec des fonctionnalités très spécifiques. Les outils natifs d'Anthropic ou la sortie JSON stricte d'OpenAI sont exposés par LangChain avec un léger décalage. Pour utiliser une nouveauté du jour, l'SDK officiel est en avance.
Le vrai gain

LangChain n'accélère pas votre premier appel : il rend possible le passage de l'appel unique au pipeline testé, tracé, portable, sans réécrire le tout. C'est un investissement qui devient rentable dès qu'il y a plus d'une brique.

Ce que le module ne fait pas

Ce cours n'oppose pas LangChain à ses concurrents (LlamaIndex, Haystack). Les concepts — chaîne, récupérateur, mémoire, outil, agent — sont universels. Après ce cours, vous saurez lire n'importe lequel de ces cadres.

En résumé

  • LangChain propose des interfaces communes aux fournisseurs de LLM, de vecteurs et d'outils : on change d'implémentation en changeant un import.
  • L'écosystème utile en 2026 : langchain-core pour les interfaces, langchain-<fournisseur> pour les adaptateurs, langgraph pour les agents.
  • LCEL compose des Runnable avec | et donne gratuitement .invoke, .stream, .batch et l'exécution asynchrone.
  • L'abstraction se justifie à partir de la deuxième brique ; pour un appel isolé, l'SDK du fournisseur reste plus simple à lire.

Module suivant : les modèles chat, les gabarits de consigne et les analyseurs de sortie qui ferment la première brique du pipeline.