Doc Orchestrator
Generate long, multi-chapter documents by coordinating sub-agents with a contract-first, serial-then-parallel strategy and persistent orchestration state.
When This Applies
- - Document has 3+ chapters/sections with cross-references
- Total expected output > 500 lines
- Multiple sections share definitions (names, enums, constants, values)
Core Principles
- 1. Contract First — Define all shared definitions before delegating
- File Isolation — Each sub-agent writes to its own file; main agent merges
- State Persistence — Write orchestration state to JSON so context compaction can't break the workflow
Workflow
Phase 1 — Analyze Dependencies
Build a dependency graph. For each pair ask: "Does chapter B need chapter A's output?"
Classify:
- - Contract — defines shared values (main agent writes directly)
- Serial — has upstream dependency (spawn after dependency completes)
- Parallel — no unresolved dependencies (run concurrently)
Optimize: if multiple chapters depend only on the contract, they can run in parallel.
Phase 2 — Initialize State File
Create {task-dir}/{TASK-ID}-orchestration.json:
CODEBLOCK0
Status values: pending | running | done | INLINECODE4
Update this file after every state change. After context compaction, read this file to restore full state.
Phase 3 — Write the Contract
Main agent writes all contract chapters directly. Include a Global Conventions table:
CODEBLOCK1
This is the single source of truth.
Phase 4 — Execute (Serial + Parallel)
For each chapter whose deps are all done:
- 1. Update state: INLINECODE7
- Spawn sub-agent with the prompt template (see below)
- On completion: update state to
"done"; check what new chapters are unblocked - On failure: update state to
"failed"; decide retry or main-agent fallback
Spawn all unblocked chapters in parallel. Wait for serial dependencies.
After context compaction: read the orchestration JSON to recover state, then continue.
Phase 5 — Merge & Validate
Concatenate files in chapter order. During merge:
- 1. Strip duplicate document titles — Sub-agents often repeat the top-level
# Document Title. Remove all occurrences except the one in the contract file:
CODEBLOCK2
- 2. Run consistency checks:
CODEBLOCK3
- 3. Fix any issues before delivering.
Sub-Agent Prompt Template
CODEBLOCK4
Anti-Patterns
| Don't | Do Instead |
|---|
| Rely on context memory for orchestration state | Persist state to JSON file |
| Let sub-agents write to the same file |
Each writes own file; main agent merges |
| Skip formatting rules in prompt | Explicitly say "no document title, start with ## chapter heading" |
| Assume sub-agents won't hit content filters | Have fallback: main agent writes sensitive chapters directly |
| Skip consistency check after merge | Always grep for known conflict patterns |
| Use bigger model to brute-force long output | Smaller model + smaller task > bigger model + huge task |
| Poll sub-agents in a loop | Use push-based completion (auto-announce) |
Decision Flowchart
CODEBLOCK5
Lessons from Real Usage
Test 1: PRD (9 chapters, technical)
| Metric | Naive Parallel (v1) | Contract-First (v2) |
|---|
| Output | 1,405 lines | 3,055 lines |
| Consistency |
Score 1-5 vs 1-10 conflict | Zero conflicts |
| File integrity | Chapters overwritten | All preserved |
| Rework | 4 chapters rewritten | None |
Test 2: Worldbuilding Bible (7 chapters, creative writing)
| Metric | Result |
|---|
| Output | 2,170 lines |
| Consistency |
Zero conflicts (names, factions, abilities all matched) |
| Issues hit | Content filter blocked ch5 twice; ch6 output wrong chapter content |
| Recovery | Main agent wrote ch5 directly; ch6 retried successfully |
| Duplicate titles | 4 of 6 sub-agent files repeated doc title (fixed in merge) |
Key Takeaways
- - Content filters: Sensitive topics (war, conflict) may trigger model safety filters in sub-agents. Fallback: main agent writes those chapters, or rephrase with softer language
- Wrong output: Sub-agents occasionally output content for the wrong chapter. Always verify file content, not just file existence
- Title duplication: Sub-agents copy the document title from the contract file. Prompt template now explicitly forbids this; merge step strips duplicates as safety net
Doc Orchestrator
通过协调子智能体,采用先契约后串行再并行的策略和持久化编排状态,生成长篇、多章节文档。
适用场景
- - 文档包含 3个及以上章节/小节,且存在交叉引用
- 预期总输出 > 500行
- 多个章节共享定义(名称、枚举、常量、数值)
核心原则
- 1. 契约优先 — 在委派任务前,先定义所有共享定义
- 文件隔离 — 每个子智能体写入自己的文件;主智能体负责合并
- 状态持久化 — 将编排状态写入JSON,确保上下文压缩不会破坏工作流程
工作流程
阶段一 — 分析依赖关系
构建依赖关系图。对每一对章节询问:章节B是否需要章节A的输出?
分类:
- - 契约 — 定义共享值(由主智能体直接编写)
- 串行 — 存在上游依赖(在依赖完成后生成)
- 并行 — 无未解决的依赖(可同时运行)
优化:如果多个章节仅依赖契约,它们可以并行运行。
阶段二 — 初始化状态文件
创建 {task-dir}/{TASK-ID}-orchestration.json:
json
{
document: 文档标题,
contract_file: TASK-XXX-contract.md,
final_file: TASK-XXX-final.md,
chapters: {
ch1: {title: 概述, status: done, file: TASK-XXX-contract.md, deps: []},
ch2: {title: 角色, status: pending, file: TASK-XXX-ch2.md, deps: [ch1]},
ch3: {title: 能力, status: pending, file: TASK-XXX-ch3.md, deps: [ch1]},
ch4: {title: 阵营, status: pending, file: TASK-XXX-ch4.md, deps: [ch1, ch2]}
}
}
状态值:pending | running | done | failed
每次状态变更后更新此文件。 在上下文压缩后,读取此文件以恢复完整状态。
阶段三 — 编写契约
主智能体直接编写所有契约章节。包含一个全局约定表格:
markdown
全局约定
| 项目 | 数值 | 引用方 |
|---|
| 评分范围 | 1-5整数 | ch5 API, ch6 |
这是唯一的权威来源。
阶段四 — 执行(串行 + 并行)
对于所有依赖状态均为 done 的每个章节:
- 1. 更新状态:status: running
- 使用提示模板生成子智能体(见下文)
- 完成后:将状态更新为 done;检查哪些新章节已解除阻塞
- 失败时:将状态更新为 failed;决定重试或由主智能体回退
并行生成所有已解除阻塞的章节。等待串行依赖。
在上下文压缩后: 读取编排JSON以恢复状态,然后继续。
阶段五 — 合并与验证
按章节顺序拼接文件。合并过程中:
- 1. 去除重复的文档标题 — 子智能体经常重复顶层的 # 文档标题。除契约文件中的标题外,删除所有其他出现:
bash
# 合并时删除重复的H1标题(仅保留契约中的)
cat contract.md > final.md
for f in ch2.md ch3.md ... ; do
sed /^# 文档标题$/d $f >> final.md
done
- 2. 运行一致性检查:
bash
grep -n conflicting_value final.md
grep -o [a-z_]* final.md | sort | uniq
- 3. 在交付前修复所有问题。
子智能体提示模板
任务:为[文档名称]编写[章节标题]
首先阅读: path/to/contract.md
注意全局约定表格(章节X.X)。
写入位置: path/to/output-chN.md(新文件,请勿修改其他文件)
重要的格式规则:
- - 不要包含文档标题(# 文档标题)——它只属于契约文件
- 直接从章节标题开始你的文件(## 第N章:标题)
- 不要重复契约中的定义;引用它们即可
内容要求:
[章节特定要求]
约束条件(必须与契约一致):
反模式
| 不要做 | 应该做 |
|---|
| 依赖上下文记忆来管理编排状态 | 将状态持久化到JSON文件 |
| 让子智能体写入同一文件 |
每个子智能体写入自己的文件;主智能体合并 |
| 在提示中跳过格式规则 | 明确说明不要包含文档标题,以##章节标题开头 |
| 假设子智能体不会触发内容过滤器 | 设置回退:主智能体直接编写敏感章节 |
| 合并后跳过一致性检查 | 始终使用grep检查已知冲突模式 |
| 使用更大的模型强行生成长输出 | 更小的模型 + 更小的任务 > 更大的模型 + 巨大的任务 |
| 循环轮询子智能体 | 使用推送式完成(自动通知) |
决策流程图
收到文档请求
|
+-- 预期少于500行? --> 直接编写(无需编排)
|
+-- 500-1500行,无交叉引用? --> 简单并行(每个章节一个文件)
|
+-- 超过500行且有交叉引用?
|
1. 分析依赖关系图
2. 创建编排状态JSON
3. 主智能体编写契约章节
4. 依赖章节的串行链
5. 独立章节的并行爆发
6. 合并 + 去除重复标题 + 验证
7. 交付
实际使用经验
测试1:产品需求文档(9个章节,技术类)
| 指标 | 朴素并行(v1) | 契约优先(v2) |
|---|
| 输出 | 1,405行 | 3,055行 |
| 一致性 |
评分1-5与1-10冲突 | 零冲突 |
| 文件完整性 | 章节被覆盖 | 全部保留 |
| 返工 | 4个章节重写 | 无 |
测试2:世界观构建圣经(7个章节,创意写作)
零冲突(名称、阵营、能力全部匹配) |
| 遇到的问题 | 内容过滤器两次阻止ch5;ch6输出了错误的章节内容 |
| 恢复 | 主智能体直接编写ch5;ch6重试成功 |
| 重复标题 | 6个子智能体文件中有4个重复了文档标题(合并时修复) |
关键经验
- - 内容过滤器:敏感主题(战争、冲突)可能触发子智能体中的模型安全过滤器。回退方案:主智能体编写这些章节,或使用更温和的语言重新表述
- 错误输出:子智能体偶尔会输出错误章节的内容。始终验证文件内容,而不仅仅是文件是否存在
- 标题重复:子智能体会从契约文件中复制文档标题。提示模板现已明确禁止此行为;合并步骤作为安全网去除重复标题