1. 什么是LangGraph?
┌─────────────────────────────────────────────────────────────┐ │ LangGraph 架构图 │ │ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ 节点A │───▶│ 节点B │───▶│ 节点C │ │ │ │ (Agent) │ │ (Tool) │ │ (Human) │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ 全局状态存储 │ │ │ │ { │ │ │ │ "messages": [...], │ │ │ │ "context": {...}, │ │ │ │ "next_step": "nodeB" │ │ │ │ } │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ 控制流:节点间通过状态转换进行协调,全局状态作为共享内存 │ └─────────────────────────────────────────────────────────────┘LangGraph是一个用于构建复杂AI工作流的框架,它的核心思想是将AI应用分解为多个节点 ,这些节点通过状态转换连接在一起。想象一下,每个节点就像是工厂流水线上的一个工作站,而状态就是在这条流水线上流动的产品。
- 节点:执行特定任务的单元(如调用LLM、使用工具、人工审核等)
- 状态:在节点间传递的共享数据,包含所有上下文信息
- 控制流:决定节点执行顺序的规则,可以是线性的、条件分支的或循环的
LangGraph的核心优势在于它的可控制性------你可以精确地定义每个节点的行为、节点间的流转逻辑,以及在任何时刻修改流程的能力。
2. 节点(Nodes)
2.1 节点的基本概念
┌─────────────────────────────────────────────────────────────┐
│ 节点生命周期 │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 准备阶段 │───▶│ 执行阶段 │───▶│ 更新阶段 │ │
│ │ (准备输入) │ │ (处理逻辑) │ │ (修改状态) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ │ 输入:当前全局状态
│ │ 处理:节点特定逻辑
│ │ 输出:状态增量更新
│ ▼
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 状态变更示例 │ │
│ │ 执行前: { "messages": ["你好"], "step": "start" } │ │
│ │ 执行后: { "messages": ["你好", "你好!我是助手"], │ │
│ │ "step": "response" } │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
每个节点都有一个标准的生命周期,包含三个阶段:
- 准备阶段:节点接收当前的全局状态作为输入
- 执行阶段:节点根据自己的逻辑处理输入(比如调用LLM、查询数据库等)
- 更新阶段:节点返回状态的增量更新,而不是完整的状态
关键特性:
- 无状态设计:节点不保存内部状态,所有状态都存储在全局状态中
- 增量更新:节点只返回需要修改的部分,其他状态保持不变
- 确定性:相同的输入状态总是产生相同的输出状态
2.2 节点类型
┌─────────────────────────────────────────────────────────────┐
│ 节点类型分类 │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 核心节点类型 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Agent节点 │ │ Tool节点 │ │ Human节点 │ │
│ │ (AI代理) │ │ (工具调用) │ │ (人工干预) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 调用LLM生成 │ │ 调用外部API │ │ 等待用户输入│ │
│ │ 响应内容 │ │ 执行操作 │ │ 或审核 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 特殊节点类型 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Route节点 │ │ Start节点 │ │ End节点 │ │
│ │ (路由决策) │ │ (入口点) │ │ (终止点) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 根据条件决定│ │ 工作流开始 │ │ 工作流结束 │ │
│ │ 下一个节点 │ │ 的第一个节点│ │ 的最终节点 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────┘
2.2.1 核心节点类型
Agent节点:AI的核心大脑
- 负责调用大语言模型(LLM)生成响应
- 可以处理复杂推理、对话管理、任务规划
- 示例:客服机器人、数据分析助手、内容生成器
Tool节点:AI的执行手臂
- 负责调用外部工具和API
- 可以执行数据库查询、文件操作、网络请求等
- 示例:搜索引擎、计算器、数据库查询工具
Human节点:人机协作接口
- 需要人工干预或审核的关键节点
- 可以接收用户输入、进行人工决策
- 示例:内容审核、敏感操作确认、复杂问题转人工
2.2.2 特殊节点类型
Route节点:工作流的交通警察
- 不执行具体业务逻辑,只负责决定流程走向
- 根据当前状态的条件判断下一个节点
- 示例:意图识别路由、权限检查路由、错误处理路由
Start/End节点:工作流的边界
- Start节点:工作流的唯一入口点
- End节点:工作流的终止点,可以有多个
- 确保工作流有明确的开始和结束
3. 可控制性(Controllability)
3.1 什么是可控制性?
┌─────────────────────────────────────────────────────────────┐
│ 可控制性维度 │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 控制维度 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 流程控制 │ │ 状态控制 │ │ 错误控制 │ │
│ │ (执行顺序) │ │ (数据管理) │ │ (异常处理) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 条件分支 │ │ 状态快照 │ │ 重试机制 │ │
│ │ 循环执行 │ │ 状态回滚 │ │ 降级策略 │ │
│ │ 动态路由 │ │ 状态验证 │ │ 熔断机制 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 控制粒度 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 节点级 │ │ 工作流级 │ │ 系统级 │ │
│ │ (单个节点) │ │ (整个流程) │ │ (全局策略) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────┘
可控制性是LangGraph的核心优势,它允许开发者在多个维度上精确控制AI工作流的行为:
三大控制维度:
- 流程控制:控制节点的执行顺序和条件
- 状态控制:管理数据的生命周期和一致性
- 错误控制:处理异常情况和保证系统稳定性
控制粒度:
- 节点级:单个节点的行为控制(超时、重试、输入验证)
- 工作流级:整个流程的控制(条件分支、循环、并行执行)
- 系统级:全局策略控制(限流、熔断、监控)
3.2 流程控制机制
┌─────────────────────────────────────────────────────────────┐
│ 流程控制模式 │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 顺序执行 │ │ 条件分支 │ │ 循环执行 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ A → B → C │ │ ┌───┐ │ │ ┌───┐ │ │
│ │ 线性流程 │ │ A ─┤B/C├─→ D│ │ A ─┤B │ │ │
│ └─────────────┘ │ └───┘ │ │ └─┬─┘ │ │
│ │ 条件选择 │ │ │ │ │
│ └─────────────┘ │ ┌─▼─┐ │ │
│ │ │ A │ │ │
│ │ └───┘ │ │
│ │ 循环直到条件│ │
│ │ 满足 │ │
│ └─────────────┘ │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 并行执行 │ │ 动态路由 │ │ 人工干预 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ ┌───┐ │ │ ┌───┐ │ │ ┌───┐ │ │
│ │ A ─┤B/C├─→ D│ │ A ─┤ ? ├──→ X│ │ A ─┤HUM├─→ B│ │
│ │ └───┘ │ │ └───┘ │ │ └───┘ │ │
│ │ B,C同时执行 │ │ 运行时决定 │ │ 人工决策后 │ │
│ └─────────────┘ │ 下一个节点 │ │ 继续执行 │ │
│ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────┘
3.2.1 基础控制模式
顺序执行:最简单的控制模式
- 节点按预定义顺序依次执行
- 适用于线性的、确定性的流程
- 示例:数据预处理 → 分析 → 生成报告
条件分支:基于条件的决策
- 根据状态中的条件值选择不同的执行路径
- 类似编程中的if-else语句
- 示例:根据用户意图路由到不同的处理节点
循环执行:重复执行直到条件满足
- 当某个条件不满足时,重复执行特定节点
- 需要设置终止条件防止无限循环
- 示例:多次尝试直到获得有效数据
3.2.2 高级控制模式
并行执行:同时执行多个节点
- 多个节点可以并行处理,提高效率
- 需要处理结果的合并和同步
- 示例:同时调用多个数据源获取信息
动态路由:运行时决定流程
- 下一个节点的选择在运行时动态确定
- 可以基于AI的决策或外部输入
- 示例:根据对话上下文动态调整响应策略
人工干预:人机协作控制
- 在关键节点暂停,等待人工决策
- 人工决策后可以选择继续、终止或修改流程
- 示例:敏感操作确认、内容审核、异常处理
3.3 状态控制机制
┌─────────────────────────────────────────────────────────────┐
│ 状态控制机制 │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 状态生命周期 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 状态创建 │───▶│ 状态更新 │───▶│ 状态销毁 │ │
│ │ (初始状态) │ │ (节点修改) │ │ (会话结束) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ { "step": │ │ { "step": │ │ 清理内存 │ │
│ │ "start" }│ │ "done", │ │ 释放资源 │ │
│ │ │ │ "result":│ │ │ │
│ │ │ │ "success"}│ │ │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 状态控制策略 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 状态验证 │ │ 状态快照 │ │ 状态回滚 │ │
│ │ (数据校验) │ │ (历史记录) │ │ (错误恢复) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 检查必填字段│ │ 保存关键 │ │ 回退到上一 │ │
│ │ 验证数据格式│ │ 状态点 │ │ 个有效状态 │ │
│ │ 确保一致性 │ │ 用于调试 │ │ 保证可靠性 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────┘
状态生命周期:
- 状态创建:工作流开始时初始化状态
- 状态更新:每个节点执行后更新状态
- 状态销毁:工作流结束时清理状态
关键控制策略:
状态验证:确保数据质量
- 在关键节点前验证状态的完整性
- 检查必填字段、数据格式、业务规则
- 防止无效状态传播到后续节点
状态快照:记录历史轨迹
- 在重要节点保存状态的完整快照
- 用于调试、审计、回滚操作
- 支持工作流的可重现性
状态回滚:错误恢复机制
- 当节点执行失败时,回退到上一个有效状态
- 避免部分失败导致的不一致状态
- 提供事务性的状态管理
3.4 错误控制机制
┌─────────────────────────────────────────────────────────────┐
│ 错误控制机制 │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 错误检测层 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 超时检测 │ │ 异常捕获 │ │ 状态验证 │ │
│ │ (执行时间) │ │ (异常类型) │ │ (数据质量) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ ▼
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 错误处理层 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 重试机制 │ │ 降级策略 │ │ 熔断机制 │ │
│ │ (指数退避) │ │ (简化逻辑) │ │ (快速失败) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 重试3次后 │ │ 使用备用 │ │ 停止执行 │ │
│ │ 放弃 │ │ 逻辑或数据 │ │ 防止级联 │ │
│ │ 记录错误 │ │ 返回简化 │ │ 错误 │ │
│ │ │ │ 结果 │ │ │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 监控反馈层 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 日志记录 │ │ 指标收集 │ │ 告警通知 │ │
│ │ (详细跟踪) │ │ (性能统计) │ │ (关键错误) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────┘
三层错误控制架构:
3.4.1 错误检测层
- 超时检测:监控节点执行时间,防止长时间阻塞
- 异常捕获:捕获各种异常类型(网络错误、数据错误、逻辑错误)
- 状态验证:在节点执行前后验证状态的合理性
3.4.2 错误处理层
-
重试机制:对暂时性错误进行自动重试
- 指数退避策略:重试间隔逐渐增加
- 有限重试次数:避免无限重试
- 重试条件判断:只对可重试的错误进行重试
-
降级策略:当主逻辑失败时的备选方案
- 功能降级:提供简化版的功能
- 数据降级:使用缓存或默认数据
- 体验降级:提供友好的错误提示
-
熔断机制:防止级联故障
- 错误率阈值:当错误率达到一定比例时触发熔断
- 快速失败:熔断后直接返回错误,不执行业务逻辑
- 自动恢复:经过一段时间后尝试恢复
3.4.3 监控反馈层
- 日志记录:详细的错误日志,包含上下文信息
- 指标收集:性能指标、错误率、响应时间等
- 告警通知:关键错误的实时告警,支持多种通知方式
4. 实际应用场景
┌─────────────────────────────────────────────────────────────┐
│ 智能客服工作流 │
│ │
│ ┌─────────────┐ │
│ │ Start节点 │ │
│ │ (用户输入) │ │
│ └──────┬──────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Intent │───▶│ Simple │───▶│ End节点 │ │
│ │ Router │ │ Response │ │ (简单回答) │ │
│ └──────┬──────┘ └─────────────┘ └─────────────┘ │
│ │ │
│ │ 条件:是否为简单查询? │
│ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Complex │───▶│ Data │───▶│ Validation │ │
│ │ Handler │ │ Retrieval │ │ Check │ │
│ └──────┬──────┘ └─────────────┘ └──────┬──────┘ │
│ │ │ │
│ │ 条件:数据是否有效? │ │
│ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Human │◀───┤ Error │ │ Response │───┐ │
│ │ Review │ │ Handler │ │ Generation │ │ │
│ └──────┬──────┘ └─────────────┘ └──────┬──────┘ │ │
│ │ │ │ │
│ ▼ ▼ │ │
│ ┌─────────────┐ ┌─────────────────────────────────┐ │ │
│ │ Approval │───▶│ End节点 │◀──┘ │
│ │ Handler │ │ (最终响应) │ │
│ └─────────────┘ └─────────────────────────────────┘ │
│ │
│ 控制流说明: │
│ 1. 用户输入路由到意图识别节点 │
│ 2. 简单查询直接回答,复杂查询进入数据检索流程 │
│ 3. 数据验证失败时进入错误处理或人工审核 │
│ 4. 人工审核通过后生成最终响应 │
│ 5. 全程可监控、可回滚、可重试 │
└─────────────────────────────────────────────────────────────┘
总结:
LangGraph通过节点和可控制性两个核心概念,为构建复杂AI工作流提供了强大的工具:
- 节点是功能单元,将复杂任务分解为可管理的小块
- 可控制性是协调机制,确保工作流按照预期执行