什么是 LangGraph?
引言
在构建智能应用的过程中,我们经常需要让 AI 系统能够自主决策、动态调整执行路径。传统的链式结构虽然可靠,但缺乏灵活性。LangGraph 正是为了解决这一问题而诞生的框架。
本节将带你深入理解 LangGraph 的核心概念,了解它如何改变我们构建 AI 应用的方式,以及它与传统方法的本质区别。
核心概念解释
LangGraph 的定义
LangGraph 是一个用于构建智能代理(Agent)应用的 JavaScript/TypeScript 框架。它将 LLM 应用的控制流程建模为图结构,其中:
- 节点(Nodes) 代表不同的功能组件
- 边(Edges) 代表信息流和控制流
- 状态(State) 代表应用的当前快照
LangGraph 的核心理念是让 LLM 能够自主决定应用的执行路径,而不是按照预定义的固定步骤执行。
图结构 vs 链式结构
让我们通过可视化图表来理解两种架构的区别:
关键特性对比
链式结构 (Chain)
特点:
- ✅ 高度可靠和可预测
- ✅ 易于理解和调试
- ❌ 执行路径固定
- ❌ 缺乏动态决策能力
- ❌ 难以处理复杂场景
适用场景:
- 简单的数据处理流程
- 固定的业务逻辑
- 对可预测性要求极高的场景
图结构 (Graph)
特点:
- ✅ 动态控制流
- ✅ LLM 自主决策
- ✅ 支持复杂交互
- ✅ 高度可扩展
- ⚠️ 需要更多的设计考虑
适用场景:
- 智能代理系统
- 复杂的多步骤任务
- 需要动态决策的应用
- 人机交互场景
LangGraph 的核心构建块
理解 LangGraph 需要掌握四个核心概念:
1. 状态(State)
状态是贯穿整个图执行过程的数据容器。所有节点都可以读取和修改状态。
// 使用 Annotation 定义状态结构
const StateAnnotation = Annotation.Root({
messages: Annotation<BaseMessage[]>({
reducer: messagesStateReducer,
default: () => [],
}),
step: Annotation<number>({
default: () => 0,
}),
});
状态定义了「数据长什么样」以及「数据如何更新」(通过 reducer)。
2. 节点(Node)
节点是执行具体逻辑的函数。每个节点接收当前状态,返回状态更新。
// 节点是一个普通函数
const analyzeInput = (state: typeof StateAnnotation.State) => {
// 读取状态
const lastMessage = state.messages[state.messages.length - 1];
// 返回状态更新(部分更新)
return {
step: state.step + 1,
};
};
节点函数返回的是部分状态更新,LangGraph 会自动合并到完整状态中。
3. 边(Edge)
边定义了节点之间的连接关系,分为两种:
- 普通边:无条件跳转,如
addEdge('nodeA', 'nodeB') - 条件边:根据状态动态决定下一个节点,如
addConditionalEdges('nodeA', routeFunction)
// 路由函数根据状态返回下一个节点名称
const routeDecision = (state) => {
if (state.needsTool) return 'tool_node';
return 'answer_node';
};
4. 图(Graph)
图是将状态、节点、边组合在一起的容器。
const graph = new StateGraph(StateAnnotation)
.addNode('analyze', analyzeInput)
.addNode('decide', makeDecision)
.addEdge(START, 'analyze')
.addEdge('analyze', 'decide')
.addConditionalEdges('decide', routeDecision)
.compile();
注意最后的 .compile() 是必需的,它将图定义转换为可执行的应用。
执行流程可视化
下面的图表展示了 LangGraph 应用的典型执行流程:
关键点:
- 状态在整个执行过程中被维护和传递
- LLM 可以在决策节点决定执行路径
- 循环和分支都是自然支持的
实践指导
理解核心组件
在开始使用 LangGraph 之前,确保你理解以下核心组件的作用:
| 组件 | 作用 | 类比 |
|---|---|---|
| StateGraph | 图的容器,定义整体结构 | React 的组件树 |
| Annotation | 定义状态的结构和更新规则 | TypeScript 的 interface |
| 节点函数 | 执行具体业务逻辑 | Express 的路由处理器 |
| 边 | 定义节点间的跳转关系 | 状态机的转换规则 |
设计你的第一个图
设计 LangGraph 应用的基本步骤:
- 定义状态结构:思考你的应用需要维护哪些数据
- 识别节点:将业务逻辑拆分为独立的处理单元
- 设计边:确定节点之间的跳转逻辑
- 编译运行:调用 compile() 并通过 invoke() 执行
调试技巧
使用 LangGraph 的内置可视化功能来理解你的图结构:
const representation = graph.getGraph();
console.log(representation.drawMermaid());
这会输出 Mermaid 格式的图定义,可以在支持 Mermaid 的工具中可视化。
小结与延伸
通过本节学习,你应该已经理解了:
- LangGraph 的核心概念:图结构建模、动态控制流
- 与传统链式结构的区别:灵活性 vs 可预测性
- 基本组件:状态、节点、边、图
- 适用场景:智能代理、复杂决策系统
在下一节《Agent概念》中,我们将深入探讨如何使用 LangGraph 构建不同类型的智能代理。
相关资源
- LangGraph 官方文档
- LangGraph Studio - 可视化调试工具
- 示例代码仓库
准备好深入了解智能代理了吗?让我们继续学习《Agent概念》!