langchain_core.runnables
模块是 LangChain 核心库中的核心组件之一,用于构建和组合可运行对象(Runnables),支持 LangChain Expression Language (LCEL) 的链式工作流。
本文基于 LangChain 0.3.x,详细介绍 langchain_core.runnables
模块的结构、核心类及其功能,并提供一个独立示例,展示如何结合多个 Runnable(如 RunnableLambda
、RunnableParallel
和 ChatOpenAI
)实现人工智能主题的问答工作流,示例突出模块的灵活性和 LCEL 的链式组合能力。
langchain_core.runnables
模块概览
langchain_core.runnables
模块是 LangChain 核心库的核心部分,提供了构建、组合和执行可运行对象(Runnables)的工具。Runnables 是 LCEL 的基础,代表可以处理输入并生成输出的组件(如模型、函数、链)。该模块定义了多种 Runnable 类,支持灵活的工作流设计,适用于从简单的数据处理到复杂的对话系统。
核心功能:
- 提供标准化的 Runnable 接口,支持输入输出处理。
- 支持 LCEL 的链式操作(
|
),实现组件组合。 - 提供多种 Runnable 类型,满足不同场景(如条件分支、并行执行、批量处理)。
- 支持同步和异步调用,以及流式输出。
适用场景:
- 构建问答系统、RAG(Retrieval-Augmented Generation)工作流。
- 实现条件路由、并行任务或批量处理。
- 组合模型、检索器、提示模板和自定义逻辑。
- 开发聊天机器人、工具调用或复杂数据处理管道。
模块位置:
- 源码路径:
langchain_core/runnables/
- 文档参考:LangChain Core API
模块中的主要类
以下是 langchain_core.runnables
模块中的核心类(基于 LangChain 0.3.x),包括功能和典型用法。
1. Runnable
- 功能:所有 Runnable 类的基类,定义标准接口(如
invoke
、ainvoke
)。 - 方法:
invoke(input, config)
:同步调用。ainvoke(input, config)
:异步调用。stream(input, config)
:流式输出。|
:LCEL 管道操作符,连接 Runnable。
- 使用场景:作为其他 Runnable 的父类,提供统一接口。
- 示例:
from langchain_core.runnables import Runnable class CustomRunnable(Runnable): def invoke(self, input, config=None): return input.upper()
2. RunnableLambda
- 功能:将 Python 函数(通常是
lambda
)封装为 Runnable,支持自定义逻辑。 - 参数:
func
(Callable
):同步函数。afunc
(Optional[Callable]
):异步函数。
- 使用场景:数据预处理、格式转换。
- 示例:
from langchain_core.runnables import RunnableLambda runnable = RunnableLambda(lambda x: x.upper())
3. RunnablePassthrough
- 功能:直接传递输入,不做任何处理。
- 参数:无。
- 使用场景:占位符,保留输入到链的下一部分。
- 示例:
from langchain_core.runnables import RunnablePassthrough passthrough = RunnablePassthrough()
4. RunnableParallel
- 功能:并行执行多个 Runnable,输出字典。
- 参数:
**kwargs
(Runnable | Callable | Any
):键值对,键为输出字段,值为 Runnable 或常量。
- 使用场景:并行检索和处理输入。
- 示例:
from langchain_core.runnables import RunnableParallel parallel = RunnableParallel( upper=RunnableLambda(lambda x: x.upper()), length=RunnableLambda(lambda x: len(x)) )
5. RunnableBranch
- 功能:根据条件选择执行某个 Runnable。
- 参数:
branches
(List[Tuple[Callable, Runnable]]
):条件-分支对。default
(Runnable
):默认分支。
- 使用场景:动态路由、条件逻辑。
- 示例:
from langchain_core.runnables import RunnableBranch branch = RunnableBranch( [(lambda x: "AI" in x, RunnableLambda(lambda x: "AI 问题"))], RunnableLambda(lambda x: "其他问题") )
6. RunnableEach
- 功能:对输入序列的每个元素应用同一 Runnable,输出序列。
- 参数:
bound
(Runnable
):要应用的 Runnable。
- 使用场景:批量处理查询或数据。
- 示例:
from langchain_core.runnables import RunnableEach runnable = RunnableEach(bound=RunnableLambda(lambda x: x.upper()))
7. RunnableSequence
- 功能:按顺序执行多个 Runnable,输出为最后一个 Runnable 的结果。
- 参数:
first
(Runnable
):第一个 Runnable。middle
(List[Runnable]
):中间 Runnable 列表。last
(Runnable
):最后一个 Runnable。
- 使用场景:构建线性工作流。
- 示例:
from langchain_core.runnables import RunnableSequence sequence = RunnableSequence( first=RunnableLambda(lambda x: x.strip()), last=RunnableLambda(lambda x: x.upper()) )
8. RunnableWithMessageHistory
- 功能:包装 Runnable,自动注入和保存消息历史。
- 参数:
runnable
(Runnable
):要包装的链。get_session_history
(Callable
):返回消息历史实例。input_messages_key
、history_messages_key
:输入和历史的键。
- 使用场景:多轮对话。
- 示例:
from langchain_core.runnables.history import RunnableWithMessageHistory from langchain_community.chat_message_histories import ChatMessageHistory chain_with_history = RunnableWithMessageHistory( runnable=chain, get_session_history=lambda session_id: ChatMessageHistory() )
其他类
RunnableBinding
:绑定配置或工具到 Runnable。RunnableRetry
:为 Runnable 添加重试逻辑。RunnableGenerator
:支持生成器函数作为 Runnable。RunnablePick
:从字典输入中提取指定键。
基类:
- 所有类继承自
Runnable
,提供标准接口:invoke
:同步执行。ainvoke
:异步执行。stream
:流式输出。batch
:批量处理。
使用方式
以下是使用 langchain_core.runnables
模块的通用步骤。
1. 安装依赖
pip install --upgrade langchain langchain-openai
2. 设置 OpenAI API 密钥
export OPENAI_API_KEY="your-api-key"
或在代码中:
import os
os.environ["OPENAI_API_KEY"] = "your-api-key"
3. 构建 Runnable 链
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnableLambda, RunnableParallel
llm = ChatOpenAI(model="gpt-3.5-turbo")
prompt = ChatPromptTemplate.from_template("回答: {input}")
chain = RunnableParallel(
original=RunnableLambda(lambda x: x),
processed=prompt | llm
)
4. 调用链
result = chain.invoke("什么是 AI?")
print(result)
使用 langchain_core.runnables
的示例
以下是一个独立示例,展示如何使用 langchain_core.runnables
模块中的 RunnableLambda
和 RunnableParallel
结合 ChatOpenAI
实现人工智能主题的问答工作流。RunnableLambda
清理输入,RunnableParallel
并行生成原始和处理后的回答。
准备环境:
- 获取 OpenAI API 密钥:OpenAI Platform。
- 设置环境变量:
export OPENAI_API_KEY="your-api-key"
- 安装依赖:
pip install --upgrade langchain langchain-openai
代码:
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnableLambda, RunnableParallel
from langchain_core.output_parsers import StrOutputParser
# 初始化 ChatOpenAI
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0.7)
# 定义提示模板
prompt = ChatPromptTemplate.from_template(
"你是一个人工智能专家,回答问题:{input}\n回答:"
)
# 定义输出解析器
parser = StrOutputParser()
# 创建工作流,使用 RunnableLambda 和 RunnableParallel
chain = RunnableParallel(
original=RunnableLambda(lambda x: x.strip()),
answer=RunnableLambda(lambda x: x.strip()) | prompt | llm | parser
)
# 测试 langchain_core.runnables 工作流
print("测试 langchain_core.runnables 工作流:")
try:
question = " 什么是人工智能? "
result = chain.invoke(question)
print(f"输入问题: {question}")
print(f"清理后的问题: {result['original']}")
print(f"回答: {result['answer']}")
except Exception as e:
print(f"错误: {e}")
输出示例(实际输出取决于模型和 API 响应):
测试 langchain_core.runnables 工作流:
输入问题: 什么是人工智能?
清理后的问题: 什么是人工智能?
回答: 人工智能(AI)是计算机科学的一个分支,旨在模拟人类智能,如学习、推理和问题解决。
代码说明
- LLM 初始化:
- 使用
ChatOpenAI
调用gpt-3.5-turbo
,设置temperature=0.7
。
- 使用
- 提示模板:
- 定义 AI 专家提示,接收清理后的输入。
- 工作流:
- 使用
RunnableParallel
并行执行:original
:清理输入并保留。answer
:清理输入后通过prompt | llm | parser
生成回答。
RunnableLambda(lambda x: x.strip())
去除输入两端空格。
- 使用
- 测试:
- 测试 AI 相关问题,展示原始和处理后的输出。
- 错误处理:
- 使用
try-except
捕获 API 或链错误。
- 使用
运行要求:
- 有效的 OpenAI API 密钥:
export OPENAI_API_KEY="your-api-key"
- 安装依赖:
pip install --upgrade langchain langchain-openai
- 网络连接:访问
https://api.openai.com
.
注意事项
- API 密钥:
- 确保
OPENAI_API_KEY
已设置:echo $OPENAI_API_KEY
- 或在代码中设置:
llm = ChatOpenAI(api_key="your-api-key")
- 确保
- LCEL 管道:
- 使用
|
组合 Runnable:chain = runnable1 | runnable2
- 确保输入输出类型匹配:
chain = RunnableLambda(lambda x: x.strip()) | prompt
- 使用
- 性能优化:
- 异步调用:使用
ainvoke
:result = await chain.ainvoke(input)
- 流式输出:使用
stream
:for chunk in chain.stream(input): print(chunk)
- 批量处理:使用
batch
或RunnableEach
:results = chain.batch([input1, input2])
- 异步调用:使用
- 错误调试:
- 链失败:
- 检查链结构:
print(chain)
- 单独测试 Runnable:
print(runnable.invoke("测试"))
- 检查链结构:
- API 错误:
- 检查密钥:
print(os.environ.get("OPENAI_API_KEY"))
- 增加超时:
llm = ChatOpenAI(timeout=30)
- 检查密钥:
- 类型不匹配:
- 检查输入:
print(type(input))
- 验证输出:
print(chain.invoke(input))
- 检查输入:
- 链失败:
常见问题
Q1:如何选择合适的 Runnable 类?
A:根据需求:
- 自定义逻辑:
RunnableLambda
。 - 输入传递:
RunnablePassthrough
。 - 并行任务:
RunnableParallel
。 - 条件路由:
RunnableBranch
。 - 批量处理:
RunnableEach
。 - 对话历史:
RunnableWithMessageHistory
。
Q2:如何与 RAG 结合?
A:添加检索器:
from langchain.vectorstores import FAISS
vectorstore = FAISS.from_documents(docs, OpenAIEmbeddings())
retriever = vectorstore.as_retriever()
chain = RunnableParallel(
context=retriever,
question=RunnableLambda(lambda x: x.strip())
) | prompt | llm
Q3:如何支持流式输出?
A:使用 stream
:
for chunk in chain.stream("什么是 AI?"):
print(chunk, end="", flush=True)
Q4:如何支持开源模型?
A:使用 ChatOllama
:
from langchain_ollama import ChatOllama
llm = ChatOllama(model="llama3")
chain = RunnableParallel(
original=RunnableLambda(lambda x: x.strip()),
answer=RunnableLambda(lambda x: x.strip()) | prompt | llm | parser
)
总结
langchain_core.runnables
模块是 LangChain 的核心,包含以下关键类:
Runnable
:基类,提供标准接口。RunnableLambda
:封装自定义函数。RunnablePassthrough
:传递输入。RunnableParallel
:并行执行。RunnableBranch
:条件路由。RunnableEach
:批量处理。RunnableWithMessageHistory
:对话历史管理。