内容节点实现.md 25 KB

内容节点实现

本文档引用的文件

  • content.node.ts
  • graph.ts
  • book-generator.types.ts
  • templates.ts
  • content-cleaner.ts
  • book-type-config.ts
  • stage-manager.ts
  • book-generator.store.ts
  • async-pool.ts
  • sequential.strategy.ts
  • per-chapter.strategy.ts
  • outline.node.ts
  • sections.node.ts

目录

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

简介

本文件面向“内容节点”(writeChaptersNode 与 writeChaptersParallelNode)的实现,系统性阐述其设计原理、核心算法、文本处理流程与格式化规则;解释与大纲节点、章节节点、阶段管理器、存储层及提示词模板的交互方式;说明在AI生成流程中的作用、输入输出规范、错误处理机制;并提供配置选项、性能优化技巧与调试方法,辅以实际使用案例与扩展开发指导。

项目结构

内容节点位于书籍生成模块的节点层,与工作流策略、提示词模板、阶段管理、存储层协同工作,形成从规划到内容生成再到音频生成的完整链路。

graph TB
subgraph "工作流策略"
S1["sequential.strategy.ts<br/>串行策略"]
S2["per-chapter.strategy.ts<br/>逐章策略"]
end
subgraph "节点层"
N1["outline.node.ts<br/>大纲生成"]
N2["sections.node.ts<br/>节/小节大纲"]
N3["content.node.ts<br/>内容生成串行/并行"]
end
subgraph "支撑模块"
G["graph.ts<br/>状态定义"]
T["templates.ts<br/>提示词模板"]
C["content-cleaner.ts<br/>内容清洗"]
B["book-type-config.ts<br/>类型配置"]
M["stage-manager.ts<br/>阶段管理"]
K["book-generator.store.ts<br/>存储层"]
P["async-pool.ts<br/>并发池"]
end
S1 --> N1 --> N2 --> N3
S2 --> N1 --> N2 --> N3
N3 --> T
N3 --> C
N3 --> B
N3 --> M
N3 --> K
N3 --> P
G --> N3

图示来源

  • sequential.strategy.ts:21-59
  • per-chapter.strategy.ts:21-55
  • outline.node.ts:14-129
  • sections.node.ts:19-235
  • content.node.ts:102-332
  • graph.ts:23-82
  • templates.ts:154-169
  • content-cleaner.ts:12-78
  • book-type-config.ts:9-133
  • stage-manager.ts:100-198
  • book-generator.store.ts:163-800
  • async-pool.ts:8-50

章节来源

  • content.node.ts:102-332
  • graph.ts:23-82
  • book-generator.types.ts:8-112
  • templates.ts:154-169
  • content-cleaner.ts:12-78
  • book-type-config.ts:9-133
  • stage-manager.ts:100-198
  • book-generator.store.ts:163-800
  • async-pool.ts:8-50
  • sequential.strategy.ts:21-59
  • per-chapter.strategy.ts:21-55
  • outline.node.ts:14-129
  • sections.node.ts:19-235

核心组件

  • 内容生成节点(writeChaptersNode)
    • 串行遍历所有叶节点(无子节点的章节),按需生成内容,支持短文与长篇书籍两种路径。
    • 集成额度检查、累计字数上限、三层安全防护(章节预算偏差、全书字数上限)、音频分钟消耗与状态推进。
    • 生成完成后自动触发音频生成,并更新书籍进度。
  • 并行内容生成节点(writeChaptersParallelNode)
    • 基于 AsyncPool 控制并发,按深度规划中的交叉引用关系进行拓扑排序,优先生成依赖章节。
    • 单节点生成函数 generateSingleNodeContent 抽象出统一的生成流程,便于并行复用。
  • 文本处理与格式化
    • cleanThinkingText:多模式清洗思考标签与无关文本,智能提取正文,压缩多余空行。
    • truncateAtBoundary:按段落/句子边界智能截断,避免破坏语义完整性。
  • 阶段管理与状态推进
    • advanceChapter/regenerateChapter:线性阶段模型,严格前进/回退,配合资源清理规则。
  • 存储与数据传递
    • bookStore:统一的内存/数据库访问接口,负责章节内容更新、音频生成触发、书籍状态联动。
  • 提示词与系统提示
    • SUBSECTION_CONTENT_SYSTEM_PROMPT:面向小节内容生成的系统提示,支持工具调用以提升质量。
  • 类型与配置
    • BookGenStage/ChapterGenStage:线性阶段枚举,确保状态一致性。
    • book-type-config:字数上限、章节范围、音频分钟估算等配置。

章节来源

  • content.node.ts:102-332
  • content.node.ts:444-545
  • content-cleaner.ts:12-78
  • content-cleaner.ts:87-145
  • stage-manager.ts:158-198
  • book-generator.store.ts:163-800
  • templates.ts:154-169
  • book-type-config.ts:9-133

