1. Wprowadzenie do LCEL

LCEL (LangChain Expression Language) to prosty i łatwy w użyciu framework do budowania skomplikowanych łańcuchów. Zapewnia on znormalizowane interfejsy i podstawowe elementy składowe, które ułatwiają budowę łańcuchów. Każdy obiekt LCEL implementuje interfejs Runnable, definiując zestaw powszechnie używanych metod wywołania (takich jak invoke, batch, stream, ainvoke, itp.). Dlatego łańcuchy obiektów LCEL mogą również automatycznie obsługiwać te metody wywołania, co sprawia, że łańcuch każdego obiektu LCEL jest sam w sobie obiektem LCEL.

2. Wywoływanie

2.1. Bez użycia LCEL

Bez użycia LCEL możesz użyć poniższego kodu, aby przekazać ciąg tematów i uzyskać ciąg dowcipu.

from typing import List
import openai

szablon_promptu = "Powiedz mi krótki kawał na temat {topic}"
klient = openai.OpenAI()

def wywołaj_model_chat(messages: List[dict]) -> str:
    odpowiedź = klient.chat.completions.create(
        model="gpt-3.5-turbo", 
        messages=messages,
    )
    return odpowiedź.choices[0].message.content

def wywołaj_łańcuch(topic: str) -> str:
    wartość_promptu = szablon_promptu.format(topic=topic)
    messages = [{"role": "user", "content": wartość_promptu}]
    return wywołaj_model_chat(messages)

wywołaj_łańcuch("lody")

2.2. Korzystając z LCEL

Natomiast korzystając z LCEL można osiągnąć tę samą funkcjonalność bardziej zwięźle. Poniższy fragment kodu demonstruje, jak łatwo zbudować łańcuch za pomocą obiektów 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

prompt = ChatPromptTemplate.from_template(
    "Powiedz mi krótki kawał na temat {topic}"
)
output_parser = StrOutputParser()
model = ChatOpenAI(model="gpt-3.5-turbo")
chain = (
    {"topic": RunnablePassthrough()} 
    | prompt
    | model
    | output_parser
)

chain.invoke("lody")

3. Strumieniowanie

3.1. Bez użycia LCEL

Poniższy fragment kodu demonstruje, jak przetwarzać wyniki strumieniowo bez użycia LCEL.

from typing import Iterator

def strumieniuj_model_chat(messages: List[dict]) -> Iterator[str]:
    strumień = klient.chat.completions.create(
        model="gpt-3.5-turbo",
        messages=messages,
        stream=True,
    )
    for odpowiedź in strumień:
        zawartość = odpowiedź.choices[0].delta.content
        if zawartość is not None:
            yield zawartość

def strumieniuj_łańcuch(topic: str) -> Iterator[str]:
    wartość_promptu = prompt.format(topic=topic)
    strumień = strumieniuj_model_chat([{"role": "user", "content": wartość_promptu}])
    for kawałek in strumień:
        print(kawałek, end="", flush=True)

strumieniuj_łańcuch("lody")

3.2. Korzystając z LCEL

Przetwarzanie wyników strumieniowo za pomocą LCEL jest bardziej wygodne. Poniższy fragment kodu demonstruje, jak strumieniować za pomocą LCEL.

for kawałek in chain.stream("lody"):
    print(kawałek, end="", flush=True)

4. Przetwarzanie wsadowe

4.1. Bez użycia LCEL

Poniższy fragment kodu demonstruje, jak równolegle przetwarzać wsadowo zestaw wejść bez użycia LCEL.

from concurrent.futures import ThreadPoolExecutor

def przetwarzaj_łańcuch_wsadowo(topics: list) -> list:
    with ThreadPoolExecutor(max_workers=5) as executor:
        return list(executor.map(wywołaj_łańcuch, topics))

przetwarzaj_łańcuch_wsadowo(["lody", "makaron", "pierogi"])

4.2. Korzystając z LCEL

Przetwarzanie wsadowe za pomocą LCEL jest bardzo proste. Poniższy fragment kodu demonstruje, jak używać LCEL do przetwarzania wsadowego.

chain.batch(["lody", "makaron", "pierogi"])