---
title: "LangChain Runnables: The DNA of AI Pipelines"
description: "## What Are LangChain Runnables? If you are learning **LangChain**, one of the most important concepts you will come across is **Runnables**. A Runnable is a unit of work that takes an input, processes it, and produces an output. **Simple…"
url: "https://csestudy247.com/docs/langchain-runnables-the-dna-of-ai-pipelines/"
updated: "2026-08-16"
category: LangChain
---

# LangChain Runnables: The DNA of AI Pipelines

## What Are LangChain Runnables?

If you are learning **LangChain**, one of the most important concepts you will come across is **Runnables**.

A Runnable is a unit of work that takes an input, processes it, and produces an output.

  **Simple definition:** A Runnable is a reusable component that follows a common interface for processing data in a LangChain workflow.

You can think of Runnables as **Lego blocks**. Each block performs a particular task, and multiple blocks can be connected together to build an LLM application.

  Input → Runnable → Output

## Why Were Runnables Introduced?

An LLM application usually contains multiple steps. For example:

  User Input ↓ Prompt ↓ LLM ↓ Output Parser ↓ Final Answer

Runnables provide a common interface that makes it easier to connect these components together.

Using LangChain Expression Language (LCEL), you can write:

```
chain = prompt | llm | parser
```

The `|` operator means that the output of one component is passed to the next component.

## Why Use Runnables?

### 01. Standardization

Different components can use a common interface such as `invoke()`, `batch()`, and `stream()`.

### 02. Easy Composition

Components can be connected easily using the pipe operator.

```
prompt | llm | parser
```

### 03. Parallel Processing

Independent tasks can be executed using `RunnableParallel`.

### 04. Custom Logic

Normal Python functions can be added to workflows using `RunnableLambda`.

### 05. Conditional Workflows

Different paths can be selected using `RunnableBranch`.

## Runnable Execution Methods

Runnables provide a common way to execute LangChain components.

| Method | Purpose |
| --- | --- |
| `invoke()` | Process a single input |
| `batch()` | Process multiple inputs |
| `stream()` | Stream output progressively |
| `ainvoke()` | Asynchronous execution |
| `abatch()` | Asynchronous batch processing |
| `astream()` | Asynchronous streaming |

## 1. invoke()

Use `invoke()` when you want to process one input.

```
result = chain.invoke(input)
```

### Example

```
from langchain_core.runnables import RunnableLambda

square = RunnableLambda(lambda x: x ** 2)

result = square.invoke(5)

print(result)
```

  **Output:** `25`   Input **→** invoke() **→** Output

## 2. RunnableSequence

`RunnableSequence` executes multiple Runnables one after another.

  Prompt → LLM → Parser

The most common way to create a sequence is with the **pipe operator**:

```
chain = prompt | llm | parser
```

This syntax is part of **LangChain Expression Language (LCEL)**.

### Example: Prompt → LLM → Parser

```
from langchain_ollama import ChatOllama
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

llm = ChatOllama(model="gemma3:1b")

prompt = ChatPromptTemplate.from_template(
    "Explain {topic} in simple words."
)

parser = StrOutputParser()

chain = prompt | llm | parser

result = chain.invoke({
    "topic": "LangChain"
})

print(result)
```

  Input → Prompt → LLM → Parser → Output

## Important: A Chain Is Also a Runnable

This is one of the most important concepts to understand.

```
chain = prompt | llm | parser
```

The resulting `chain` is itself a Runnable. Therefore, you can use the same Runnable methods:

```
chain.invoke(...)
chain.batch(...)
chain.stream(...)
```

You can even connect this chain to another Runnable:

```
new_chain = chain | another_runnable
```

  **Key idea:** Runnables are composable. Small components can be combined into larger workflows.

## 3. RunnableParallel

`RunnableParallel` is used when multiple independent tasks need to run using the same input.

  Input: LangChain ↓ RunnableParallel ↙     ↘  Summary Questions

### Example

```
from langchain_ollama import ChatOllama
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnableParallel

llm = ChatOllama(model="gemma3:1b")

summary_prompt = ChatPromptTemplate.from_template(
    "Give a short explanation of {topic}"
)

question_prompt = ChatPromptTemplate.from_template(
    "Create 3 interview questions about {topic}"
)

summary_chain = summary_prompt | llm
question_chain = question_prompt | llm

parallel_chain = RunnableParallel(
    summary=summary_chain,
    questions=question_chain
)

result = parallel_chain.invoke({
    "topic": "LangChain"
})

print("SUMMARY:")
print(result["summary"].content)

print("QUESTIONS:")
print(result["questions"].content)
```

`RunnableParallel` returns the results using the keys you provide.

```
result["summary"].content
result["questions"].content
```

  **When should you use it?** Use RunnableParallel when multiple tasks are independent and can use the same input.

## 4. RunnablePassthrough

`RunnablePassthrough` passes the input forward without changing it.

