Match each LCEL Runnable method to the call pattern it is designed for
Same topic, related formats. Practice these next.
Same topic, related formats. Practice these next.
Every LCEL Runnable exposes five core call methods on a 2-axis grid: input is single or list; output is sync, async, or streaming chunks; the `a`-prefix marks async.
Think of a coffee shop with one barista. You can place a single order and wait at the counter (invoke). You can hand over a list of five orders to be prepared together (batch). You can ask for a drip coffee where the cup fills sip by sip while you watch (stream). The same three shapes exist in an async version of the shop where you can walk away and come back when notified (astream and abatch). One axis is 'how many drinks am I ordering,' the other is 'do I want it now, or to receive it as it pours.' The five LCEL methods are exactly the cells in that grid.
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example.
Everything important, quickly.
5 minutes: the two-axis grid, the five core methods, why `.batch` is free parallelism, and when `.astream_events` beats plain `.astream`.
from langchain_anthropic import ChatAnthropic
from langchain_core.prompts import ChatPromptTemplate
prompt = ChatPromptTemplate.from_template("Summarise {topic} in 3 bullets.")
chain = prompt | ChatAnthropic(model="claude-sonnet-4-6")
# 1. Single sync call
result = chain.invoke({"topic": "OpenTelemetry"})
# 2. List of inputs, parallel up to max_concurrency
results = chain.batch([{"topic": t} for t in topics], config={"max_concurrency": 8})
# 3. Sync streaming for a CLI
for chunk in chain.stream({"topic": "vector databases"}):
print(chunk.content, end="", flush=True)
# 4. Async streaming for FastAPI / SSE
async def handler(topic: str):
async for chunk in chain.astream({"topic": topic}):
yield chunk.content| Method | Input shape | Output delivery | Async? | Typical use |
|---|---|---|---|---|
| `.invoke` | Single | Complete value | No | Simple sync call |
| `.batch` | List | List of complete values, in order | No | Parallel sync evaluation |
| `.stream` | Single | Sync iterator of chunks | No | CLI / sync UI streaming |
| `.astream` | Single | Async generator of chunks | Yes | FastAPI SSE / WebSocket |
| `.abatch` | List | List in input order | Yes | Async eval / web batch jobs |
Real products, models, and research that use this idea.
What an interviewer would ask next. Try answering before peeking at the approach.
Red flags and common mistakes that signal junior thinking. Click to expand.
Calling `.invoke` in a hot loop over a list of inputs when `.batch` would parallelise the same work for free, then debugging 'why is my pipeline slow?'
The night-before-the-interview bullets. Scan these on the way to the call.
Primary sources. Skim if you want the original framing.