Files
2026Technology-Competition/docs/design.md
T

76 KiB
Raw Blame History

概要设计书自动生成 Agent 设计文档

版本: v1.0 | 日期: 2026-07-21 | 状态: 初版


目录

  1. 项目概述
  2. 整体架构
  3. Parser Agent 详细设计
  4. Impact Agent 详细设计
  5. RAG 基础设施层
  6. Writer Agent 详细设计
  7. QA Agent 详细设计
  8. Web UI 设计
  9. 数据模型与 Provenance 层
  10. 异常处理策略
  11. 通信语言与文档规范
  12. Phase 5Writer / QA 子系统

1. 项目概述

1.1 目标

开发一个 Web 服务形态的 Agent,能够读取以下输入资料:

  • Excel 版要件定义(核心数据源)
  • Word 版概要设计模板(输出章结构与样式)
  • Word 版概要设计做成说明书(各章作成指引)
  • Word 版记入规则 / 图表规则等规则文档
  • (可选) 现有系统的源代码与设计书(追加/改修场景)

自动生成符合规范的 Word 版概要设计书

1.2 成功标准

  1. 格式精确 — 输出文档的样式、字体、表格格式严格符合模板
  2. 内容准确 — 生成的所有信息必须来源于要件定义,不能捏造
  3. 可追溯 — 每一段生成内容都能追溯到原始数据来源(单元格/行/列)

1.3 开发范式

本项目的开发遵循 5 个步骤,对应 AI 使用日志的"范式步骤"列:

  1. 需求理解 — 分析大赛规则,理解概要设计书生成需求
  2. 架构设计 — AI 生成方案,人工审核设计
  3. Agent 实现 — AI 编码实现各 Agent 模块
  4. 测试验证 — 单元测试与集成测试验证
  5. 反馈迭代 — 基于测试结果反馈修正

2. 整体架构

2.1 Agent 构成

系统由 4 个 Agent + 1 个基础设施层构成:

┌─────────────────────────────────────────────────────────────┐
│                       Web UI (React)                          │
│    上传资料 | 确认解析 | 确认影响调查 | 启动生成 | 预览结果   │
└──────────────────────┬──────────────────────────────────────┘
                       │ REST API
┌──────────────────────▼──────────────────────────────────────┐
│                  Orchestrator (流程协调器)                    │
│   职责: 编排整个流程、管理会话状态、处理异常、人工介入点       │
└────┬──────────┬──────────┬──────────┬───────────────────────┘
     │          │          │          │
┌────▼───┐ ┌───▼────┐ ┌──▼────┐ ┌──▼──────────┐
│ Parser │ │ Impact │ │ Writer│ │ QA           │
│ Agent  │ │ Agent  │ │ Agent │ │ Agent        │
├────────┤ ├────────┤ ├───────┤ ├──────────────┤
│ 解析   │ │ 要素   │ │ 章节  │ │ 校验         │
│ 全部   │ │ 抽出   │ │ 生成  │ │ 格式/内容/   │
│ 输入   │ │ 关联   │ │ 模板  │ │ 可追溯性     │
│ 资料   │ │ 推論   │ │ 填充  │ │              │
└────────┘ └────────┘ └───────┘ └──────────────┘
     │          │                     │
     └──────────┴─────────────────────┘
                        │
                 ┌──────▼──────┐
                 │  RAG Layer   │
                 │  (基础设施)   │
                 │  规则检索服务 │
                 └─────────────┘

2.2 处理流程

① Parser Agent — 解析所有输入资料
   ├── Excel要件定义 → 结构化数据(各单元格带Provenance)
   ├── Word模板 → 章结构、占位符、样式
   ├── 规则文档 → Markdown化 + 分类(设计规则/写入规则)
   ├── 图像/图形式 → Vision LLM识别
   └──(可选)现系统代码/设计书 → 现系统结构数据
       │
       ▼
② 用户确认 — Web界面
   ├── 确认Excel解析结果(Sheet类型判定、数据预览)
   ├── 确认模板章结构
   └── 确认现系统探索结果(如有)
       │
       ▼
③ Impact Agent — 影响调查
   ├── Step 1: 要素抽出
   ├── Step 2: 批注分析(先理解,不明再问)
   ├── Step 3: 关联推理(细粒度 + 证据 + 置信度)
   ├── Step 4: 影响矩阵构建
   └── Step 5: 影响调查书输出(中间成果物)
       │
       ▼
④ 用户确认 — 影响调查结果
   ├── 逐条确认・修正(追加/删除/种类变更/证据修正)
   ├── 不确定处由用户判断
   └── 点击「确认完成」按钮进入 Writer
       │
       ▼
⑤ Writer Agent — 逐章生成(每章循环)
   ├── 从RAG检索相关规则(写入规则)
   ├── 从设计规则检出约束
   ├── 从StructuredSource提取数据
   ├── 从ImpactReport提取关联关系
   └── LLM生成 → 注入模板对应章节
       │
       ▼
⑥ QA Agent — 全量校验
   ├── 格式校验(vs 模板样式)
   ├── 内容校验(vs 源数据)
   ├── 规则遵守校验(vs RAG规则)
   └── 可追溯性校验(每个断言有来源)
       │
       ▼
⑦ 输出最终文档

2.3 共通工具层

为了避免 Parser Agent 过于臃肿,以下功能拆分为独立工具服务:

工具 职责 输出 复用者
FileReader 读取任意格式文件为统一内存结构 UnifiedDocument(元数据+内容+格式特有信息) Parser, QA
CodeParser 解析 Java 项目结构 CodeStructure(类+注解+依赖) Parser, Impact
ImageAnalyzer Vision LLM 封装,识别图片内容 ImageDescription(类型+文本+关系) Parser, Impact

3. Parser Agent 详细设计

3.1 职责

解析所有输入资料为结构化数据(StructuredSource),作为后续 Agent 的唯一数据来源。

3.2 两阶段策略

Phase 1: Probe(探查)
  快速扫描所有文件,返回概览信息 → 用户确认
  - Sheet列表(名称、行数列数)
  - 各Sheet表头(前3行)
  - 自动识别的Sheet类型(機能/画面/帳票/DB/IF)
  - Word模板的章结构与使用样式
  - 规则文档的章结构
  
