跳到主要内容

Runnable 接口

Runnable 接口是使用 LangChain 组件的基础,它在许多组件中实现,例如语言模型输出解析器检索器编译后的 LangGraph 图等等。

本指南涵盖了 Runnable 接口的主要概念和方法,这些概念和方法允许开发人员以一致且可预测的方式与各种 LangChain 组件进行交互。

相关资源

Runnable 接口概述

Runnable 方式定义了一个标准接口,允许 Runnable 组件

  • 调用:将单个输入转换为输出。
  • 批处理:将多个输入高效地转换为输出。
  • 流式传输:在生成输出时对其进行流式传输。
  • 检查:可以访问有关 Runnable 的输入、输出和配置的示意信息。
  • 组合:可以使用 LangChain 表达式语言 (LCEL) 将多个 Runnables 组合在一起以创建复杂的管道。

请查看 LCEL 速查表,了解一些涉及 Runnable 接口和 LCEL 表达式的常见模式。

优化的并行执行(批处理)

LangChain Runnables 提供了一个内置的 batch API,允许您并行处理多个输入。

当需要处理多个独立输入时,使用此方法可以显着提高性能,因为可以并行而不是顺序地完成处理。

批处理方法是

  • batch:并行处理多个输入,并以与输入相同的顺序返回结果。

batch 的默认实现并行执行 invoke 方法。

某些 Runnables 可能会提供其自己的 batch 实现,这些实现针对其特定用例进行了优化(例如,依赖于模型提供商提供的 batch API)。

提示

当使用 batch 处理大量输入时,用户可能希望控制最大并行调用数。这可以通过在 RunnableConfig 对象中设置 maxConcurrency 属性来完成。有关更多信息,请参阅 RunnableConfig

流式 API

流式传输对于使基于 LLM 的应用程序对最终用户感觉响应迅速至关重要。

Runnables 公开以下三个流式 API

  1. stream:在生成 Runnable 的输出时产生输出。
  2. streamEvents:一种更高级的流式 API,允许流式传输中间步骤和最终输出
  3. 旧版 streamLog:一种旧版流式 API,流式传输中间步骤和最终输出

有关如何在 LangChain 中进行流式传输的更多详细信息,请参阅流式传输概念指南

输入和输出类型

每个 Runnable 都以输入和输出类型为特征。这些输入和输出类型可以是任何 TypeScript 对象,并且由 Runnable 本身定义。

导致 Runnable 执行的 Runnable 方法(例如,invokebatchstreamstreamEvents)使用这些输入和输出类型。

  • invoke:接受一个输入并返回一个输出。
  • batch:接受输入列表并返回输出列表。
  • stream:接受一个输入并返回一个生成器,该生成器产生输出。

输入类型和输出类型因组件而异

组件输入类型输出类型
提示对象PromptValue
聊天模型字符串、聊天消息列表或 PromptValueChatMessage
LLM字符串、聊天消息列表或 PromptValue字符串
输出解析器LLM 或聊天模型的输出取决于解析器
检索器字符串文档列表
工具字符串或对象,取决于工具取决于工具

有关输入和输出类型以及如何使用它们的更多信息,请参阅各个组件文档。

RunnableConfig

任何用于执行 runnable 的方法(例如,invokebatchstreamstreamEvents)都接受第二个参数,称为 RunnableConfig (API 参考)。此参数是一个对象,其中包含 Runnable 的配置,该配置将在 runnable 执行期间在运行时使用。

RunnableConfig 可以定义以下任何属性

属性描述
runName用于给定 Runnable 的名称(不继承)。
runId此调用的唯一标识符。子调用将获得其自己的唯一运行 ID。
tags此调用和任何子调用的标签。
metadata此调用和任何子调用的元数据。
callbacks此调用和任何子调用的回调。
maxConcurrency要进行的最大并行调用数(例如,由 batch 使用)。
recursionLimit调用可以递归的最大次数(例如,由返回 Runnables 的 Runnables 使用)
configurableRunnable 的可配置属性的运行时值。

config 传递给 invoke 方法是这样完成的

await someRunnable.invoke(someInput, {
runName: "myRun",
tags: ["tag1", "tag2"],
metadata: { key: "value" },
});

RunnableConfig 的传播

