【LangChain】 langchain_core.runnables 模块:构建和组合可运行对象(Runnables)

langchain_core.runnables 模块是 LangChain 核心库中的核心组件之一,用于构建和组合可运行对象(Runnables),支持 LangChain Expression Language (LCEL) 的链式工作流。

本文基于 LangChain 0.3.x,详细介绍 langchain_core.runnables 模块的结构、核心类及其功能,并提供一个独立示例,展示如何结合多个 Runnable(如 RunnableLambdaRunnableParallelChatOpenAI)实现人工智能主题的问答工作流,示例突出模块的灵活性和 LCEL 的链式组合能力。


langchain_core.runnables 模块概览

langchain_core.runnables 模块是 LangChain 核心库的核心部分,提供了构建、组合和执行可运行对象(Runnables)的工具。Runnables 是 LCEL 的基础,代表可以处理输入并生成输出的组件(如模型、函数、链)。该模块定义了多种 Runnable 类,支持灵活的工作流设计,适用于从简单的数据处理到复杂的对话系统。

核心功能

  • 提供标准化的 Runnable 接口,支持输入输出处理。
  • 支持 LCEL 的链式操作(|),实现组件组合。
  • 提供多种 Runnable 类型,满足不同场景(如条件分支、并行执行、批量处理)。
  • 支持同步和异步调用,以及流式输出。

适用场景

  • 构建问答系统、RAG(Retrieval-Augmented Generation)工作流。
  • 实现条件路由、并行任务或批量处理。
  • 组合模型、检索器、提示模板和自定义逻辑。
  • 开发聊天机器人、工具调用或复杂数据处理管道。

模块位置


模块中的主要类

以下是 langchain_core.runnables 模块中的核心类(基于 LangChain 0.3.x),包括功能和典型用法。

1. Runnable
  • 功能:所有 Runnable 类的基类,定义标准接口(如 invokeainvoke)。
  • 方法
    • 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,支持自定义逻辑。
  • 参数
    • funcCallable):同步函数。
    • afuncOptional[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,输出字典。
  • 参数
    • **kwargsRunnable | 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。
  • 参数
    • branchesList[Tuple[Callable, Runnable]]):条件-分支对。
    • defaultRunnable):默认分支。
  • 使用场景:动态路由、条件逻辑。
  • 示例
    from langchain_core.runnables import RunnableBranch
    branch = RunnableBranch(
        [(lambda x: "AI" in x, RunnableLambda(lambda x: "AI 问题"))],
        RunnableLambda(lambda x: "其他问题")
    )
    
6. RunnableEach
  • 功能:对输入序列的每个元素应用同一 Runnable,输出序列。
  • 参数
    • boundRunnable):要应用的 Runnable。
  • 使用场景:批量处理查询或数据。
  • 示例
    from langchain_core.runnables import RunnableEach
    runnable = RunnableEach(bound=RunnableLambda(lambda x: x.upper()))
    
7. RunnableSequence
  • 功能:按顺序执行多个 Runnable,输出为最后一个 Runnable 的结果。
  • 参数
    • firstRunnable):第一个 Runnable。
    • middleList[Runnable]):中间 Runnable 列表。
    • lastRunnable):最后一个 Runnable。
  • 使用场景:构建线性工作流。
  • 示例
    from langchain_core.runnables import RunnableSequence
    sequence = RunnableSequence(
        first=RunnableLambda(lambda x: x.strip()),
        last=RunnableLambda(lambda x: x.upper())
    )
    
8. RunnableWithMessageHistory
  • 功能:包装 Runnable,自动注入和保存消息历史。
  • 参数
    • runnableRunnable):要包装的链。
    • get_session_historyCallable):返回消息历史实例。
    • input_messages_keyhistory_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 模块中的 RunnableLambdaRunnableParallel 结合 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)是计算机科学的一个分支,旨在模拟人类智能,如学习、推理和问题解决。
代码说明
  1. LLM 初始化
    • 使用 ChatOpenAI 调用 gpt-3.5-turbo,设置 temperature=0.7
  2. 提示模板
    • 定义 AI 专家提示,接收清理后的输入。
  3. 工作流
    • 使用 RunnableParallel 并行执行:
      • original:清理输入并保留。
      • answer:清理输入后通过 prompt | llm | parser 生成回答。
    • RunnableLambda(lambda x: x.strip()) 去除输入两端空格。
  4. 测试
    • 测试 AI 相关问题,展示原始和处理后的输出。
  5. 错误处理
    • 使用 try-except 捕获 API 或链错误。

运行要求

  • 有效的 OpenAI API 密钥:
    export OPENAI_API_KEY="your-api-key"
    
  • 安装依赖:
    pip install --upgrade langchain langchain-openai
    
  • 网络连接:访问 https://api.openai.com.

注意事项

  1. API 密钥
    • 确保 OPENAI_API_KEY 已设置:
      echo $OPENAI_API_KEY
      
    • 或在代码中设置:
      llm = ChatOpenAI(api_key="your-api-key")
      
  2. LCEL 管道
    • 使用 | 组合 Runnable:
      chain = runnable1 | runnable2
      
    • 确保输入输出类型匹配:
      chain = RunnableLambda(lambda x: x.strip()) | prompt
      
  3. 性能优化
    • 异步调用:使用 ainvoke
      result = await chain.ainvoke(input)
      
    • 流式输出:使用 stream
      for chunk in chain.stream(input):
          print(chunk)
      
    • 批量处理:使用 batchRunnableEach
      results = chain.batch([input1, input2])
      
  4. 错误调试
    • 链失败
      • 检查链结构:
        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:对话历史管理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

彬彬侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值