本文档引用的文件
本文件面向“内容节点”(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
图示来源
章节来源
章节来源
内容节点在 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 : 返回进度/错误
图示来源
关键特性
失败章节记录与重试策略(通过阶段回退与重新生成)。
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
图示来源
章节来源
关键特性
统一的错误收集与中断信息拼接。
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-->>调用方 : 返回进度/错误
图示来源
章节来源
cleanAndTruncate
组合清洗与截断,返回是否截断与原始长度。
flowchart TD
In["原始LLM输出"] --> Clean["cleanThinkingText<br/>多模式清洗/提取正文"]
Clean --> Len{"长度<=阈值?"}
Len -- 是 --> Out["返回清洗后内容"]
Len -- 否 --> Boundary{"策略=段落?"}
Boundary -- 是 --> Para["按段落边界截断"]
Boundary -- 否 --> Sent["按句子边界截断"]
Para --> Out
Sent --> Out
图示来源
章节来源
乐观锁:使用当前状态作为条件更新,避免竞态。
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
图示来源
章节来源
章节来源
章节来源
章节来源
外部依赖
并发池与阶段管理器
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"]
图示来源
章节来源
章节来源
内容节点通过“串行/并行双通道”实现高效、稳健的内容生成,结合三层安全防护、严格的阶段管理与统一的存储接口,确保在长篇与短文场景下均能产出高质量内容。配合提示词模板与内容清洗工具,进一步提升生成稳定性与可维护性。
章节来源
章节来源
章节来源
章节来源