LangGraph工作流设计.md 21 KB

LangGraph工作流设计

本文引用的文件

  • graph.ts
  • langgraph-types.ts
  • book-generator.types.ts
  • content.node.ts
  • outline.node.ts
  • plan.node.ts
  • stage-manager.ts
  • utils.ts
  • fault-tolerance.ts
  • book-type-config.ts
  • langgraph-controller.ts

目录

  1. 简介
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖关系分析
  7. 性能考量
  8. 故障排查指南
  9. 结论
  10. 附录

简介

本文件面向LangGraph工作流设计,聚焦“基于Annotation的状态定义机制”,系统阐述:

  • 进度reducer与章节完成数reducer等自定义reducer的设计理念与实现
  • GraphState中各字段的语义与作用,如bookId、userId、topic、bookScale、genLevel、description、bookPlan、currentChapter、completedChapters、finished、error、progress、failedChapters等
  • 状态流转的实现原理,包括状态更新策略、数据持久化机制、错误处理流程
  • 如何定义新节点、配置状态转换、处理异常情况的具体示例路径

项目结构

LangGraph相关代码主要位于后端模块的book-generator目录中,采用“状态定义 + 节点实现 + 控制器路由”的分层组织方式。

graph TB
subgraph "状态定义"
G["graph.ts<br/>GraphState与reducer"]
T["langgraph-types.ts<br/>类型参考"]
U["utils.ts<br/>进度常量"]
end
subgraph "节点实现"
P["plan.node.ts<br/>书籍规划"]
O["outline.node.ts<br/>大纲生成"]
C["content.node.ts<br/>内容生成串行/并行"]
S["stage-manager.ts<br/>线性阶段管理"]
F["fault-tolerance.ts<br/>容错层"]
end
subgraph "控制器与类型"
L["langgraph-controller.ts<br/>API路由"]
B["book-generator.types.ts<br/>业务类型"]
K["book-type-config.ts<br/>规模配置"]
end
G --> P
G --> O
G --> C
P --> L
O --> L
C --> L
S --> C
F --> P
F --> O
F --> C
K --> P
K --> O
K --> C
B --> L
U --> C

图表来源

  • graph.ts:1-83
  • plan.node.ts:145-201
  • outline.node.ts:14-129
  • content.node.ts:102-332
  • stage-manager.ts:100-198
  • fault-tolerance.ts:16-50
  • langgraph-controller.ts:29-29
  • book-generator.types.ts:1-226
  • book-type-config.ts:61-133
  • utils.ts:15-24

章节来源

  • graph.ts:1-83
  • langgraph-controller.ts:388-512

核心组件

  • 状态定义与reducer
    • 进度reducer:只增不减,防止中间步骤回退导致进度丢失
    • 章节完成数reducer:累加而非覆盖,保证历史完成记录不丢失
    • 其他字段reducer:多数采用“更新即覆盖”的策略,保持幂等性
  • GraphState字段语义
    • 标识与输入:bookId、userId、topic、bookScale、description
    • 规划与层级:bookPlan、genLevel
    • 进度与阶段:currentChapter、completedChapters、progress、finished、error、failedChapters
  • 节点职责
    • planBookNode:书籍规划,产出bookPlan与genLevel
    • generateOutlineNode:基于bookPlan与规模生成大纲
    • writeChaptersParallelNode:并行生成叶节点内容,含安全防护与配额消耗
  • 容错与监控
    • AI调用重试、节点超时、进度监控、自动恢复
  • 阶段管理
    • 线性阶段模型与安全转移,支持回退与资源清理

章节来源

  • graph.ts:9-82
  • plan.node.ts:145-201
  • outline.node.ts:14-129
  • content.node.ts:102-332
  • stage-manager.ts:12-92
  • fault-tolerance.ts:67-179

架构总览

LangGraph工作流以GraphState为核心,通过多个节点串联执行,每个节点负责特定阶段的工作,并通过reducer更新状态。控制器负责对外暴露API,协调生成流程。

