【LangChain】langchain_core.runnables.chain 装饰器函数:将普通函数转换为 Runnable 对象

langchain_core.runnables.chain 详解

langchain_core.runnables.chain 是 LangChain 框架中用于将 Python 函数转换为可运行对象(Runnable)的装饰器函数。本文详细介绍其功能、参数、使用方法、实际应用及注意事项,确保内容条理清晰、易于理解。

1. 概述

1.1 什么是 chain 装饰器?

langchain_core.runnables.chain 是一个装饰器函数,位于 langchain_core.runnables.base 模块,用于将普通的 Python 函数转换为 LangChain 的 Runnable 对象。Runnable 是 LangChain 生态系统的核心组件,支持同步、异步、批处理和流式处理等操作。通过 @chain 装饰器,开发者可以将自定义逻辑无缝集成到 LangChain 的工作流中,与其他组件(如提示模板、语言模型、输出解析器)组合成复杂的处理链。

该装饰器通过自动设置函数名称并追踪依赖项,简化了自定义 Runnable 的创建过程。它在 langchain-core 0.2.14 版本中引入,广泛应用于数据处理管道、实时应用和高并发场景。

1.2 与其他组件的关系

  • @tool 装饰器:前文讨论的 langchain_core.tools.tool 用于创建工具型 Runnable,专注于语言模型调用外部功能;而 chain 更适合封装通用逻辑,如数据预处理或后处理。
  • InjectedToolArgchain 可用于工具调用链中注入运行时参数,例如为工具提供动态输入。
  • RunnableSequenceRunnableParallelchain 创建的 Runnable 可通过 | 运算符或 .pipe() 方法与其他 Runnable 组成顺序或并行处理链。

1.3 核心功能

  • 自动转换:将函数转换为 Runnable,名称默认为函数名。
  • 依赖追踪:记录函数中调用的其他 Runnable 作为依赖项,便于调试。
  • 灵活支持:兼容同步函数、异步函数、生成器和异步生成器。
  • LCEL 集成:支持 LangChain Expression Language (LCEL),通过 |.pipe() 构建复杂链。
  • 调试支持:与 LangSmith 等工具配合,提供执行跟踪和调试功能。

2. 使用方法

@chain 装饰器通过简单的方式将函数转换为 Runnable。以下是不同场景下的使用示例:

2.1 同步函数

将普通函数转换为 Runnable

from langchain_core.runnables import chain

@chain
def add_one(x: int) -> int:
    """将输入加一"""
    return x + 1
  • 调用方式add_one.invoke(5) 返回 6。
  • 组合链
    from langchain_core.runnables import RunnableLambda
    sequence = add_one | RunnableLambda(lambda x: x * 2)
    print(sequence.invoke(5))  # 输出 12
    

2.2 流式处理函数

使用生成器函数支持流式输出:

@chain
def generate_numbers(n: int):
    """生成从 0 到 n-1 的数字"""
    for i in range(n):
        yield i
  • 调用方式for chunk in generate_numbers.stream(3): print(chunk) 输出 0、1、2。

2.3 异步函数

支持异步逻辑,提高并发性能:

import asyncio
from langchain_core.runnables import chain

@chain
async def async_add_one(x: int) -> int:
    """异步将输入加一"""
    await asyncio.sleep(1)  # 模拟异步操作
    return x + 1
  • 调用方式await async_add_one.ainvoke(5) 返回 6。

2.4 综合示例

结合提示模板和语言模型,展示复杂场景:

from langchain_core.runnables import chain
from langchain_core.prompts import PromptTemplate
from langchain_openai import OpenAI

@chain
def greet_user(fields):
    """生成个性化问候语"""
    prompt = PromptTemplate.from_template("Hello, {name}!")
    llm = OpenAI()
    formatted = prompt.invoke(**fields)
    for chunk in llm.stream(formatted):
        yield chunk
  • 调用方式for chunk in greet_user.stream({"name": "Alice"}): print(chunk) 输出流式问候语。

2.5 结合 InjectedToolArg

结合 InjectedToolArg,在工具调用中注入运行时参数:

from langchain_core.runnables import chain
from langchain_core.tools import tool, InjectedToolArg
from typing import Annotated, List

@tool
def update_favorite_pets(pets: List[str], user_id: Annotated[str, InjectedToolArg]) -> None:
    """更新用户的收藏宠物"""
    user_to_pets[user_id] = pets  # 假设的存储

@chain
def inject_user_id(input):
    """注入用户 ID 到工具调用"""
    tool_call = input["tool_call"]
    user_id = input["user_id"]
    tool_call_copy = tool_call.copy()
    tool_call_copy["args"]["user_id"] = user_id
    return {"tool_call": tool_call_copy}

