第六章 LangGraph基础:有状态工作流与核心概念
1. LangGraph 架构知识图谱
-
图 (Graph):整体工作流容器。
-
状态 (State):核心中枢(共享黑板、数据载体、持久化快照)。
-
节点 (Nodes):执行单元(逻辑运算、调用 LLM、工具调用)。每个节点接收当前 State,返回更新后的 State 片段。
-
边 (Edges):路由逻辑(决定下一步去哪、是否循环、条件分支)。
-
2. 状态 (State) 的核心特性表
| 特性 | 详细描述 | 实际价值 |
| 共享黑板 | 所有节点都面向同一个 State 对象进行读写。 | 消除节点间复杂的参数传递,实现解耦。 |
| 增量更新 | 节点通常只返回需要修改的字段,系统自动合并(Merge)。 | 保护数据完整性,减少不必要的重复赋值。 |
| 状态快照 | 每一跳(Step)的变化都会被 Checkpointer 自动记录。 | 断点续传:任务中断可恢复;回溯:支持 Time Travel。 |
| 类型约束 | 采用 TypedDict 和 Annotated 定义数据结构。 | 提供 IDE 补全、静态检查,减少运行时因字段错误导致的崩溃。 |
3. 状态设计原则 (Best Practices)
| 原则 | 执行动作 | 避坑指南 |
| 最小必要 | 只保留影响流程走向和最终输出的字段。 | 别把海量的原始文档全文塞进 State,会导致内存/序列化压力。 |
| 可更新性 | 明确哪些字段是 list(需追加)或 dict(需覆盖)。 | 善用 Annotated[list, operator.add] 来实现消息流的自动追加。 |
| 清晰命名 | 使用业务语义化命名,如 is_quality_passed。 | 避免使用 data1, temp_var 等模糊命名,防止多节点维护时混乱。 |
状态传递机制

1. 节点(Nodes):
节点的执行模型:输入-处理-输出
-
输入 (Input):节点接收当前的
State对象。 -
处理 (Process):在函数内部执行逻辑(如 AI 演算或 API 调用)。
-
输出 (Output):返回一个字典,其中的键值对会更新到全局
State中。
三大核心节点类型对比:
| 节点类型 | 核心任务 (Task) | 输入示例 | 输出示例 |
| LLM 调用节点 | 决策、生成、推理 | {"messages": [...]} | {"messages": [AI_Message]} |
| 工具调用节点 | 外部交互(查天气、搜数据库) | {"tool_params": "London"} | {"tool_result": "20°C"} |
| 数据处理节点 | 格式化、清洗、校验 | {"raw_text": "..."} | {"is_valid": True, "clean_text": "..."} |
节点作为“纯函数”的意义
-
可预测性:给定相同的状态输入,节点永远产生相同的更新结果。
-
易于调试:如果流程出错了,你可以直接把报错那一刻的状态快照拿出来,单独运行该节点进行排查。
-
支持重试:当节点执行失败(如网络抖动)时,系统可以安全地重新运行该节点,而不用担心产生重复的干扰。
小结
-
节点是独立工位:每个节点只管好自己的事。
-
状态是唯一粘合剂:节点之间不直接传参,全部通过修改
State来实现信息传递。 -
颗粒度建议:一个节点只做一件完整的事。如果发现一个节点逻辑太复杂(既调模型又改数据库还做长文本清洗),建议拆分为多个节点。
演示:

