RunnablePassthrough is the LCEL primitive for this: it can act as a transparent pipe that forwards data unchanged or as an injector that adds/overrides keys in the runtime input.
This document provides concise, corrected examples that illustrate the common patterns for using RunnablePassthrough, plus guidance and best practices.
Overview
- Purpose: Pass through input unchanged, or inject/modify runtime keys.
- Typical uses: preserve existing call signatures, insert context/configuration, or compute values before downstream runnables.
- Works well inside LCEL chains built with prompts, LLMs, and parsers.
Basic prompt -> LLM -> output parser chain
Example showing a simple chain: Prompt → LLM → Output Parser.RunnablePassthrough as a no-op passthrough
Inserting a plainRunnablePassthrough() anywhere in the pipeline with no .assign(...) simply forwards the data unchanged. This is useful as a placeholder or to preserve structure when conditionally inserting logic.
RunnablePassthrough as an injector (.assign(...))
RunnablePassthrough can add or override keys in the input dictionary at the point where it is placed in the chain. Use .assign(...) to compute or pin values. The assign mappers receive the runtime input (commonly named x), so you can compute values based on the current state or return constants.
Example: build a chain that accepts only question and injects topic = "movies" before the prompt is evaluated.
Use cases and quick reference
Why this is useful
RunnablePassthrough is a small but powerful primitive. Use it to:- keep pipeline elements as hollow pipes when no transformation is required,
- inject or compute additional inputs at runtime with
.assign(...), - pin or hide configuration/context values so external callers don’t need to supply them.
Notes and best practices
.assign(...)mappers are evaluated at runtime and merged into the dictionary forwarded to downstream components.- The lambda parameter name (often
x) is arbitrary; it represents the current runtime input at that stage. If the injected value is constant, you can ignore it (e.g.,lambda x: "movies"). - Instantiate parsers and runnables explicitly (e.g.,
StrOutputParser()), and prefer clear variable names for readability. - Use
RunnablePassthroughto preserve external call signatures while adding internal context or configuration. - When computing values based on prior steps, ensure the required keys exist to avoid runtime errors — validate or provide fallbacks inside your lambda.
Example patterns
- Insert configuration or user context only when needed.
- Replace complex conditional logic in the chain with targeted, testable mappers using
.assign(...). - Combine multiple
.assign(...)calls to coalesce values from different sources (e.g., session, defaults, and request).
Next steps
You can convert arbitrary Python functions into runnable components (for example, using aRunnableLambda) to encapsulate custom logic as first-class LCEL runnables. This lets custom logic participate directly in chains and simplifies testing and reuse.