架构概览

内容节点在 LangGraph 工作流中作为“写入章节内容”的终端节点,承接大纲生成与节/小节大纲生成的结果,驱动 LLM 生成正文内容,并通过阶段管理器推进状态、通过存储层持久化、通过提示词模板提供上下文。

sequenceDiagram
participant W as "工作流策略"
participant N as "内容节点(writeChaptersNode)"
participant L as "LLM服务"
participant T as "提示词模板"
participant S as "阶段管理器"
participant D as "存储层"
participant A as "音频服务"
W->>N : 初始化状态(书ID/主题/规模/层级)
N->>D : 查询书籍与大纲/叶节点
loop 遍历叶节点
N->>T : 构建消息(短文/长篇)
N->>L : 调用LLM(工具/消息)
L-->>N : 生成内容
N->>N : 清洗/截断/统计字数
N->>S : advanceChapter(content_generating)
N->>D : 更新章节内容/字数
N->>S : advanceChapter(content_completed)
N->>A : 触发章节音频生成
end
N-->>W : 返回进度/错误

图示来源

  • content.node.ts:102-332
  • templates.ts:154-169
  • stage-manager.ts:158-198
  • book-generator.store.ts:758-800

详细组件分析

串行内容生成节点(writeChaptersNode)

  • 输入
    • GraphState:包含 bookId、topic、bookScale、genLevel、description 等。
    • 数据库:书籍、章节树、大纲。
  • 处理流程
    • 识别叶节点(无子节点),过滤未完成内容的叶节点。
    • 为每个叶节点构建消息(短文直写或长篇基于父章节/节信息)。
    • LLM 调用(优先工具调用,失败则降级为消息调用)。
    • 清洗思考文本、字数统计、三层安全防护(预算×3截断、全书上限)。
    • 更新章节内容与字数,推进到 content_completed,触发音频生成。
    • 更新书籍进度,返回结果。
  • 关键特性

    • 额度检查与中断标记。
    • 累计字数达到规模上限(±20%)时停止。
    • 失败章节记录与重试策略(通过阶段回退与重新生成)。

      flowchart TD
      Start(["进入节点"]) --> Load["加载书籍与大纲"]
      Load --> FindLeaves["查找叶节点并过滤未完成项"]
      FindLeaves --> HasTargets{"存在待生成目标?"}
      HasTargets -- 否 --> TriggerAudio["触发已完成章节音频生成"] --> End(["返回完成"])
      HasTargets -- 是 --> Loop["遍历每个目标"]
      Loop --> BuildMsg["构建消息(短文/长篇)"]
      BuildMsg --> CallLLM["LLM调用(工具/消息)"]
      CallLLM --> Clean["清洗思考文本/统计字数"]
      Clean --> Safety1{"预算×3异常?"}
      Safety1 -- 是 --> Trunc["按预算×2.5截断(边界)"] --> Safety2{"全书超限?"}
      Safety1 -- 否 --> Safety2
      Safety2 -- 是 --> Interrupt["中断并标记"] --> End
      Safety2 -- 否 --> Consume["消耗音频分钟配额"]
      Consume --> Save["更新章节内容/字数"]
      Save --> Advance["推进到 content_completed"]
      Advance --> GenAudio["触发音频生成"]
      GenAudio --> Next{"还有目标?"}
      Next -- 是 --> Loop
      Next -- 否 --> UpdateParent["更新父节/章状态为 content_completed"] --> End
      

图示来源

  • content.node.ts:102-332
  • content-cleaner.ts:12-78
  • content-cleaner.ts:87-145
  • stage-manager.ts:158-198
  • book-type-config.ts:9-133

章节来源

  • content.node.ts:102-332

并行内容生成节点(writeChaptersParallelNode)

  • 输入
    • 与串行节点相同的 GraphState 与数据。
  • 处理流程
    • 基于 AsyncPool 控制并发(默认 8),为每个叶节点创建任务。
    • generateSingleNodeContent 抽象统一生成流程,包含消息构建、LLM 调用、清洗、截断、保存、推进、音频触发。
    • 并发执行后汇总结果,更新父级状态,检查累计字数与规模上限,返回错误信息。
  • 关键特性

    • 通过拓扑排序与 crossReferences 决策生成顺序,解决依赖问题。
    • 统一的错误收集与中断信息拼接。

      sequenceDiagram
      participant P as "并行节点"
      participant Pool as "AsyncPool"
      participant F as "generateSingleNodeContent"
      participant L as "LLM服务"
      participant S as "阶段管理器"
      participant D as "存储层"
      P->>Pool : 构建任务列表(叶节点)
      Pool->>F : 并发执行(fn)
      loop 每个任务
      F->>F : 构建消息/调用LLM
      F->>F : 清洗/截断/统计字数
      F->>S : advanceChapter(content_generating)
      F->>D : 更新章节内容/字数
      F->>S : advanceChapter(content_completed)
      F-->>Pool : 返回结果(wordCount)
      end
      Pool-->>P : 汇总结果(成功/失败/总字数)
      P->>D : 更新父节/章状态
      P-->>调用方 : 返回进度/错误
      

