docs(design): add Phase 5 Writer/QA subsystem section
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
9. [数据模型与 Provenance 层](#9-数据模型与-provenance-层)
|
||||
10. [异常处理策略](#10-异常处理策略)
|
||||
11. [通信语言与文档规范](#11-通信语言与文档规范)
|
||||
12. [Phase 5:Writer / QA 子系统](#12-phase-5writer--qa-子系统)
|
||||
|
||||
---
|
||||
|
||||
@@ -1710,3 +1711,73 @@ Step 3(关联推理)中部分功能推理失败:
|
||||
- 不得将客户数据、公司信息上传至外部公开仓库
|
||||
- API Key 配置在环境变量或配置文件中,不得硬编码在源码
|
||||
- 确认所有依赖的许可证类型,禁止使用盗版软件
|
||||
|
||||
---
|
||||
|
||||
## 12. Phase 5:Writer / QA 子系统
|
||||
|
||||
> 本章记录在 phase5/writer-qa 分支上落地的「Writer / QA 子系统」实现,作为设计 §6(Writer Agent 详细设计)与 §7(QA Agent 详细设计)的工程落地补充。实现严格遵循设计基线,并诚实标注了范围边界与推后项。
|
||||
|
||||
### 12.1 目标与范围
|
||||
|
||||
**目标**:打通「结构化源 → 单章内容生成 → 渲染 → 注入 Word 模板 → QA 校验 → 闭环仅重失败章」的最小可用链路。
|
||||
|
||||
**范围内**:
|
||||
- 单章内容生成(WriterAgent 调用 InferenceEngine 产出 `ChapterContent`)。
|
||||
- 内容块渲染(`render_chapter_blocks` 将 `ChapterContent` 转 `Block` 序列)。
|
||||
- Word 注入(`DocxInjector.inject` 将章节内容写入模板对应 `{{section:id}}` 占位符)。
|
||||
- QA 校验(确定性维度:`traceability` / `placeholder_residue` / `chapter_completeness`)。
|
||||
- QA 闭环(`QALoop` 仅对失败章重新生成,受 `QALoopController(DEFAULT_MAX_QA_ROUNDS=3)` 约束)。
|
||||
|
||||
**范围外(诚实标注)**:
|
||||
- **语义 QA 为探针**:内容准确性 / 幻觉检测 / 规则遵守等 LLM 语义维度,经 `ChapterScorer.llm_evaluators` 钩子注入,默认中性分,尚未接入真实推理(设计 §7.5 已声明待 Phase5)。
|
||||
- **图表生成**:本实现不生成图形/图表,仅支持表格/列表/段落/提示框等文本型 Block(设计 §6.4 的 table/list/paragraph/note)。
|
||||
- **跨章引用一致性**:设计 §7.2 第 4 项「关联一致性」由 `WriterState.cross_refs` 记录,但端到端语义校验(与 ImpactReport 逐条比对)超出本实现范围,留待人工质量门禁与后续里程碑。
|
||||
|
||||
### 12.2 组件与数据流
|
||||
|
||||
```
|
||||
StructuredSource
|
||||
│ build_contexts(structured_source, samples_dir)
|
||||
▼
|
||||
list[ChapterContext] (每章:chapter_id / 数据选择器 / 模板标记)
|
||||
│ WriterAgent.generate_chapter(ctx) 逐章串行
|
||||
▼
|
||||
ChapterContent(blocks: list[ContentBlock] + source_uris)
|
||||
│ render_chapter_blocks(content)
|
||||
▼
|
||||
list[Block](DocxInjector.Block:paragraph/heading/table/list/note)
|
||||
│ DocxInjector(template_path).inject(sections, meta)
|
||||
▼
|
||||
Document(注入后 Word 文档)
|
||||
│ QALoop(DEFAULT_MAX_QA_ROUNDS=3)
|
||||
│ ├─ QAValidator 校验各章(仅确定性维度)
|
||||
│ └─ 仅对失败章:WriterAgent.generate_chapter → render → 重新注入
|
||||
▼
|
||||
最终 Document + QAReport
|
||||
```
|
||||
|
||||
关键约定:
|
||||
- 逐章**串行**生成(设计 §6.8.1 基线约束),`WriterState` 跨章共享摘要与关键表结构供后章引用。
|
||||
- QA 闭环**仅重失败章**,不重新生成全部,受最大轮次护栏约束,禁止无限重试(设计 §7.4 护栏)。
|
||||
|
||||
### 12.3 实现期发现的真实 API 适配(避坑记录)
|
||||
|
||||
实现过程中,以下真实接口与设计/规范文档存在偏差,已按真实接口落地,此处统一记录供后人避坑:
|
||||
|
||||
1. **`DocxInjector` 真实接口**:为 `DocxInjector(template_path).inject(sections: dict[section_id, list[Block]], meta) -> Document`。**不存在** `inject_blocks` 方法;`sections` 字典的键是 `{{section:id}}` 中的 `id`(不含 `section:` 前缀)。
|
||||
2. **`InferenceEngine.chat_structured`** 签名为 `chat_structured(*, session_id, prompt, variables, schema, retry_count=2) -> StructuredResult`,返回对象含 `.data`(解析后的 dict)与 `.status`(ok / parse_error / failed)。调用时必须关键字传参。
|
||||
3. **`RagService.retrieve_*`** 为**同步**方法(非 async)。调用方在同步编排链路中直接调用即可,无需 `await`。
|
||||
4. **`map_template`** 消费真实的 `ParsedTemplate.sections`(元素类型为 `ChapterMarker`,含 `type` / `name` / `level`)。映射按文档顺序:遇到 `heading` 起一章;其后的 `section:<id>` 占位符归属该章 → `chapter_id = id`、`section_placeholder = "section:<id>"`。
|
||||
5. **`ChapterScorer.score(chapters: list[ChapterArtifact], source: StructuredSource)`**:QA 层需要 `ChapterContent → ChapterArtifact` 适配器(由 `ChapterContent.blocks` 拼接得到 `text`,并从各 block 收集 `source_uris`);设计 §7.5 的 `ChapterArtifact` 并非直接由 Writer 产出,需经适配。
|
||||
6. **真实 `DocxInjector.Block`** 已支持 `table` / `list` / `note` 类型;表格注入会渲染 `caption` 段落(caption 非空时在其上方/下方生成说明段落),非空 caption 不应被丢弃。
|
||||
|
||||
### 12.4 垂直切片状态
|
||||
|
||||
**FakeLLM 模式已打通(可回归)**:
|
||||
- 运行 `python scripts/run_phase5_slice.py --fake`,使用 `FakeLLMClient` 驱动整条链路,产出 `samples/phase5-slice/output.docx`。
|
||||
- 该切片覆盖:build_contexts → 逐章生成 → 渲染 → 注入 → QA 闭环(仅重失败章),并附带 `QAReport`。
|
||||
|
||||
**真实 LLM 生成 + 人工质量门禁(待人工执行项,P5-T10 推后)**:
|
||||
- 真实推理接入(DeepSeek / Qwen 等)与端到端人工质量门禁(内容准确性 / 格式精度 / 规则遵守的人工判读)不在本自动实现范围内,标记为推后项。
|
||||
- 真实 LLM 接入点已预留(`InferenceEngine` 默认实例 + `PromptRegistry` 注入),人工执行时仅需提供可用模型配置与 `scripts/run_phase5_slice.py` 的非 `--fake` 路径。
|
||||
|
||||
Reference in New Issue
Block a user