Back to roadmaps langchain Course

Composing Complex Chains with RunnableSequence

While basic chains connect a prompt to a model, real-world apps require multi-step logic (for example, generating a topic, writing a blog post based on that topic, and then parsing the output). LangChain uses RunnableSequence to manage these multi-stage data flows.


1. Composition Syntax

RunnableSequence allows you to create pipelines where data is transformed between execution nodes:

import { RunnableSequence } from "@langchain/core/runnables";

// Data flows from step1, gets processed, passes to step2
const sequence = RunnableSequence.from([
  step1,
  step2,
  step3
]);

2. Implementing a Multi-Stage Sequence

Let us build a pipeline that first generates a catchy topic name, and then writes a social media post outline about it:

// src/services/blogSequence.ts
import { ChatOpenAI } from "@langchain/openai";
import { ChatPromptTemplate } from "@langchain/core/prompts";
import { StringOutputParser } from "@langchain/core/output_parsers";
import { RunnableMap, RunnableSequence } from "@langchain/core/runnables";

const model = new ChatOpenAI({ modelName: "gpt-4o-mini", temperature: 0.7 });
const parser = new StringOutputParser();

// 1. Stage 1 Prompt (Generate topic)
const topicPrompt = ChatPromptTemplate.fromTemplate(
  "Generate one software store product category based on this key feature: {feature}"
);

// 2. Stage 2 Prompt (Write outline using output from Stage 1)
const outlinePrompt = ChatPromptTemplate.fromMessages([
  ["system", "You are an advertising copywriter."],
  ["user", "Write a short product announcement for this category: {category}"]
]);

// 3. Compose the runnable sequence
export const productPromoPipeline = RunnableSequence.from([
  // Step A: Format feature, call model, parse to get category string
  {
    category: topicPrompt.pipe(model).pipe(parser)
  },
  // Step B: Inject category string into Stage 2 prompt, call model, parse
  outlinePrompt,
  model,
  parser
]);

export async function runPipeline(productFeature: string) {
  const result = await productPromoPipeline.invoke({
    feature: productFeature,
  });

  console.log("Promo Output:", result);
  return result;
}

3. Dynamic Routing in Chains

RunnableSequence also supports routing data to different models or prompts based on input criteria. By nesting conditional branch functions within the sequence array, you can direct traffic (for example, routing programming questions to a code model and accounting queries to a math model) automatically.

Published on Last updated: