Runnable 接口
Runnable 接口是使用 LangChain 组件的基础,它在许多组件中实现,例如语言模型、输出解析器、检索器、编译后的 LangGraph 图等等。
本指南涵盖了 Runnable 接口的主要概念和方法,这些概念和方法允许开发人员以一致且可预测的方式与各种 LangChain 组件进行交互。
- “Runnable”接口 API 参考提供了 Runnable 接口及其方法的详细概述。
- 内置 Runnables 的列表可以在 LangChain Core API 参考中找到。当使用 LangChain 表达式语言 (LCEL) 在 LangChain 中组合自定义“链”时,这些 Runnables 中的许多都非常有用。
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
stream
:在生成 Runnable 的输出时产生输出。streamEvents
:一种更高级的流式 API,允许流式传输中间步骤和最终输出- 旧版
streamLog
:一种旧版流式 API,流式传输中间步骤和最终输出
有关如何在 LangChain 中进行流式传输的更多详细信息,请参阅流式传输概念指南。
输入和输出类型
每个 Runnable
都以输入和输出类型为特征。这些输入和输出类型可以是任何 TypeScript 对象,并且由 Runnable 本身定义。
导致 Runnable 执行的 Runnable 方法(例如,invoke
、batch
、stream
、streamEvents
)使用这些输入和输出类型。
invoke
:接受一个输入并返回一个输出。batch
:接受输入列表并返回输出列表。stream
:接受一个输入并返回一个生成器,该生成器产生输出。
输入类型和输出类型因组件而异
组件 | 输入类型 | 输出类型 |
---|---|---|
提示 | 对象 | PromptValue |
聊天模型 | 字符串、聊天消息列表或 PromptValue | ChatMessage |
LLM | 字符串、聊天消息列表或 PromptValue | 字符串 |
输出解析器 | LLM 或聊天模型的输出 | 取决于解析器 |
检索器 | 字符串 | 文档列表 |
工具 | 字符串或对象,取决于工具 | 取决于工具 |
有关输入和输出类型以及如何使用它们的更多信息,请参阅各个组件文档。
RunnableConfig
任何用于执行 runnable 的方法(例如,invoke
、batch
、stream
、streamEvents
)都接受第二个参数,称为 RunnableConfig
(API 参考)。此参数是一个对象,其中包含 Runnable 的配置,该配置将在 runnable 执行期间在运行时使用。
RunnableConfig
可以定义以下任何属性
属性 | 描述 |
---|---|
runName | 用于给定 Runnable 的名称(不继承)。 |
runId | 此调用的唯一标识符。子调用将获得其自己的唯一运行 ID。 |
tags | 此调用和任何子调用的标签。 |
metadata | 此调用和任何子调用的元数据。 |
callbacks | 此调用和任何子调用的回调。 |
maxConcurrency | 要进行的最大并行调用数(例如,由 batch 使用)。 |
recursionLimit | 调用可以递归的最大次数(例如,由返回 Runnables 的 Runnables 使用) |
configurable | Runnable 的可配置属性的运行时值。 |
将 config
传递给 invoke
方法是这样完成的
await someRunnable.invoke(someInput, {
runName: "myRun",
tags: ["tag1", "tag2"],
metadata: { key: "value" },
});
RunnableConfig 的传播
许多 Runnables 由其他 Runnables 组成,并且重要的是 RunnableConfig
被传播到 Runnable 进行的所有子调用。这允许向父 Runnable 提供运行时配置值,这些值由所有子调用继承。
如果不是这种情况,则不可能设置和传播回调或其他配置值,如 tags
和 metadata
,这些值应由所有子调用继承。
创建新 Runnables 主要有两种模式
声明式地使用 LangChain 表达式语言 (LCEL)
const chain = prompt.pipe(chatModel).pipe(outputParser);
使用自定义 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
对象的 runName
、tags
和 metadata
属性可用于为给定 Runnable 设置自定义运行名称、标签和元数据。
runName
是一个字符串,可用于设置运行的自定义名称。此名称将在日志和其他地方用于标识运行。它不会被子调用继承。
tags
和 metadata
属性分别是数组和对象,可用于为运行设置自定义标签和元数据。这些值由子调用继承。
使用这些属性对于跟踪和调试运行非常有用,因为它们将在 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
:当需要流式传输时,将其用于更复杂的转换。
有关如何使用 RunnableLambda
和 RunnableGenerator
的更多信息,请参阅如何运行自定义函数指南。
用户不应尝试子类化 Runnables 以创建新的自定义 Runnable。它比简单地使用 RunnableLambda
或 RunnableGenerator
更复杂且更容易出错。