Phase 2: Extract(深度提取)
  用户确认后,按需深度解析
  - 全表数据提取(每个单元格带Provenance
  - 规则文档的Markdown转换 + 分类
  - 现系统代码/设计书解析

3.3 输入资料清单

输入 格式 用途 解析难度
要件定义 .xlsx 核心数据源 ★★★(合并单元格・层级表头・自由记述混在)
概要设计模板 .docx 输出结构与样式 ★★☆(标题层级・占位符・书签)
做成说明书 .docx 各章作成指引 ★☆☆(纯文本+标题结构)
记入规则 .docx/.xlsx/.pptx 写法规范 ★★☆(多格式跨文档)
图表规则 .docx/.xlsx/.pptx 图表书写规范 ★★☆
(可选)现系统源码 .java/.xml/.yml 现系统结构把握 ★★★(Spring Boot解析)
(可选)现系统设计书 .docx/.xlsx 现系统功能把握 ★★☆

3.4 内部模块

Parser Agent
│
├── ExcelParser(要件定义解析)
│   ├── SheetDetector — 自动识别Sheet类型
│   ├── TableExtractor — 表格提取 + 合并单元格处理
│   ├── FreeTextParser — 自由记述型Sheet的LLM结构化
│   ├── FormattingDetector — 取消线检测、背景色检测
│   ├── CommentExtractor — 批注提取
│   └── ProvenanceAnnotator — 来源标注
│
├── WordParser(模板+规则文档解析)
│   ├── TemplateParser — 章结构、占位符、样式提取
│   └── RuleDocParser — 规则文档解析、Markdown化
│
├── PPTXParserPPT规则文档解析)
│   └── TextExtractor — 幻灯片文本提取
│
├── ExistingSystemExplorer(现系统探索)
│   ├── DirectoryScanner — 目录结构遍历
│   ├── JavaParser — Java代码解析(Controller/Service/Entity/Repository
│   ├── AnnotationAnalyzer — Spring Boot注解解析
│   └── ExistingDocParser — 现系统设计书解析
│
├── SourceAggregator(汇总器)
│   └── 统一输出为StructuredSource
│
└── 调用 → 共通工具层
    ├── FileReader(文件读取)
    ├── CodeParser(代码解析)
    └── ImageAnalyzer(图像识别)

3.5 Excel 解析详细策略

3.5.1 Sheet 类型自动识别

def detect_sheet_type(sheet_name, headers):
    """
    判断依据(优先级高→低):
    1. Sheet名关键词
    2. 表头关键词
    3. 数据类型分布
    """

说明:关键词为日文,用于匹配日文要件定义文件中的实际 Sheet 名/表头(技术必要保留)。

关键词模式 判定类型
"機能" in name / "機能ID" in headers FUNCTION
"画面" in name / "画面ID" in headers SCREEN
"帳票" in name / "帳票ID" in headers REPORT
"DB" in name / "テーブル" in name / "TABLE" in headers DATABASE
"IF" in name / "インターフェース" in headers INTERFACE
"バッチ" in name / "ジョブ" in name BATCH
"コード" in name / "マスタ" in name MASTER
都不符合 GENERIC

3.5.2 Sheet 性质判定(表格型 vs 自由记述型 vs 混合型)

判断指标:
1. 空行比率 > 30% → 自由记述型可能性
2. "・""■"开头行多 → 条目型可能性
3. 全部单元格为字符串类型 → 非表形式可能性
4. 没有表头行 → 自由记述型可能性
5. 仅使用 A 列、其他列几乎为空 → 自由记述型可能性

综合评分判定:
  text_score > 阈值 → 自由记述型 / 混合型
  table_score > 阈值 → 结构化表格型
  • 结构化表格型 → openpyxl 行列解析
  • 自由记述型 → 全部单元格文本合并 → 通过 LLM 结构化
  • 混合型 → 先进行段落分割 → 各段落最优解析

3.5.3 合并单元格处理

def forward_fill(rows, merged_cells):
    """
    下行填充策略:
    1. 识别合并单元格范围(r1, c1, r2, c2
    2. 遍历数据行,如果在合并范围内且为空值 → 填充主单元格值
    3. 记录 Provenance(来自合并单元格的主位置)
    """

3.5.4 取消线处理

if cell.font.strike:
    row_meta["excluded"] = True
    row_meta["exclude_reason"] = "strikethrough"
    # 值保留但不参与后续处理

3.5.5 批注处理

comment = cell.comment
if comment:
    cell_meta["comment"] = {
        "author": comment.author,
        "text": comment.text,
        "source_uri": f"file#sheet!{cell.coordinate}/comment"
    }
    # Impact Agent 侧「先分析,不明再问」

3.5.6 图像/图形处理

1.  ZIP 中提取全部图像xl/media/
2. 定位图像锚点位置单元格位置
3. 图像数 < 10   通过 Vision LLM 识别
4. 图像数 >= 10   仅记录存在
5. 图形自动形状)→ 提取文本

3.5.7 公式单元格处理

# 同时保留公式字符串与计算值
cell_meta = {
    "value": cell.value,          # 计算值
    "formula": cell.formula,      # 公式字符串(from openpyxl
    "has_formula": True,
    "provenance": provenance
}

3.6 Excel 解析风险一览