图示来源

  • content.node.ts:444-545
  • async-pool.ts:22-36
  • content.node.ts:342-433

章节来源

  • content.node.ts:444-545
  • async-pool.ts:8-50

文本处理与格式化(cleanThinkingText 与 truncateAtBoundary)

  • cleanThinkingText
    • 多模式清洗:HTML/XML 标签、常见思考块标记/、未闭合标记、思考前缀、孤立闭合标签。
    • 智能提取正文:当内容以思考性语言开头或正文前有大量非标题内容时,截取到首个标题。
    • 压缩空行,去除首尾空白。
    • truncateAtBoundary
      • 段落边界优先:按段落拼接,超过阈值则停止,避免截断语义。
      • 句子边界回退:若首个段落超限,则按句子边界截断,必要时硬截但保留完整词。
    • cleanAndTruncate

      • 组合清洗与截断,返回是否截断与原始长度。

        flowchart TD
        In["原始LLM输出"] --> Clean["cleanThinkingText<br/>多模式清洗/提取正文"]
        Clean --> Len{"长度<=阈值?"}
        Len -- 是 --> Out["返回清洗后内容"]
        Len -- 否 --> Boundary{"策略=段落?"}
        Boundary -- 是 --> Para["按段落边界截断"]
        Boundary -- 否 --> Sent["按句子边界截断"]
        Para --> Out
        Sent --> Out
        

    图示来源

    • content-cleaner.ts:12-78
    • content-cleaner.ts:87-145
    • content-cleaner.ts:151-168

    章节来源

    • content-cleaner.ts:12-78
    • content-cleaner.ts:87-145
    • content-cleaner.ts:151-168

    阶段管理与状态推进(advanceChapter / regenerateChapter)

    • 线性阶段模型:章节状态按固定顺序前进,禁止回退(除非显式回退)。
    • 转移矩阵:定义允许的阶段转移,确保业务一致性。
    • 资源清理:回退到更低阶段时自动清理下游资源(音频/视频 URL 与时长)。
    • 乐观锁:使用当前状态作为条件更新,避免竞态。

      stateDiagram-v2
      [*] --> outline_completed
      outline_completed --> content_generating
      content_generating --> content_completed
      content_completed --> audio_generating
      audio_generating --> audio_completed
      audio_completed --> video_generating
      video_generating --> video_completed
      content_generating --> failed
      content_completed --> failed
      audio_generating --> failed
      audio_completed --> failed
      video_generating --> failed
      video_completed --> failed
      

    图示来源

    • stage-manager.ts:57-67
    • stage-manager.ts:158-198

    章节来源

    • stage-manager.ts:100-198

    存储与数据传递(bookStore)

    • 统一接口:创建/更新书籍、章节、音频生成与关联、章节树构建、公开状态切换等。
    • 章节内容更新:支持按 number 或 id 更新,含字数统计与生成时间戳。
    • 音频生成:异步生成并回调更新章节音频 URL 与时长。
    • 书籍阶段计算:根据所有章节最低阶段映射到书籍阶段。

    章节来源

    • book-generator.store.ts:163-800

    提示词与系统提示(SUBSECTION_CONTENT_SYSTEM_PROMPT)

    • 面向小节内容生成的系统提示,强调工具调用能力(查看大纲、已有章节、报告问题)与写作要求。
    • 为长篇书籍提供上下文(书名、章/节标题/概述、小节标题/概述、核心知识点、预估字数)。

    章节来源

    • templates.ts:154-169
    • content.node.ts:60-96

    类型与配置(BookGenStage/ChapterGenStage、book-type-config)

    • 线性阶段枚举:确保状态机一致性与可追踪性。
    • 字数与章节配置:提供规模上限(±20%)、章节范围、每章字数浮动、音频分钟估算、全局绝对上限等。
    • 与订阅配额结合:生成内容时消耗音频分钟,支持额度检查与中断标记。

    章节来源

    • book-generator.types.ts:8-112
    • book-type-config.ts:9-133

    依赖分析

    • 节点间依赖
      • outline.node.ts → sections.node.ts → content.node.ts(串行策略)
      • per-chapter.strategy.ts → outline.node.ts → perChapterNode(章节内聚策略)
    • 外部依赖

      • LangGraph 状态与工作流编排
      • LLM 服务(工具调用与消息调用)
      • 数据库(Prisma)与存储层
      • 提示词模板与内容清洗工具
      • 并发池与阶段管理器

        graph LR
        O["outline.node.ts"] --> S["sections.node.ts"]
        S --> C["content.node.ts"]
        P["per-chapter.strategy.ts"] --> O
        C --> T["templates.ts"]
        C --> CC["content-cleaner.ts"]
        C --> ST["stage-manager.ts"]
        C --> BS["book-generator.store.ts"]
        C --> AP["async-pool.ts"]
        

    图示来源

    • outline.node.ts:14-129
    • sections.node.ts:19-235
    • content.node.ts:102-332
    • per-chapter.strategy.ts:21-55
    • templates.ts:154-169
    • content-cleaner.ts:12-78
    • stage-manager.ts:158-198
    • book-generator.store.ts:163-800
    • async-pool.ts:8-50

    章节来源

    • sequential.strategy.ts:21-59
    • per-chapter.strategy.ts:21-55
    • outline.node.ts:14-129
    • sections.node.ts:19-235
    • content.node.ts:102-332

    性能考虑

    • 并发控制
      • 默认并发数 8,可根据 LLM 限流与硬件资源调整。
      • 使用 AsyncPool 保证吞吐最大化同时避免 API 限流。
    • 字数与截断
      • 章节预算×3 异常即截断,避免超大输出;全书字数超限直接中断,保护资源。
    • I/O 与网络
      • LLM 调用与数据库更新为瓶颈,建议在边缘或本地部署 LLM API,减少网络延迟。
    • 阶段推进与回退
      • 严格前进/回退策略减少状态竞争,降低重试成本。

    故障排查指南

    • 常见错误
      • 额度不足:检查订阅配额与累计字数,确认中断标记与错误信息。
      • 全书字数超限:核对全局绝对上限与当前累计字数,必要时缩短内容或调整规模。
      • LLM 工具调用失败:自动降级为消息调用;若仍失败,检查提示词与上下文。
      • 音频生成失败:检查音频服务配置与回调更新逻辑。
    • 调试建议
      • 打印每轮进度与累计字数,定位中断点。
      • 使用最小化输入复现问题,逐步扩大范围。
      • 校验父章节/节映射是否正确,避免长篇路径消息缺失。
      • 检查阶段推进日志,确认状态是否按预期前进。

    章节来源

    • content.node.ts:182-195
    • content.node.ts:266-281
    • stage-manager.ts:100-198
    • book-generator.store.ts:758-800

    结论

    内容节点通过“串行/并行双通道”实现高效、稳健的内容生成,结合三层安全防护、严格的阶段管理与统一的存储接口,确保在长篇与短文场景下均能产出高质量内容。配合提示词模板与内容清洗工具,进一步提升生成稳定性与可维护性。

    附录

    输入输出规范

    • 输入
      • GraphState:bookId、topic、bookScale、genLevel、description、bookPlan(可选)。
      • 数据库:书籍、章节树、大纲。
    • 输出
      • 进度 progress(0-100,只增不减)
      • 当前处理章节 currentChapter
      • 错误信息 error(包含失败章节与中断原因)

    章节来源

    • graph.ts:23-82
    • content.node.ts:102-332

    配置选项

    • 并发数:默认 8,可通过构造函数调整。
    • 字数上限:基于规模值的 ±20% 上限与全局绝对上限。
    • 截断策略:段落优先,句子回退。
    • 阶段推进:严格前进,回退需显式调用回退函数。

    章节来源

    • content.node.ts:337-337
    • book-type-config.ts:9-133
    • content-cleaner.ts:87-145
    • stage-manager.ts:158-198

    实际使用案例

    • 串行策略:适合稳定可控、资源有限的环境,调用量较大但易于调试。
    • 并行策略:适合大规模书籍生成,显著缩短总耗时,需关注依赖关系与并发控制。

    章节来源

    • sequential.strategy.ts:21-59
    • per-chapter.strategy.ts:21-55

    扩展开发指导

    • 新增提示词:在 templates.ts 中新增系统提示,确保格式约束与质量要求明确。
    • 新增清洗规则:在 content-cleaner.ts 中扩展清洗模式,保持健壮性。
    • 新增阶段:在 stage-manager.ts 中扩展阶段枚举与转移矩阵,确保资源清理逻辑完备。
    • 新增策略:参考现有策略实现,接入工作流编排与状态推进。

    章节来源

    • templates.ts:154-169
    • content-cleaner.ts:12-78
    • stage-manager.ts:12-36
    • sequential.strategy.ts:21-59
    • per-chapter.strategy.ts:21-55