Topics in this subject
LangChain 3 min read Updated 11 Aug 2026

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?#

  1. Readability: chain = prompt | model | parser is incredibly easy to read and understand at a glance.
  2. 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)
    
  3. Parallel Execution: If you use a RunnableParallel block 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.