LangChain Core Cheat Sheet
Runnables, LCEL composition and the streaming interface
Modern LangChain is one interface — the Runnable — and a pipe operator for composing them. Learning that pair covers most of the library.
The Runnable interface
| Method | Does | Returns |
|---|---|---|
invoke(input)
|
Runs once | One output |
batch(inputs)
|
Runs many, in parallel where possible | A list of outputs |
stream(input)
|
Runs once, yielding as it goes | An iterator of chunks |
astream_events(input)
|
Streams every internal step | An iterator of typed events |
with_retry()
|
Wraps with a retry policy | A Runnable |
with_fallbacks()
|
Adds alternatives on failure | A Runnable |
Composition
| Construct | Meaning |
|---|---|
a | b
|
Pipe: a's output becomes b's input |
RunnableParallel({"x": a, "y": b})
|
Run both on the same input, return a dict |
RunnablePassthrough()
|
Forward the input unchanged — used to keep the original alongside a result |
RunnableLambda(fn)
|
Lift any plain function into the chain |
RunnableBranch(...)
|
Conditional routing |
.bind(**kwargs)
|
Pin arguments — model parameters, tools — onto a step |
Composition is what buys streaming
Anything built by piping Runnables gets streaming, batching, async and tracing for free, because every link implements the same interface. Dropping to plain Python inside a step is allowed — but that step becomes a black box that cannot stream, which is usually why a chain "suddenly stopped streaming".
Code examples
An LCEL chain that streams
Everything built by piping Runnables inherits streaming, batching and async for free.
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnableParallel, RunnablePassthrough
prompt = ChatPromptTemplate.from_template(
"Answer using ONLY this context.\n\n{context}\n\nQuestion: {question}"
)
chain = (
RunnableParallel(
context=retriever | (lambda docs: "\n\n".join(d.page_content for d in docs)),
question=RunnablePassthrough(), # keep the original question
)
| prompt
| model
| StrOutputParser()
)
for chunk in chain.stream("What changed in the refund policy?"):
print(chunk, end="", flush=True)
Frequently asked questions
Why did my chain stop streaming?
Almost always a step that dropped to plain Python. Anything not implementing the Runnable interface is a black box the streaming machinery cannot see through.
Do I need LangChain at all?
For a single model call, no — the provider SDK is simpler. It earns its place when you want composition, retries, fallbacks and tracing across many steps without writing that layer yourself.
Was this cheat sheet useful?
Comments
No comments yet — be the first.
Need a different cheat sheet?
Tell us what you would like to see and we will build it — free.
Request a cheat sheet