AI Engineering Academy · Leçon

Construire des chaînes avec LCEL

Utilisez l’opérateur de tube pour relier un modèle de prompt, un LLM et un analyseur de sortie en une séquence Runnable, appelez-la de manière synchrone et asynchrone, puis examinez les sorties intermédiaires.

Leçon 2 sur 413 étapes

Construire des chaînes avec LCEL est une leçon AI Engineering Academy gratuite sur CoddyKit. Ceci est la leçon 2 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage AI Engineering Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours AI Engineering Academy comprend 4 leçons au total.

Qu’est-ce que LCEL ?

LCEL (LangChain Expression Language) est la manière déclarative de composer des composants LangChain en pipelines. Au lieu d’instancier des classes Chain verbeuses, vous connectez les Runnables avec l’opérateur |. Les chaînes LCEL prennent automatiquement en charge la transmission en continu, l’exécution asynchrone, le traitement par lots et les solutions de repli : vous bénéficiez de toutes ces fonctionnalités simplement en utilisant la syntaxe pipeline.

Votre première chaîne LCEL

La chaîne LCEL la plus simple combine un PromptTemplate, un ChatModel et un OutputParser. Chaque composant est un Runnable et l’opérateur pipeline les relie. Lorsque vous appelez chain.invoke(), l’entrée traverse chaque étape dans l’ordre, la sortie de chacune devenant l’entrée de la suivante.

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

prompt = ChatPromptTemplate.from_template(
    'Write a product description for: {product}'
)
model = ChatOpenAI(model='gpt-4o-mini', temperature=0.7)
parser = StrOutputParser()

chain = prompt | model | parser

result = chain.invoke({'product': 'noise-cancelling headphones'})
print(result)

Examiner les composants internes d’une chaîne

Les chaînes LCEL exposent leur structure de manière transparente. chain.steps répertorie les composants dans l’ordre. Vous pouvez appeler chain.input_schema et chain.output_schema pour examiner les types qui entrent et sortent. L’appel invoke() accepte également un paramètre config permettant de transmettre les noms d’exécution, les balises et les rappels à un appel donné sans modifier la définition de la chaîne.

# Inspect chain structure
print('Steps:', chain.steps)
print('Input schema:', chain.input_schema.schema())
print('Output schema:', chain.output_schema.schema())

# Named run for observability
result = chain.invoke(
    {'product': 'coffee maker'},
    config={'run_name': 'product-desc-run', 'tags': ['production']}
)

Appel synchrone ou asynchrone

Les chaînes LCEL proposent des versions synchrones et asynchrones de toutes les méthodes. invoke() bloque le thread appelant. ainvoke() est l’équivalent asynchrone et doit être utilisé dans les gestionnaires FastAPI et autres contextes asynchrones afin d’éviter de bloquer la boucle d’événements. La version asynchrone a une sémantique identique : seule l’interface diffère, avec await.

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

chain = ChatPromptTemplate.from_template('Explain {topic}') | ChatOpenAI() | StrOutputParser()

async def main():
    # Async invocation
    result = await chain.ainvoke({'topic': 'quantum computing'})
    print(result)

asyncio.run(main())

Transmettre les jetons dans la chaîne

Les chaînes LCEL transmettent le flux continu de bout en bout. Appelez chain.stream() pour recevoir les jetons au fur et à mesure de leur génération par le modèle. StrOutputParser sait gérer la transmission en continu et transmet les fragments de chaîne individuels au lieu d’attendre la réponse complète. Les utilisateurs obtiennent ainsi un retour immédiat plutôt qu’une longue pause suivie de la réponse entière.

chain = (
    ChatPromptTemplate.from_template('Tell me about {topic} in detail.')
    | ChatOpenAI(model='gpt-4o-mini')
    | StrOutputParser()
)

# Print each token as it arrives
for chunk in chain.stream({'topic': 'neural networks'}):
    print(chunk, end='', flush=True)
print()  # newline at end

# Async streaming
async def stream_async():
    async for chunk in chain.astream({'topic': 'transformers'}):
        print(chunk, end='', flush=True)

Traiter plusieurs entrées par lots

chain.batch() accepte une liste de dictionnaires d’entrée et les traite avec une concurrence configurable. En interne, LangChain exécute les appels dans des threads parallèles, ce qui rend le traitement par lots bien plus rapide qu’un appel à invoke() dans une boucle. Le paramètre max_concurrency limite le nombre d’appels d’API parallèles afin de respecter les limites de débit. Les résultats sont renvoyés dans le même ordre que les entrées.

products = [
    {'product': 'laptop'},
    {'product': 'tablet'},
    {'product': 'smartwatch'},
    {'product': 'earbuds'},
]

# Process all 4 concurrently
results = chain.batch(products, config={'max_concurrency': 4})

for product, description in zip(products, results):
    print(f'{product["product"]}: {description[:80]}...')

RunnablePassthrough et RunnableLambda

RunnablePassthrough transmet son entrée sans la modifier, ce qui est utile pour faire circuler le contexte d’origine avec des données transformées. RunnableLambda encapsule n’importe quelle fonction Python en tant que Runnable, ce qui vous permet d’insérer une logique arbitraire dans une chaîne LCEL. Ensemble, ils permettent de manipuler les données entre les étapes d’une chaîne sans écrire une classe Runnable personnalisée complète.

from langchain_core.runnables import RunnablePassthrough, RunnableLambda

def word_count(text: str) -> str:
    count = len(text.split())
    return f'{text}\n\n[Word count: {count}]'

chain = (
    ChatPromptTemplate.from_template('Write about {topic}')
    | ChatOpenAI(model='gpt-4o-mini')
    | StrOutputParser()
    | RunnableLambda(word_count)  # Add word count to output
)

result = chain.invoke({'topic': 'climate change'})
print(result)

Transmettre un contexte supplémentaire avec RunnablePassthrough

Dans les systèmes RAG, il est courant de transmettre à l’invite finale à la fois les documents récupérés et la question de l’utilisateur. Utilisez RunnablePassthrough.assign() pour ajouter des champs calculés au dictionnaire d’entrée sans perdre les clés d’origine. Cela enrichit l’objet de contexte au fil de la chaîne et rend toutes les données disponibles pour le modèle d’invite.

from langchain_core.runnables import RunnablePassthrough

# Fake retriever for illustration
def retrieve_docs(question: str):
    return ['Doc 1 content', 'Doc 2 content']

retriever = RunnableLambda(retrieve_docs)

rag_chain = (
    RunnablePassthrough.assign(context=retriever)  # adds 'context' key
    | ChatPromptTemplate.from_template(
        'Context: {context}\n\nAnswer: {question}'
    )
    | ChatOpenAI()
    | StrOutputParser()
)

result = rag_chain.invoke({'question': 'What is machine learning?'})

Ajouter des solutions de repli aux chaînes

Les chaînes LCEL prennent en charge les solutions de repli — des chaînes de remplacement à essayer si la chaîne principale lève une exception. Appelez chain.with_fallbacks([backup_chain]) pour enregistrer une ou plusieurs chaînes de repli. LangChain essaie d’abord la chaîne principale, intercepte toute exception, puis essaie chaque solution de repli dans l’ordre. C’est la méthode standard pour gérer correctement les interruptions d’un fournisseur ou les erreurs de modèle.

from langchain_openai import ChatOpenAI
from langchain_anthropic import ChatAnthropic

primary_chain = (
    ChatPromptTemplate.from_template('Answer: {question}')
    | ChatOpenAI(model='gpt-4o')
    | StrOutputParser()
)

fallback_chain = (
    ChatPromptTemplate.from_template('Answer: {question}')
    | ChatAnthropic(model='claude-3-haiku-20240307')
    | StrOutputParser()
)

robust_chain = primary_chain.with_fallbacks([fallback_chain])
# If OpenAI fails, automatically tries Anthropic

