核心组件详解
节点设计
深入探讨节点的类型、编写规范以及异步和配置化节点的实现
📚 学习目标
学完这篇文章后,你将能够:
- 编写标准的同步及异步节点函数
- 使用
RunnableConfig编写可配置的节点 - 理解节点的输入输出规范
- 掌握节点内的错误处理最佳实践
前置知识
在开始学习之前,建议先阅读:
你需要了解:
- Async/Await 异步编程模式
- JavaScript 异常处理 (try/catch)
1️⃣ 节点函数规范
在 LangGraph 中,节点就是一个简单的函数。
基本签名
import { RunnableConfig } from "@langchain/core/runnables";
// state: 当前状态
// config: 运行时配置(可选)
const myNode = async (state: State, config?: RunnableConfig) => {
// 业务逻辑
const result = await doSomething(state.input);
// 返回状态更新
return {
output: result,
};
};2️⃣ 节点类型详解
1. 异步节点(最常用)
绝大多数涉及 LLM 调用、数据库查询、API 请求的节点都是异步的。
const llmNode = async (state: typeof StateAnnotation.State) => {
const response = await model.invoke(state.messages);
return { messages: [response] };
};2. 同步节点
用于纯逻辑处理,如数据格式化、简单计算。
const formatNode = (state: typeof StateAnnotation.State) => {
return { content: state.content.trim() };
};3. 可配置节点
通过 config 参数,让节点行为在运行时可调整。这在多用户多配置场景下非常有用。
const configurableNode = async (state: State, config?: RunnableConfig) => {
// 从配置中读取参数,默认为 'gpt-3.5-turbo'
const modelName = config?.configurable?.modelName || 'gpt-3.5-turbo';
const model = new ChatOpenAI({ model: modelName });
// ...
};调用时传入配置:
await graph.invoke(inputs, {
configurable: { modelName: 'gpt-4' }
});3️⃣ 错误处理
在节点内部处理错误,可以防止整个图崩溃,并允许实现重试或降级逻辑。
推荐模式
const safeToolNode = async (state: State) => {
try {
const result = await tool.invoke(state.query);
return { toolResult: result, error: null };
} catch (e) {
console.error("Tool execution failed", e);
// 返回错误状态,而不是抛出异常
return {
error: e.message,
// 可选:触发重试逻辑
retryCount: state.retryCount + 1
};
}
};4️⃣ 节点怎么拆:把复杂逻辑拆成可测试的“小块”
一个很常见的反模式是:
- 一个节点里同时做“解析输入 -> 检索 -> 生成 -> 格式化 -> 记录指标”
结果就是:难测、难改、难复用。
更好的做法是按“职责”拆节点:
拆分之后,你可以:
- 对
parse写单元测试(纯函数) - 对
search做超时/重试 - 对
answer做模型切换与 token 限制
5️⃣ 特殊节点:START 和 END
5️⃣ 特殊节点:START 和 END
- START:虽然代码中常用
addEdge(START, 'node'),但 START 本身不是一个你需要编写函数的节点,它只是一个标记,代表图的入口。 - END:同样是标记,代表流程结束。
import { START, END } from '@langchain/langgraph';
graph.addEdge(START, 'entryNode');
graph.addEdge('finalNode', END);💡 练习题
- 改造题:将一个硬编码了 API Key 的节点函数,改造成从
RunnableConfig中读取 Key 的可配置节点。 - 设计题:设计一个“网络请求节点”,要求包含超时处理(例如 5 秒超时)和简单的重试机制(如果失败,检查重试计数)。
📚 参考资源
官方文档
✅ 总结
本章要点:
- 节点本质上是
(State) => Partial<State>的函数。 - 充分利用
async/await处理 I/O 操作。 - 使用
RunnableConfig提升节点的复用性。 - 优雅的错误处理是构建健壮 Agent 的关键。
下一步:节点只是孤岛,让我们通过边将它们连接起来。
登录以继续阅读
解锁完整文档、代码示例及更多高级功能。