HOW-TO · RAG
How to Compose Multiple Chains with Pipe Operator
Target environment
Ubuntu 24.04 · Ollama 0.4.x
PREREQUISITES
LangChain installed with LCEL support, Python 3.10+
What this does
LCEL's | operator lets you compose independent chains into pipelines, where the output of one chain feeds into the next. This enables modular, reusable workflow construction.
Steps
- Create two independent chains. Each should accept and return structured dicts.
from langchain_ollama import ChatOllama
from langchain.prompts import ChatPromptTemplate
from langchain.schema.output_parser import StrOutputParser
from langchain.schema.runnable import RunnablePassthrough
llm = ChatOllama(model="llama3.2", temperature=0.7)
# Chain 1: Summarize input text
summarize_prompt = ChatPromptTemplate.from_template(
"Summarize the following text in one sentence:\n\n{text}"
)
summarize_chain = summarize_prompt | llm | StrOutputParser()
# Chain 2: Extract keywords from summary
keywords_prompt = ChatPromptTemplate.from_template(
"Extract 3 keywords from this summary:\n\n{summary}"
)
keywords_chain = keywords_prompt | llm | StrOutputParser()
- Compose with RunnablePassthrough. Pass
summaryoutput as input to the next chain.
from langchain.schema.runnable import RunnableParallel
pipeline = (
RunnablePassthrough.assign(summary=summarize_chain)
| RunnablePassthrough.assign(keywords=keywords_chain)
)
- Run the composed pipeline.
result = pipeline.invoke({"text": "LangChain is a framework for building LLM applications. It provides tools for prompt management, chains, and memory."})
print("Summary:", result["summary"])
print("Keywords:", result["keywords"])
- Branch into parallel chains. Use
RunnableParallelto fan out.
chain_a = summarize_prompt | llm | StrOutputParser()
chain_b = keywords_prompt | llm | StrOutputParser()
parallel = RunnableParallel(summary=chain_a, keywords=chain_b)
result = parallel.invoke({"text": "AI is transforming industries."})
- Route results conditionally. Use
RunnableBranchfor if-else logic within the pipeline.
from langchain.schema.runnable import RunnableBranch
branch = RunnableBranch(
(lambda x: len(x["text"]) > 100, summarize_chain),
keywords_chain # default
)
Verification
python -c "
from langchain.schema.runnable import RunnableParallel, RunnablePassthrough
chain = RunnablePassthrough() | RunnableParallel(a=lambda x: x['x'] + 1, b=lambda x: x['x'] * 2)
r = chain.invoke({'x': 5})
print(r)
# Expected: {'a': 6, 'b': 10}
"
Common failures
- Key propagation breaks. Intermediate chain returns a string but the next chain expects a dict with a specific key. Use
RunnablePassthrough.assign()to wrap. - Type mismatch in branch conditions.
RunnableBranchconditions must return a boolean. Ensure lambda predicates are correct. - Parallel chains share state unexpectedly. Each branch in
RunnableParallelreceives the full input dict — design branch prompts to extract only the keys they need. - Version mismatch - The installed package or runtime differs from the command shown; check the version first and rerun the smallest verification command.
- Local environment drift - Another service, virtual environment, model, or path is being used; print the active binary path and configuration before changing the guide steps.
Related guides
- How to Create Basic LangChain Chains with LCEL
- How to Build Custom LLM Chain with Prompt Templates