```
from langchain_core.runnables import RunnablePassthrough

passthrough = RunnablePassthrough()

result = passthrough.invoke("Hello")

print(result)
```

  **Output:** `Hello`   Input → Passthrough → Same Input

### Example with RunnableParallel

```
from langchain_core.runnables import (
    RunnableParallel,
    RunnableLambda,
    RunnablePassthrough
)

chain = RunnableParallel(
    original=RunnablePassthrough(),
    uppercase=RunnableLambda(lambda x: x.upper())
)

result = chain.invoke("hello")

print(result)
```

  **Output:**

```
{
    "original": "hello",
    "uppercase": "HELLO"
}
```

## 5. RunnableLambda

`RunnableLambda` allows you to use your own Python functions inside a LangChain workflow.

```
from langchain_core.runnables import RunnableLambda

word_counter = RunnableLambda(
    lambda x: len(x.split())
)

result = word_counter.invoke(
    "LangChain makes LLM applications easier"
)

print(result)
```

  **Output:** `6`

### Why Use RunnableLambda?

- Data cleaning
- Text preprocessing
- Calculations
- Validation
- Formatting
- Custom business logic

## 6. RunnableBranch

`RunnableBranch` is used when your workflow needs conditional logic.

Think of it as the LangChain equivalent of an `if/else` decision.

  Input ↓ Condition ↙     ↘  True → Path A False → Path B

### Example

```
from langchain_core.runnables import (
    RunnableBranch,
    RunnableLambda
)

long_text = RunnableLambda(
    lambda x: "The text is long."
)

short_text = RunnableLambda(
    lambda x: "The text is short."
)

branch = RunnableBranch(
    (
        lambda x: len(x) > 20,
        long_text
    ),
    short_text
)

result = branch.invoke(
    "This is a very long sentence"
)

print(result)
```

If the condition `len(x) > 20` is true, the first path is executed. Otherwise, the default path runs.

## 7. batch()

Use `batch()` when you want to process multiple inputs using the same Runnable.

```
from langchain_core.runnables import RunnableLambda

double = RunnableLambda(lambda x: x * 2)

results = double.batch([1, 2, 3, 4])

print(results)
```

  **Output:** `[2, 4, 6, 8]`

This is useful when processing many independent inputs.

## 8. Streaming with stream()

LLM responses can take some time to generate. With `stream()`, output can be received progressively.

```
for chunk in chain.stream(input):
    print(chunk, end="")
```

Streaming is especially useful for:

- Chatbots
- AI assistants
- Interactive applications
- Real-time user interfaces

## Runnables in RAG

Runnables are particularly useful when building **RAG (Retrieval-Augmented Generation)** applications.

  User Question ↓ Retriever ↓ Context ↓ Prompt ↓ LLM ↓ Answer

A simplified RAG Runnable pipeline can look like:

```
from langchain_core.runnables import RunnablePassthrough

rag_chain = (
    {
        "context": retriever,
        "question": RunnablePassthrough()
    }
    | prompt
    | llm
    | parser
)
```

Here, the retriever generates the context while `RunnablePassthrough()` keeps the original question.

## Runnable Types at a Glance

| Runnable | What It Does | Example |
| --- | --- | --- |
| `RunnableSequence` | Executes steps in order | Prompt → LLM → Parser |
| `RunnableParallel` | Executes independent paths | Summary + Questions |
| `RunnablePassthrough` | Keeps the input unchanged | Preserve original question |
| `RunnableLambda` | Runs custom Python logic | Word counting |
| `RunnableBranch` | Selects a path conditionally | If/else routing |

## Easy Way to Remember Runnables

   **Sequence** A → B → C   **Parallel** A → B + C   **Passthrough** A → A   **Lambda** Python → Runnable   **Branch** Condition → Path

## Final Takeaway

You don't need to memorize every Runnable class when you are just starting with LangChain.

### Remember These Three Ideas

  1  **Runnable = Unit of Work** `Input → Runnable → Output`    2  **`|` = Connect Components** `prompt | llm | parser`    3  **Runnable primitives control the workflow** `Sequence → Parallel → Lambda → Branch`    **In one sentence:** Runnables provide a standard and composable way to build LLM workflows in LangChain.

Once you understand Runnables, you will have a much easier time understanding advanced LangChain concepts such as **RAG pipelines, chatbots, agents, and multi-step LLM workflows.**

## Quiz

Q.1 In the context of LangChain's history, what was a primary issue with using specific chain classes like 'LLMChain' or 'RetrievalQA'?