sequenceDiagram
participant Client as "客户端"
participant Ctrl as "langgraph-controller.ts"
participant Plan as "plan.node.ts"
participant Outline as "outline.node.ts"
participant Content as "content.node.ts"
participant Stage as "stage-manager.ts"
participant FT as "fault-tolerance.ts"
Client->>Ctrl : POST /api/book-generator/langgraph/books
Ctrl->>Ctrl : 创建书籍并设置初始状态
Ctrl->>Plan : 调用 planBookNode
Plan-->>Ctrl : 返回 bookPlan 与 genLevel
Ctrl->>Outline : 调用 generateOutlineNode
Outline-->>Ctrl : 返回大纲与进度
Ctrl->>Content : 调用 writeChaptersParallelNode
Content->>Stage : advanceChapter/ regenerateChapter
Content-->>Ctrl : 返回进度/错误
Ctrl-->>Client : 返回生成状态
Note over Plan,FT : 容错包装器贯穿各节点

图表来源

  • langgraph-controller.ts:388-512
  • plan.node.ts:145-201
  • outline.node.ts:14-129
  • content.node.ts:102-332
  • stage-manager.ts:158-198
  • fault-tolerance.ts:130-179

详细组件分析

状态定义与reducer设计

  • 设计理念
    • 进度与完成数采用“只增不减”策略,确保可观测性与可追溯性
    • 其他字段采用“覆盖式更新”,避免脏数据污染
  • 关键reducer
    • 进度reducer:Math.max(prev, update)
    • 章节完成数reducer:appendReducer(prev, update) 对数组进行合并
  • 字段默认值与覆盖策略

    • 多数字段提供default工厂函数,确保首次渲染安全
    • reducer为undefined时保持原值,避免意外清空

      flowchart TD
      Start(["状态更新入口"]) --> CheckPrev["检查prev与update"]
      CheckPrev --> IsUndefined{"update为undefined?"}
      IsUndefined --> |是| KeepPrev["保持原值"]
      IsUndefined --> |否| ApplyReducer["应用对应reducer"]
      ApplyReducer --> Progress["progress/maxReducer"]
      ApplyReducer --> Completed["completedChapters/appendReducer"]
      ApplyReducer --> Other["其他字段/覆盖式更新"]
      KeepPrev --> End(["返回新状态"])
      Progress --> End
      Completed --> End
      Other --> End
      
  • 图表来源

    • graph.ts:9-82

    章节来源

    • graph.ts:9-82

    GraphState字段详解

    • 标识与输入
      • bookId:书籍唯一标识,用于持久化与追踪
      • userId:用户标识,参与配额与权限控制
      • topic:书籍主题,作为LLM提示词的重要上下文
      • bookScale:书籍规模(字数等级),影响章节数量与字数预算
      • description:用户输入的书籍描述
    • 规划与层级
      • bookPlan:AI规划结果(JSON字符串),包含大纲层级、写作风格、结构逻辑等
      • genLevel:最终确定的大纲层级(1/2/3)
    • 进度与阶段
      • currentChapter:当前处理的章节号(只增不减)
      • completedChapters:已完成章节号列表(累加)
      • progress:整体进度百分比(0-100,只增不减)
      • finished:是否完成
      • error:错误信息
      • failedChapters:失败章节列表(累加)

    章节来源

    • graph.ts:23-82

    节点实现与状态转换

    书籍规划节点(planBookNode)

    • 功能:在生成前对书籍做全面规划,决定大纲层级与风格
    • 关键流程
      • 构建提示词,调用LLM,解析JSON
      • 若用户未显式指定genLevel,则采用AI规划结果
      • 将bookPlan与genLevel写入GraphState,并持久化到数据库
    • 容错:解析失败时降级,不影响后续流程

      sequenceDiagram
      participant Plan as "plan.node.ts"
      participant LLM as "LLM服务"
      participant DB as "bookStore"
      Plan->>LLM : 发送规划提示词
      LLM-->>Plan : 返回规划JSON
      Plan->>Plan : 解析并验证genLevel
      Plan->>DB : 更新bookAnalysis
      Plan-->>Plan : 返回 {progress, genLevel, bookPlan}
      

    图表来源

    • plan.node.ts:145-201

    章节来源

    • plan.node.ts:145-201

    大纲生成节点(generateOutlineNode)

    • 功能:基于bookPlan与规模生成大纲,校验章节数并持久化
    • 关键流程
      • 读取bookPlan作为指导
      • 调用LLM生成大纲,解析并校验
      • 根据bookScale的章节数范围进行截断或补充
      • 写入outlineJson与章节信息,更新进度
    • 容错:超时与重试包装,失败时标记书籍失败

      sequenceDiagram
      participant Outline as "outline.node.ts"
      participant FT as "fault-tolerance.ts"
      participant LLM as "LLM服务"
      participant DB as "bookStore"
      Outline->>FT : executeNodeWithTimeout
      FT->>LLM : 调用LLM带重试
      LLM-->>FT : 返回大纲文本
      FT-->>Outline : 返回解析后的大纲
      Outline->>Outline : 校验章节数范围
      Outline->>DB : 写入outlineJson与章节
      Outline-->>Outline : 返回 {progress}
      

    图表来源

    • outline.node.ts:14-129
    • fault-tolerance.ts:130-179

    章节来源

    • outline.node.ts:14-129
    • fault-tolerance.ts:16-50

    内容生成节点(writeChaptersParallelNode)

    • 功能:并行生成叶节点内容,含多层安全防护与配额消耗
    • 关键流程
      • 查找所有叶节点(level=3),过滤未完成项
      • 构建父节点映射,准备消息上下文
      • 并发池执行(AsyncPool),逐个生成内容
      • 安全防护:章节预算偏差检测、全书累计字数上限
      • 配额消耗:按字数消耗音频分钟
      • 章节完成后推进阶段,触发音频生成
    • 容错:失败章节收集至failedChapters,返回错误信息

      flowchart TD
      A["查找叶节点"] --> B["构建父节点映射"]
      B --> C["构造消息与工具"]
      C --> D["AsyncPool并发执行"]
      D --> E{"安全防护"}
      E --> |预算超限| F["截断内容"]
      E --> |字数超限| G["中断并标记"]
      F --> H["保存内容并推进阶段"]
      G --> H
      H --> I["触发音频生成"]
      I --> J["更新进度与错误"]
      

    图表来源

    • content.node.ts:444-545
    • stage-manager.ts:158-198

    章节来源

    • content.node.ts:102-332
    • content.node.ts:444-545
    • stage-manager.ts:158-198

    阶段管理与状态更新策略

    • 线性阶段模型
      • 章节阶段:idle → outline_completed → content_generating → content_completed → audio_generating → audio_completed → video_generating → video_completed → failed
      • 严格的安全转移函数,支持回退与资源清理
    • 更新策略
      • 前进:advanceChapter(只能前进,不回退)
      • 重新生成:regenerateChapter(可回退到上游阶段,自动清理下游资源)
    • 数据持久化

      • 通过Prisma乐观锁更新章节状态,避免竞态
      • 失败场景下清理下游资源(如音频/视频URL)

        stateDiagram-v2
        [*] --> idle
        idle --> outline_completed : "outline完成"
        outline_completed --> content_generating : "开始内容生成"
        content_generating --> content_completed : "内容完成"
        content_generating --> failed : "失败"
        content_completed --> audio_generating : "开始音频生成"
        audio_generating --> audio_completed : "音频完成"
        audio_generating --> content_completed : "回退到内容"
        audio_completed --> video_generating : "开始视频生成"
        video_generating --> video_completed : "视频完成"
        video_generating --> audio_completed : "回退到音频"
        failed --> content_generating : "重新生成"
        failed --> audio_generating : "失败重试"
        failed --> video_generating : "失败重试"
        

    图表来源

    • stage-manager.ts:37-92
    • stage-manager.ts:100-198

    章节来源

    • stage-manager.ts:12-92
    • stage-manager.ts:158-198

    容错与错误处理

    • AI调用重试:指数退避,最多3次
    • 节点超时:针对不同节点设定超时阈值,超时后自动降级
    • 进度监控:长时间无响应时发出告警并尝试自动恢复
    • 自动恢复:在限定次数内重启生成流程

      flowchart TD
      Start(["节点执行"]) --> Timeout{"是否超时?"}
      Timeout --> |是| TimeoutAction["通知超时并降级"]
      Timeout --> |否| Retry{"是否AI调用失败?"}
      Retry --> |是| RetryLoop["指数退避重试"]
      Retry --> |否| Monitor["进度监控"]
      Monitor --> Idle{"长时间无响应?"}
      Idle --> |是| Recovery["自动恢复"]
      Idle --> |否| Done(["完成"])
      TimeoutAction --> Done
      RetryLoop --> Done
      Recovery --> Done
      

    图表来源

    • fault-tolerance.ts:67-179
    • fault-tolerance.ts:187-324

    章节来源

    • fault-tolerance.ts:16-50
    • fault-tolerance.ts:67-179
    • fault-tolerance.ts:187-324

    数据持久化机制

    • 书籍与章节信息通过bookStore与Prisma进行持久化
    • 生成过程中的进度、章节状态、错误信息实时更新
    • 并发场景下使用乐观锁避免状态冲突

    章节来源

    • outline.node.ts:100-114
    • content.node.ts:292-297
    • stage-manager.ts:118-147

    API与控制器

    • 提供书籍创建、类型检测、预估信息、进度查询等接口
    • 支持异步生成与交互模式,避免阻塞请求
    • 生成前进行配额检查,失败时返回详细信息

    章节来源

    • langgraph-controller.ts:388-512
    • langgraph-controller.ts:643-680

    依赖关系分析

    • 组件耦合
      • GraphState作为单一事实来源,被所有节点读取与更新
      • 节点间通过GraphState传递bookPlan、genLevel等跨阶段信息
      • stage-manager与content.node紧密协作,确保状态推进与资源清理
    • 外部依赖

      • LLM服务:用于规划、大纲、内容生成
      • 数据库:Prisma与bookStore提供持久化能力
      • 容错层:统一的重试、超时、监控与恢复机制

        graph LR
        GS["GraphState<br/>graph.ts"] --> PN["plan.node.ts"]
        GS --> ON["outline.node.ts"]
        GS --> CN["content.node.ts"]
        PN --> FT["fault-tolerance.ts"]
        ON --> FT
        CN --> FT
        CN --> SM["stage-manager.ts"]
        CN --> BTC["book-type-config.ts"]
        ON --> BTC
        PN --> BTC
        LC["langgraph-controller.ts"] --> GS
        LC --> PN
        LC --> ON
        LC --> CN
        

    图表来源

    • graph.ts:23-82
    • plan.node.ts:145-201
    • outline.node.ts:14-129
    • content.node.ts:102-332
    • stage-manager.ts:158-198
    • fault-tolerance.ts:130-179
    • book-type-config.ts:61-133
    • langgraph-controller.ts:388-512

    章节来源

    • graph.ts:23-82
    • langgraph-controller.ts:388-512

    性能考量

    • 并行生成:通过AsyncPool提升内容生成吞吐,降低总体时延
    • 安全防护:三层防护体系(章节预算、累计字数、全局上限)避免资源滥用
    • 进度与配额:实时统计与消耗,减少无效工作
    • 容错与恢复:自动重试与恢复,提高成功率与用户体验

    故障排查指南

    • 常见问题
      • AI调用失败:查看重试日志与失败记录,确认模型可用性
      • 节点超时:检查LLM响应时间与网络状况,适当调整超时阈值
      • 进度停滞:启用进度监控,关注长时间无响应告警
      • 额度不足:核对用户配额与消耗记录,必要时引导充值
    • 排查步骤
      • 检查bookStore中的errorMsg与genStage
      • 核对failedChapters与error字段
      • 使用stage-manager的安全转移函数验证状态一致性
      • 触发自动恢复流程,观察是否可恢复正常

    章节来源

    • fault-tolerance.ts:187-324
    • stage-manager.ts:100-198

    结论

    本设计以Annotation为核心,通过精心设计的reducer与严格的阶段管理,实现了稳定、可观测、可扩展的LangGraph工作流。容错层与安全防护确保了在复杂业务场景下的鲁棒性;并行生成与配额机制提升了性能与资源利用率。通过清晰的API与状态流转,开发者可以便捷地扩展新节点与优化流程。

    附录

    如何定义新的节点

    • 参考现有节点的实现模式
      • 读取GraphState,构造消息与工具
      • 调用LLM或外部服务,处理结果
      • 更新GraphState(progress、error、finished等)
      • 必要时调用stage-manager推进阶段
    • 示例路径
      • plan.node.ts:145-201
      • outline.node.ts:14-129
      • content.node.ts:102-332

    如何配置状态转换

    • 使用advanceChapter进行前进式转换
    • 使用regenerateChapter进行回退式转换
    • 确保遵循阶段转移矩阵,避免非法状态
    • 示例路径
      • stage-manager.ts:158-198

    如何处理异常情况

    • 使用fault-tolerance.ts中的callLLMWithRetry与executeNodeWithTimeout
    • 在节点内部捕获错误,更新error字段并返回finished=true
    • 示例路径
      • outline.node.ts:115-128
      • content.node.ts:308-317