LCEL (LangChain Expression Language)
The modern pipe syntax (|) for chaining components together seamlessly.
🧑🏫 Sabse pehle — simple mein samjho#
Pichle section mein humne Prompt banaya, LLM ko bheja, aur Output ko parse kiya. Ye 3 alag-alag steps the. LCEL (LangChain Expression Language) is process ko ekdum chota aur clean kar deta hai. Linux terminal ki tarah, ye | (pipe) symbol use karta hai. Tum bas bolte ho: Prompt | LLM | Parser. Pehle ka output automatically dusre ka input ban jata hai. Ye itna powerful hai ki iske andar streaming (jaise ChatGPT me ek-ek word type hota hai) apne aap kaam karti hai!
What is a Runnable?#
In modern LangChain, almost every component (Prompts, ChatModels, Parsers, Retrievers) implements the Runnable interface. This means they all share the exact same methods:
.invoke(): Pass an input and get an output..stream(): Get the output piece by piece (great for frontends)..batch(): Run multiple inputs at the same time concurrently.
Because they share this interface, they can be chained together using the pipe | operator.
Building a Chain with LCEL#
Let's rebuild the recipe generator from the previous section, but using LCEL.
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
# 1. Initialize the components
prompt = ChatPromptTemplate.from_template("Tell me a short joke about {topic}.")
model = ChatOpenAI(model="gpt-3.5-turbo")
# StrOutputParser simply extracts the raw text from the AIMessage object,
# so you don't have to manually do `response.content` later.
parser = StrOutputParser()
# 2. CREATE THE CHAIN
# The output of the prompt flows into the model, and the model's output flows into the parser.
chain = prompt | model | parser
# 3. Invoke the chain
# We pass a dictionary containing the variables needed by the prompt
result = chain.invoke({"topic": "programmers"})
print(result)
# "Why do programmers prefer dark mode? Because light attracts bugs!"
Why is LCEL better?#
- Readability:
chain = prompt | model | parseris incredibly easy to read and understand at a glance. - Streaming for free: If you want to stream the response to your frontend so the user doesn't have to wait 5 seconds for the joke to generate, you just change
.invoke()to.stream(). The chain handles the rest!for chunk in chain.stream({"topic": "programmers"}): print(chunk, end="", flush=True) - Parallel Execution: If you use a
RunnableParallelblock within your chain, LangChain automatically runs tasks simultaneously using Python's asyncio, drastically speeding up your application.
A More Complex Example (with Pydantic Parser)#
If we used the PydanticOutputParser from the previous notes:
# The chain definition
chain = prompt | model | pydantic_parser
# When we invoke it, it automatically returns the fully structured Pydantic object!
recipe_object = chain.invoke({
"dish": "Pizza",
"format_instructions": pydantic_parser.get_format_instructions()
})
LCEL is the backbone of modern LangChain. Every complex Agent or RAG system is ultimately just a sophisticated LCEL chain.