大模型:runnable

Runnable:LangChain 的"万能接口"

在 LangChain 的世界里,Runnable 是一个统一的、标准的执行接口 。所有能够"被调用、被组合、被传输"的组件,无论是模型(ChatTongyi)、提示模板(ChatPromptTemplate)、输出解析器(StrOutputParser)、链(Chain),甚至是整个 LangGraph 图,都实现了 Runnable 接口。

一句话定义Runnable 是 LangChain 表达语言(LCEL)的基石,它定义了一个"如何执行一个任务"的通用契约。任何实现了 Runnable 的对象,都可以用统一的 API 去调用它,并可以用管道符 | 去和另一个 Runnable 串联。


为什么需要 Runnable?(解决了什么问题?)

Runnable 出现之前,LangChain 中存在 LLMChainConversationChainRetrievalQA 等多种"硬编码"的 Chain 类,它们各自的调用方式各不相同,无法统一组合。

Runnable 提供了一套标准化的接口,使得:

  • 所有组件可以无缝组合(LCEL)。
  • 所有组件支持统一的调用方式(invokestreambatch)。
  • 所有组件天然可观测(可与 LangSmith 集成)。
  • 所有组件可被包装和增强(如 RunnableWithMessageHistory)。

Runnable 的核心方法

任何实现了 Runnable 的对象,都至少实现了以下三个核心方法:

方法 作用 适用场景
invoke(input, config=None) 同步执行,返回完整结果。 常规单次调用。
ainvoke(input, config=None) 异步执行,返回完整结果。 异步环境(如 FastAPI)。
stream(input, config=None) 同步流式执行,逐个产出结果。 需要逐步输出长文本时。
astream(input, config=None) 异步流式执行,逐个产出结果。 异步流式输出。
batch(inputs, config=None) 批量执行,返回结果列表。 并发处理多个输入。
abatch(inputs, config=None) 异步批量执行 高并发场景。

所有 *async* 方法是 *sync* 方法的异步版本,前缀 a 代表 async


哪些东西是 Runnable?(几乎一切!)

组件类型 示例
模型 ChatTongyiChatOpenAITongyi(LLM)
提示模板 PromptTemplateChatPromptTemplateMessagesPlaceholder
输出解析器 StrOutputParserPydanticOutputParserJsonOutputParser
检索器 Chroma.as_retriever() 返回的 Retriever 对象
向量库 Chroma 本身(直接调用)
工具 @tool 装饰的函数(如 get_weather
所有用 `
Agent create_react_agent 返回的图(编译后)
Graph StateGraph.compile() 返回的图
自定义函数 RunnableLambda 包装的任意函数

如何创建一个 Runnable?

1. 最直接:用 | 管道符组合 LCEL 链

python 复制代码
chain = prompt | model | str_parser

chain 自动成为一个 RunnableSequence,支持所有 Runnable 方法。

2. 用 RunnableLambda 包装普通函数

python 复制代码
from langchain_core.runnables import RunnableLambda

def my_func(x):
    return x.upper()

runnable_func = RunnableLambda(my_func)

# 然后可以放进链里
chain = prompt | model | runnable_func | str_parser

3. 用 RunnableParallel 并行执行

python 复制代码
from langchain_core.runnables import RunnableParallel

# 同时执行两个任务,返回字典结果
parallel_chain = RunnableParallel(
    answer=chain1,
    context=chain2
)

Runnable 的核心原则

1. 输入类型决定输出类型

Runnable 是类型安全的。例如,ChatPromptTemplate 接受 dict(包含变量值),输出 PromptValueChatModel 接受 PromptValue,输出 AIMessage。如果类型不匹配,| 管道会报错。

2. 配置(config)是可传递的

在调用 invoke(input, config=...) 时,config 可以携带 metadatatagscallbacksmax_concurrency 等参数,这些会贯穿整个链的执行过程,特别适合可观测性(LangSmith)和限流。

3. 所有 Runnable 都可绑定回调

python 复制代码
from langchain_core.callbacks import StdOutCallbackHandler

chain.invoke(input, config={"callbacks": [StdOutCallbackHandler()]})

这样会打印链中每一步的执行日志,极其有助于调试。


Runnable 与 LangGraph 的关系

LangGraph 中编译后的 graph 本身就是一个 Runnable,因此你可以:

  • 像调用普通链一样 graph.invoke(input)graph.stream(input)
  • graph 作为子节点嵌入到更大的 LCEL 链中(prompt | graph | str_parser)。
  • graph 挂载回调、配置 thread_id 等。
  • 利用 astream_events 获取更细粒度的事件(这是 LangGraph 对 Runnable 接口的扩展)。

这也是为什么 LangGraph 与 LangChain 无缝集成:它本质上是在 LangChain 的 Runnable 体系之上增加了"状态图"的编排能力。


Runnable 在面试中的高频追问

Q1:RunnableSequence 和普通的 Chain 有什么区别?

ARunnableSequence 是 LCEL 方式的链,它是 Runnable 接口的统一实现;而传统 Chain(如 LLMChain)是硬编码类,无法用 | 灵活组合。LangChain 官方推荐弃用旧 Chain,全面转向 LCEL。

Q2:invokestream 的区别是什么?

Ainvoke 是一次性返回完整结果;stream 是逐步产出结果(生成器),适合长文本流式输出。两者都是 Runnable 的标准方法,所有组件都可选支持。

Q3:batchabatch 的优势是什么?

A :可以批量处理多个输入,且自动并发执行,提升吞吐量。比如同时处理 10 条用户消息,batch 会比循环调用快数倍。

Q4:自定义 Runnable 应该怎么做?

A :通常不需要显式实现 Runnable,只需用 RunnableLambda 包装函数;若需要更复杂的逻辑(如状态管理),可继承 Runnable 并实现 invokestream 等方法。


总结

Runnable 是 LangChain 生态的"基石接口",它统一了所有组件的执行方式,定义了 invokestreambatch 三大核心方法,并通过 LCEL(|)实现了组件的无限组合。无论是提示、模型、解析器、工具、检索器,还是 LangGraph 图,最终都归一为同一个 Runnable 接口,这是 LangChain 能够保持高度灵活性和扩展性的根本原因。理解 Runnable,就理解了 LangChain 的"哲学"。

相关推荐
2401_868534781 小时前
系统分析师案例分析题常考知识点
python·计算机网络
江华森2 小时前
Python 实现 2048 游戏(三):面向对象重构与AI模拟
python
可以飞的话2 小时前
五、数据处理1
python
鱼毓屿御2 小时前
Python 装饰器与函数调用机制(复习笔记 · 2026-07-07)
开发语言·python
AC赳赳老秦3 小时前
采购专员自动化:OpenClaw 自动比价、生成询价单、跟踪供应商报价进度实战指南
开发语言·数据库·人工智能·python·自动化·github·openclaw
ednO8nqdR3 小时前
Python小游戏制作:如何实现可配置的跨分辨率界面布局
python·plotly·django·virtualenv·scikit-learn·fastapi·pygame
林泽毅3 小时前
Qwen3.5 DPO 模型对齐实战(pytrio训练版)
人工智能·python·算法
荣码3 小时前
LangGraph多步工作流:Agent不够用的时候,我踩了4个坑
java·python
曲幽3 小时前
从卡顿到丝滑:FastAPI 调用外部 API 的正确姿势(httpx 实战)
python·fastapi·web·async·httpx·client·await·requests·aiohttp