Files
2026Technology-Competition/docs/milestone2-excel-parser-review.md

5.7 KiB
Raw Permalink Blame History

里程碑 2ExcelParser Agent)评审与交付报告

  • 日期:2026-08-09
  • 状态:有条件通过 → 评审发现 2 项 must-fix,已闭环修复后通过
  • 关联文档:docs/superpowers/plans/2026-08-08-milestone2-excel-parser.mddocs/design.md(§3.5/§9.4

一、交付内容

新实现 8 个任务、39+2 个测试用例(当前全量 41 passed),12 个提交:

任务 提交 说明
Task 1 ExcelParser 基础 df9427c excel_reader.pyopen_workbook/sheet_matrix)、provenance.pysource_uri 格式 file.xlsx#SheetName!CellRef)、拒绝 .xls
Task 2 SheetDetector 66753e4 sheet_detector.py 名称/表头关键词三级判定 → SheetType
Task 3 Sheet 性质判定 4f61d24 sheet_nature.pySheetNature(TABLE/FREE_TEXT/MIXED)、find_header_rowclassify_sheetdesign §3.5.2 启发式)
Task 4 MergeHandler+TableExtractor 63d0c90 merge_fill.py(合并单元格展开 forward_fill)、table_extractor.pyextract_tableCellValue+Provenance
Task 5 FormattingDetector 5818dd0 formatting_detector.py(取消线/背景色/批注),修正 2 处 openpyxl 3.1.5 兼容问题
Task 6 FreeTextExtractor a9cc3c9 free_text_extractor.py(全空行分段 + 占位表,extraction_method="llm_from_free_text"
Task 7 ExcelParser 编排器 18da20d excel_parser.pyExcelParseResult dataclass、ExcelParser.parse 编排全流程)
Task 8 真实样本集成测试 3307d7b test_real_samples.py 3 个端到端用例(新規開発/追加改修/自由記述)
最终评审 must-fix eebed38 header_row 接线 + formatting 回填(见下)

二、验收结论

验收项 结论
表格型解析(openpyxl 行列) 新規開発 6 表全通过,DB定義 20 行
自由记述型解析(分段+占位表) extract_text_blocks + build_free_text_tableLLM 结构化显式延后
混合型解析(§3.5.2 各段落最优解析) ⚠️ MIXED 折叠进纯表路径(评审跟踪#1,见「遗留记录」)
合并单元格下行填充 forward_fill 纵/横合并用例通过,编排器实际调用
source_uri 格式 file.xlsx#Sheet!Ref 用例通过
.xls 拒绝(ValueError 用例通过
取消率/背景色/批注保留 检测模块单测过 + 编排器实际回填(must-fix#2 后)
每任务 pytest 全绿 41 passed(含 3 样本用例无 skip
覆盖率 >80% ⚠️ 未安装 pytest-cov,未产出覆盖率报告(可选增强,非阻塞)

三、最终评审发现与修复(must-fix 闭环)

已过门的最终评审(里程碑级)发现 2 项 must-fix,均属本里程碑验收范围,已按 TDD 修复并回归:

1. find_header_row 结果未传入 extract_table

  • 问题:编排器 excel_parser.py 恒以默认 header_row=0 调用 extract_table;标题行置上(标题在首行、表头在第二行)的 Sheet 会把标题误当表头,损坏真实数据。
  • 修复:结构化路径改为 header_row = find_header_row(filled)<0 时回落 0。
  • 测试tests/test_excel_parser.py::test_parse_uses_detected_header_row(断言 headers 取第二行真实表头)。

2. cell_formatting 死代码(CellValue.formatting 恒 None

  • 问题:检测模块存在且单测过,但运行时从未被编排器调用,取消率样式到不了下游消费者。
  • 修复table_extractor.extract_table 新增可选参数 formatting_map: dict[(row,col), CellFormatting]excel_parser 遍历 ws.iter_rows() 构建 fmt_map 并传入。
  • 测试tests/test_excel_parser.py::test_parse_attaches_strikethrough_formatting(断言 CellValue.formatting.strikethrough is True)。

四、移交下个里程碑的遗留记录(deferred)

  1. MIXED 分段解析design §3.5.2「段落分割→各段落最优解析」正式延后;本里程碑固定为「MIXED→表格路径」(追加改修样本观测确认,弱断言接受)。
  2. comments 回填契约CellComment.source_uri 用物理坐标(file#sheet!A2),CellValue.provenance 用「列字母+相对数据行号」;消费方重链需做偏移换算(header_row≠0 时还需偏移)。建议给 Provenance.row 补注释明确「数据行号」语义。
  3. 提取方法枚举同源extraction_method 硬编码字符串 vs ExtractionMethod 枚举(§9.4.6 第 4 条);建议统一 ExtractionMethod.OPENPYXL.value / LLM_FROM_FREE_TEXT.valueTask6/7 已用字符串)。
  4. theme 色忽略_to_rgb_hex 对真实 theme 色(tinted)恒返 None,正式声明「仅检测显式 RGB 颜色」。
  5. sheet 命名规范sheet_matrix 对空 sheet 是否产生 [[None]] 幽灵表,skipped 实际难触发 —— 留待 Parser/Impact 衔接时验证。
  6. 公式双保留(§3.5.7)、多级表头扁平化、隐藏行列/密码:均超出本里程碑边界,确认延后(样本规模内无影响)。

五、测试证据

  • 全量:python -m pytest41 passed in ~4.35s14 基线 + 27 新增)
  • 真实样本端到端:新規開発 6 表 openpyxl / 追加改修 2 表 openpyxl + 改修ポイント FREE_TEXT 1 行 / 自由記述 3 表 llm_from_free_text
  • 缺陷观察:3 样本均 0 批注、无空 sheet

六、合规自查

  • data_models.py 全程未改动(评审 #4 验证)
  • 交流统一中文、标识符英文
  • 每次修改均追加 _AI_USAGE_LOG.md(范式步骤:需求理解/Agent 实现/测试验证/整体迭代)
  • 未上传任何客户/公司数据;API Key 未在源码中出现