# 组合链
chain = inject_user_id | update_favorite_pets
chain.invoke({"tool_call": {"name": "update_favorite_pets", "args": {"pets": ["dog"]}}, "user_id": "123"})

3. 参数与签名

chain 装饰器的签名如下:

langchain_core.runnables.base.chain(func: Callable[[Input], Output]) -> Runnable[Input, Output]

3.1 参数

参数类型描述
funcCallable要装饰的函数,接受输入并返回输出。

支持的函数类型:

  • 同步函数:Callable[[Input], Output]
  • 异步函数:Callable[[Input], Coroutine[Any, Any, Output]]
  • 生成器函数:Callable[[Input], Iterator[Output]]
  • 异步生成器函数:Callable[[Input], AsyncIterator[Output]]

3.2 返回值

返回值类型描述
RunnableRunnable[Input, Output]支持 LangChain 标准接口的可运行对象。

4. 核心方法

chain 装饰器生成的 Runnable 继承自 RunnableSerializable,支持以下标准方法:

方法描述输入输出
invoke同步调用,处理单个输入。input: Input, config: Optional[RunnableConfig]Output
ainvoke异步调用。input: Input, config: Optional[RunnableConfig]Output
batch同步批量处理多个输入。inputs: List[Input], config: Optional[RunnableConfig | List[RunnableConfig]]List[Output]
abatch异步批量处理。inputs: List[Input], config: Optional[RunnableConfig | List[RunnableConfig]]List[Output]
stream同步流式输出。input: Input, config: Optional[RunnableConfig]Iterator[Output]
astream异步流式输出。input: Input, config: Optional[RunnableConfig]AsyncIterator[Output]
astream_events异步流式事件,需 langchain-core>=0.2.29input: Input, config: Optional[RunnableConfig], version: Literal['v1', 'v2']AsyncIterator[StreamEvent]

这些方法使 chain 创建的 Runnable 能够灵活适应不同场景。

5. 实际应用

chain 装饰器在以下场景中广泛使用:

  • 数据处理管道:组合数据预处理、模型推理和后处理。例如,格式化用户输入、调用语言模型、解析输出。
  • 流式应用:如实时聊天机器人,逐步生成响应。例如,使用生成器函数流式输出模型响应。
  • 异步任务:在高并发场景下提高性能。例如,异步处理多个用户请求。
  • 工具调用注入:结合 InjectedToolArg,为工具调用注入运行时参数。
  • 自定义逻辑:将特定业务逻辑封装为 Runnable,与 LangChain 组件集成。

示例:复杂数据处理管道

from langchain_core.runnables import chain
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser

@chain
def format_input(data: dict) -> dict:
    """格式化输入数据"""
    return {"question": data["input"].upper()}

prompt = ChatPromptTemplate.from_template("Answer: {question}")
model = ChatOpenAI()
parser = StrOutputParser()

chain = format_input | prompt | model | parser
result = chain.invoke({"input": "hello"})  # 输出模型对 "HELLO" 的回答

6. 最佳实践

  • 类型清晰:确保函数的输入和输出类型与链中其他 Runnable 的预期类型兼容。
  • 文档字符串:为函数提供详细的文档字符串,便于调试和维护。
  • 流式处理:对于实时输出的场景,使用生成器函数支持 stream 方法。
  • 异步优化:在高并发场景下,优先使用异步函数以提高性能。
  • 版本检查:确保使用 langchain-core>=0.2.14,通过 pip install -qU langchain 安装。
  • 调试工具V:复杂链使用 LangSmith 等工具进行跟踪和调试。

7. 注意事项与限制

  • 输入输出兼容性:函数的输入和输出需与链中其他 Runnable 的预期类型匹配,否则可能导致运行时错误。
  • 异步环境:异步函数需在支持 asyncio 的环境中运行。
  • 生成器格式:流式函数需正确使用 yield 确保输出逐块生成。
  • 版本依赖:某些功能(如 astream_events)需 langchain-core>=0.2.29
  • 调试复杂性:复杂链可能需要 LangSmith 等工具进行跟踪和调试。

8. 结论

langchain_core.runnables.chain 是一个强大而灵活的装饰器函数,通过将普通 Python 函数转换为 Runnable 对象,简化了自定义逻辑与 LangChain 生态系统的集成。它支持同步、异步、生成器和异步生成器函数,适用于数据处理管道、流式应用、异步任务和工具调用注入等场景。开发者应遵循最佳实践,确保类型兼容性和版本要求,以构建高效、可维护的 LangChain 应用。

9. 参考资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

彬彬侠

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

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

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

打赏作者

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

抵扣说明:

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

余额充值