LangChain/Core Concepts
Intermediate14 min

LCEL: Advanced Runnables

RunnableParallel, RunnableBranch, RunnableLambda, and RunnableConfig form the production toolkit for LCEL pipelines. Know when each earns its place, how they fail, and how to compose them without regrets at 3am.

Quick Reference

  • RunnablePassthrough.assign() enriches a dict without losing existing keys
  • RunnableParallel runs branches concurrently via asyncio — I/O-bound only, no CPU speedup
  • RunnableBranch: use for 2–4 static branches; use LangGraph for state or 5+ branches
  • RunnableLambda wraps any Python callable into the Runnable interface
  • .configurable_fields() lets callers swap model params at runtime with no redeploy
  • .configurable_alternatives() lets callers swap entire model objects at runtime
  • .with_retry(stop_after_attempt=2) before .with_fallbacks([...]) — retry first, then fall back
  • When one RunnableParallel branch fails, the entire step fails — guard each branch individually

When to Use Advanced Runnables

Advanced runnables are for custom pipelines, not agent loops

In LangChain v1, agent logic belongs in langchain.agents.create_agent. Advanced runnables — RunnableParallel, RunnableBranch, configurable_fields — are best for RAG chains, data pipelines, and model composition where you control the structure. For tool-calling loops or multi-step reasoning, reach for create_agent or LangGraph first.

Use caseToolWhy not the others
Fetch from multiple sources before promptingRunnableParallelCuts total latency when sources are I/O-bound (vector index, DB, API)
Route between 2–4 static content typesRunnableBranchLangGraph is overkill; plain if/else loses streaming and Runnable interface
Transform data between chain stepsRunnableLambdaMore explicit than a dict comprehension; gets .batch() and .astream() for free
Swap model or temperature at runtimeconfigurable_fieldsAvoids code branching and redeploys for configuration changes
Swap entire provider at runtimeconfigurable_alternativesOne chain, multiple backends, zero if/else in caller code
Survive model downtime or rate limits.with_fallbacks()Native to the Runnable interface — no custom try/except needed
Handle transient 429 / 500 errors.with_retry()Adds exponential backoff in one call; always pair with with_fallbacks()
Complex routing with state or memoryLangGraphRunnableBranch has no state — each call is independent
Tool calling / agent loopcreate_agentLCEL doesn't manage tool execution or message history