1. การแนะนำเกี่ยวกับ LCEL
LCEL (LangChain Expression Language) เป็นโครงสร้างที่ง่ายและใช้ง่ายสำหรับการสร้างเส้นเชือดที่ซับซ้อน มันมีอินเตอร์เฟซที่เป็นไปได้และหลายฟังก์ชันเบื้องต้นเพื่อทำให้การสร้างเส้นเชือดเป็นเรื่องง่ายขึ้น แต่ละอ็อบเจ็กต์ของ LCEL นำไอ้มพลีเมนท์ของ Runnable
interface ซึ่งกำหนดชุดของเมทอดที่ใช้บ่อย (เช่น invoke
, batch
, stream
, ainvoke
, เป็นต้น) ดังนั้น เส้นเชือดของ LCEL ก็สามารถสนับสนุนเมทอดเหล่านี้โดยอัตโนมัติ ทำให้เส้นเชือดของแต่ละอ็อบเจ็กต์ของ LCEL เองก็เป็นอ็อบเจ็กต์ของ LCEL ด้วย
2. การเรียกใช้
2.1. โดยไม่ใช้ LCEL
โดยไม่ใช้ LCEL คุณสามารถใช้รายการโค้ดต่อไปนี้เพื่อส่งผ่านสตริงหัวข้อและเรียกคืนสตริงข้อขำ
from typing import List
import openai
prompt_template = "บอกข้อขำสั้นๆ เกี่ยวกับ {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("ไอศครีม")
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(
"บอกข้อขำสั้นๆ เกี่ยวกับ {topic}"
)
output_parser = StrOutputParser()
model = ChatOpenAI(model="gpt-3.5-turbo")
chain = (
{"topic": RunnablePassthrough()}
| prompt
| model
| output_parser
)
chain.invoke("ไอศครีม")
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("ไอศครีม")
3.2. การใช้ LCEL
การสตรีมผลลัพธ์โดยใช้ LCEL เป็นไปได้ง่ายมากขึ้น รายการโค้ดต่อไปนี้สาธิตถึงวิธีการสตรีมด้วย LCEL
for chunk in chain.stream("ไอศครีม"):
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(["ไอศครีม", "สปาเก็ตตี้", "เกี้ยว"])
4.2. การใช้ LCEL
การประมวลผลแบบกลุ่มโดยใช้ LCEL เป็นเรื่องง่ายขึ้นมาก รายการโค้ดต่อไปนี้สาธิตถึงวิธีการใช้ LCEL ในการประมวลผลแบบกลุ่ม
chain.batch(["ไอศครีม", "สปาเก็ตตี้", "เกี้ยว"])