1. مقدمهای درباره LCEL
LCEL (زبان بیان لنگ یا LangChain Expression Language) یک چارچوب ساده و آسان برای ساخت زنجیرههای پیچیده است. این یک رابط یکپارچه و اولویتهای ترکیبی را فراهم میکند تا ساخت زنجیرهها را آسانتر کند. هر شیئ LCEL رابط Runnable
را پیادهسازی میکند که یک مجموعهای از روشهای فراخوانی متدهای معمول (مانند invoke
، batch
، stream
، ainvoke
و غیره) را تعریف میکند. بنابراین، زنجیرههای شیهای LCEL همچنین این روشهای فراخوانی را به طور خودکار پشتیبانی میکنند، زیرا زنجیره هر شی LCEL به تنهایی یک شی LCEL است.
2. فراخوانی
2.1. بدون استفاده از LCEL
بدون استفاده از LCEL، میتوانید از کد زیر برای ارسال یک رشته موضوع و دریافت یک شوخی استفاده کنید.
from typing import List
import openai
prompt_template = "Tell me a short joke about {topic}"
client = openai.OpenAI()
def call_chat_model(messages: List[dict]) -> str:
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=messages,
)
return response.choices[0].message.content
def invoke_chain(topic: str) -> str:
prompt_value = prompt_template.format(topic=topic)
messages = [{"role": "user", "content": prompt_value}]
return call_chat_model(messages)
invoke_chain("ice cream")
2.2. با استفاده از LCEL
در مقابل، با استفاده از LCEL میتوان به طور خلاصهتر قابلیت مشابه را به دست آورد. کد زیر نشان میدهد که چگونه با استفاده از اشیاء 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(
"Tell me a short joke about {topic}"
)
output_parser = StrOutputParser()
model = ChatOpenAI(model="gpt-3.5-turbo")
chain = (
{"topic": RunnablePassthrough()}
| prompt
| model
| output_parser
)
chain.invoke("ice cream")
3. استریمینگ
3.1. بدون استفاده از LCEL
کد زیر نشان میدهد که چگونه میتوان نتایج پردازش را بدون استفاده از LCEL استریم کرد.
from typing import Iterator
def stream_chat_model(messages: List[dict]) -> Iterator[str]:
stream = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=messages,
stream=True,
)
for response in stream:
content = response.choices[0].delta.content
if content is not None:
yield content
def stream_chain(topic: str) -> Iterator[str]:
prompt_value = prompt.format(topic=topic)
stream = stream_chat_model([{"role": "user", "content": prompt_value}])
for chunk in stream:
print(chunk, end="", flush=True)
stream_chain("ice cream")
3.2. با استفاده از LCEL
استریم کردن نتایج پردازش با استفاده از LCEL راحتتر است. کد زیر نشان میدهد که چگونه میتوان با LCEL استریم کرد.
for chunk in chain.stream("ice cream"):
print(chunk, end="", flush=True)
4. پردازش دستهای
4.1. بدون استفاده از LCEL
کد زیر نشان میدهد که چگونه میتوان یک دسته از ورودیها را به صورت موازی پردازش کرد بدون استفاده از LCEL.
from concurrent.futures import ThreadPoolExecutor
def batch_chain(topics: list) -> list:
with ThreadPoolExecutor(max_workers=5) as executor:
return list(executor.map(invoke_chain, topics))
batch_chain(["ice cream", "spaghetti", "dumplings"])
4.2. با استفاده از LCEL
پردازش دستهای با استفاده از LCEL بسیار ساده است. کد زیر نشان میدهد که چگونه میتوان از LCEL برای پردازش دستهای استفاده کرد.
chain.batch(["ice cream", "spaghetti", "dumplings"])