Files
cobol-java-v3/docs/plans/db-pipeline-agent2data-integration.md
T

282 lines
9.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# DB 管道接入 Agent2Data — 实现计划
## 问题
DB 管道 (`orchestrator_db.py`) 从未调用 Agent2Data,而 Agent2Data 的 LLM 场景/边界数据是 cobol_testgen 覆盖率基线的补充,应作为第 4 个数据源合并。
同时,非 DB 管道存在两条重复入口(`orchestrator.py` + `__init__.py:main()` 行内管线),导致:
- 行内管线不经过我们刚修的 Agent2Data 合并逻辑
- 行内管线不走质量门/hina 分类/Agent3 诊断
- 两条管线功能不一致
---
## 阶段 ADB 管道接入 Agent2Data
### 目标
`data_merger.py:generate_all_data()` 中新增 Agent2Data 作为第 4 个数据源,使其在 DB 管道 (`orchestrator_db.py`) 中生效。
### 修改文件
#### A1. `data_merger.py` — `generate_all_data()` 新增 Agent2Data 源
**现状**:三路合并(白盒 + 功能 + 策略),参数不含 FieldTree
**改动**
```python
def generate_all_data(
program_id: str,
src_text: str,
st: dict,
copybook_dirs: list = None,
design_doc_dir: str = None,
llm_client=None,
config: dict = None,
merge_strategy: str = "default",
field_tree=None, # ← NEW: Agent2Data 需要的 FieldTree
) -> list[dict]:
```
在原有 `_dedup()` 链后新增第 4 个源:
```python
# ④ Agent2Data LLM 场景数据 (NEW)
agent2_records = []
if field_tree is not None and llm_client is not None:
try:
from agents import Agent2Data
suite = Agent2Data(llm_client).design(
field_tree,
target=config.get("coverage_default", "boundary"),
spark_mode=False,
)
for tc in suite.test_cases:
rec = dict(tc.fields)
rec["_source"] = "agent2"
agent2_records.append(rec)
logger.info(f" Agent2Data records: {len(agent2_records)}")
except Exception as e:
logger.warning(f" Agent2Data failed, skipped: {e}")
# 合并:additional(agent2) 优先,再追加 whitebox+func 中不重复的
all_records = _dedup(addition=agent2_records, main=all_records)
```
**优雅降级**`field_tree=None``llm_client=None` 时不调用,不影响现有管线。
#### A2. `orchestrator_db.py:step2_generate_inputs()` — 构造 FieldTree 并传入
**现状**:调用 `generate_all_data()` 时未传 field_tree 参数
**改动**(在 `generate_all_data` 调用附近):
```python
from data.field_tree import FieldTree, Field
# 从 structure['data_fields'] 构造 FieldTree
data_fields = st.get("data_fields", [])
field_tree = None
if data_fields:
try:
fields = []
for f in data_fields:
if f.get("is_88"):
continue
pi = f.get("pic_info", {})
fields.append(Field(
name=f["name"],
level=f.get("level", 0),
pic=f.get("pic", ""),
usage=f.get("usage", "DISPLAY"),
length=pi.get("length", 0) or pi.get("digits", 0) + pi.get("decimal", 0),
decimal=pi.get("decimal", 0),
signed=pi.get("signed", False),
redefines=f.get("redefines"),
occurs=f.get("occurs"),
))
field_tree = FieldTree(fields=fields, copybook_name=self.program_id)
except Exception as e:
logger.warning(f" FieldTree construction failed (Agent2Data will be skipped): {e}")
# 传入 generate_all_data
recs = generate_all_data(
...,
field_tree=field_tree, # ← NEW
)
```
#### A3. 前置:`data_merger.py` 导入补充
```python
# 文件头部新增 import (紧接现有 import)
try:
from agents import Agent2Data
except ImportError:
Agent2Data = None
```
---
### 验证方法
```bash
cd C:\Users\marye\Desktop\2026技术大赛\cobol-java-v3
set COB_LIBRARY_PATH=<tna>\bin;<v3>\gixsql\lib
set GIXSQL_DB_PATH=C:\Temp\gix
python -m cobol_testgen --gcov <tna>\src\ZAN06UPD.cbl runtime\
```
检查日志输出是否包含 `Agent2Data records: N`
---
## 阶段 B:统一非 DB 入口
### 目标
消除 `__init__.py:main()` 中的 ~350 行行内管线代码,非 DB 程序统一走 `orchestrator.py:run_pipeline()`,同时将行内管线的 gcov + HTML 覆盖率报告功能搬迁到 `orchestrator.py`
### 修改文件
#### B1. `orchestrator.py:run_pipeline()` — 增加 gcov 支持 + HTML 覆盖率报告
**现状**`orchestrator.py``CobolRunner.compile()` + `CobolRunner.run()`(旧 APIstdin/stdout 管道),没有 gcov,没有 HTML 覆盖率报告。
**改动**
```python
def run_pipeline(cfg: Config, cpath: str, cbl: str, java: str, map_path: str) -> VerificationRun:
t0 = time.time()
vr = VerificationRun(program=Path(java).stem, runner=cfg.runner_mode)
try:
text = Path(cpath).read_text()
# ... 保持 Agent1Parser + cobol_testgen + hina + Agent2Data + DataWriter 不变 ...
# COBOL 编译 (改为新 API + gcov 支持)
cob = CobolRunner()
source_dir = str(Path(cbl).parent)
work_dir = Path("temp_work").resolve()
work_dir.mkdir(parents=True, exist_ok=True)
copybook_dirs = [str(Path(cbl).parent.parent / "cpy")] # 从 config/copybook_paths 获取
sub_o = compile_sub_modules(source_dir, work_dir, copybook_dirs)
exe_path = compile_program(
program_name=Path(cbl).stem,
source_dir=source_dir,
work_dir=work_dir,
sub_objects=sub_o,
cpy_dir=copybook_dirs,
gcov=cfg.gcov_enabled,
)
# COBOL 运行 (文件 I/O)
skip_expected = ...
run_all(
program_name=Path(cbl).stem,
outdir=str(output_dir),
temp_dir=work_dir,
fields_dict=..., fd_fields=...,
select_info=..., open_dir=...,
term_types=..., records=...,
expected_records=...,
source_dir=source_dir,
path_infos=...,
multi_write_fds=...,
skip_records=...,
skip_term_types=...,
)
# HTML 覆盖率报告
if cfg.gcov_enabled:
run_coverage(...)
generate_coverage_index(...)
# ... 保持 Java 编译运行 + 比对 + Agent3 + ReportGenerator 不变 ...
```
#### B2. `__init__.py:main()` 非 DB 分支 — 委托给 `orchestrator.py`
**现状**~350 行行内管线代码
**改动**
```python
# 非 DB 程序
for filepath in non_db_files:
try:
from orchestrator import run_pipeline
from config import Config
cfg = Config()
cfg.gcov_enabled = gcov_mode
# 复制相关路径配置
cfg.copybook_paths = [str(filepath.parent / ".." / "cpy")]
vr = run_pipeline(
cfg=cfg,
cpath=str(filepath), # 用作 COPYBOOK
cbl=str(filepath),
java="", # 无双版本验证时跳过
map_path="",
)
# 输出处理(拷贝到 prog_outdir,生成覆盖率索引等)
...
except Exception as e:
logger.error(f" orchestrator pipeline failed: {e}")
# 回退:行内管线
...
```
**回退策略**:如果 `orchestrator.py` 调用失败,自动回退到行内管线(保留原有行为)。
---
### 验证方法
统一前后结果应完全一致:
```bash
# 统一前
python -m cobol_testgen --gcov <tna>\src\ZAN01CHK.cbl runtime-new\
# 统一后
python -m cobol_testgen --gcov <tna>\src\ZAN01CHK.cbl runtime-unified\
diff -r runtime-new runtime-unified
```
两条命令的输出目录结构、覆盖率数据应一致。
---
## 实施顺序与依赖
```
阶段 A (DB + Agent2Data) ──────────── 独立,无外部依赖
├── A1: data_merger.py ─── 新增 field_tree 参数 + Agent2Data 调用
└── A2: orchestrator_db.py ─── 构造 FieldTree 并传入
阶段 B (入口统一) ─────────────────── 依赖阶段 A 完成后可开始
├── B1: orchestrator.py ─── 增加 gcov + HTML 覆盖率能力
├── B2: __init__.py:main() ─── 非 DB 委托给 orchestrator.py
└── B3: 验证一致性 + 清理旧代码
```
### 主要风险
| 风险 | 等级 | 缓解 |
|------|:----:|------|
| Agent2Data 字段值不符合 PIC 格式(阶段 A | 🟡 | Agent2Data 数据排在末尾,不破坏基线;后续可加 PIC 格式化 |
| FieldTree 构造精度不足(阶段 A) | 🟡 | `st["data_fields"]` 来自 `extract_structure()`,与 Agent1Parser 的 FieldTree 结构等价但来源不同 |
| `orchestrator.py` 搬入 gcov 后与行内管线行为不一致(阶段 B) | 🔴 | 并排运行对比,保持回退机制 |
| 行内管线的 C01 特定逻辑 (`_inject_c01_coverage_records` 等) 在 orchestrator.py 中缺失(阶段 B | 🔴 | 搬迁时确认 orchestrator.py 是否也需要这些逻辑;若不需要则跳过(行内管线专门为 KIN/ZAN 程序集优化) |
---
## 不纳入范围
- Agent2Data 输出值的 PIC 格式化(后续优化)
- 统一后删除 `__init__.py` 行内管线死代码(阶段 B 完成后清理)
- `main.py` 废弃(阶段 B 后单独处理)