docs: 更新设计文档以匹配Black-white-box-Merge分支最新代码
- 00-overview.md: 重写架构图(移除web/入口)、更新模块清单、更新API签名 - 05-agents-llm.md: 修复章节编号(Section 7/8子节编号错误) - 08-data-flow.md: 修复Mermaid代码块格式(单反引号→三反引号) - 09-run-pipeline.md: 新增run.py全流程入口+black-box-data-create详细设计 - DESIGN.md: 重写为竞赛要求格式(场景价值、范式图、Agent架构、工具清单) - README.md: 添加项目性质声明(新规)、团队分工、技术难度评估
This commit is contained in:
+137
-106
@@ -1,6 +1,6 @@
|
||||
# V3系统总体设计
|
||||
|
||||
> 版本: v1.0 | 日期: 2026-08-22
|
||||
> 版本: v2.0 | 日期: 2026-08-23
|
||||
> 本文档描述COBOL迁移验证平台V3的总体架构和模块设计。
|
||||
|
||||
---
|
||||
@@ -15,21 +15,23 @@ COBOL迁移验证平台V3是一个AI辅助的自动化测试工具,用于验
|
||||
|
||||
| 能力 | 说明 |
|
||||
|------|------|
|
||||
| COBOL源码解析 | 自动解析DATA DIVISION和PROCEDURE DIVISION |
|
||||
| 测试数据生成 | 基于分支覆盖的测试数据自动生成 |
|
||||
| COBOL源码解析 | 自动解析DATA DIVISION和PROCEDURE DIVISION(支持新旧双解析器) |
|
||||
| 测试数据生成 | 基于分支覆盖的测试数据自动生成(规则引擎 + LLM双模式) |
|
||||
| 双管道验证 | 支持非DB(flat file)和DB(SQLite)两种验证模式 |
|
||||
| 覆盖率分析 | 静态分支覆盖 + 动态gcov覆盖 |
|
||||
| AI辅助 | LLM驱动的程序分类和测试策略生成 |
|
||||
| 全流程入口 | `run.py` 一键执行白盒+黑盒全流程 |
|
||||
| 黑盒LLM生成 | `black-box-data-create` 基于设计书的LLM测试数据生成 |
|
||||
| 覆盖率分析 | 静态分支覆盖 + 动态gcov覆盖,生成HTML报告 |
|
||||
| AI辅助 | LLM驱动的程序分类、测试策略生成、诊断建议 |
|
||||
|
||||
### 1.3 技术栈
|
||||
|
||||
| 组件 | 技术 |
|
||||
|------|------|
|
||||
| 语言 | Python 3.12+ |
|
||||
| 解析器 | Lark (Earley parser) |
|
||||
| 解析器 | Lark (Earley parser) + 新fast parser (line-based state machine) |
|
||||
| COBOL编译 | GnuCOBOL 3.2.0 |
|
||||
| DB管道 | gixsql + SQLite |
|
||||
| AI模型 | DeepSeek |
|
||||
| AI模型 | DeepSeek (deepseek-v4-flash) |
|
||||
| 测试框架 | pytest |
|
||||
|
||||
---
|
||||
@@ -39,39 +41,44 @@ COBOL迁移验证平台V3是一个AI辅助的自动化测试工具,用于验
|
||||
### 2.1 架构图
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ V3系统架构 │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||||
│ │ CLI入口 │ │ Web界面 │ │ API接口 │ │
|
||||
│ │ main.py │ │ web/ │ │ __init__ │ │
|
||||
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
|
||||
│ │ │ │ │
|
||||
│ └────────────────────┼────────────────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||||
│ │ 编排层 (Orchestrator) │ │
|
||||
│ │ orchestrator.py (非DB) orchestrator_db.py (DB) │ │
|
||||
│ └─────────────────────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ ┌────────────────────┼────────────────────┐ │
|
||||
│ │ │ │ │
|
||||
│ ▼ ▼ ▼ │
|
||||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||||
│ │ 核心引擎 │ │ 运行引擎 │ │ AI代理 │ │
|
||||
│ │ cobol_testgen│ │ runners/ │ │ agents/ │ │
|
||||
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||||
│ │ │ │ │
|
||||
│ │ │ │ │
|
||||
│ ▼ ▼ ▼ │
|
||||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||||
│ │ 比对模块 │ │ 报告模块 │ │ 配置模块 │ │
|
||||
│ │ comparator/ │ │ report/ │ │ config/ │ │
|
||||
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
┌─────────────────────────────────────────────────────────────────────┐
|
||||
│ V3系统架构 │
|
||||
├─────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌──────────────┐ ┌──────────────┐ │
|
||||
│ │ run.py │ │ main.py │ │
|
||||
│ │ 全流程入口 │ │ CLI入口 │ │
|
||||
│ └──────┬───────┘ └──────┬───────┘ │
|
||||
│ │ │ │
|
||||
│ ▼ ▼ │
|
||||
│ ┌──────────────┐ ┌──────────────────────────────────────────┐ │
|
||||
│ │ Step1: │ │ 编排层 (Orchestrator) │ │
|
||||
│ │ cobol_testgen│ │ orchestrator.py (非DB) │ │
|
||||
│ │ (白盒) │ │ orchestrator_db.py (DB, 6步) │ │
|
||||
│ │ Step2: │ └──────────────────────────────────────────┘ │
|
||||
│ │ black-box │ │ │
|
||||
│ │ (黑盒LLM) │ │ │
|
||||
│ └──────┬───────┘ │ │
|
||||
│ │ ┌────────────┼────────────┐ │
|
||||
│ │ │ │ │ │
|
||||
│ ▼ ▼ ▼ ▼ │
|
||||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||||
│ │ 核心引擎 │ │ 运行引擎 │ │ AI代理 │ │
|
||||
│ │ cobol_testgen│ │ runners/ │ │ agents/ │ │
|
||||
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||||
│ │ │ │ │
|
||||
│ ▼ ▼ ▼ │
|
||||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||||
│ │ 比对模块 │ │ 报告模块 │ │ 配置模块 │ │
|
||||
│ │ comparator/ │ │ report/ │ │ config/ │ │
|
||||
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||||
│ │
|
||||
│ ┌──────────────────────────────────────────────────────────────┐ │
|
||||
│ │ black-box-data-create/ (黑盒LLM模块) │ │
|
||||
│ │ InputParser → RuleLoader → PromptBuilder → APIClient → Writer│ │
|
||||
│ └──────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 2.2 分层架构
|
||||
@@ -82,7 +89,7 @@ COBOL迁移验证平台V3是一个AI辅助的自动化测试工具,用于验
|
||||
| **L2 核心层** | cobol_testgen/, config/ | COBOL解析、配置管理 |
|
||||
| **L3 业务层** | hina/, agents/, comparator/ | 分类、AI代理、比对 |
|
||||
| **L4 编排层** | orchestrator*, runners/ | 流程编排、执行 |
|
||||
| **L5 接口层** | main.py, web/, __init__.py | 用户接口 |
|
||||
| **L5 接口层** | run.py, main.py, black-box-data-create/ | 用户接口 |
|
||||
|
||||
---
|
||||
|
||||
@@ -92,13 +99,15 @@ COBOL迁移验证平台V3是一个AI辅助的自动化测试工具,用于验
|
||||
|
||||
| 模块 | 文件数 | 行数 | 职责 |
|
||||
|------|--------|------|------|
|
||||
| cobol_testgen/ | 22 | ~8000 | COBOL解析、测试数据生成 |
|
||||
| orchestrator_db.py | 1 | 1334 | DB管道6步编排 |
|
||||
| runners/ | 8 | ~600 | 编译运行引擎 |
|
||||
| hina/ | 11 | ~2000 | HINA程序分类 |
|
||||
| agents/ | 6 | ~800 | LLM代理 |
|
||||
| cobol_testgen/ | 22 | ~10000 | COBOL解析、测试数据生成 |
|
||||
| black-box-data-create/ | 12 | ~1500 | 黑盒LLM测试数据生成 |
|
||||
| orchestrator_db.py | 1 | ~1000 | DB管道6步编排 |
|
||||
| orchestrator.py | 1 | ~500 | 非DB管道编排 |
|
||||
| runners/ | 7 | ~600 | 编译运行引擎 |
|
||||
| hina/ | 12 | ~2600 | HINA程序分类 |
|
||||
| agents/ | 7 | ~1100 | LLM代理 |
|
||||
| comparator/ | 6 | ~400 | 字段比对 |
|
||||
| config/ | 5 | ~300 | 配置管理 |
|
||||
| config/ | 4 | ~400 | 配置管理 |
|
||||
| report/ | 1 | ~200 | 报告生成 |
|
||||
|
||||
### 3.2 模块依赖关系
|
||||
@@ -109,12 +118,16 @@ models.py (零依赖)
|
||||
├── read.py (lark)
|
||||
├── cond.py (stdlib)
|
||||
├── core.py (cond)
|
||||
├── procedure_parser.py (re) [新]
|
||||
├── pipeline_bridge.py (procedure_parser, core) [新]
|
||||
├── design.py (models, cond, core)
|
||||
├── design_mcdc.py (models, cond) [新]
|
||||
├── coverage.py (models, cond)
|
||||
├── output.py (file_io)
|
||||
├── to_sql.py (stdlib)
|
||||
├── runner.py (file_io)
|
||||
├── flatfile.py (read, file_io)
|
||||
├── flatfile.py (read, file_io) [新]
|
||||
├── data_merger.py (generate_data, design_data) [新]
|
||||
├── gcov.py [新]
|
||||
│
|
||||
└── __init__.py (所有上层模块)
|
||||
```
|
||||
@@ -123,59 +136,44 @@ models.py (零依赖)
|
||||
|
||||
## 四、数据流
|
||||
|
||||
### 4.1 非DB管道数据流
|
||||
### 4.1 全流程入口 (run.py)
|
||||
|
||||
```
|
||||
COBOL源码
|
||||
│
|
||||
▼
|
||||
read.py: preprocess() + parse_data_division()
|
||||
│
|
||||
▼
|
||||
core.py: build_branch_tree()
|
||||
│
|
||||
▼
|
||||
design.py: enum_paths() + generate_records()
|
||||
│
|
||||
▼
|
||||
output.py: output_json() + output_input_files()
|
||||
│
|
||||
▼
|
||||
runners/cobol_runner.py: compile() + run()
|
||||
│
|
||||
▼
|
||||
comparator/: compare_field()
|
||||
│
|
||||
▼
|
||||
report/generator.py: generate_report()
|
||||
run.py
|
||||
│
|
||||
├── Step1: python -m cobol_testgen --gcov <source> <output>
|
||||
│ │
|
||||
│ ├── read.py: preprocess() + parse_data_division()
|
||||
│ ├── core.py / procedure_parser.py: build_branch_tree()
|
||||
│ ├── design.py / design_mcdc.py: enum_paths() + generate_records()
|
||||
│ ├── output.py: output_json() + output_input_files()
|
||||
│ └── coverage.py: HTML覆盖率报告
|
||||
│
|
||||
└── Step2: black-box-data-create/main.py
|
||||
│
|
||||
├── InputParser: 解析设计书 + COPYBOOK + DB定义
|
||||
├── RuleLoader: PGM模式匹配 → 规则文件
|
||||
├── PromptBuilder: 组装LLM提示词
|
||||
├── APIClient: DeepSeek API调用
|
||||
└── OutputWriter: JSON/SQL输出
|
||||
```
|
||||
|
||||
### 4.2 DB管道数据流
|
||||
### 4.2 非DB管道数据流
|
||||
|
||||
```
|
||||
COBOL源码 (含EXEC SQL)
|
||||
│
|
||||
▼
|
||||
gixsql_runner.py: preprocess() + compile()
|
||||
│
|
||||
▼
|
||||
orchestrator_db.py: step2_generate_inputs()
|
||||
│
|
||||
├── cobol_testgen: extract_structure + generate_data
|
||||
├── to_sql.py: build_db_input()
|
||||
└── flatfile.py: write_all_files()
|
||||
│
|
||||
▼
|
||||
orchestrator_db.py: step3_run_cobol()
|
||||
│
|
||||
▼
|
||||
orchestrator_db.py: step4_extract_intermediate()
|
||||
│
|
||||
▼
|
||||
orchestrator_db.py: step5_run_java() (可选)
|
||||
│
|
||||
▼
|
||||
orchestrator_db.py: step6_verify()
|
||||
COBOL源码 → read.py → core.py → design.py → output.py → cobol_runner.py → comparator/ → report/
|
||||
```
|
||||
|
||||
### 4.3 DB管道数据流
|
||||
|
||||
```
|
||||
COBOL源码 → gixsql_runner.py → orchestrator_db.py (6步)
|
||||
Step1: gixpp + cobc编译
|
||||
Step2: generate_data → flatfile.write_all_files + DB初始化 + JSON输出
|
||||
Step3: gixsql_runner.run (COBOL + SQLite)
|
||||
Step4: SQLite → JSON中间数据
|
||||
Step5: Java执行 (可选)
|
||||
Step6: 结果比对
|
||||
```
|
||||
|
||||
---
|
||||
@@ -191,7 +189,7 @@ def extract_structure(
|
||||
cobol_source: str,
|
||||
copybook_dirs: list[str] = None
|
||||
) -> dict:
|
||||
"""解析COBOL源码,返回结构信息"""
|
||||
"""解析COBOL源码,返回结构信息(段落、决策点、分支树、文件信息等)"""
|
||||
pass
|
||||
|
||||
def generate_data(
|
||||
@@ -199,7 +197,15 @@ def generate_data(
|
||||
structure: dict,
|
||||
copybook_dirs: list[str] = None
|
||||
) -> list[dict]:
|
||||
"""生成分支覆盖测试数据"""
|
||||
"""基于分支覆盖生成测试数据"""
|
||||
pass
|
||||
|
||||
def incremental_supplement(
|
||||
branch_tree: list,
|
||||
gaps: list,
|
||||
data_fields: list
|
||||
) -> list[dict]:
|
||||
"""增量补充未覆盖分支的测试数据"""
|
||||
pass
|
||||
|
||||
def main():
|
||||
@@ -207,14 +213,35 @@ def main():
|
||||
pass
|
||||
```
|
||||
|
||||
### 5.2 配置接口
|
||||
### 5.2 黑盒LLM API
|
||||
|
||||
```python
|
||||
# black-box-data-create/agent/__init__.py
|
||||
|
||||
def generate(
|
||||
design_md: str, # 詳細設計書パス
|
||||
source_cbl: str, # COBOLソースパス
|
||||
file_db_md: str, # COPY句定義書パス
|
||||
cpy_dir: str, # COPYBOOKディレクトリ
|
||||
db_md: str, # DB定義書パス
|
||||
output_dir: str, # 出力ディレクトリ
|
||||
api_key: str, # DeepSeek API Key
|
||||
api_model: str, # モデル名 (default: deepseek-v4-flash)
|
||||
rules_dir: str, # ルールディレクトリ
|
||||
max_tokens: int, # トークン上限 (default: 32768)
|
||||
) -> dict:
|
||||
"""黑盒LLM测试数据生成主入口"""
|
||||
pass
|
||||
```
|
||||
|
||||
### 5.3 配置接口
|
||||
|
||||
```python
|
||||
# config/__init__.py
|
||||
|
||||
@dataclass
|
||||
class Config:
|
||||
"""全局配置"""
|
||||
"""全局配置(从TOML加载)"""
|
||||
project_name: str
|
||||
copybook_paths: list[str]
|
||||
dialect: str
|
||||
@@ -235,13 +262,15 @@ class Config:
|
||||
| 编译错误 | cobc编译失败 | 记录日志,跳过该程序 |
|
||||
| 运行错误 | 程序执行异常 | 捕获异常,标记失败 |
|
||||
| 超时错误 | 执行超时 | 强制终止,记录超时 |
|
||||
| API错误 | DeepSeek调用失败 | 3次重试后回退到规则引擎 |
|
||||
|
||||
### 6.2 容错机制
|
||||
|
||||
- **解析器超时**:pipeline_bridge 3秒超时回退
|
||||
- **LLM失败**:回退到规则引擎
|
||||
- **解析器超时**:pipeline_bridge 3秒超时回退(新parser → 旧parser)
|
||||
- **LLM失败**:black-box-data-create 回退到空结果
|
||||
- **gcov失败**:跳过覆盖率收集
|
||||
- **DB连接失败**:重试或跳过
|
||||
- **API重试**:3次指数退避重试
|
||||
|
||||
---
|
||||
|
||||
@@ -255,12 +284,14 @@ class Config:
|
||||
| 测试数据生成 | < 30秒 |
|
||||
| 编译运行 | < 60秒 |
|
||||
| 覆盖率报告 | < 10秒 |
|
||||
| 全流程 (run.py) | < 120秒 |
|
||||
|
||||
### 7.2 优化策略
|
||||
|
||||
- **路径枚举**:O(N)线性算法替代O(2^N)
|
||||
- **路径枚举**:O(N)线性算法(procedure_parser)替代O(2^N)
|
||||
- **新解析器**:line-based state machine,10-50ms完成解析
|
||||
- **并行执行**:多场景gcov并行收集
|
||||
- **缓存机制**:LLM结果缓存
|
||||
- **缓存机制**:LLM结果SHA256缓存
|
||||
- **增量补充**:质量门循环最多4次
|
||||
|
||||
---
|
||||
@@ -295,7 +326,7 @@ class Config:
|
||||
|
||||
- 43个COBOL基准程序
|
||||
- 33+2种程序类型
|
||||
- 58个电信测试程序
|
||||
- 14个程序YAML schema
|
||||
|
||||
---
|
||||
|
||||
@@ -314,7 +345,7 @@ class Config:
|
||||
|
||||
```bash
|
||||
# 1. 安装Python依赖
|
||||
pip install lark pathlib pyyaml
|
||||
pip install lark pathlib pyyaml requests
|
||||
|
||||
# 2. 安装GnuCOBOL
|
||||
# 下载GC32-BDB-SP1,添加到PATH
|
||||
|
||||
@@ -282,11 +282,11 @@ class Agent3Diagnostic:
|
||||
|
||||
## 7. 式样书驱动测试数据生成器(DesignDataGenerator)
|
||||
|
||||
### 6.1 职责
|
||||
### 7.1 职责
|
||||
|
||||
从日文详细设计书(.md)中提取程序元信息(`ProgramMeta`),结合 COBOL 源码、COPYBOOK 结构和 DB 定义,通过 LLM 生成有业务意义的机能测试数据。
|
||||
|
||||
### 6.2 数据流
|
||||
### 7.2 数据流
|
||||
|
||||
```
|
||||
设计书 .md + COBOL 源码
|
||||
@@ -300,7 +300,7 @@ JSON: {"records": [{field_name: value}]}
|
||||
list[dict]
|
||||
```
|
||||
|
||||
### 6.3 核心类
|
||||
### 7.3 核心类
|
||||
|
||||
```python
|
||||
class DesignDataGenerator:
|
||||
@@ -309,7 +309,7 @@ class DesignDataGenerator:
|
||||
db_md_text=None, replacing_rules=None, v3_field_names=None) -> list[dict]
|
||||
```
|
||||
|
||||
### 6.4 式样书解析器(DesignDataInputParser)
|
||||
### 7.4 式样书解析器(DesignDataInputParser)
|
||||
|
||||
解析日文详细设计书 Markdown 文档,提取以下结构化信息:
|
||||
|
||||
@@ -323,7 +323,7 @@ class DesignDataGenerator:
|
||||
|
||||
解析通过 Markdown 标题匹配(`## 基本情報`、`## 使用ファイル一覧` 等)和表格解析实现,不依赖外部 Markdown 解析库。
|
||||
|
||||
### 6.5 输入类型自动判定
|
||||
### 7.5 输入类型自动判定
|
||||
|
||||
`_determine_input_type` 根据输入文件的媒体类型自动判定:
|
||||
|
||||
@@ -333,7 +333,7 @@ class DesignDataGenerator:
|
||||
| 仅 DB(数据库) | `db` |
|
||||
| 混合或无输入 | `mixed` / `file` |
|
||||
|
||||
### 6.6 字段名映射(_resolve_field_names)
|
||||
### 7.6 字段名映射(_resolve_field_names)
|
||||
|
||||
外部 Agent 生成的字段名可能与 V3 内部字段名不一致,映射规则:
|
||||
|
||||
@@ -344,21 +344,21 @@ class DesignDataGenerator:
|
||||
5. **去下划线匹配**:`R01_EMP_ID` → `R01EMPID`
|
||||
6. **无法映射的字段丢弃**
|
||||
|
||||
### 6.7 规则加载
|
||||
### 7.7 规则加载
|
||||
|
||||
`_load_rules` 从 `rules/pgm_pattern/` 和 `rules/special_feature/` 目录加载所有 `.md` 规则文件,作为 LLM 上下文的一部分。
|
||||
|
||||
### 6.8 记录去重(_dedup)
|
||||
### 7.8 记录去重(_dedup)
|
||||
|
||||
支持按指定键字段去重,`additional_records` 优先保留。
|
||||
|
||||
## 8. LLM 接口封装(LLMClient)
|
||||
|
||||
### 7.1 职责
|
||||
### 8.1 职责
|
||||
|
||||
封装 LLM API 调用,提供文件缓存、自动重试、多模型兼容能力。所有 Agent 通过此客户端与 LLM 交互。
|
||||
|
||||
### 7.2 核心类
|
||||
### 8.2 核心类
|
||||
|
||||
```python
|
||||
class LLMClient:
|
||||
@@ -369,14 +369,14 @@ class LLMClient:
|
||||
def _set(self, k: str, v: str) -> None # 缓存写入
|
||||
```
|
||||
|
||||
### 7.3 缓存机制
|
||||
### 8.3 缓存机制
|
||||
|
||||
- **键生成**:对消息列表进行 JSON 序列化后取 SHA256 哈希
|
||||
- **存储**:以 `{hash}.json` 文件存储在 `.cache/llm/` 目录
|
||||
- **格式**:`{"response": "..."}`
|
||||
- **效果**:相同输入直接返回缓存结果,避免重复调用 LLM
|
||||
|
||||
### 7.4 重试机制
|
||||
### 8.4 重试机制
|
||||
|
||||
- 默认重试 1 次(共 2 次尝试)
|
||||
- 使用 `httpx.post` 发送 HTTP 请求
|
||||
|
||||
@@ -613,7 +613,7 @@ Path 是一条完整执行路径的所有约束集合。
|
||||
|
||||
### 5.1 非 DB 管道完整流程 (Mermaid)
|
||||
|
||||
`mermaid
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[COBOL 源码 .cbl] --> B[read.py preprocess]
|
||||
B --> C[read.py parse_data_division]
|
||||
@@ -652,11 +652,11 @@ flowchart TD
|
||||
|
||||
Y --> Z[report/generator generate_html]
|
||||
Z --> AA[HTML 验证报告]
|
||||
`
|
||||
```
|
||||
|
||||
### 5.2 DB 管道完整流程 (Mermaid)
|
||||
|
||||
`mermaid
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[COBOL 源码 含 EXEC SQL] --> B[Step 1: 环境整备]
|
||||
B --> B1[gixpp 预处理]
|
||||
@@ -695,11 +695,11 @@ flowchart TD
|
||||
D2 --> G
|
||||
G --> G1[VerificationRun]
|
||||
G1 --> G2[PASS / MISMATCH]
|
||||
`
|
||||
```
|
||||
|
||||
### 5.3 数据流关键节点汇总
|
||||
|
||||
`mermaid
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph 输入层
|
||||
A1[COBOL 源码]
|
||||
@@ -754,7 +754,7 @@ flowchart LR
|
||||
E3 --> F1
|
||||
F1 --> F2 --> F4
|
||||
B3 --> F3 --> F4
|
||||
`
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,483 @@
|
||||
# 全流程管道详细设计 (run.py + black-box-data-create)
|
||||
|
||||
> 版本: v1.0 | 日期: 2026-08-23
|
||||
> 本文档描述 COBOL 迁移验证平台 V3 的全流程入口 `run.py` 和黑盒 LLM 数据生成模块 `black-box-data-create/`。
|
||||
|
||||
---
|
||||
|
||||
## 1. 模块概述
|
||||
|
||||
### 1.1 职责
|
||||
|
||||
全流程管道模块是 V3 系统的顶层入口,负责:
|
||||
|
||||
1. **一键执行** 白盒 + 黑盒全流程测试数据生成
|
||||
2. **黑盒 LLM 生成** 基于详细设计书的 LLM 测试数据生成
|
||||
3. **管道编排** 两步顺序执行,任一步失败即停止
|
||||
|
||||
### 1.2 边界
|
||||
|
||||
| 在范围内 | 不在范围内 |
|
||||
|---------|-----------|
|
||||
| 白盒 `cobol_testgen` 调用 | COBOL 程序执行(由 runners/ 负责) |
|
||||
| 黑盒 `black-box-data-create` 调用 | 字段比对(由 comparator/ 负责) |
|
||||
| 参数解析和传递 | LLM API 调用细节(由 black-box-data-create 内部处理) |
|
||||
| 错误传播和退出码 | 覆盖率分析(由 coverage.py 负责) |
|
||||
|
||||
---
|
||||
|
||||
## 2. 文件清单
|
||||
|
||||
### 2.1 run.py(全流程入口)
|
||||
|
||||
| 文件 | 行数 | 职责 |
|
||||
|------|------|------|
|
||||
| `run.py` | 86 | 全流程入口:白盒 + 黑盒顺序执行 |
|
||||
|
||||
### 2.2 black-box-data-create/(黑盒 LLM 模块)
|
||||
|
||||
| 文件 | 行数 | 职责 |
|
||||
|------|------|------|
|
||||
| `main.py` | 67 | CLI 入口,参数解析,调用 generate() |
|
||||
| `agent/__init__.py` | 57 | 模块入口,generate() 函数,管道编排 |
|
||||
| `agent/models.py` | ~80 | 数据类定义:ProgramMeta, FileInfo, CopyField, KeyInfo, TableColumn, TableInfo |
|
||||
| `agent/input_parser.py` | 330 | 设计书 + COPYBOOK + DB定义解析 |
|
||||
| `agent/markdown_utils.py` | ~100 | Markdown 表格解析工具 |
|
||||
| `agent/rule_loader.py` | 226 | PGM模式 → 规则文件匹配 |
|
||||
| `agent/prompt_builder.py` | 146 | LLM 提示词组装 |
|
||||
| `agent/api_client.py` | 132 | DeepSeek API 调用 + 3次重试 |
|
||||
| `agent/output_writer.py` | 59 | JSON/SQL 文件输出 |
|
||||
| `rules/pgm_pattern/` | ~30 files | PGM 模式规则文件(.md) |
|
||||
| `tests/` | 10 files | 单元测试 + 集成测试 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 全流程管道设计 (run.py)
|
||||
|
||||
### 3.1 架构图
|
||||
|
||||
```
|
||||
run.py (全流程入口)
|
||||
│
|
||||
├── Step 1: python -m cobol_testgen --gcov <source> <output>
|
||||
│ │
|
||||
│ ├── read.py: 预处理 + DATA DIVISION 解析
|
||||
│ ├── core.py / procedure_parser.py: 分支树构建
|
||||
│ ├── design.py / design_mcdc.py: 路径枚举 + 值生成
|
||||
│ ├── output.py: JSON 输出
|
||||
│ └── coverage.py: HTML 覆盖率报告
|
||||
│
|
||||
└── Step 2: black-box-data-create/main.py
|
||||
│
|
||||
├── InputParser: 解析设计书 + COPYBOOK + DB定义
|
||||
├── RuleLoader: PGM模式匹配 → 规则文件
|
||||
├── PromptBuilder: 组装 LLM 提示词
|
||||
├── APIClient: DeepSeek API 调用
|
||||
└── OutputWriter: JSON/SQL 输出
|
||||
```
|
||||
|
||||
### 3.2 参数设计
|
||||
|
||||
```python
|
||||
def build_parser():
|
||||
p = argparse.ArgumentParser(
|
||||
description="COBOL 迁移验证平台:先跑白盒 cobol_testgen,再跑黑盒 LLM 数据生成")
|
||||
p.add_argument("--design", required=True, help="詳細設計書 .md のパス")
|
||||
p.add_argument("--source", required=True, help="COBOL ソース .cbl のパス")
|
||||
p.add_argument("--file-db-md", required=True, help="ファイル/DB 構造 .md のパス")
|
||||
p.add_argument("--cpy", required=True, help="COPYBOOK 格納ディレクトリ")
|
||||
p.add_argument("--db-md", required=True, help="DB 定義書 .md のパス")
|
||||
p.add_argument("--output", default="output", help="出力ディレクトリ")
|
||||
p.add_argument("--api-key", help="DeepSeek API Key(透传给黑盒)")
|
||||
p.add_argument("--model", help="API モデル名(透传给黑盒)")
|
||||
p.add_argument("--rules", help="ルール格納ディレクトリ(透传给黑盒)")
|
||||
p.add_argument("--max-tokens", type=int, help="API 生成トークン上限(透传给黑盒)")
|
||||
p.add_argument("--dry-run", action="store_true", help="只打印要执行的命令,不真正执行")
|
||||
return p
|
||||
```
|
||||
|
||||
### 3.3 执行流程
|
||||
|
||||
```python
|
||||
def main():
|
||||
args = build_parser().parse_args()
|
||||
|
||||
# Step 1: 白盒 cobol_testgen
|
||||
rc = _run(
|
||||
[sys.executable, "-m", "cobol_testgen", "--gcov", args.source, args.output],
|
||||
cwd=ROOT,
|
||||
label="步骤1: cobol_testgen 白盒数据生成",
|
||||
dry_run=args.dry_run,
|
||||
)
|
||||
if rc != 0:
|
||||
return rc
|
||||
|
||||
# Step 2: 黑盒 black-box-data-create
|
||||
bb_cmd = [
|
||||
sys.executable, BLACKBOX_MAIN,
|
||||
"--design", args.design,
|
||||
"--source", args.source,
|
||||
"--file-db-md", args.file_db_md,
|
||||
"--cpy", args.cpy,
|
||||
"--db-md", args.db_md,
|
||||
"--output", args.output,
|
||||
]
|
||||
for opt in ("--api-key", "--model", "--rules", "--max-tokens"):
|
||||
v = getattr(args, opt.lstrip("-").replace("-", "_"))
|
||||
if v is not None:
|
||||
bb_cmd.extend([opt, str(v)])
|
||||
|
||||
return _run(
|
||||
bb_cmd,
|
||||
cwd=ROOT,
|
||||
label="步骤2: black-box-data-create LLM 数据生成",
|
||||
dry_run=args.dry_run,
|
||||
)
|
||||
```
|
||||
|
||||
### 3.4 输出目录结构
|
||||
|
||||
```
|
||||
output/
|
||||
└── {PROGRAM_ID}/
|
||||
├── main/ # Step 1 白盒输出
|
||||
│ ├── {PROGRAM_ID}.json # 测试数据
|
||||
│ ├── input/ # 输入文件
|
||||
│ └── coverage/ # 覆盖率报告
|
||||
└── g{N}/ # Step 2 黑盒输出(按组分目录)
|
||||
├── {PROGRAM_ID}_g{N}.json
|
||||
└── {PROGRAM_ID}_g{N}.sql
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 黑盒 LLM 模块详细设计 (black-box-data-create/)
|
||||
|
||||
### 4.1 架构图
|
||||
|
||||
```
|
||||
black-box-data-create/
|
||||
│
|
||||
├── main.py (CLI入口)
|
||||
│ │
|
||||
│ └── agent.generate() (管道入口)
|
||||
│
|
||||
└── agent/
|
||||
│
|
||||
├── InputParser ──────────────────────────────────────┐
|
||||
│ 解析设计书 + COPYBOOK + DB定义 │
|
||||
│ 输出: ProgramMeta │
|
||||
│ │
|
||||
├── RuleLoader ──────────────────────────────────────┐│
|
||||
│ PGM模式 → 规则文件匹配 ││
|
||||
│ 输出: rules_text, group_descriptions ││
|
||||
│ ││
|
||||
├── PromptBuilder ──────────────────────────────────┐││
|
||||
│ 组装 LLM 提示词 │││
|
||||
│ 输出: prompt (str) │││
|
||||
│ │││
|
||||
├── APIClient ─────────────────────────────────────┐│││
|
||||
│ DeepSeek API 调用 + 3次重试 ││││
|
||||
│ 输出: Dict[str, Any] (AI 生成结果) ││││
|
||||
│ ││││
|
||||
└── OutputWriter ─────────────────────────────────┐││││
|
||||
JSON/SQL 文件输出 │││││
|
||||
输出: Dict[str, str] (文件路径映射) │││││
|
||||
│││││
|
||||
▼▼▼▼▼
|
||||
generate()
|
||||
```
|
||||
|
||||
### 4.2 核心数据流
|
||||
|
||||
```
|
||||
设计书 .md + COBOL 源码 + COPY句定義書.md + DB定義書.md
|
||||
│
|
||||
▼ InputParser.run()
|
||||
ProgramMeta {
|
||||
program_id, program_name, system_name,
|
||||
pgm_type, pgm_pattern,
|
||||
files: list[FileInfo],
|
||||
keys: list[KeyInfo],
|
||||
modules: list[ModuleInfo],
|
||||
process_detail, output_records,
|
||||
input_type: "file" | "db" | "mixed",
|
||||
copy_fields: dict[str, list[CopyField]],
|
||||
db_tables: dict[str, TableInfo]
|
||||
}
|
||||
│
|
||||
▼ RuleLoader.load()
|
||||
rules_text: str (规则文本)
|
||||
group_descriptions: list[str] (组描述)
|
||||
group_count: int (组数)
|
||||
│
|
||||
▼ PromptBuilder.build()
|
||||
prompt: str (完整 LLM 提示词)
|
||||
│
|
||||
▼ APIClient.generate()
|
||||
Dict[str, Any] (AI 生成结果,按组分)
|
||||
│
|
||||
▼ OutputWriter.write()
|
||||
Dict[str, str] (文件路径映射)
|
||||
```
|
||||
|
||||
### 4.3 InputParser 详细设计
|
||||
|
||||
#### 4.3.1 职责
|
||||
|
||||
解析日文详细设计书 Markdown 文档,提取程序元信息。
|
||||
|
||||
#### 4.3.2 输入
|
||||
|
||||
| 参数 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `design_md_path` | str | 详细设计书路径 |
|
||||
| `source_cbl_path` | str | COBOL 源码路径 |
|
||||
| `file_db_md_path` | str | COPY句定義書路径 |
|
||||
| `cpy_dir` | str | COPYBOOK 目录 |
|
||||
| `db_md_path` | str | DB定義書路径 |
|
||||
|
||||
#### 4.3.3 输出
|
||||
|
||||
`ProgramMeta` 数据类,包含程序的所有元信息。
|
||||
|
||||
#### 4.3.4 解析流程
|
||||
|
||||
```python
|
||||
def run(self) -> ProgramMeta:
|
||||
self._design_text = self._read_file(self.design_md_path)
|
||||
self._source_text = self._read_file(self.source_cbl_path)
|
||||
|
||||
meta = ProgramMeta(...)
|
||||
self._parse_basic_info(meta) # 基本情報セクション
|
||||
self._parse_use_files(meta) # 使用ファイル一覧
|
||||
self._parse_keys(meta) # キー情報
|
||||
self._parse_modules(meta) # モジュール情報
|
||||
self._parse_process_detail(meta) # 処理詳細
|
||||
self._parse_output_records(meta) # 出力レコード
|
||||
self._determine_input_type(meta) # 入力タイプ判定
|
||||
self._parse_copybooks(meta) # COPYBOOK解析
|
||||
self._parse_db_definition(meta) # DB定義解析
|
||||
return meta
|
||||
```
|
||||
|
||||
### 4.4 RuleLoader 详细设计
|
||||
|
||||
#### 4.4.1 职责
|
||||
|
||||
根据程序的 PGM 模式匹配对应的规则文件。
|
||||
|
||||
#### 4.4.2 PGM 模式映射
|
||||
|
||||
```python
|
||||
PGM_PATTERN_MAP = {
|
||||
'マッチング(1:1)': 'マッチング(1-1).md',
|
||||
'マッチング(1:N)': 'マッチング(1-N).md',
|
||||
'マッチング(N:1)': 'マッチング(N-1).md',
|
||||
'マッチング(M:N)': 'マッチング(M-N).md',
|
||||
'キーブレイク(集計)': 'キーブレイク(集計).md',
|
||||
'キーブレイク(非集計)': 'キーブレイク(非集計).md',
|
||||
'項目チェック': '項目チェック(重複含まず).md',
|
||||
'振り分け': '振り分け(IF).md',
|
||||
'GETPUT': 'レイアウト編集のみ(GETPUT).md',
|
||||
# ... 30+ 映射
|
||||
}
|
||||
```
|
||||
|
||||
#### 4.4.3 匹配逻辑
|
||||
|
||||
1. **完全匹配**:`PGM_PATTERN_MAP` 中查找 `pgm_pattern`
|
||||
2. **部分匹配**:规则文件名(去除 .md)是否包含在 `pgm_pattern` 中
|
||||
3. **半角/全角括弧容错**:`()` vs `()`
|
||||
|
||||
### 4.5 PromptBuilder 详细设计
|
||||
|
||||
#### 4.5.1 职责
|
||||
|
||||
将 ProgramMeta 和规则文本组装成 LLM 提示词。
|
||||
|
||||
#### 4.5.2 提示词结构
|
||||
|
||||
```
|
||||
## プログラム基本情報
|
||||
- システム名: ...
|
||||
- プログラムID: ...
|
||||
- PGMパターン: ...
|
||||
- 入力タイプ: ...
|
||||
|
||||
## 処理詳細
|
||||
```
|
||||
{process_detail}
|
||||
```
|
||||
|
||||
## 入力構造
|
||||
### ファイル {identifier}
|
||||
| 項目名 | PIC | バイト数 |
|
||||
|--------|-----|----------|
|
||||
| ... | ... | ... |
|
||||
|
||||
## ルール
|
||||
{rules_text}
|
||||
|
||||
## 出力フォーマット
|
||||
{output_format_instruction}
|
||||
|
||||
## 生成指示
|
||||
{generation_instruction}
|
||||
```
|
||||
|
||||
### 4.6 APIClient 详细设计
|
||||
|
||||
#### 4.6.1 职责
|
||||
|
||||
调用 DeepSeek API 生成测试数据。
|
||||
|
||||
#### 4.6.2 核心参数
|
||||
|
||||
| 参数 | 默认值 | 说明 |
|
||||
|------|--------|------|
|
||||
| `model` | `deepseek-v4-flash` | API 模型 |
|
||||
| `base_url` | `https://api.deepseek.com/chat/completions` | API 端点 |
|
||||
| `max_retries` | 3 | 最大重试次数 |
|
||||
| `timeout` | 120 | 超时时间(秒) |
|
||||
| `max_tokens` | 32768 | 最大生成 token 数 |
|
||||
|
||||
#### 4.6.3 重试机制
|
||||
|
||||
- **指数退避**:1s, 2s, 4s
|
||||
- **截断处理**:`finish_reason=length` 时追加压缩指示重试
|
||||
- **错误传播**:3次重试后抛出异常
|
||||
|
||||
#### 4.6.4 系统提示词
|
||||
|
||||
```
|
||||
你是COBOL程序的测试数据生成专家。
|
||||
请严格按照提供的规则,生成符合格式要求的测试数据。
|
||||
输出必须是可被json.loads()直接解析的JSON,不要包裹在```json```代码块中。
|
||||
不要在JSON前后添加任何说明文字。
|
||||
```
|
||||
|
||||
### 4.7 OutputWriter 详细设计
|
||||
|
||||
#### 4.7.1 职责
|
||||
|
||||
将 AI 生成的数据写入文件系统。
|
||||
|
||||
#### 4.7.2 输出格式
|
||||
|
||||
| input_type | 输出文件 |
|
||||
|------------|----------|
|
||||
| `file` | `{PROGRAM_ID}_{GROUP}.json` |
|
||||
| `db` | `{PROGRAM_ID}_{GROUP}.sql` |
|
||||
| `mixed` | 两者都生成 |
|
||||
|
||||
---
|
||||
|
||||
## 5. 接口设计
|
||||
|
||||
### 5.1 run.py 接口
|
||||
|
||||
```python
|
||||
# run.py
|
||||
|
||||
def build_parser() -> argparse.ArgumentParser:
|
||||
"""构建命令行参数解析器"""
|
||||
pass
|
||||
|
||||
def main() -> int:
|
||||
"""全流程入口,返回退出码"""
|
||||
pass
|
||||
```
|
||||
|
||||
### 5.2 black-box-data-create 接口
|
||||
|
||||
```python
|
||||
# black-box-data-create/agent/__init__.py
|
||||
|
||||
def generate(
|
||||
design_md: str, # 詳細設計書パス
|
||||
source_cbl: str, # COBOL ソースパス
|
||||
file_db_md: str, # COPY句定義書パス
|
||||
cpy_dir: str, # COPYBOOKディレクトリ
|
||||
db_md: str, # DB定義書パス
|
||||
output_dir: str, # 出力ディレクトリ
|
||||
api_key: str, # DeepSeek API Key
|
||||
api_model: str, # モデル名 (default: deepseek-v4-flash)
|
||||
rules_dir: str, # ルールディレクトリ
|
||||
max_tokens: int, # トークン上限 (default: 32768)
|
||||
) -> dict:
|
||||
"""黑盒 LLM 测试数据生成主入口"""
|
||||
pass
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 错误处理
|
||||
|
||||
### 6.1 错误分类
|
||||
|
||||
| 类别 | 示例 | 处理策略 |
|
||||
|------|------|----------|
|
||||
| 文件不存在 | 设计书路径错误 | 返回退出码 1 |
|
||||
| API 调用失败 | 网络超时、认证失败 | 3次重试后抛出异常 |
|
||||
| JSON 解析失败 | LLM 返回非法 JSON | 抛出异常 |
|
||||
| 程序类型为サブ | 子程序不处理 | ValueError |
|
||||
| 白盒步骤失败 | cobol_testgen 错误 | 停止后续步骤 |
|
||||
|
||||
### 6.2 退出码
|
||||
|
||||
| 退出码 | 说明 |
|
||||
|--------|------|
|
||||
| 0 | 成功 |
|
||||
| 1 | 文件不存在或参数错误 |
|
||||
| 2 | 白盒步骤失败 |
|
||||
| 3 | 黑盒步骤失败 |
|
||||
|
||||
---
|
||||
|
||||
## 7. 测试策略
|
||||
|
||||
### 7.1 单元测试
|
||||
|
||||
- `test_input_parser.py`:设计书解析
|
||||
- `test_rule_loader.py`:规则匹配
|
||||
- `test_prompt_builder.py`:提示词组装
|
||||
- `test_api_client.py`:API 调用(mock)
|
||||
- `test_output_writer.py`:文件输出
|
||||
- `test_models.py`:数据类定义
|
||||
- `test_markdown_utils.py`:Markdown 解析
|
||||
|
||||
### 7.2 集成测试
|
||||
|
||||
- `test_integration.py`:端到端管道测试
|
||||
|
||||
---
|
||||
|
||||
## 8. 依赖关系
|
||||
|
||||
### 8.1 内部依赖
|
||||
|
||||
```
|
||||
run.py
|
||||
└── black-box-data-create/main.py
|
||||
└── agent/__init__.py
|
||||
├── agent/input_parser.py
|
||||
│ └── agent/models.py
|
||||
│ └── agent/markdown_utils.py
|
||||
├── agent/rule_loader.py
|
||||
│ └── agent/models.py
|
||||
├── agent/prompt_builder.py
|
||||
│ └── agent/models.py
|
||||
├── agent/api_client.py
|
||||
│ └── requests
|
||||
└── agent/output_writer.py
|
||||
```
|
||||
|
||||
### 8.2 外部依赖
|
||||
|
||||
| 依赖 | 用途 |
|
||||
|------|------|
|
||||
| requests | HTTP 请求(DeepSeek API) |
|
||||
| json | JSON 解析 |
|
||||
| argparse | 命令行参数解析 |
|
||||
| os, sys | 文件系统操作 |
|
||||
Reference in New Issue
Block a user