LangChain Mastery

Course Content

LangChain Mastery

7 sections · 109 lessons

How do you create a sequential chain in LangChain?


The dict grows as each assign step runs2BHK HSR, this week——2BHK HSR, this weekhot—2BHK HSR, this weekhotHi! Sitevisit on...enquirylabelreplyInputAfter assign(label)After assign(reply)
assign adds a key and keeps the rest, so the reply step can still read the original enquiry that the label step consumed.

What you need to know

The simplest sequence passes one output straight on:

Python
classify = (ChatPromptTemplate.from_template("Label hot, warm or cold: {enquiry}")            | llm | StrOutputParser())reply = (ChatPromptTemplate.from_template(            "Write a WhatsApp reply to a {label} lead. Enquiry: {enquiry}")         | llm | StrOutputParser())

classify returns a string, but reply needs a dict with label and enquiry. Piping them directly would fail. There are two ways to fix the shape.

Option 1: an adapter function (loses the original input)

Python
chain = classify | (lambda label: {"label": label})

This only works if the next step needs nothing else. Here it would lose enquiry.

Option 2: RunnablePassthrough.assign (keeps everything)

Python
from langchain_core.runnables import RunnablePassthroughpipeline = (RunnablePassthrough.assign(label=classify)            | RunnablePassthrough.assign(reply=reply))pipeline.invoke({"enquiry": "2BHK in HSR Layout, want to book this week"})# {'enquiry': '...', 'label': 'hot', 'reply': 'Hi! Thanks for ...'}

Each assign runs its chain on the current dict and adds the result under a new key. The final dict has the input and every intermediate result, which is useful for logging and for later steps.

The legacy version

Python
from langchain_classic.chains import LLMChain, SequentialChainc1 = LLMChain(llm=llm, prompt=label_prompt, output_key="label")c2 = LLMChain(llm=llm, prompt=reply_prompt, output_key="reply")seq = SequentialChain(chains=[c1, c2], input_variables=["enquiry"],                      output_variables=["label", "reply"])

It does the same key mapping, but without streaming, with limited batching, and with a deprecation warning on every run.

A real-life example

A Bengaluru real-estate firm gets about 600 website enquiries a day. Their lead pipeline has three steps in sequence: extract budget, locality and move-in date into a structured object; label the lead hot, warm or cold using that object; and draft a WhatsApp reply. Built with three assign steps, the final dict holds the enquiry, the extracted fields, the label and the draft, and all of it is saved to the CRM. When the sales head asked why a lead was marked "cold", the saved dict showed the extraction had read "90 lakh" as "90 thousand"; the fix went into step one only, and steps two and three did not change.

Follow-up questions to expect

  • "How do you run two steps at the same time instead of one after another?" — Put them in a dict or RunnableParallel; both get the same input and run concurrently.
  • "How do you pick out one key for the next step?" — Pipe into itemgetter("label") from operator, or call .pick("label") on the step that produces the dict.
  • "When does a sequence become a LangGraph graph?" — When a step must loop back, retry based on output, or wait for a person.