- The sheer number of specific chains led to a heavy code base and a steep learning curve.
- They were too computationally expensive to run on standard hardware.
- They could only handle single-step tasks and were incapable of being combined.
- They were only compatible with OpenAI models and could not use open-source alternatives.

    Consider how having dozens of specialized functions affects the library's maintenance and a beginner's experience.    [Discuss it](#)

Explanation

LangChain originally included many specialized chain classes. This increased the library's complexity, made it harder to maintain, and created a steeper learning curve for developers.

Q.2 Which standard method is implemented across all Runnables to allow them to process a single input and return an output?

- format
- predict
- invoke
- execute

    The name of this method suggests calling or summoning the logic of the component.    [Discuss it](#)

Explanation

Every Runnable implements the invoke() method, which accepts a single input and returns the corresponding output, providing a consistent interface across LangChain components.

Q.3 How does 'RunnableParallel' handle the input it receives?

- It sends the exact same input to every internal Runnable simultaneously.
- It splits the input into chunks and sends one chunk to each internal Runnable.
- It modifies the input based on the requirements of each specific component before sending it.
- It passes the input to the first Runnable and then passes that output to the next one.

    Think about whether the different tasks in a parallel chain are competing for data or sharing it.    [Discuss it](#)

Explanation

RunnableParallel broadcasts the same input to multiple Runnables at the same time, allowing them to execute independently and return their results together.

Q.4 What is the primary purpose of the 'RunnablePassThrough' primitive?

- To filter out unnecessary metadata from the LLM response.
- To convert a standard Python function into a format compatible with LangChain.
- To output the input exactly as it was received without any processing.
- To automatically retry a failed API call in a sequential chain.

    The name implies that the data simply 'goes through' the component without being touched.    [Discuss it](#)

Explanation

RunnablePassThrough simply forwards the input unchanged. It is useful when you need to preserve or reuse the original input while other processing occurs in the chain.

Q.5 When using 'RunnableBranch', what happens if none of the defined conditions are met?

- A default Runnable, provided as the last argument, is executed.
- The input is passed directly to the next component in the sequence.
- The chain throws an error and stops execution.
- It randomly selects one of the existing branches to execute.

    Consider the standard structure of an if-else statement in programming.    [Discuss it](#)

Explanation

RunnableBranch works like an if-else statement. If none of the specified conditions match, the default Runnable provided as the final argument is executed.

Q.6 What is the main benefit of converting a Python function into a 'RunnableLambda'?

- It allows the custom logic within the function to be seamlessly piped into a LangChain sequence.
- It automatically translates the Python code into JavaScript for cross-platform use.
- It encrypts the function's logic to protect sensitive intellectual property.
- It makes the function run 10× faster by using the LangChain runtime.

    Think about what a component needs to 'be' in order to work with the | operator.    [Discuss it](#)

Explanation

RunnableLambda wraps a normal Python function as a Runnable so it can be combined with other LangChain components using LCEL operators like the pipe (|).

Q.7 Which LCEL (LangChain Expression Language) operator is used to create a 'RunnableSequence'?

- The Ampersand operator (&)
- The Arrow operator (->)
- The Pipe operator (|)
- The Plus operator (+)

    This symbol is commonly used in Unix/Linux terminals to send the output of one command to another.    [Discuss it](#)

Explanation

The pipe (|) operator connects Runnables into a RunnableSequence, where the output of one component becomes the input of the next.

Q.8 Which of the following best describes 'Task-Specific Runnables'?

- They are temporary runnables that only exist during the debugging phase of development.
- They are runnables specifically designed to manage hardware resources like GPU memory.
- They are core LangChain components, like models or parsers, that have been standardized as runnables.
- They are the building blocks that define how other runnables interact.

    Think of components that have a singular, concrete job like 'ChatOpenAI' or 'PromptTemplate'.    [Discuss it](#)

Explanation

Task-specific Runnables are standard LangChain components such as chat models, prompt templates, retrievers, output parsers, and tools that all implement the Runnable interface.

Q.9 According to the analogy provided in the source material, why are Runnables like Lego blocks?

- Because they are inexpensive and easy to replace if a better version is released.
- Because every block has a specific purpose and uses a standard interface to connect to any other block.
- Because they come in different colors to help organize the code visually.
- Because they are designed primarily for educational purposes and not for professional applications.

    Consider what allows two completely different Lego shapes to fit together perfectly.    [Discuss it](#)

Explanation

Like Lego blocks, every Runnable has a specific role but follows the same interface, allowing developers to combine different components together in flexible and reusable workflows.

Q.10 If you wanted to calculate the number of words in an LLM's response using a custom Python function inside a chain, which primitive would you use?

- RunnableLambda
- RunnableParallel
- RunnablePassThrough
- RunnableSequence

    Look for the primitive that acts as a bridge between standard Python code and the LangChain ecosystem.    [Discuss it](#)

Explanation

RunnableLambda is designed to wrap custom Python functions so they can participate in LangChain pipelines alongside prompts, models, retrievers, and other Runnables.

[What are Runnables in LangChain | Generative AI using LangChain | Video 8 | CampusX](https://www.youtube.com/embed/u3b-W1NgYa4?list=PLKnIA16_RmvaTbihpo4MtzVm4XOQa0ER0)

[Langchain Runnables - Part 2 | Generative AI using LangChain | Video 9 | CampusX](https://www.youtube.com/embed/47nc0n-e4_w?list=PLKnIA16_RmvaTbihpo4MtzVm4XOQa0ER0)