Déboguer avec intermediate_steps

Le débogage des chaînes LCEL est plus simple avec la configuration de invoke() et l’option verbose=True. Vous pouvez également utiliser .with_config({'verbose': True}) sur n’importe quelle chaîne afin de journaliser l’entrée et la sortie de chaque étape. Pour un débogage structuré, enveloppez globalement la chaîne avec set_verbose(True) ou utilisez le traçage LangSmith afin de capturer chaque valeur intermédiaire dans un explorateur visuel des traces.

from langchain.globals import set_verbose, set_debug

# Verbose: logs LLM inputs/outputs
set_verbose(True)

# Debug: logs everything including prompts, parsers, and runnables
set_debug(True)

result = chain.invoke({'product': 'smart watch'})

# Or per-chain verbose config
chain_debug = chain.with_config({'verbose': True})
result = chain_debug.invoke({'product': 'laptop'})

Chaînes configurables à l’exécution

Les chaînes LCEL prennent en charge la configuration à l’exécution via ConfigurableField. Vous pouvez exposer les paramètres du modèle — température, nom du modèle, max_tokens — comme options configurables sans les coder en dur. Au moment de l’appel, transmettez une configuration Configurable pour remplacer les valeurs par défaut. Une même chaîne peut ainsi servir plusieurs utilisateurs ayant des paramètres différents ou permettre de tester des configurations de modèle en A/B.

from langchain_core.runnables import ConfigurableField

llm = ChatOpenAI(model='gpt-4o-mini').configurable_fields(
    temperature=ConfigurableField(
        id='temperature',
        name='LLM Temperature',
        description='Controls output creativity'
    )
)

chain = ChatPromptTemplate.from_template('Write about {topic}') | llm | StrOutputParser()

# Low temperature for factual output
factual = chain.invoke(
    {'topic': 'history of Rome'},
    config={'configurable': {'temperature': 0.0}}
)

Vérification rapide

Vérifiez votre compréhension de la création de chaînes avec LCEL.

Récapitulatif de la leçon

Dans cette leçon, vous avez appris que la composition LCEL avec l’opérateur pipeline relie les Runnables avec | pour former des pipelines clairs et lisibles ; que RunnablePassthrough et RunnableLambda permettent d’insérer des étapes de manipulation des données sans sortir du paradigme LCEL ; et que les solutions de repli rendent les chaînes résistantes aux erreurs en essayant automatiquement des chaînes de secours en cas d’échec. Nous allons maintenant explorer les chaînes parallèles et à embranchements pour gérer des routages plus complexes.

Gratuit pour commencer

Apprends Python avec un tuteur IA — gratuit

Écris et exécute du vrai code dans ton navigateur, obtiens de l'aide instantanée d'un tuteur IA disponible 24h/24, et reprends là où tu t'es arrêté sur le web ou dans l'app.

Cours
30
Leçons
120

Questions Fréquemment Posées

La leçon « Construire des chaînes avec LCEL » est-elle gratuite ?

Oui — le texte complet de « Construire des chaînes avec LCEL » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours AI Engineering Academy, passe à CoddyKit PRO. Le cours AI Engineering Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Construire des chaînes avec LCEL » ?

Utilisez l’opérateur de tube pour relier un modèle de prompt, un LLM et un analyseur de sortie en une séquence Runnable, appelez-la de manière synchrone et asynchrone, puis examinez les sorties inter… Tu pratiques AI Engineering Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer AI Engineering Academy ?

Aucune expérience préalable n'est requise. AI Engineering Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 2 sur 4.

Combien de temps prend la leçon « Construire des chaînes avec LCEL » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon AI Engineering Academy ?

Oui. Chaque leçon AI Engineering Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Architecture de LangChain et abstractions fondamentales
  2. Construire des chaînes avec LCEL
  3. Chaînes conditionnelles et parallèles
  4. Diffuser la sortie avec LangChain
← Retour à AI Engineering Academy