许多 Runnables 由其他 Runnables 组成,并且重要的是 RunnableConfig 被传播到 Runnable 进行的所有子调用。这允许向父 Runnable 提供运行时配置值,这些值由所有子调用继承。

如果不是这种情况,则不可能设置和传播回调或其他配置值,如 tagsmetadata,这些值应由所有子调用继承。

创建新 Runnables 主要有两种模式

  1. 声明式地使用 LangChain 表达式语言 (LCEL)

    const chain = prompt.pipe(chatModel).pipe(outputParser);
  2. 使用自定义 Runnable(例如,RunnableLambda)或使用 tool 函数

    const foo = (input) => {
    // Note that .invoke() is used directly here
    return barRunnable.invoke(input);
    };
    const fooRunnable = RunnableLambda.from(foo);

LangChain 将尝试为这两种模式自动传播 RunnableConfig

手动传播 RunnableConfig 是这样完成的

// Note the config argument
const foo = (input, config) => {
return barRunnable.invoke(input, config);
};
const fooRunnable = RunnableLambda.from(foo);

设置自定义运行名称、标签和元数据

RunnableConfig 对象的 runNametagsmetadata 属性可用于为给定 Runnable 设置自定义运行名称、标签和元数据。

runName 是一个字符串,可用于设置运行的自定义名称。此名称将在日志和其他地方用于标识运行。它不会被子调用继承。

tagsmetadata 属性分别是数组和对象,可用于为运行设置自定义标签和元数据。这些值由子调用继承。

使用这些属性对于跟踪和调试运行非常有用,因为它们将在 LangSmith 中作为跟踪属性显示,您可以在其上进行过滤和搜索。

这些属性也将传播到 回调,并将作为流中每个事件的一部分出现在流式 API(如 streamEvents)中。

设置运行 ID

注意

这是一个高级功能,对于大多数用户来说是不必要的。

您可能需要为给定的运行设置自定义 runId,以防您以后要引用它或将其与其他系统关联。

runId 必须是有效的 UUID 字符串,并且对于每次运行都是唯一的。它用于标识父运行,子类将自动获得其自己的唯一运行 ID。

要设置自定义 runId,您可以在调用 Runnable 时将其作为键值对传递到 config 对象中

import { v4 as uuidv4 } from "uuid";

const runId = uuidv4();

await someRunnable.invoke(someInput, {
runId,
});

// Do something with the runId

设置递归限制

注意

这是一个高级功能,对于大多数用户来说是不必要的。

某些 Runnables 可能会返回其他 Runnables,如果不正确处理,可能会导致无限递归。为了防止这种情况,您可以在 RunnableConfig 对象中设置 recursion_limit。这将限制 Runnable 可以递归的次数。

设置最大并发数

如果使用 batch 方法,您可以在 RunnableConfig 对象中设置 maxConcurrency 属性,以控制要进行的最大并行调用数。当您想限制并行调用数以防止服务器或 API 过载时,这可能很有用。

设置可配置项

configurable 字段用于传递 Runnable 的可配置属性的运行时值。

它在 LangGraph 中与 LangGraph Persistence内存 频繁使用。

它在 RunnableWithMessageHistory 中用于类似的目的,以指定 session_id 以跟踪对话历史记录。

设置回调

使用此选项在运行时为 runnable 配置回调。回调将传递给 runnable 进行的所有子调用。

await someRunnable.invoke(someInput, {
callbacks: [SomeCallbackHandler(), AnotherCallbackHandler()],
});

有关如何在 LangChain 中使用回调的更多信息,请阅读回调概念指南

从函数创建 runnable

您可能需要创建一个运行任意逻辑的自定义 Runnable。如果使用 LangChain 表达式语言 (LCEL) 组合多个 Runnables 并且需要在其中一个步骤中添加自定义处理逻辑,这将特别有用。

有两种方法可以从函数创建自定义 Runnable

  • RunnableLambda:在不需要流式传输的简单转换中使用此项。
  • RunnableGenerator:当需要流式传输时,将其用于更复杂的转换。

有关如何使用 RunnableLambdaRunnableGenerator 的更多信息,请参阅如何运行自定义函数指南。

信息

用户不应尝试子类化 Runnables 以创建新的自定义 Runnable。它比简单地使用 RunnableLambdaRunnableGenerator 更复杂且更容易出错。


此页是否对您有帮助?


您也可以留下详细的反馈 在 GitHub 上.