配置管理与 Configurable
使用 RunnableConfig 动态控制图的行为,实现参数热更新
📚 学习目标
学完这篇文章后,你将能够:
- 理解
RunnableConfig对象的作用 - 在节点中访问运行时配置
- 实现可配置的 Agent(如动态切换模型、Prompt)
前置知识
在开始学习之前,建议先阅读:
你需要了解:
- 环境变量的基本概念
1 什么是 RunnableConfig?
在调用 invoke, stream, batch 时,LangGraph 允许传入第二个参数:RunnableConfig。
import { RunnableConfig } from '@langchain/core/runnables';
await app.invoke(inputs, {
configurable: {
model: "gpt-4",
temperature: 0.5
},
recursionLimit: 50,
runName: "MyAgentRun"
});这些配置不仅控制运行时的行为(如递归限制),还可以透传给图中的每个节点。
如果你把它当成一个“运行时上下文对象”会更好理解:
configurable:你自定义的运行参数(用户ID、模型名、feature flag...)tags/metadata:可观测性与追踪用(打标签、记录额外信息)recursionLimit:防止循环失控
2 RunnableConfig 里常用的字段
下面是一个“面向教学”的简化心智模型(不同版本字段可能略有差异):
export type ExampleRunnableConfig = {
configurable?: Record<string, unknown>;
tags?: string[];
metadata?: Record<string, unknown>;
recursionLimit?: number;
runName?: string;
};3 节点内访问配置
节点函数的第二个参数就是 config。
const myNode = async (state: State, config: RunnableConfig) => {
// 1. 获取配置
const modelName = config.configurable?.model || "gpt-3.5-turbo";
// 2. 使用配置
const model = new ChatOpenAI({ model: modelName });
const response = await model.invoke(state.messages);
return { messages: [response] };
};为什么这很有用?
- 多租户支持:不同用户使用不同的 prompt 或模型。
- A/B 测试:运行时动态决定使用哪个策略。
- 安全性:动态传入 User ID 或 API Token。
📝 提醒
不要把明文 API Key 放进 configurable。更稳妥的方式是传 keyId / tenantId,在节点里再去你的密钥系统取真实 key。
4 预置配置项
LangGraph 有一些内置的配置键:
- recursionLimit: 最大递归深度(默认 25)。防止死循环。
- thread_id: 用于 Checkpoint 持久化(区分不同会话)。
- runName: 在 LangSmith 追踪中显示的名称。
// 防止死循环的保护机制
try {
await app.invoke(inputs, { recursionLimit: 5 });
} catch (e) {
console.log("达到递归限制!");
}5 配置继承:子图/节点如何拿到同一套参数
当你把一个“编译后的 subgraph”当作节点接入父图时,运行时配置通常会沿调用链传递下去。
6 配置优先级
当同一参数在多处定义时,优先级通常是:
- 运行时传入(invoke/stream)
- 节点内覆盖(节点逻辑里手动覆盖)
- 默认值(Annotation/代码默认值)
const config = { configurable: { model: 'gpt-4' } };
await app.invoke(inputs, config); // 最高优先级7 环境变量 + Configurable 组合
你可以用环境变量做全局默认,用 configurable 做动态覆盖:
const defaultModel = process.env.OPENAI_MODEL_NAME ?? 'gpt-4o-mini';
const modelName = config.configurable?.model ?? defaultModel;💡 说明
环境变量适合部署级配置,configurable 适合运行时差异化。
8 A/B 测试示例
通过 config 传入实验组:
const group = config.configurable?.experiment ?? 'control';
const temperature = group === 'variant' ? 0.7 : 0.2;9 类型安全与校验
为了避免运行时出错,建议给 configurable 做简单校验:
const ConfigSchema = z.object({
model: z.string().optional(),
temperature: z.number().min(0).max(1).optional(),
});
const safeConfig = ConfigSchema.parse(config.configurable ?? {});⚠️ 注意
校验失败时要有兜底策略,避免直接崩溃。
💡 练习题
-
编码题:修改你的 ReAct Agent,使其接受一个
systemPrompt配置参数。在运行时动态传入不同的角色设定(如“你是一个海盗” vs “你是一个医生”)。点击查看答案
在节点中读取
config.configurable?.systemPrompt,作为 SystemMessage 注入。 -
场景题:如果在
configurable中传入了一个敏感的 API Key,它会被 LangSmith 记录吗?如何避免?点击查看答案
不建议明文传入;可以传
keyId并在节点内获取真实密钥。 -
操作题:为配置添加
temperature校验,超出范围自动回退默认值。点击查看答案
用 zod 校验并在 catch 中回退默认温度。
-
思考题:什么时候应该用环境变量而不是 configurable?
点击查看答案
环境变量适合部署级配置,configurable 适合运行时差异化。
-
操作题:实现一个简单的 A/B 测试配置,控制不同温度值。
点击查看答案
根据
config.configurable?.experiment选择温度。
✅ 总结
本章要点:
configurable字段是运行时动态传参的主要通道。- 节点函数的签名是
(state, config) => ...。 - 合理使用配置可以让你的 Graph 更加通用和灵活。
下一步:如果运行出错了怎么办?继续学习:错误处理。
登录以继续阅读
解锁完整文档、代码示例及更多高级功能。