1. Introduction à LCEL

LCEL (LangChain Expression Language) est un framework simple et facile à utiliser pour construire des chaînes complexes. Il fournit une interface unifiée et des primitives composites pour faciliter la construction des chaînes. Chaque objet LCEL implémente l'interface Runnable, définissant un ensemble de méthodes d'invocation couramment utilisées (telles que invoke, batch, stream, ainvoke, etc.). Par conséquent, les chaînes d'objets LCEL peuvent également automatiquement prendre en charge ces méthodes d'invocation, faisant ainsi de la chaîne de chaque objet LCEL un objet LCEL en soi.

2. Invocation

2.1. Sans utiliser LCEL

Sans utiliser LCEL, vous pouvez utiliser le code suivant pour transmettre une chaîne de sujet et récupérer une chaîne de blague.

from typing import List
import openai

template_demande = "Raconte-moi une petite blague à propos de {sujet}"
client = openai.OpenAI()

def appeler_modele_chat(messages: List[dict]) -> str:
    reponse = client.chat.completions.create(
        model="gpt-3.5-turbo", 
        messages=messages,
    )
    return reponse.choices[0].message.content

def invoquer_chaine(sujet: str) -> str:
    valeur_demande = template_demande.format(sujet=sujet)
    messages = [{"role": "utilisateur", "content": valeur_demande}]
    return appeler_modele_chat(messages)

invoquer_chaine("glace")

2.2. En utilisant LCEL

En revanche, l'utilisation de LCEL permet d'obtenir la même fonctionnalité de manière plus concise. Le code suivant démontre comment construire facilement une chaîne en utilisant des objets LCEL.

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

demande = ChatPromptTemplate.from_template(
    "Raconte-moi une petite blague à propos de {sujet}"
)
output_parser = StrOutputParser()
modele = ChatOpenAI(model="gpt-3.5-turbo")
chaine = (
    {"sujet": RunnablePassthrough()} 
    | demande
    | modele
    | output_parser
)

chaine.invoke("glace")

3. Diffusion

3.1. Sans utiliser LCEL

Le code suivant démontre comment diffuser des résultats de processus sans utiliser LCEL.

from typing import Iterator

def diffuser_modele_chat(messages: List[dict]) -> Iterator[str]:
    stream = client.chat.completions.create(
        model="gpt-3.5-turbo",
        messages=messages,
        stream=True,
    )
    for reponse in stream:
        contenu = reponse.choices[0].delta.content
        if contenu is not None:
            yield contenu

def diffuser_chaine(sujet: str) -> Iterator[str]:
    valeur_demande = template_demande.format(sujet=sujet)
    stream = diffuser_modele_chat([{"role": "utilisateur", "content": valeur_demande}])
    for morceau in stream:
        print(morceau, end="", flush=True)

diffuser_chaine("glace")

3.2. En utilisant LCEL

Diffuser des résultats de processus en utilisant LCEL est plus pratique. Le code suivant démontre comment diffuser avec LCEL.

for morceau in chaine.stream("glace"):
    print(morceau, end="", flush=True)

4. Traitement par lot

4.1. Sans utiliser LCEL

Le code suivant démontre comment traiter en parallèle un lot d'entrées sans utiliser LCEL.

from concurrent.futures import ThreadPoolExecutor

def chaine_lot(sujets: list) -> list:
    with ThreadPoolExecutor(max_workers=5) as executor:
        return list(executor.map(invoquer_chaine, sujets))

chaine_lot(["glace", "spaghetti", "boulettes"])

4.2. En utilisant LCEL

Le traitement par lot en utilisant LCEL est très simple. Le code suivant démontre comment utiliser LCEL pour le traitement par lot.

chaine.batch(["glace", "spaghetti", "boulettes"])