风险 影响度 频率 应对
字符编码(Shift-JIS/UTF-8 chardet 自动判别
隐藏行/列 检测→排除标记,可用户确认
公式单元格 formula + value 同时保持
巨大文件 read_only 模式 / 切换 Polars
密码保护 检测后通知
.xls 旧格式 错误通知 / LibreOffice 转换
多行单元格(Alt+Enter 保留换行
多级表头 分析开头 N 行进行扁平化
Sheet 间相互引用 作为上下文传给 LLM
打印范围设置 记录到 Provenance
大纲(分组) 记录分组层级
单元格内多种字体混在 仅获取纯文本
条件格式 现阶段忽略
外部引用链接 检测后警告
VBA/宏 检测存在(不执行)

3.7 现有系统探索

3.7.1 对应技术栈

技术 解析内容
Java / Spring Boot Controller/Service/Repository/Entity + 注解 + API 端点
MyBatis 从 Mapper XML 提取 SQL + 表名
Python / FastAPI Router/Route/Model
C# / .NET Controller/DTO/Entity
HTML/JSP 画面文件一览/跳转链接
Word/Excel 设计书 提取现有构成信息

3.7.2 探索深度

优先级1: 目录信息(文件名、类名、API 端点)
  方法: 目录遍历 + 正则表达式 / CodeParser
  精度: 高

优先级2: Schema 信息(DB 表、DTO 结构)
  方法: 解析 Entity/Model 文件
  精度: 中〜高

优先级3: 依赖信息(Controller→Service 调用关系)
  方法: 解析 import/调用关系
  精度: 低

3.8 Parser Agent 的输出:StructuredSource

@dataclass
class Provenance:
    file_name: str
    sheet_name: str
    row: int
    column: str
    column_header: str

@dataclass
class CellValue:
    value: Any
    provenance: Provenance
    formatting: CellFormatting | None = None
    comment: CellComment | None = None

@dataclass
class CellFormatting:
    strikethrough: bool = False
    font_color: str | None = None
    bg_color: str | None = None

@dataclass
class CellComment:
    author: str
    text: str
    source_uri: str

@dataclass
class ExcelTable:
    name: str
    detected_type: SheetType
    extraction_method: str  # "openpyxl" | "llm_from_free_text"
    headers: list[str]
    rows: list[dict[str, CellValue]]

@dataclass
class ParsedTemplate:
    file_name: str
    sections: list[ChapterMarker]
    placeholders: dict[str, str]
    styles: dict

@dataclass
class ChapterMarker:
    type: str  # "heading" | "bookmark" | "placeholder"
    name: str
    level: int

@dataclass
class ExistingSystemInfo:
    controller_layer: list[ControllerInfo]
    service_layer: list[ServiceInfo]
    entity_layer: list[EntityInfo]
    api_endpoints: list[EndpointInfo]
    source_path: str

@dataclass
class StructuredSource:
    tables: list[ExcelTable]
    template: ParsedTemplate
    rule_docs: list[RuleDocument]
    image_analyses: list[ImageAnalysis]
    existing_system: ExistingSystemInfo | None
    comments: list[CellComment]

4. Impact Agent 详细设计

4.1 职责

接收 Parser Agent 的 StructuredSource,分析要素间的关联关系,输出影响调查书(中间成果物)。

4.2 处理步骤

Step 0: 变更点定位(仅新增/改修时)
  → 从 Parser 的解析结果中识别「新增/追加/变更/删除」的各行
  → 从现有系统信息与要件定义的差异中定位变更范围

Step 1: 要素抽取
  → LLM 从各 Sheet 数据中识别「功能/画面/账票/DB/IF/批处理」
  → 取消线行除外、批注进行分析
  → 确认抽取精度(置信度)

Step 2: 批注分析
  → 先用 LLM 理解・分类批注内容
  → 提取应反映到设计书中的内容
  → 仅对不明点向用户提问(先分析、后提问)

Step 3: 关联推理(核心)
  → 从业务描述中推理要素间的关联
  → 关联类型: 利用 / 参照 / 更新 / 输出 / 输入 / 依赖
  → 证据(evidence)必须附带根据原文
  → 交叉检查进行置信度补正
  → 设计规则(来自 RAG)也作为考虑材料使用

Step 4: 影响矩阵构建
  → 双向矩阵(该要素影响什么 / 什么影响该要素)

Step 5: 影响调查书输出
  → JSON(供 Writer Agent 使用)+ 摘要(供 UI 确认用)

4.3 关联推理详情

4.3.1 关联类型定义

类型 含义
利用 功能利用画面/账票 F001 → SC001
参照 功能/画面读取 DB/IF 数据 F001 → TB001SELECT
更新 功能/画面写入 DB/IF 数据 F001 → TB001INSERT/UPDATE
输出 功能生成账票 F001 → RP001
输入 画面接受输入并传给功能 SC001 → F001
依赖 功能依赖其他功能/模块 F001 → AUTH001(必须认证)

4.3.2 置信度定义

置信度 条件 证据要求 用户确认
high 有明确记载(关联画面=SC001 等) 证据明确 默认折叠显示
medium 关键词一致・ID 名一致 证据可引用 展开显示
low 仅根据名称相似性推理 证据弱 强调显示

4.3.3 交叉检查

def cross_validate(candidates):
    """从多个根据推理出同一关联时,置信度升级"""
    same_relation = [r for r in candidates if r.from_id==x and r.to_id==y]
    if len(same_relation) >= 2:
        # 例: 明示 + 准明示 → high
        upgrade_confidence(relation)

4.3.4 矛盾检测

def check_consistency(relations):
    """
    - 循环引用的检测(A→B→C→A)
    - 类型不一致(功能→功能的「利用」)
    - 孤立要素(不与任何要素关联)
    """

4.4 影响调查书的结构(完整版)

{
  "metadata": {
    "version": "v1",
    "session_id": "genesis-xxx",
    "created_at": "2026-07-21",
    "llm_model": "deepseek-chat",
    "parser_version": "1.0"
  },
  "change_analysis": {
    "project_type": "new_development" | "enhancement",
    "new_elements": [...],
    "modified_elements": [...],
    "deleted_elements": [...],
    "unchanged_elements": [...]
  },
  "extracted_elements": [
    {
      "element_id": "F001",
      "element_type": "功能",
      "name": "用户注册",
      "description": "业务描述的摘录",
      "source_uris": ["file#sheet!A3"],
      "comments_related": [...],
      "images_nearby": [...],
      "coverage": "complete" | "partial" | "speculative",
      "provenance_chain": [...]
    }
  ],
  "relations": [
    {
      "from_id": "F001",
      "from_type": "功能",
      "to_id": "SC001",
      "to_type": "画面",
      "relation_type": "利用",
      "confidence": "high",
      "evidence": "evidence text",
      "source_uri": "file#sheet!D3",
      "cross_validated": true,
      "user_corrected": false
    }
  ],
  "impact_matrix": {
    "F001": {
      "name": "用户注册",
      "type": "功能",
      "impacts": [
        {"to_id": "SC001", "to_type": "画面", "relation_type": "利用",
         "confidence": "high", "source_uri": "file#sheet!D3"}
      ],
      "impacted_by": [
        {"from_id": "TB001", "from_type": "DB", "relation_type": "参照",
         "confidence": "high", "source_uri": "file#sheet!E4"}
      ]
    }
  },
  // 注: impact_matrix 的元素与 relations[] 使用同一关系对象结构
  //     from_id/to_id [+type]、relation_type、confidence、evidence、source_uri),
  //     impacts  = 该要素影响什么(to 方向),impacted_by = 什么影响该要素(from 方向)
  //     Writer 消费时以此为章内引用与“影响范围”描述的依据
  "comments_analysis": [
    {
      "source_uri": "...",
      "summary": "摘要",
      "category": "review_feedback" | "supplementary" | "clarification" | "status_mark" | "question",
      "importance": "must" | "should" | "nice_to_have" | "irrelevant",
      "actionable_content": "...",
      "confidence": "high",
      "uncertainty": null
    }
  ],
  "uncertainties": [
    {
      "element_id": "F004",
      "issue": "不明点的说明",
      "source_uri": "...",
      "suggested_question": "向用户提问的语句"
    }
  ],
  "quality_indicators": {
    "provenance_chain": {...},
    "coverage_markers": [...],
    "orphan_warnings": [...],
    "risk_flags": [
      {"element": "F001", "risk": "high", "reason": "若删除将影响 5 个要素"}
    ],
    "user_corrections": [...]
  },
  "summary": {
    "total_elements": 45,
    "total_relations": 128,
    "by_type": {"功能": 12, "画面": 10, ...},
    "high_confidence_relations": 85,
    "medium_confidence_relations": 32,
    "low_confidence_relations": 11,
    "uncertainties_count": 2,
    "orphan_count": 1
  }
}

4.5 影响调查书的生命周期

v1(初版): Impact Agent 生成 → 保存
    ↓ 用户确认・逐条修正
v2(确认版): 应用用户修正 → 保存 ← Writer Agent 使用此版本
    ↓ 设计书生成完成
在设计书的元数据中记录「使用的影响调查书: v2」

4.6 用户确认界面方针

  • 显示所有关联(无 auto-pass
  • 证据(evidence)默认折叠、可展开
  • 用户可以对各关联进行追加・删除・种类变更・证据修正(逐条修正)
  • 保存修正履历(correction_history
  • 责任在于「用户已确认并批准」这一点

5. RAG 基础设施层

详细设计见 docs/rag-layer-design.md。本章为概要。

5.1 定位

RAG 不是独立 Agent,而是 Parser 和 Writer/QA 之间的基础设施层。

5.2 为什么需要 RAG

条件 结论
规则分散在 Word/Excel/PPT 多种格式 需要统一检索入口
规则本身没有按设计书章节整理 无法用静态索引做到 1:1 映射
同一个主题的规则散落在不同文档 需要跨文档的语义检索
目标:用户无感遵守规则 规则必须理解后精准注入生成过程
规则变化频率低但会变 需要持久化 + 版本管理

5.3 规则文档的分类

Parser 处理时分为:

1. 写入规则(记入规则、图表规则、字体指定)
   → RAG Layer → Writer Agent 参考
   → 每章生成时检索该章相关规则

2. 设计规则(架构约束、安全要求、设计方针)
   → 影响调查的关联推理也参考
   → 传递给 Impact Agent 作为补充信息

3. 参考设计文档(可选增强)
   → 过往概要设计书、设计决策记录
   → Impact Agent 改修场景参考

5.4 规则手册的生命周期

初期设定(首次):
  用户上传规则文档
    ↓
  Parser + RAG 处理 → 规则手册 v1(持久化保存)
    ↓
通常使用:
  用户只上传要件定义与模板
  Writer Agent 自动参照规则手册

规则更新时:
  用户点击 Web UI 的「规则更新」按钮
    ↓
  上传新规则文档
    ↓
  Parser + RAG 再处理 → 规则手册 v2(文档级增量,只重建变化文档)
    ↓
  旧版本保留(用于与历史设计书关联)

5.5 关键设计决策(概要)

设计点 决策
向量数据库 Chromav1 唯一;Qdrant 切换为 v2 预留,Scope 缩减裁定)
Embedding bge-m3(多语言,适配日文语料;OV2/T11)
实现方式 手写(chromadb + rank_bm25 + sentence-transformers
分割策略 按格式适配(Word 标题层级 / Excel 规则块 / PPT 1-2 页)
检索策略 双通道(向量 top-10 + BM25 top-10+ RRF 融合 + rerank 精排(bge-reranker-v2-m3
分类存储 分 Collection 隔离(rules-write / rules-design / ref-docs
版本管理 文档级增量 + 版本组合(hash 对比,只重建变化文档)
版本路由 会话开始锁版本
规则冲突 检测到矛盾时由用户确认采用哪条规则

6. Writer Agent 详细设计

6.1 职责

逐章节生成设计书内容,并注入 Word 模板中对应的位置。

6.2 各章生成时的输入

Writer Agent(每章循环)
    │
    ├── ① 从 RAG 检索该章相关的写入规则
    ├── ② 从设计规则中检出约束条件
    ├── ③ 从 StructuredSource 提取该章所需的数据
    ├── ④ 从 ImpactReport 提取关联关系
    ├── ⑤ 从模板获取该章的样式定义
    │
    └── LLM 生成内容 → 注入模板对应位置

6.3 模板注入策略

  • 章位置识别:模板中的 Heading 层级 / 书签 / 占位符
  • 内容注入:python-docx / docxtpl
  • 样式保持:继承模板定义样式,LLM 只生成内容不控制格式

6.4 LLM 输出格式(JSON 内容块)

决策LLM 不直接输出 HTML 或 Word 格式,而是输出结构化 JSON 内容块ContentBlock)。渲染器统一将内容块转换为 chapter_html(前端预览)与 docx(最终下载)。

{
  "chapter_id": "db_design",
  "version": 2,
  "title": "DB設計",
  "blocks": [
    {
      "block_id": "b-001",
      "type": "paragraph",              // paragraph | heading | table | list | note
      "level": 2,                       // 仅 heading 使用(对应模板 Heading 层级)
      "text": "本システムのDBは以下の通り。",
      "source_uris": ["要件定義.xlsx#DB定義!A1"]
    },
    {
      "block_id": "b-002",
      "type": "table",
      "caption": "テーブル一覧",
      "headers": ["テーブルID", "テーブル名", "概要"],
      "rows": [
        ["TB001", "ユーザー", "ユーザー情報"],
        ["TB002", "注文", "注文情報"]
      ],
      "source_uris": ["要件定義.xlsx#DB定義!A3", "要件定義.xlsx#DB定義!B3"]
    },
    {
      "block_id": "b-003",
      "type": "list",
      "style": "bullet",                // bullet | numbered
      "items": ["PK は ユーザーID とする", "外部キー制約を設定する"],
      "source_uris": ["記入規則.docx#見出し!5.1"]
    }
  ]
}

设计原则

  • LLM 只负责内容(文本/表格/列表),不控制格式(字号/字体/颜色由模板样式决定)
  • 每个 block 携带 source_uris → 满足「可追溯」成功标准,QA 第8项可追溯性校验据此执行
  • block_id 全局唯一 → 幂等重写(runtime §7)按 (chapter_id, version) 覆盖时定位
  • 表格结构天然支持 docx 表格渲染与 chapter_html 预览

6.5 章节 ↔ 模板映射规则

模板解析(Parser §3.8 ParsedTemplate)产出 ChapterMarker 列表。Writer 生成时按以下规则映射:

模板 ChapterMarker:           Writer 内容块:
───────────────────────      ───────────────────────
heading level 1 (章)  ────►  chapter(1 个章节 = 1 次生成循环)
heading level 2 (节)  ────►  blocks[].type="heading" level=2
heading level 3 (小节) ───►  blocks[].type="heading" level=3
bookmark / placeholder ──►  blocks[].type="paragraph"(占位锚点)

映射规则细化

模板元素 Writer 处理
## 3. DB設計H1 生成循环入口:chapter_id = "db_design"
### 3.1 テーブル一覧H2 生成 heading level=2 block,随后为该节内容块
{{section:db_tables}} 占位符 定位到该占位符处,注入内容块渲染结果
书签(bookmark 作为内容块的插入锚点,渲染器在其后插入
模板自带示例文本 替换为生成内容(不保留示例)

生成顺序控制:按模板章节顺序逐章生成。章间引用(如「3.2 画面一覧」引用「2. 機能一覧」的表)通过 WriterState 记录已生成章节的摘要与关键表结构,后章生成时引用(详见 6.9)。

6.6 docxtpl 占位符语法规范

模板中使用 docxtpl 语法定义占位符。支持两种模式:

模式 A: 章节级占位符(整章内容注入)
  {{section:db_design}}
  → 渲染器将「db_design」章节的全部内容块渲染为 docx 元素序列,
    替换该占位符

模式 B: 行内占位符(单值注入,用于封面/元信息)
  {{doc_title}}  {{version}}  {{created_at}}
  → 从会话元数据取值填充

规范约束

  • 占位符命名:section:<chapter_id> 用于章节;其余为元信息字段
  • 模板中未找到占位符时,回退到「按 Heading 层级定位」(§6.5 规则),在对应 Heading 后插入
  • 渲染器输出后做一次「占位符残留检查」:若存在未替换的 {{...}} 视为渲染失败,报错

6.7 渲染链路(ContentBlock → chapter_html / docx

ContentBlockJSONLLM 输出)
      │
      ▼
统一渲染器(Writer 内)
      ├──► chapter_html  (每章生成后即时产出,供前端「生成执行」页实时预览)
      │      渲染: blocks → HTML 元素(p/h2/h3/table/ul
      │      样式: 内联基础样式 + 标记「该元素样式继承模板」
      │
      └──► docx 元素序列(全章完成后统一注入模板)
            渲染: blocks → python-docx 元素(add_paragraph/add_table/add_heading
            样式: 从模板对应样式定义继承(模板样式名映射表)
            注入: 按 §6.6 占位符 / §6.5 Heading 定位写入模板

T17 docx 注入原型(OV8,已落地 src/genesis/writer/docx_injector.py: 将最难的「格式精度」成功标准提前验证。原型用原生 python-docx 实现 §6.6 占位符注入:

  • 章节级 {{section:id}} → 替换为内容块渲染的 docx 元素序列(heading/paragraph/table
  • 行内 {{meta}} → 元信息填充
  • 残留检查:未替换 {{...}} 视为渲染失败(抛 DocxInjectError),与 §6.6 规范约束一致
  • 格式精度:注入 heading 继承模板对应 Heading 样式(如 Heading 2),原有模板内容样式不被破坏

该原型在 Writer 完整实现前即可独立验证 docx 注入关键路径,规避「格式精度排末尾导致返工」的风险。

模板样式映射表(渲染器配置):

style_map:
  paragraph: "Normal"          # 模板中的段落样式名
  heading_1: "Heading 1"
  heading_2: "Heading 2"
  heading_3: "Heading 3"
  table: "Table Grid"          # 表格样式名
  list_bullet: "List Bullet"
  list_number: "List Number"

预览与最终文件的一致性chapter_html 与 docx 渲染自同一份 ContentBlock,内容一致;差异仅在格式载体(HTML 内联样式 vs docx 模板样式)。

6.8 每章生成流程(详细时序)

┌──────────────────────────────────────────────────────────┐
│ WriterAgent.generate_chapter(chapter_id, state)          │
│                                                          │
│ ① 组装输入:                                               │
│    RAG.search(query=章标题+要素ID, category="write")      │
│    → rules: list[RuleChunk]                              │
│    DataGate.load(structured_source, selector=该章数据)     │
│    ImpactReport 中该章相关要素/关联                         │
│    ParsedTemplate 中该章的样式定义                          │
│                                                          │
│ ② 冲突检测:                                               │
│    ConflictDetector(rules) → 有冲突则阻塞该章,等用户决策    │
│    (已决策的冲突直接采用,不重复询问)                      │
│                                                          │
│ ③ Prompt 组装:                                            │
│    [系统指令] 你是概要设计书撰写助手…(固定文本)             │
│    [用户数据] ┌─边界─┐ 规则/要件/要素描述 └─边界─┐            │
│    [任务] 生成该章内容,输出 JSON 内容块(schema 约束)       │
│                                                          │
│ ④ InferenceEngine.chat_structured(                        │
│      prompt="writer_chapter",                             │
│      variables={chapter_id, rules, data, relations, style},│
│      schema=ContentBlockSchema,                           │
│      retry_count=2)                                       │
│                                                          │
│ ⑤ 校验输出:                                               │
│    内容块结构校验(schema 校验)→ 失败则重试               │
│    source_uris 存在性校验(引用的 URI 必须能在输入中定位,   │
│       T12 resolver.validate_source_uris → unresolved 非空即失败)│
│                                                          │
│ ⑥ 渲染:                                                   │
│    产出 chapter_html → 前端实时预览                        │
│    暂存 ContentBlock(按 chapter_id + version 幂等写入)    │
│                                                          │
│ ⑦ 更新 WriterState:                                       │
│    记录该章摘要 + 关键表结构(供后续章引用)                 │
└──────────────────────────────────────────────────────────┘

6.8.1 串行生成约束(T10 文档化,I14)

架构审查 I14 裁定:Writer 各章必须串行生成,不得并行。本约束为设计基线, 而非实现细节,需在编排层与 UI 显式体现。

理由

  1. 章间引用依赖:后章(如「3.2 画面一覧」)需引用前章(「2. 機能一覧」)的 表结构与摘要,串行保证前章 WriterState 已就绪(§6.9),避免竞态或空引用
  2. 并行收益低、复杂度高:单章生成 3-5 分钟,并行需解决状态回写锁与 跨章引用一致性,复杂度远超收益(编审查 OV 一致结论)
  3. Token 友好:前章摘要注入后章 prompt 的方式(§6.9)天然要求前章先完成

约束落地点

  • 编排层:POST /generate 投递任务后,同一会话的逐章任务严格按模板章节顺序串行消费 (共享 orchestrator/,状态机 writing 态内顺序推进;单章失败可独立 retry,不影响其他章)
  • UI:生成按钮触发后展示预估总时长(章数 × 单章 ~3-5 分钟)与逐章进度 (「第 3/12 章生成中」),让用户对串行等待有预期
  • 实现反模式(禁止):同一会话并发投递多章生成任务、跳过 WriterState 直接全量重载

6.9 章间引用机制(WriterState

WriterState(会话级,跨章节共享):
{
  "chapter_states": {
    "function_list": {
      "status": "completed",
      "summary": "全15機能、一覧表あり",
      "tables": [{"id": "機能一覧", "headers": ["機能ID", "機能名", "概要"], "row_count": 15}],
      "key_elements": ["F001", "F002", ...]
    },
    "screen_list": {"status": "generating", ...},
    ...
  },
  "cross_refs": [           // 章间引用记录
    {"from": "screen_list", "to": "function_list", "ref_type": "table", "table_id": "機能一覧"}
  ]
}

引用规则

  • 后章需要前章数据时,不重新加载全量数据,而是从 WriterState 读取前章的摘要/表结构
  • 引用内容在 prompt 中以「前章摘要」形式注入(token 友好,符合 runtime §2.6 Token 管理)
  • 跨章引用关系记录到 cross_refs,供 QA 第4项「关联一致性」校验

7. QA Agent 详细设计

7.1 职责

生成后的全量校验,覆盖格式、内容、规则遵守、可追溯性四个维度。校验在全章生成完成后执行,发现问题时反馈给 Writer Agent 修正该章节,形成「QA 校验 → Writer 修正 → 重新校验」循环。

7.2 十项校验清单

# 校验项 维度 方法 判定标准
1 格式一致性 格式 与模板逐项对比(字号/字体/字色/行距/段距/表样式) 与模板定义一致
2 内容准确性 内容 与要件定义源数据对比 所有信息可追溯到源,无缺失
3 幻觉检测 内容 LLM 语义校验「是否写了源数据中没有的内容」 无凭空生成
4 关联一致性 内容 与影响调查书对比 生成的关联与 ImpactReport 一致
5 写入规则遵守 规则 via RAG 检索写入规则并对比 符合记入规则/图表规则
6 设计规则遵守 规则 via RAG 检索设计规则并对比 符合设计约束
7 矛盾检测 规则 全文扫描自相矛盾的描述 无矛盾表述
8 可追溯性 可追溯 每段内容检查 source_uri 标注 每个断言有来源
9 术语一致性 规则 与统一术语表对比 无术语混用
10 章节完整性 内容 与模板章结构对比 所有章节已生成且无缺章

7.3 校验方法

双重校验策略:
1. 确定性校验(代码)
   - 格式校验(python-docx 对比模板样式)
   - 可追溯性校验(正则检查 source_uri)
   - 章节完整性校验(章结构对比)

2. LLM 语义校验(推理引擎)
   - 内容准确性(源数据逐条核对)
   - 幻觉检测(对比源数据与生成内容)
   - 规则遵守(注入 RAG 检索的规则,LLM 判断是否符合)
   - 矛盾/术语检测

7.4 校验结果与反馈

QA 输出:
{
  "version": "v1",
  "total_items": 10,
  "results": [
    {"item": "格式一致性", "status": "pass"},
    {"item": "内容准确性", "status": "fail",
     "details": [{"chapter": "DB設計", "issue": "TB003 的列名与源数据不一致", "source_uri": "要件定義.xlsx#DB!D5"}]},
    ...
  ],
  "summary": {"pass": 8, "fail": 2, "warnings": 1}
}

反馈循环:
  QA 发现错误 → 将问题列表反馈给 Writer
  → Writer 只修正错误章节(不重新生成全部)
  → 重新 QA 校验

> **QA 护栏(T15 机制化,对应审查 OV6**
> 1. **循环边界**:「QA 校验 → Writer 修正 → 重新校验」循环受 `QALoopController`
>    `DEFAULT_MAX_QA_ROUNDS=3`)约束,超过上限必须停止并上报人工/降级处理,
>    禁止无限重试(`src/genesis/qa/guardrails.py`)。
> 2. **独立校验模型(防自校验盲区)**:QA 校验强制走 `resolve_qa_model()` 返回的
>    **fallback 模型**(如 qwen-max),不得与生成主模型(deepseek-chat)同源;
>    否则「DeepSeek 生成 + DeepSeek 校验」会形成同族模型盲点,难以发现自身偏误。
>    无 fallback 配置时返回 None,迫使调用方显式指定独立校验模型,而非静默回退主模型。
>    实现调用示例:`engine.chat(session_id=..., prompt=..., model=resolve_qa_model(models))`。

### 7.5 黄金集与评分器(T13 机制化,OV4)

> OV4 裁定:成功标准须有量度 → 建立黄金集 + 评分器(已实现于 `src/genesis/eval/`)。

- **评分器(ChapterScorer**:按 §7.2 指标体系输出各维度 `DimensionScore(score, passed)` 与总分 `EvalReport`。
  - 确定性维度(代码可验证,无需 LLM):
    - `traceability`:所有 `source_uri` 经 `resolver.validate_source_uris` 定位(不可解析 → 扣分,防 QA#8 作弊)
    - `placeholder_residue`:渲染文本无 `{{...}}` 残留(残留即 fail
    - `chapter_completeness`:生成章节覆盖模板期望集合(覆盖率)
  - LLM 语义维度(内容准确性/幻觉/规则遵守):通过 `llm_evaluators` 钩子注入,默认中性分,待 Phase5 接入真实推理
- **黄金集(GoldenSet**:从 YAML 加载回归基线,`samples/` 真实脱敏样本作 `input_ref`(审查报告 §8.2 已确认 7 个样本为黄金集基础);每条 `GoldenCase` 标注 `expected_min_score`Phase5 后用于端到端回归
- 评分器作为 CI 质量门禁:生成结果总分 < 阈值 → 阻断合并(与 fail_under=99 覆盖率门禁同级)
  → 重复至全部通过或用户确认放行

7.5 与 RAG 的交互

  • QA 校验规则遵守时,通过 RagService 检索写入规则/设计规则(category="write" 或 "design"
  • 对已由用户决策的规则冲突(conflict_resolve 记录),以已决策规则为准,不再告警

7.6 输出

  • 设计书附带 QA 报告(JSON,可下载)
  • 前端「结果预览」页面展示 QA 结果(全10项 pass/fail + 警告)

8. Web UI 设计

8.1 概述

概要设计书自动生成 Agent 的 Web UI 是用户与系统交互的唯一界面,承担以下功能:

  • 文件上传(要件定义、模板、规则文档、现系统文件)
  • 各步骤的确认与修正(解析结果、影响调查结果、生成结果)
  • 生成进度实时展示
  • 最终设计书的预览与下载
  • 规则手册管理(更新、版本查看)
  • 多用户支持(数据隔离)

8.2 页面结构

全局布局:

┌─────────────────────────────────────────────────────────────┐
│  Genesis    [上传] [解析] [影响调查] [生成] [结果] [历史] [设置] │ ← 顶部导航
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌─ 对话区域 ──────────────────────────────────────────┐   │
│  │  🤖 ...(状态信息、进度、结果)                    │   │
│  │  🧑 ...(用户输入、文件拖拽、回答)                │   │
│  └──────────────────────────────────────────────────────┘   │
│                                                             │
│  ┌─ 组件区域 ──────────────────────────────────────────┐   │
│  │  (根据当前步骤切换: 表格/确认画面/进度等)              │   │
│  └──────────────────────────────────────────────────────┘   │
│                                                             │
│  状态栏: [📤已上传] [✅完成] [⏳进行中] [⏸未开始]          │
└─────────────────────────────────────────────────────────────┘

导航步骤:

① 上传  →  ② 解析确认  →  ③ 影响调查确认  →  ④ 生成执行  →  ⑤ 结果预览
(文件选择)     (Sheet判定等)    (关联・不确定处)   (进度显示)     (设计书浏览/下载)

8.3 各页面详细设计

页面1: 文件上传

┌─────────────────────────────────────────────┐
│  1. 上传文件                                    │
├─────────────────────────────────────────────┤
│                                             │
│  📁 要件定义 (必须)                          │
│  ┌─────────────────────────────────────┐    │
│  │  .xlsx, .xls, .docx, .pptx 拖放即可  │    │
│  │  或 [选择文件]                       │    │
│  └─────────────────────────────────────┘    │
│                                             │
│  📁 设计书模板 (必须)                          │
│  ┌─────────────────────────────────────┐    │
│  │  .docx (Word)                       │    │
│  └─────────────────────────────────────┘    │
│                                             │
│  📁 记入规则 (推荐, 可多个)                   │
│  📁 图表规则 (推荐)                          │
│  📁 做成说明书 (推荐, 独立类型)                │
│                                             │
│  📁 现有系统文件 (任意, 追加/改修场景使用)      │
│                                             │
│  [更新规则] ← 规则手册再构建按钮              │
│                                             │
│  [上传完成 → 进入解析]                       │
└─────────────────────────────────────────────┘

上传规则:

  • 要件定义文件至少一个
  • 模板文件必须是一个 .docx
  • 做成说明书 / 记入规则 / 图表规则 均可多个,也可零个(规则手册已存在时);做成说明书使用独立 file_type=write_instructionapi-design §2.2
  • 现系统文件仅在追加/改修场景时需要
  • 文件大小限制:最大100MB
  • 支持拖拽上传、点击上传、取消上传

页面2: 解析结果确认

┌─────────────────────────────────────────────┐
│  2. 确认解析结果                              │
├─────────────────────────────────────────────┤
│                                             │
│  ▶ Excel要件定义 - Sheet类型判定               │
│  ┌────────┬────────────┬────────┬─────────┐ │
│  │ Sheet名│ 类型判定    │ 修正   │ 行数/列数│ │
│  ├────────┼────────────┼────────┼─────────┤ │
│  │ 功能一览 │ ✅ FUNCTION │  [修正]│ 150x5   │ │
│  │ 画面一览 │ ✅ SCREEN   │  [修正]│ 30x4    │ │
│  │ 账票一览 │ ✅ REPORT   │  [修正]│ 12x6    │ │
│  │ DB定义  │ ✅ DATABASE │  [修正]│ 20x8    │ │
│  │ 自由记述 │ ⚠ 自由记述型│  [修正]│ 45行    │ │
│  └────────┴────────────┴────────┴─────────┘ │
│  ※ 取消线行将从生成对象中排除                    │
│                                             │
│  ▶ Word模板 - 章节构成                     │
│  检测到的章节:                                   │
│  1. 目的                                      │
│  2. 功能一览                                    │
│  ...(全部章节一览)                                  │
│  [修改章节]                                      │
│                                             │
│  ▶ 现有系统探索结果 (仅追加/改修场景显示)          │
│  检测: Controller / Service / Entity / API      │
│  [查看详情]  [要修正吗?]                  │
│                                             │
│  [确认并进入影响调查]                          │
└─────────────────────────────────────────────┘

交互说明:Sheet类型判定由 AI 自动完成,但用户可点击修正。章节构成同理。

页面3: 影响调查确认

┌─────────────────────────────────────────────┐
│  3. 确认影响调查结果                           │
├─────────────────────────────────────────────┤
│                                             │
│  ── 影响调查概要 ──                             │
│  要素数: 45件 | 关联数: 128件 | 高置信度: 85件 │
│  不确定处: 2件                                 │
│                                             │
│  ── 要素一览(可折叠) ──                       │
│  ▸ F001 用户注册 (功能)                      │
│    关联: SC001(利用/h) SC002(利用/h) TB001(更新/h) │
│    [编辑] [删除]                                │
│                                             │
│  ── 未确定项目 ──                               │
│  ❓ F004 → TB007 的关联不明                     │
│     根据: 仅名称相似                          │
│     → [追加] [否决] [修正]                      │
│                                             │
│  ── 质量指标 ──                                 │
│  ⚠ 孤立要素: F012 与任何要素均无关联            │
│  ⚠ 风险: 删除 F001 将影响 5 个要素             │
│                                             │
│  [确认完成 → 进入生成]                          │
└─────────────────────────────────────────────┘

交互说明:一栏显示全部关联(无 auto-pass)。仅高亮关注未确定项目。

页面4: 生成执行

┌─────────────────────────────────────────────┐
│  4. 概要设计书生成中...                        │
├─────────────────────────────────────────────┤
│                                             │
│  进度:                                     │
│                                             │
│  ✅ 功能一览 - 完成 (23秒)                      │
│  ✅ 画面一览 - 完成 (18秒)                      │
│  ⠋ DB设计  - 生成中...                          │
│  ⬜ 账票一览 - 等待                              │
│  ⬜ IF定义  - 等待                              │
│  ⬜ 非功能要件 - 等待                           │
│                                             │
│  已过时间: 41秒 / 预计时间: ~3分                │
│                                             │
│  ──────────────────────────────────────      │
│  DB设计章 生成中:                              │
│  关联要素: F001, F003, TB001, TB002        │
│  适用规则: 写入规则_v3                      │
│                                             │
│  [中途中断]  [查看日志]                     │
│                                             │
│  ┌─ 规则冲突 (浮动卡片) ───────────────────┐   │
│  │  ⚠ 检测到规则冲突(DB设计章)                  │   │
│  │  记入规则 2.3「表头仅加粗」                    │   │
│  │  图表规则 2.3「表头加粗+下划线」                │   │
│  │  [采用「记入规则」] [采用「图表规则」] [标注]    │   │
│  └──────────────────────────────────────┘   │
└─────────────────────────────────────────────┘

交互说明:用户可保持此画面打开同时进行其他工作。生成完成时通知。选择中断时,已完成的章节保留。规则冲突由 WS 事件 conflict_pending 触发浮动卡片,决策后调用 /api/rules/conflicts/{id}/resolve 继续生成。

页面6: 设置

简版:规则手册版本管理(versions / 更新 / 回滚)+ LLM 配置只读摘要(脱敏)。见 docs/web-ui-design.md §3.6。

页面7: 会话历史

简版:会话列表(恢复 / 删除 / 新建),对应 GET /api/sessions。见 docs/web-ui-design.md §3.7。

页面5: 结果预览与下载

┌─────────────────────────────────────────────┐
│  5. 生成完成                                   │
├─────────────────────────────────────────────┤
│                                             │
│  ┌─ QA报告 ──────────────────────────┐   │
│  │  ✅ 全部10项检查通过                    │   │
│  │  警告 1件: 「功能概要应包含影响范围」  │   │
│  └────────────────────────────────────────┘   │
│                                             │
│  ┌─ 预览 ──────────────────────────┐   │
│  │  (ContentBlock → HTML 渲染)      │   │
│  │  [章标题]  [段落]  [表]  ...              │   │
│  └────────────────────────────────────────┘   │
│                                             │
│  ┌─ 下载区域 ──────────────────────────┐   │
│  │  📥 下载设计书 (.docx)         │   │
│  │  📥 下载QA报告 (.json)      │   │
│  │  📥 下载影响调查书 (.json)     │   │
│  └────────────────────────────────────────┘   │
│                                             │
│  [修正后重新生成]  [进行新生成]               │
└─────────────────────────────────────────────┘

8.4 技术设计

8.4.1 任务管理

TaskQueue(抽象接口,v1 仅 PersistentTaskQueueRedis/Valkey 为 v2 预留,Scope 缩减裁定)
  ├── task:generate-chapter-1
  │     status: completed
  │     result: {chapter: "功能一览", html: "...", time_ms: 23000}
  │
  ├── task:generate-chapter-2
  │     status: running
  │     started_at: 2026-07-21T12:01:00Z
  │
  └── task:generate-chapter-3
        status: pending

8.4.2 会话管理(SQLite

会话表设计:

CREATE TABLE sessions (
    id          TEXT PRIMARY KEY,
    user_id     TEXT NOT NULL,
    created_at  DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at  DATETIME,
    status      TEXT,
    current_step TEXT,
    metadata    JSON
);

CREATE TABLE session_snapshots (
    id          INTEGER PRIMARY KEY AUTOINCREMENT,
    session_id  TEXT NOT NULL REFERENCES sessions(id),
    step        TEXT NOT NULL,
    data        BLOB,
    version     INTEGER DEFAULT 1,
    created_at  DATETIME DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE session_files (
    id          INTEGER PRIMARY KEY AUTOINCREMENT,
    session_id  TEXT NOT NULL REFERENCES sessions(id),
    file_type   TEXT NOT NULL,
    file_name   TEXT NOT NULL,
    file_path   TEXT NOT NULL,
    file_size   INTEGER,
    mime_type   TEXT,
    uploaded_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

为什么用 SQLite

  • 单一文件,无需额外安装
  • 通过 SQL 查询即可轻松搜索会话
  • ACID 事务保证数据一致性
  • 进程重启后数据仍保留
  • 迁移到 PostgreSQL 也容易(表定义兼容性高)

8.4.3 多用户

工作区结构:
  /data/users/{user_id}/
  ├── uploads/           # 用户上传的文件
  │   ├── session_001/
  │   │   ├── requirements.xlsx
  │   │   └── template.docx
  │   └── session_002/
  ├── outputs/           # 生成的设计书
  │   ├── session_001.docx
  │   └── session_002.docx
  └── config/

共享数据(所有用户通用):
  /data/shared/
  ├── rules-handbook/    # 规则手册(所有用户通用)
  │   ├── v1/
  │   └── v2/            # 规则更新版本
  └── templates/         # 模板(所有用户通用)

8.4.4 斜杠命令

/upload     → 聚焦到文件上传区域
/probe      → 跳转到解析结果画面
/impact     → 跳转到影响调查画面
/generate   → 跳转到生成执行画面
/result     → 跳转到结果画面
/history    → 跳转到历史会话页
/settings   → 跳转到设置画面
/status     → 显示当前生成任务的状态
/cancel     → 取消当前生成
/help       → 显示帮助

8.5 异常处理UX

生成出错时

DB设计 生成过程中发生错误
┌─────────────────────────────────────────┐
│  ⚠ DB设计章生成时发生错误                    │
│  错误详情: LLM API调用失败    │
│  错误码: LLM_TIMEOUT                 │
│                                           │
│  [重试]  [跳过并继续]  [中断]     │
└─────────────────────────────────────────┘

会话恢复

浏览器关闭后再次打开时:

「要恢复上次的会话吗?」
上次的状态: Step 3 (影响调查确认)
 ・解析结果: ✅ 完成
 ・影响调查: ✅ 完成(以上述v2确认)
 ・Writer: 未开始

[恢复并继续]  [开始新会话]

9. 数据模型与 Provenance 层

9.1 核心概念

每个数据元素携带 Provenance(来源信息):
  Excel哪个文件 → 哪个Sheet → 哪行哪列 → 哪个字段

9.2 Citation URI 格式

格式: file.xlsx#SheetName!ColumnRow
例:   "要件定義.xlsx#機能一覧!C3"

T12 机制化(OV3URI 的解析/存在性验证已落地为 src/genesis/parsers/resolver.py

  • parse_source_uri(uri):解析为 SourceRef(格式非法 → URIError
  • provenance_to_uri(prov):从 Provenance 还原 URI(与 build 互逆)
  • resolve_source_uri(uri, source):在 StructuredSource 内定位真实单元格
  • validate_source_uris(uris, source) → ValidationResult(resolved, unresolved)

该机制支撑 design.md §6.8 第五步「source_uris 存在性校验」——QA 校验时 所有引用的 URI 必须能在输入源中定位,否则落入 unresolved(防 QA#8 编造 URI 作弊)。

9.3 Provenance Chain

记录「该信息如何被加工」:
  [
    {"step": "raw", "source_uri": "...", "content": "原始值"},
    {"step": "llm_extracted", "model": "deepseek-chat", "prompt_version": "v2"},
    {"step": "user_corrected", "user": "田中", "date": "2026-07-21"}
  ]

9.4 完整数据模型定义

本节为编码所需的字段级完整定义,是阶段1.2data_models.py)的直接实现依据。凡 §3.8 引用但未展开的类型,均在此定义。

9.4.1 枚举与基础类型

from enum import Enum
from typing import Any, Optional
from dataclasses import dataclass, field

class SheetType(Enum):
    """Excel Sheet 的类型(Parser SheetDetector 判定结果)"""
    FUNCTION  = "FUNCTION"   # 功能一览
    SCREEN    = "SCREEN"     # 画面一览
    REPORT    = "REPORT"     # 账票一览
    DATABASE  = "DATABASE"   # DB 定义
    INTERFACE = "INTERFACE"  # IF 定义
    BATCH     = "BATCH"      # 批处理一览
    MASTER    = "MASTER"     # 主数据定义
    GENERIC   = "GENERIC"    # 无法归类

class ElementType(Enum):
    """Impact Agent 抽取的构成要素类型"""
    FUNCTION = "機能"    # 功能
    SCREEN   = "画面"    # 画面
    REPORT   = "帳票"    # 账票
    DB       = "DB"      # 数据表
    IF       = "IF"      # 接口
    BATCH    = "バッチ"  # 批处理

class RelationType(Enum):
    """关联类型(Impact Agent 推理结果)"""
    USE      = "利用"    # 功能利用画面/账票
    REFER    = "参照"    # 读取 DB/IF 数据
    UPDATE   = "更新"    # 写入 DB/IF 数据
    OUTPUT   = "输出"    # 生成账票
    INPUT    = "输入"    # 画面接受输入传给功能
    DEPEND   = "依赖"    # 依赖其他功能/模块

class Confidence(Enum):
    """置信度等级"""
    HIGH   = "high"
    MEDIUM = "medium"
    LOW    = "low"

class ExtractionMethod(Enum):
    """Excel 表的抽取方式"""
    OPENPYXL          = "openpyxl"            # 结构化表格解析
    LLM_FROM_FREE_TEXT = "llm_from_free_text"  # 自由记述 → LLM 结构化

9.4.2 Parser 相关类型补全

@dataclass
class RuleDocument:
    """规则文档(Parser 解析后传给 RAG 的中间形态)"""
    file_name: str              # 源文件名
    category: str               # "write" | "design" | "ref"(写入规则/设计规则/参考文档)
    markdown_content: str       # 规则文档的 Markdown 化文本
    source_path: str            # 源文件路径
    file_type: str              # "word" | "excel" | "ppt"
    hash: str                   # 内容 hash(版本管理用,RAG 层 §5)

@dataclass
class ImageAnalysis:
    """图片/图形的分析结果(Parser 输出,供 Writer 参考)。

    区分 ImageDescription(§9.4.3):
      - ImageDescription = ImageAnalyzer 的**原始识别输出**(仅 image_ref/description/confidence/model
      - ImageAnalysis    = Parser 在原始输出基础上**组装**,追加 sheet_name/anchor_cell/nearby_text/
                            source_uri/status 等解析上下文(写入 StructuredSource.image_analyses
    调用方(Writer/Impact)只消费 ImageAnalysis,不应直接消费 ImageDescription。
    """
    image_ref: str              # 图片引用(ZIP 内路径 或 提取后的文件路径)
    description: str            # Vision LLM 的识别描述
    confidence: float           # 0.0 ~ 1.0
    source_uri: str             # 来源(如 file.xlsx#Sheet1!A1 附近图片)
    sheet_name: str             # 所属 Sheet
    anchor_cell: str            # 锚点单元格坐标
    status: str                 # "recognized" | "recorded_only" | "failed"
    nearby_text: str = ""       # 图片附近文本(上下文)

# ExistingSystemInfo 的 4 个子类型
@dataclass
class ControllerInfo:
    name: str
    class_name: str
    path: str                   # 类所在文件路径
    base_path: str              # @RequestMapping 等类级路径
    endpoints: list[str]        # 端点列表(如 ["GET /api/users"]
    source_uri: str             # 溯源(file#类名!行号)

@dataclass
class ServiceInfo:
    name: str
    class_name: str
    path: str
    methods: list[str]          # 公开方法名
    source_uri: str

@dataclass
class EntityInfo:
    name: str
    class_name: str
    path: str
    table_name: str | None      # 对应 DB 表名(有 @Table 注解时)
    fields: list[str]           # 字段名列表
    source_uri: str

@dataclass
class EndpointInfo:
    method: str                 # GET/POST/PUT/DELETE
    path: str
    controller: str | None      # 所属 Controller
    description: str            # 功能描述
    source_uri: str

9.4.3 共通工具层输出类型补全

@dataclass
class UnifiedDocument:
    """FileReader 的统一输出(多格式归一化)"""
    file_name: str
    file_type: str              # "excel" | "word" | "ppt" | "text"
    source_path: str
    content_type: str           # 按格式的内容载体类型
    # 按 file_type 填充不同字段(未命中的为 None)
    tables: list[list[list[Any]]] | None = None   # excel: [sheet][row][col]
    sheet_names: list[str] | None = None          # excel
    paragraphs: list[dict] | None = None          # word: [{style, text}]
    slides: list[dict] | None = None              # ppt: [{title, body, notes}]
    text: str | None = None                       # text / 兜底
    encoding: str | None = None                   # 检测到的编码(chardet

@dataclass
class CodeStructure:
    """CodeParser 的解析输出"""
    root_path: str
    language: str               # "java" | "python" | "csharp" | ...
    modules: list[dict]         # 模块/包列表 [{name, path}]
    classes: list[dict]         # 类列表 [{name, kind, path}]
    controllers: list[ControllerInfo]
    services: list[ServiceInfo]
    entities: list[EntityInfo]
    endpoints: list[EndpointInfo]
    raw_imports: list[dict]     # import 关系(依赖分析用)[{from, to}]

@dataclass
class ImageDescription:
    """ImageAnalyzer 的原始识别输出(工具层)。

    区分 ImageAnalysis(§9.2):Parser 会将本类型**组装**为带 Sheet 锚点与状态的
    ImageAnalysis 后写入 StructuredSource;业务层不应直接消费本类型。
    """
    image_ref: str
    description: str
    objects: list[str]          # 识别出的对象标签
    ocr_text: str | None        # OCR 文本(若有)
    confidence: float
    model: str                  # 使用的 Vision 模型

9.4.4 运行时层类型汇总(引用关系)

运行时层(docs/agent-runtime-design.md)已定义的类型,此处列出与业务数据模型的衔接点,不重复定义:

类型 定义位置 与业务模型的衔接
ChatResult / StructuredResult / TokenUsage agent-runtime §2.2 InferenceEngine 输出,各 Agent 消费
Prompt / PromptRegistry agent-runtime §2.7 Prompt 模板库
ArtifactRef / MemoryService agent-runtime §4.4 StructuredSource/ImpactReport 存取的引用
ToolResult / ToolExecutor agent-runtime §5.3 UnifiedDocument/CodeStructure/ImageDescription 经此返回
LLMCallEvent / ToolCallEvent agent-runtime §6.1 可观测性事件
VectorStoreAdapter / VectorHit rag-layer §9.2 RAG 存储适配

9.4.5 数据模型引用关系图

生产方                                    消费方
────────                                    ────────
FileReader ── UnifiedDocument ──► ParserExcel/Word/PPT 解析)
CodeParser ── CodeStructure ────► ParserExistingSystemExplorer
ImageAnalyzer ── ImageDescription ► ParserImageAnalysis 组装)
                                         │
Parser ── StructuredSource ─────────────► Impact(要素抽取)
   └─ 内含: ExcelTable / ParsedTemplate / RuleDocument /
             ImageAnalysis / ExistingSystemInfo / CellComment
                                         │
Impact ── ImpactReport(影响调查书 JSON)► Writer(章节生成)
                                         │
RAG ── RuleChunk ───────────────────────► Writer / Impact / QA(规则检索)
                                         │
Writer ── ContentBlockJSON 内容块)────► 渲染器(chapter_html / docx
                                          │
QA ── QAReport(校验结果 JSON)──────────► UI / 反馈 Writer

9.4.6 实现落地说明(P0-1 修复:前向引用与定义顺序)

§3 与 §9.4 的类型存在交叉引用(如 §3 的 ExcelTable.detected_type: SheetTypeCellValue.formatting: CellFormatting 等引用 §3 或 §9.4 中后置定义的类型)。实现时须遵守以下约定,避免类定义时的 NameError:

  1. 全部数据模型统一放置于 src/genesis/data_models.py(或按包拆分但共用同一模块边界),不散落各 Agent。
  2. 该文件(及引用数据模型的任何文件)首行启用 from __future__ import annotations,使注解惰性求值,类定义顺序与引用顺序无关。
  3. 枚举(SheetType/ElementType/RelationType/Confidence/ExtractionMethod)与 EventType 等,建议在文件后部集中定义;dataclass 内部可前向引用(依赖 future.annotations)。
  4. ExtractionMethod 的取值字符串("openpyxl" / "llm_from_free_text")用于 ExcelTable.extraction_method,与 settings 中 ExtractionMethod 枚举保持同一常量来源,避免魔法字符串。
# src/genesis/data_models.py(示意开头)
from __future__ import annotations
from enum import Enum
from dataclasses import dataclass, field
from typing import Any, Optional

10. 异常处理策略

10.1 基本方针

参考 OpenCode / Claude Code 模式:

  • 出错时显示错误信息
  • 用户可选择「重做」「继续」「中断」
  • 已处理的 Step 保留结果,恢复时从中途继续

10.2 具体模式

Step 1(要素抽取)中 LLM 调用失败:
  画面: 「要素抽取时发生错误」
  选择: [重试] [取消]

Step 3(关联推理)中部分功能推理失败:
  画面: 「F005, F008 的推理失败。其余已完成」
  选择: [继续(跳过对应功能)] [重试] [中断]

10.3 恢复保证

  • 各 Step 完成时保存中间结果
  • 中断后,以相同会话 ID 恢复 → 从已完成的 Step 继续
  • 未完成的 Step 从头执行

11. 通信语言与文档规范

11.1 通信语言

本项目的所有 AI 交流、文档、注释、代码中的文本,统一使用中文。不得使用日文、英文或其他语言进行交流(专有名词、技术术语、代码关键字等不可避免的情况除外)。

11.2 文档保存位置

所有设计文档、方案、报告等内容,必须保存到 docs/ 目录下。

11.3 信息安全

  • 不得将客户数据、公司信息上传至外部公开仓库
  • API Key 配置在环境变量或配置文件中,不得硬编码在源码
  • 确认所有依赖的许可证类型,禁止使用盗版软件

12. Phase 5Writer / QA 子系统

本章记录在 phase5/writer-qa 分支上落地的「Writer / QA 子系统」实现,作为设计 §6(Writer Agent 详细设计)与 §7(QA Agent 详细设计)的工程落地补充。实现严格遵循设计基线,并诚实标注了范围边界与推后项。

12.1 目标与范围

目标:打通「结构化源 → 单章内容生成 → 渲染 → 注入 Word 模板 → QA 校验 → 闭环仅重失败章」的最小可用链路。

范围内

  • 单章内容生成(WriterAgent 调用 InferenceEngine 产出 ChapterContent)。
  • 内容块渲染(render_chapter_blocksChapterContentBlock 序列)。
  • 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)  逐章串行
      ▼
ChapterContentblocks: list[ContentBlock] + source_uris
      │  render_chapter_blocks(content)
      ▼
list[Block]DocxInjector.Blockparagraph/heading/table/list/note
      │  DocxInjector(template_path).inject(sections, meta)
      ▼
Document(注入后 Word 文档)
      │  QALoopDEFAULT_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)与 .statusok / parse_error / failed)。调用时必须关键字传参。
  3. RagService.retrieve_*同步方法(非 async)。调用方在同步编排链路中直接调用即可,无需 await
  4. map_template 消费真实的 ParsedTemplate.sections(元素类型为 ChapterMarker,含 type / name / level)。映射按文档顺序:遇到 heading 起一章;其后的 section:<id> 占位符归属该章 → chapter_id = idsection_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 路径。