# 概要设计书自动生成 Agent 设计文档
> 版本: v1.0 | 日期: 2026-07-21 | 状态: 初版
---
## 目录
1. [项目概述](#1-项目概述)
2. [整体架构](#2-整体架构)
3. [Parser Agent 详细设计](#3-parser-agent-详细设计)
4. [Impact Agent 详细设计](#4-impact-agent-详细设计)
5. [RAG 基础设施层](#5-rag-基础设施层)
6. [Writer Agent 详细设计](#6-writer-agent-详细设计)
7. [QA Agent 详细设计](#7-qa-agent-详细设计)
8. [Web UI 设计](#8-web-ui-设计)
9. [数据模型与 Provenance 层](#9-数据模型与-provenance-层)
10. [异常处理策略](#10-异常处理策略)
11. [通信语言与文档规范](#11-通信语言与文档规范)
12. [Phase 5:Writer / QA 子系统](#12-phase-5writer--qa-子系统)
---
## 1. 项目概述
### 1.1 目标
开发一个 Web 服务形态的 Agent,能够读取以下输入资料:
- Excel 版要件定义(核心数据源)
- Word 版概要设计模板(输出章结构与样式)
- Word 版概要设计做成说明书(各章作成指引)
- Word 版记入规则 / 图表规则等规则文档
- (可选) 现有系统的源代码与设计书(追加/改修场景)
自动生成符合规范的 **Word 版概要设计书**。
### 1.2 成功标准
1. **格式精确** — 输出文档的样式、字体、表格格式严格符合模板
2. **内容准确** — 生成的所有信息必须来源于要件定义,不能捏造
3. **可追溯** — 每一段生成内容都能追溯到原始数据来源(单元格/行/列)
### 1.3 开发范式
本项目的开发遵循 6 个步骤,对应 AI 使用日志的"范式步骤"列(评审时按 范式图 ↔ AI 日志 逐步骤对照验证):
```mermaid
flowchart LR
A[需求理解
分析大赛规则] --> B[架构设计
AI 生成方案 + 人工审核]
B --> C[Agent 实现
AI 编码实现各模块]
C --> D[测试验证
TDD 单元/集成测试]
D --> E[反馈迭代
基于测试结果修正]
E -. 未达标 .-> C
E -. 文档沉淀 .-> F[文档规范
设计文档/AI 日志同步]
F -. 新需求 .-> A
```
| 步骤 | 说明 |
|---|---|
| 需求理解 | 分析大赛规则,理解概要设计书生成需求 |
| 架构设计 | AI 生成方案,人工审核设计 |
| Agent 实现 | AI 编码实现各 Agent 模块(TDD RED→GREEN→REFACTOR) |
| 测试验证 | 单元测试与集成测试验证(覆盖率红线 99%) |
| 反馈迭代 | 基于测试结果反馈修正 |
| 文档规范 | 设计文档、`_AI_USAGE_LOG.md`、参赛成果物同步更新 |
> AI 使用日志"范式步骤"列取值与上表一致;历史日志中出现的「整体迭代」归一为「反馈迭代」。
> 每次 AI 修改代码后自动追加日志(规则写入 `AGENTS.md`,由 AI 自动执行)。
---
## 2. 整体架构
### 2.1 Agent 构成
系统由 4 个 Agent + 1 个基础设施层构成:
```
┌─────────────────────────────────────────────────────────────┐
│ Web UI (React) │
│ 上传资料 | 确认解析 | 确认影响调查 | 启动生成 | 预览结果 │
└──────────────────────┬──────────────────────────────────────┘
│ REST API
┌──────────────────────▼──────────────────────────────────────┐
│ Orchestrator (流程协调器) │
│ 职责: 编排整个流程、管理会话状态、处理异常、人工介入点 │
└────┬──────────┬──────────┬──────────┬───────────────────────┘
│ │ │ │
┌────▼───┐ ┌───▼────┐ ┌──▼────┐ ┌──▼──────────┐
│ Parser │ │ Impact │ │ Writer│ │ QA │
│ Agent │ │ Agent │ │ Agent │ │ Agent │
├────────┤ ├────────┤ ├───────┤ ├──────────────┤
│ 解析 │ │ 要素 │ │ 章节 │ │ 校验 │
│ 全部 │ │ 抽出 │ │ 生成 │ │ 格式/内容/ │
│ 输入 │ │ 关联 │ │ 模板 │ │ 可追溯性 │
│ 资料 │ │ 推論 │ │ 填充 │ │ │
└────────┘ └────────┘ └───────┘ └──────────────┘
│ │ │
└──────────┴─────────────────────┘
│
┌──────▼──────┐
│ RAG Layer │
│ (基础设施) │
│ 规则检索服务 │
└─────────────┘
```
#### Agent 架构图(感知-规划-行动-记忆,评审必检)
按评审要求的「感知-规划-行动-记忆」框架映射系统能力:
```mermaid
flowchart TB
subgraph 感知[感知 Perception]
P1[Parser Agent
Excel/docx/Java 解析]
P2[RAG 检索
规则文档切片/召回]
P3[Impact Agent
既有系统影响调查]
end
subgraph 规划[规划 Planning]
PL1[章节 ↔ 模板映射
template_mapper]
PL2[上下文装配
build_contexts]
PL3[章节级数据定向
CHAPTER_SHEET_TYPES]
end
subgraph 行动[行动 Action]
A1[Writer Agent
LLM 分章生成]
A2[语言一致性强制
language.py]
A3[Docx 注入
docx_injector]
end
subgraph 记忆[记忆 Memory]
M1[StructuredSource
结构化输入/Provenance]
M2[WriterState
章间引用]
M3[ImpactReport
影响调查书]
M4[会话存储
sqlite/快照]
end
感知 --> 规划 --> 行动 --> 记忆
记忆 -. 上下文回读 .-> 规划
记忆 -. 状态回读 .-> 行动
```
| 框架 | 系统能力 |
|---|---|
| 感知 | Parser Agent 解析输入、RAG 规则检索、Impact Agent 既有系统影响调查 |
| 规划 | 章节↔模板映射、上下文装配、章节级数据定向注入 |
| 行动 | Writer Agent 分章生成 + 语言一致性强制 + docx 注入 |
| 记忆 | StructuredSource / WriterState / ImpactReport / 会话存储 |
### 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化
│
├── PPTXParser(PPT规则文档解析)
│ └── 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 类型自动识别
```python
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 合并单元格处理
```python
def forward_fill(rows, merged_cells):
"""
下行填充策略:
1. 识别合并单元格范围(r1, c1, r2, c2)
2. 遍历数据行,如果在合并范围内且为空值 → 填充主单元格值
3. 记录 Provenance(来自合并单元格的主位置)
"""
```
#### 3.5.4 取消线处理
```python
if cell.font.strike:
row_meta["excluded"] = True
row_meta["exclude_reason"] = "strikethrough"
# 值保留但不参与后续处理
```
#### 3.5.5 批注处理
```python
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 图像/图形处理
```python
1. 从 ZIP 中提取全部图像(xl/media/)
2. 定位图像锚点位置(单元格位置)
3. 图像数 < 10 张 → 通过 Vision LLM 识别
4. 图像数 >= 10 张 → 仅记录存在
5. 图形(自动形状)→ 提取文本
```
#### 3.5.7 公式单元格处理
```python
# 同时保留公式字符串与计算值
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
```python
@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 → TB001(SELECT) |
| 更新 | 功能/画面写入 DB/IF 数据 | F001 → TB001(INSERT/UPDATE) |
| 输出 | 功能生成账票 | F001 → RP001 |
| 输入 | 画面接受输入并传给功能 | SC001 → F001 |
| 依赖 | 功能依赖其他功能/模块 | F001 → AUTH001(必须认证) |
#### 4.3.2 置信度定义
| 置信度 | 条件 | 证据要求 | 用户确认 |
|-------|------|---------|------------|
| high | 有明确记载(关联画面=SC001 等) | 证据明确 | 默认折叠显示 |
| medium | 关键词一致・ID 名一致 | 证据可引用 | 展开显示 |
| low | 仅根据名称相似性推理 | 证据弱 | 强调显示 |
#### 4.3.3 交叉检查
```python
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 矛盾检测
```python
def check_consistency(relations):
"""
- 循环引用的检测(A→B→C→A)
- 类型不一致(功能→功能的「利用」)
- 孤立要素(不与任何要素关联)
"""
```
### 4.4 影响调查书的结构(完整版)
```json
{
"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](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 关键设计决策(概要)
| 设计点 | 决策 |
|--------|------|
| 向量数据库 | Chroma(v1 唯一;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.2.1 输出语言控制(output_language,2026-08 新增)
- 参数:`--output-language {auto,zh,ja}`(config `WriterConfig.output_language`,默认 `auto`)
- 贯通链路:`run_trial → orchestrator.generate → build_contexts → GenerationContext.output_language
→ to_vars()["language_instruction"]`(prompt 的【语言约束】段引用该变量)
- **auto 推导规则**(`src/genesis/writer/language.py::resolve_expected_language`,单一事实来源):
1. 显式 zh/ja → 直接采用
2. 标题含日文假名 → ja(纯汉字标题不可靠,跳过)
3. 规则文档(write_rules/design_rules,RAG 自作成说明书/记入规则)主导脚本
4. 均无法推导 → ""(unverifiable,不强制)
- **生成期强制**:`WriterAgent.generate_chapter` 用 `find_language_violations` 校验正文块
(paragraph/note/list;heading/table 不检——标题跟随模板、表格照抄源),违规按生成失败重试
(max_retries 默认 2),耗尽抛 `WriterGenerationError` 硬失败
- 影响调查标签按 output_language 本地化(`_format_impact`):zh=新建/变更/删除/警告,ja=新規/変更/削除/警告
- 中文输出需配合中文模板 `sample/template_design_zh.docx`(日文模板镜像,锚点 id 原样保留)
### 6.3 模板注入策略
- 章位置识别:模板中的 Heading 层级 / 书签 / 占位符
- 内容注入:python-docx / docxtpl
- 样式保持:继承模板定义样式,LLM 只生成内容不控制格式
### 6.4 LLM 输出格式(JSON 内容块)
**决策**:LLM 不直接输出 HTML 或 Word 格式,而是输出**结构化 JSON 内容块**(ContentBlock)。渲染器统一将内容块转换为 `chapter_html`(前端预览)与 docx(最终下载)。
```json
{
"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": ["rules_entry_ja.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:` 用于章节;其余为元信息字段
- 模板中未找到占位符时,回退到「按 Heading 层级定位」(§6.5 规则),在对应 Heading 后插入
- 渲染器输出后做一次「占位符残留检查」:若存在未替换的 `{{...}}` 视为渲染失败,报错
### 6.7 渲染链路(ContentBlock → chapter_html / docx)
```
ContentBlock(JSON,LLM 输出)
│
▼
统一渲染器(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 注入关键路径,规避「格式精度排末尾导致返工」的风险。
**模板样式映射表**(渲染器配置):
```yaml
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 校验清单(11 项)
| # | 校验项 | 维度 | 方法 | 判定标准 |
|---|--------|------|------|---------|
| 1 | 格式一致性 | 格式 | 与模板逐项对比(字号/字体/字色/行距/段距/表样式)| 与模板定义一致 |
| 2 | 内容准确性 | 内容 | 与要件定义源数据对比 | 所有信息可追溯到源,无缺失 |
| 3 | 幻觉检测 | 内容 | LLM 语义校验「是否写了源数据中没有的内容」| 无凭空生成 |
| 4 | 关联一致性 | 内容 | 与影响调查书对比 | 生成的关联与 ImpactReport 一致 |
| 5 | 写入规则遵守 | 规则 | via RAG 检索写入规则并对比 | 符合记入规则/图表规则 |
| 6 | 设计规则遵守 | 规则 | via RAG 检索设计规则并对比 | 符合设计约束 |
| 7 | 矛盾检测 | 规则 | 全文扫描自相矛盾的描述 | 无矛盾表述 |
| 8 | 可追溯性 | 可追溯 | 每段内容检查 source_uri 标注 | 每个断言有来源 |
| 9 | 术语一致性 | 规则 | 与统一术语表对比 | 无术语混用 |
| 10 | 章节完整性 | 内容 | 与模板章结构对比 | 所有章节已生成且无缺章 |
| 11 | 语言一致性 | 语言 | 脚本检测正文与期望语言是否一致(`language_consistency`,确定性) | 期望语言可推导时正文不混入他语言;不可推导记满分(unverifiable) |
> 第 11 项为 2026-08 新增(输出语言一致性保障)。期望语言由显式 `--output-language zh/ja` 或 auto 推导
> (标题假名 → 规则文档主导脚本)得到,单一事实来源为 `src/genesis/writer/language.py`;
> 表格/标题不检(表格照抄源、标题跟随模板);Writer 生成阶段同源强制(违规重试、耗尽硬失败)。
### 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 加载回归基线,`sample/` 真实脱敏样本作 `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_instruction`(api-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 仅 PersistentTaskQueue;Redis/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)
**会话表设计:**
```sql
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 机制化(OV3)**:URI 的解析/存在性验证已落地为 `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.2(`data_models.py`)的直接实现依据。凡 `§3.8` 引用但未展开的类型,均在此定义。
#### 9.4.1 枚举与基础类型
```python
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 相关类型补全
```python
@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 共通工具层输出类型补全
```python
@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 ──► Parser(Excel/Word/PPT 解析)
CodeParser ── CodeStructure ────► Parser(ExistingSystemExplorer)
ImageAnalyzer ── ImageDescription ► Parser(ImageAnalysis 组装)
│
Parser ── StructuredSource ─────────────► Impact(要素抽取)
└─ 内含: ExcelTable / ParsedTemplate / RuleDocument /
ImageAnalysis / ExistingSystemInfo / CellComment
│
Impact ── ImpactReport(影响调查书 JSON)► Writer(章节生成)
│
RAG ── RuleChunk ───────────────────────► Writer / Impact / QA(规则检索)
│
Writer ── ContentBlock(JSON 内容块)────► 渲染器(chapter_html / docx)
│
QA ── QAReport(校验结果 JSON)──────────► UI / 反馈 Writer
```
#### 9.4.6 实现落地说明(P0-1 修复:前向引用与定义顺序)
§3 与 §9.4 的类型存在**交叉引用**(如 §3 的 `ExcelTable.detected_type: SheetType`、`CellValue.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` 枚举保持同一常量来源,避免魔法字符串。
```python
# 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 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)` 约束)。
> **确定性维度生效说明(Phase 5 现状)**:章节级「章节完整性(`chapter_completeness`)」维度当前因 `template_sections_expected` 恒为空而实质为空操作(恒满分),生效的确定性维度为**可追溯性(`traceability`)+ 占位符残留(`placeholder_residue`)**。待模板期望章节集合回填后,`chapter_completeness` 方才参与校验。
**范围外(诚实标注)**:
- **语义 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:` 占位符归属该章 → `chapter_id = id`、`section_placeholder = "section:"`。
5. **`ChapterScorer.score(chapters: list[ChapterArtifact], source: StructuredSource)`**:QA 层需要 `ChapterContent → ChapterArtifact` 适配器(由 `ChapterContent.blocks` 拼接得到 `text`,并从各 block 收集 `source_uris`);设计 §7.5 的 `ChapterArtifact` 并非直接由 Writer 产出,需经适配。
6. **真实 `DocxInjector.Block`** 支持 `paragraph` / `heading` / `table`;`list` / `note` 当前按 `paragraph` 降级渲染(原型范围,无列表/提示框样式)。表格注入会渲染 `caption` 段落(caption 非空时在其上方/下方生成说明段落),非空 caption 不应被丢弃。
### 12.4 垂直切片状态
**FakeLLM 模式已打通(可回归)**:
- 运行 `python scripts/run_phase5_slice.py --fake`,使用 `FakeLLMClient` 驱动整条链路,产出 `sample/phase5-slice/output.docx`。
- 该切片覆盖:build_contexts → 逐章生成 → 渲染 → 注入 → QA 闭环(仅重失败章),并附带 `QAReport`。
**真实 LLM 生成 + 人工质量门禁(待人工执行项,P5-T10 推后)**:
- 真实推理接入(DeepSeek / Qwen 等)与端到端人工质量门禁(内容准确性 / 格式精度 / 规则遵守的人工判读)不在本自动实现范围内,标记为推后项。
- 真实 LLM 接入点已预留(`InferenceEngine` 默认实例 + `PromptRegistry` 注入),人工执行时仅需提供可用模型配置与 `scripts/run_phase5_slice.py` 的非 `--fake` 路径。
### 12.5 Web 服务化(2026-08,参赛成果物 03 交互界面)
新增 `src/genesis/server/`(FastAPI + SQLite + 内嵌零构建前端):
- `store.py` — 会话持久化(SessionStore,SQLite,sessions 表 data JSON)
- `service.py` — 会话化服务层(GenesisService:上传 → 解析 → 确认 → 影响 → 确认 → 生成 → QA)
- `app.py` — REST 端点(api-design §2 核心子集);`scripts/serve.py` 启动;`--fake` 离线引擎
- 前端 `static/index.html` 内嵌单页(零构建,无 node_modules 依赖,符合提交规范 §6 红线)
- **与 api-design 的偏差(诚实标注)**:v1 采用**进程内同步执行**(非"异步启动+轮询");
既有系统以 zip 上传;WebSocket 事件通道未实现(v1 范围外)。样本规模小,同步可接受。
- 测试:`tests/test_server_store.py` / `test_server_service.py` / `test_server_api.py`(TestClient 全链路)
### 12.6 聊天式交互改造(2026-08,Web UI 升级)
将 Web 前端由分步表单页(`static/index.html`)升级为 **DeepSeek 式聊天页**(`static/chat.html`):
用户用自然语言下达指令,后台 `ChatAgent` 自动驱动「解析 →(影响调查)→ 生成 → QA」整条工作流。
新增模块:
- `src/genesis/chat/intent.py` — 意图识别:`INTENT_SCHEMA`(动作 = parse/impact/generate/qa/status/confirm/reject/unknown)
与 `parse_intent_fake`(规则兜底)/ `parse_intent_llm`(真实模式,引擎 `chat_structured` 结构化抽取)
- `src/genesis/chat/agent.py` — `ChatAgent.handle_message`:
- 处于 `awaiting_impact_confirm` 时,将用户回复作为**确认节点**(确认/打回)处理
- 否则解析意图并分发;`generate` 自动推进前置步骤(解析→确认→影响→反问),影响完成先反问、记住 pending 意图
- 错误分支(解析/生成/QA/影响确认失败)均以友好回复兜底,绝不抛出未捕获异常
- `store.py` 扩展:会话增 `pending_intent` 字段;新增 `chat_messages` 表与 `add_message`/`list_messages`
- `app.py` 新增 `POST /api/chat/{sid}/messages`、`GET /api/chat/{sid}/messages`;`GET /` 改为返回聊天页
- 测试:`tests/test_chat_intent.py` / `tests/test_chat_agent.py` / `tests/test_server_chat_api.py`(TestClient 全链路)
- 真实黑盒冒烟建议:用 `python scripts/serve.py` 部署后,从聊天页用中文下达「上传了文件,生成概要设计书」并确认影响即可走通全程。
### 12.7 项目级配置与既有设计文档纳入影响调查(2026-08,Web UI 升级二)
在 12.6 聊天页基础上,进一步降低每次生成的配置负担,并把既有设计文档作为影响调查的辅助证据来源。
#### 12.7.1 会话命名与历史
- 会话 `SessionRecord` 新增 `name` / `project` 字段(默认 `name="新会话"`);`store.create_session(user_id, name, project)` 支持传入。
- 上传**要件定义 xlsx** 后,若会话名仍为默认「新会话」,自动取文件名(去扩展名)作为会话名,便于在历史列表中区分。
- 前端 `chat.html` 左侧新增**会话历史侧边栏**:`GET /api/sessions` 返回 `name`/`project`,点击可加载历史会话(`GET /api/chat/{sid}/messages`)并恢复消息;当前会话 ID 存入 `localStorage`,刷新后自动恢复。
- 顶部只显示 **会话名**(不显示会话 ID)。
#### 12.7.2 以项目为单位的配置(用户只传要件定义)
- 新增 `ProjectsStore`(复用 `sessions.db`):`projects` 表,字段 `name`(主键)/ `display_name` / `template` / `write_instruction` / `rules[]` / `existing_system_code_dir` / `design_docs_dir`。
- `ProjectConfigError`:路径不存在 / 非 `.docx` / 非目录 时抛出(对应 `api-design` 400 `PROJECT_CONFIG_INVALID`)。
- 校验规则:`_validate_project_paths` 对模板/做成说明书/规则/代码库目录/设计文档目录做存在性与类型校验;`rules` 与 `design_docs_dir` 为目录时枚举其中的 `.docx`。
- 配置 CRUD 端点:`POST /api/projects`(创建/更新,同名覆盖)、`GET /api/projects`、`GET /api/projects/{name}`、`DELETE /api/projects/{name}`。
- 会话绑定项目:`POST /api/sessions` 收 `project` 字段;`service.has_file(rec, ftype)` 与 `service._eff_path(rec, ftype)` 在用户未上传时回退到项目配置(同类型用户文件优先)。
- `_rebuild_source` 合并:模板/做成说明书/规则 = 用户上传优先,否则取项目配置(rules 两者追加);既有系统代码库与设计文档目录取项目配置。
- 前端交互:侧边栏「项目配置」面板可新建/选择项目;选中项目后新建会话即绑定,**上传区仅显示「要件定义 xlsx(必需)」**(其余由项目提供),并给出提示。
#### 12.7.3 既有设计文档纳入影响调查(确定性交叉引用)
- `StructuredSource` 新增 `design_docs: list[RuleDocument]`(`category="design"`,区别于写入规则);`SourceParser.parse` 新增 `design_doc_paths`,解析为 `RuleDocument`。
- `ImpactReport` 新增 `design_references: list[DesignReference]`(`doc_name` / `identifier` / `snippet`)。
- `ImpactAgent._cross_ref_design_docs`:以既有系统解析出的标识符(类/方法/模块名,小写键)为锚,在 `design_docs` 的 `markdown_content` 中做**大小写不敏感**子串检索;命中则记录原始大小写 token 与前后文片段。**无 LLM 参与**,纯字符串匹配。
- 序列化:`impact_report_to_dict` 输出包含 `design_references`;影响调查书下载 JSON 同步包含。
- 说明:设计文档作为 Type A 辅助证据,**不进入写入规则**,不引入额外 LLM 调用,保持影响调查零幻觉目标。
### 12.8 WebSocket 实时进度流(2026-08-29,分支 feat/websocket-progress)
新增 `ProgressHub` 进程内发布/订阅单例 + `/api/sessions/{sid}/ws` 端点 + `chat_ws.js` 前端实时渲染;进度/错误事件实时推送,既有 `role='progress'/'error'` 持久化兜底保留(重载仍可见)。**单进程假设**:hub 为进程内单例,多 worker 部署下跨进程不互通(后续可迭代 Redis 总线)。
## RAG 影响调查接入说明(Task 5,2026-08-29)
影响调查 Agent 接入可选 RAG 检索能力(既有系统源码 -> 检索上下文注入 LLM 影响分析 prompt),详见 `src/genesis/rag/` 与 `src/genesis/impact/impact_agent.py` 的 `run_impact`。
- **scope = session_id**:每个会话的既有系统源码独立索引到 `RagStore` 的同一 scope,互不串扰。
- **上传即索引(D1)**:`GenesisService.upload_file` 在 `file_type == "existing_system"` 且 `self.rag is not None` 时,解压完成后立即调用 `self.rag.index_dir(session_id, path)`;索引异常仅记录日志(`_LOGGER.warning`)不阻断上传。
- **`use_rag` 默认关闭**:`GenesisService` 构造参数 `use_rag` 默认 `False`,`rag=None` 表示不启用(向后兼容)。`run_impact(session_id, use_rag=None)` 中 `eff = self.use_rag if use_rag is None else use_rag`;仅当 `eff 且 self.rag is not None` 时走 LLM+RAG 路径,否则走原确定性 `ImpactAgent().run(...)` 路径(行为不变)。
- **异步链路**:`run_impact` 为 `async def`,RAG 路径 `await ImpactAgent(engine=..., rag=..., use_rag=True).run_impact(...)`;`app.start_impact` 端点改为 `async def` 并 `await service.run_impact(sid, use_rag=use_rag)`;`chat/agent.py` 调用处以 `asyncio.run(...)` 包裹以兼容同步消息处理。
- **线程安全(D2)**:`RagStore` 构造使用 `sqlite3.connect(db_path, check_same_thread=False)` 并加 `threading.Lock`,读写均加锁串行化,适配 Web 服务端 worker 线程复用连接。
- **向后兼容**:`use_rag=False` 时 prompt 不含 RAG 小节标题(`_RAG_CONTEXT_TITLE`),影响报告为确定性 `impact-report.json`,不调用 LLM。