1786 lines
76 KiB
Markdown
1786 lines
76 KiB
Markdown
# 概要设计书自动生成 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 开发范式
|
||
|
||
本项目的开发遵循 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化
|
||
│
|
||
├── 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.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": ["記入規則.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)
|
||
|
||
```
|
||
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 十项校验清单
|
||
|
||
| # | 校验项 | 维度 | 方法 | 判定标准 |
|
||
|---|--------|------|------|---------|
|
||
| 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_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:<id>` 占位符归属该章 → `chapter_id = id`、`section_placeholder = "section:<id>"`。
|
||
5. **`ChapterScorer.score(chapters: list[ChapterArtifact], source: StructuredSource)`**:QA 层需要 `ChapterContent → ChapterArtifact` 适配器(由 `ChapterContent.blocks` 拼接得到 `text`,并从各 block 收集 `source_uris`);设计 §7.5 的 `ChapterArtifact` 并非直接由 Writer 产出,需经适配。
|
||
6. **真实 `DocxInjector.Block`** 支持 `paragraph` / `heading` / `table`;`list` / `note` 当前按 `paragraph` 降级渲染(原型范围,无列表/提示框样式)。表格注入会渲染 `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` 路径。
|