2.边(Edges):
核心边类型详解
A. 固定边 (Fixed Edges):线性搬运工
这是最基础的连接方式。它适用于那些逻辑确定的流水线步骤。
-
操作方法:使用
graph.add_edge("node_a", "node_b")。 -
适用场景:数据预处理 -> 调用 LLM -> 格式化输出。
B. 条件边 (Conditional Edges):智能调度员
这是 LangGraph 能够处理复杂逻辑的关键。它根据当前 State 中的内容进行“判断”。
-
操作方法:使用
graph.add_conditional_edges("起始节点", 路由函数, 路由映射表)。 -
核心逻辑:
-
路由函数 (Router):一个小的 Python 函数,读取 State,返回一个字符串(分类结果)。
-
映射表 (Mapping):将返回的字符串映射到具体的“目标节点”。
-
C. 循环边 (Loop Edges):反馈闭环
循环边其实是条件边的一种特殊表现形式。
-
典型场景:自我修正 (Self-Correction)。
-
节点 A 生成代码 -> 节点 B 检查代码。
-
如果 B 发现错误,走条件边回到 A 重新生成。
-
如果 B 认为正确,走条件边到 End 节点结束。
-
| 特性 | 固定边 (Fixed Edge) | 条件边 (Conditional Edge) |
| 跳转逻辑 | 100% 确定 | 基于 State 动态决定 |
| 代码实现 | add_edge(A, B) | add_conditional_edges(A, func, {...}) |
| 分支能力 | 单一路径 | 多分支(1对N) |
| 复杂度 | 低,易于维护 | 高,需编写路由逻辑 |
| 典型类比 | 自动扶梯(顺着走就行) | 导航地图(遇到路口选最优路径) |

固定边(Fixed Edges):节点执行完成后,固定跳转到下一个节点,适用于线性流程。通过add_edge()方法配置,参数为“起始节点名”和“目标节点名”。

学习实践: 将rewrite_node 使用边连接起来,比较最后生成的图
条件边:

循环边:


LangGraph运行机制:
1. 什么是超步骤(Super-step)?
在 LangGraph 中,执行不是“一条路走到黑”的线性流,而是一轮一轮的循环迭代。每一轮迭代就是一个“超步骤”。
我们可以将一个超步骤拆解为三个动作:
-
激活 (Activation):调度引擎检查当前的
State和Edges,看看哪些节点该“干活”了。 -
执行 (Execution):所有被选中的活跃节点同时开始运行。
-
合并 (Merging/Passing):节点运行结束,把各自的“结果碎片”扔回黑板。引擎负责把这些碎片合并到全局
State中。
2. 节点活跃状态:并行执行的魅力
LangGraph 最强大的地方在于它天然支持并行(Parallelism)。在一个超步骤里,不一定只有一个节点在动。
-
单节点激活:这是最常见的,像接力棒一样,A 跑完 B 跑。
-
多节点同时激活(扇出/Fan-out):如果你的边规则允许,你可以同时启动多个节点。比如:
-
节点 A:写文案。
-
节点 B:配图。
-
超步骤 1:A 和 B 同时进入“活跃状态”,并行开工。
-
3. 超步骤执行流程对比表:
| 阶段 | 动作名称 | 发生了什么? | 状态变化 |
| T0:准备 | 待命 | State 已初始化,START 准备指向第一个节点。 | progress: 0 |
| T1:超步骤 | 激活 & 执行 | 第一个节点(如 llm_node)变绿,开始计算。 | progress: 0 (计算中) |
| T1:收尾 | 消息传递 | 节点返回 {progress: 30},引擎更新全局 State。 | progress: 30 |
| T2:超步骤 | 路由逻辑 | 引擎看边规则:下一步该去哪?发现该去 tool_node。 | progress: 30 |
4. 为什么这种机制比传统的顺序执行好?
-
支持循环 (Loops):因为是基于“步”的,引擎可以轻松地决定:这一步是往前走,还是退回上一步重跑。
-
断点续传 (Checkpoints):因为每个超步骤结束后,状态都是完整且一致的,可以把这一刻的状态存进数据库。即使服务器突然断电,重启后也能从“上个超步骤”完美恢复。
-
可观测性:可以清晰地看到工作流在哪个超步骤卡住了,哪个节点耗时最长。

综合实操:
案例1:简单线性工作流——文本处理全流程串联:

| 字段名 | 类型 | 作用 |
raw_text | str | 初始输入 |
cleaned_text | str | 去重清理后的中间结果 |
summary | str | 生成的摘要 |
has_sensitive | bool | 敏感词校验标记(True/False) |
final_output | str | 最终格式化后的文本 |


案例2:分支工作流——带结果校验的动态文本处理:


案例3:循环工作流——人机交互式文本优化

更多推荐


所有评论(0)