06. Sequential Chains

Chapter 6 of 18 · 20 min

A sequential chain runs multiple LLMChain instances in series, passing the output of one step as input to the next. For example: extract a person from text (step 1 → a name), then look up facts about that person (step 2 → a biography). The glue is SimpleSequentialChain for single-input/single-output chains, and SequentialChain for chains with multiple inputs and outputs.

Start with SimpleSequentialChain—the simple case:

from langchain.chains import LLMChain, SimpleSequentialChain
from langchain.prompts import PromptTemplate
from langchain_ollama import ChatOllama

llm = ChatOllama(model="llama3.2:3b", temperature=0.3)

# Step 1: identify the topic
step1_template = PromptTemplate.from_template(
    "Identify the main topic in this text: {text}"
)
step1 = LLMChain(prompt=step1_template, llm=llm, output_key="topic")

# Step 2: write a headline about the topic
step2_template = PromptTemplate.from_template(
    "Write a one-sentence headline about: {topic}"
)
step2 = LLMChain(prompt=step2_template, llm=llm, output_key="headline")

# Compose into sequential chain
headline_chain = SimpleSequentialChain(
    chains=[step1, step2],
    verbose=True
)

result = headline_chain.invoke({
    "text": "Researchers discovered a new species of deep-sea anglerfish that uses bioluminescent lures to attract prey in complete darkness."
})

print("Topic:", result["topic"])
print("Headline:", result["headline"])

SimpleSequentialChain passes the output_key of each chain as input to the next. This means you must set output_key explicitly on each step to control the data flow. If step2 expects an input called topic, step1 must have output_key="topic".

For pipelines with multiple inputs and outputs across steps, use SequentialChain and specify the mapping explicitly:

from langchain.chains import SequentialChain

# Chain 1: classify document type
classification_chain = LLMChain(
    prompt=PromptTemplate.from_template(
        "Classify this document as 'legal', 'technical', or 'casual': {document}"
    ),
    llm=llm,
    output_key="doc_type",
)

# Chain 2: summarize based on document type
summary_chain = LLMChain(
    prompt=PromptTemplate.from_template(
        "Write a {doc_type} summary of the following in exactly one sentence: {document}"
    ),
    llm=llm,
    output_key="summary",
)

# Declarative input/output mapping
full_pipeline = SequentialChain(
    chains=[classification_chain, summary_chain],
    input_variables=["document"],
    output_variables=["doc_type", "summary"],
    verbose=True,
)

result = full_pipeline.invoke({
    "document": "Pursuant to Section 4.2(a) of the Agreement, the party of the first part shall deliver the goods by December 31st."
})

print(result)
# {'document': '...', 'doc_type': ' legal', 'summary': 'The party of the first part...'}

Note: output_variables=["doc_type", "summary"] tells the SequentialChain what to include in the final result dict. If you omit a variable that exists in intermediate steps, it won't appear in the final output.

Failure mode: SequentialChain will fail at runtime if an upstream chain's output_key doesn't match a downstream chain's input_variables. The error message is KeyError from Python's dict operations, not from LangChain directly. Use verbose=True and inspect the intermediate outputs to debug mismatches. The fix is always to either rename output_key on the producing chain or rename the template variable on the consuming chain.

EXERCISE

Build a three-step SequentialChain: (1) extract a country name from user text, (as country), (2) look up its capital (as capital), (3) write a one-sentence travel pitch for visiting that capital (consumes country and capital). Print the final output from the pipeline.