auto-parameter-consistency-review
目标
不依赖参数表、特性表或人工清单,自动从文档中发现重复出现的参数(≥2 次)并审查其值是否一致。
输入
- 一份或多份
.docx文档(.doc需要安装 antiword 或先转换为.docx) - 无需任何参数表或外部知识库
环境准备
pip install python-docx openpyxl
> 解析 .doc 格式需要安装 antiword:brew install antiword
硬约束
- 只审查重复出现的参数(≥2 次);单次出现不输出
- 不同方案、工况、构筑物、设备实例的同名参数不做直接比对(已通过实体感知分组自动实现)
- 不编造文档中不存在的参数、数值或章节
- 始终用 LLM 完成语义判断,无需外部 API key
- 仅输出
review-result.md和review-result.xlsx - 多文档审查时,必须跨文档交叉比对:同一参数在同一实体下跨文档出现时,必须归入同一组并逐对比较
工作流
1. 解析文档为结构化文本
使用 <skill_dir>/scripts/parse_docx.py 将文档解析为 blocks JSON(支持 .docx,.doc 需安装 antiword):
python <skill_dir>/scripts/parse_docx.py <文档路径或目录> <输出blocks.json>
解析引擎:
| 引擎 | 适用格式 | 安装方式 |
|---|---|---|
| python-docx(首选) | .docx |
pip install python-docx |
| antiword(降级) | .doc(纯文本) |
brew install antiword |
每条 block 格式:
{
"doc_path": "水工报告.docx",
"doc_title": "水工报告",
"chapter_path": "5 工程布置及建筑物 > 5.3 泄洪建筑物",
"block_index": 128,
"block_type": "paragraph",
"text": "工作闸门孔口尺寸为10.0×12.0m。",
"cells": []
}
> 注意:parse_all.py 是 parse_docx.py 的包装器,直接使用 parse_docx.py 即可。
1.1 大文档分批策略
单份 blocks JSON 文本总量超过 10 万字符 时,应拆分为多个按文档+章节分组的子文件,逐批抽取参数。拆分:
python <skill_dir>/scripts/split_blocks.py review_blocks.json blocks_chunks/
拆分后每批次只抽取一个子文件中的参数。所有子文件的抽取结果(JSON 片段)最后合并为完整的出现项列表,再进入归一化和分组步骤。
经验阈值:每批次 blocks JSON 控制在 3~8 万字符以内为宜。
2. 建立上下文(多文档统一上下文)
从所有文档的 blocks JSON 中提取整个项目的统一上下文。多文档共用同一上下文,不能各文档单独建:
- 项目名称、项目地点
- 主要构筑物/建筑物/设施:水库、大坝、水闸、泵站、电站、厂房、隧洞、渠道、桥梁、道路、管道等
- 主要设备:闸门、启闭机、拦污栅、水轮机、发电机、水泵、机组、钢管、变压器、开关柜等
- 方案状态:推荐方案、选定方案、比选方案、上阶段方案
- 参与审查的文档清单及其专业归属(如水文报告、水工报告、机电报告、施工组织设计等)
该上下文在参数抽取前先建立,传递到后续每批抽取步骤中,避免重复阅读。统一上下文有助于后续跨文档归并时识别同一参数。
3. 自动抽取、归一、分组与初比较
使用 <skill_dir>/scripts/param_extract.py 一步完成:参数抽取 → 单位归一 → 参数名归一 → 分组 → 初比较。该脚本输出已分组的审查结果,LLM 只需复核确认。
python <skill_dir>/scripts/param_extract.py review_blocks.json pre_grouped_result.json
脚本处理流程:
1. 从所有 blocks 中正则匹配"参数名+数值+单位"模式、复合尺寸、表格行
2. 自动过滤非参数词(传感器、监测、施工等设备名)
3. 单位归一(m³/s、m3/s、立方米/秒 → m³/s;℃、°C、摄氏度 → ℃)
4. 参数名归一(正常水位 → 正常蓄水位、总装机 → 装机容量、多年平均风速 → 年平均风速)
5. 按实体+参数名分组,仅保留出现 ≥2 次的组(不同实体同名参数分属不同组)
6. 自动初比较:值一致标记 consistent,不一致标记 conflict,标注冲突范围(同章节/跨章节/跨文档)
3.1 实体感知分组
脚本自动按 (实体, 参数名) 分组,不同实体的同名参数分属不同组,不会误比:
| 分组方式 | 说明 | 示例 |
|---|---|---|
参数名\|实体 |
实体从章节路径中提取 | 最大坝高\|碾压混凝土重力坝方案 vs 最大坝高\|混凝土面板堆石坝方案 |
参数名 |
无实体时按参数名分组(全局参数如水位、库容) | 正常蓄水位(跨文档比较) |
核心原则:A闸的高与B闸的高不比较,只有同实体的参数才进入一致性审查。
3.2 二次冲突复核
使用 conflict_review.py 对冲突参数做自动二次复核:
python <skill_dir>/scripts/conflict_review.py pre_grouped_result.json review_blocks.json refined_result.json
二次复核自动处理:
- 过滤噪声:单字参数(长/宽/高/径/距等)自动过滤
- 方案区分:检测参数是否属于不同比选方案/工况,标记为 needs_review
- 跨文档全局参数:水位、库容、装机等全局参数,跨文档时必须一致
- 章节根路径检查:同章节的同参数值不一致 → 真实冲突
3.3 LLM 复核与补充
读取 refined_result.json(二次复核后的结果),重点做以下工作:
- 复核:检查自动分组是否正确,特别是跨文档的同一参数是否被正确归入同一组
- 修正:拆分误归并的参数(如不同构筑物的同名参数),补充 object、instance 字段
- 补充常见遗漏:脚本难以捕获的非常规表达参数(特别是跨文档出现的相同参数但命名差异较大时),手动补充到对应组中
- 气象参数确认:气温、风速、降水量、蒸发量等已由脚本自动抽取并分组,核对其分组是否正确
脚本已自动完成的步骤(无需 LLM 重复做):
❌ 不需要逐条筛选候选列表
❌ 不需要手动单位归一
❌ 不需要手动参数名归一
❌ 不需要手动分组
❌ 不需要手动区分不同方案的参数(二次复核已自动识别)
每个出现项记录为:
{
"occurrence_id": "doc1-b128-p1",
"doc_path": "水工报告.docx",
"chapter_path": "5 工程布置及建筑物 > 5.3 泄洪建筑物",
"param_name": "孔口尺寸",
"raw_value": "10.0×12.0m",
"unit": "m",
"object": "泄洪表孔",
"instance": "工作闸门",
"condition": "",
"scheme_status": "final",
"evidence": "工作闸门孔口尺寸为10.0×12.0m。"
}
3.4 参数抽取范围
LLM 应全面扫描以下类别参数,不限于此清单:
水位/水文类:正常蓄水位、死水位、汛限水位、设计洪水位、校核洪水位、坝前水位、库水位、特征水位、上游水位、下游水位、最高水位、最低水位、防洪水位、调洪水位、极限死水位、正常蓄水位(上游/下游)、设计洪水位(上游/下游)、校核洪水位(上游/下游)、正常蓄水位水深、设计洪水位水深、校核洪水位水深、总库容、调节库容、兴利库容、死库容、防洪库容、调洪库容、有效库容、拦洪库容、滞洪库容、静库容、动库容
流量类:设计流量、校核流量、洪峰流量、下泄流量、发电流量、生态流量、多年平均流量、引水流量、入库流量、出库流量、平均流量、最大流量、最小流量、泄洪流量、泄量、单宽流量、额定流量、引用流量、调洪流量、设计洪水流量、校核洪水流量、单机额定引水流量、最大泄量(单孔)
高程/尺寸类:坝顶高程、坝底高程、建基面高程、坝高、最大坝高、坝顶宽度、坝底宽度、坝顶长度、坝长、三角形顶点高程、折坡点高程、坝段长、坝段长度、上游坡比、下游坡比、堰顶高程、溢流宽度、孔口底板高程、孔口尺寸、孔口宽度、孔口高度、闸孔数、单孔净宽、闸孔总净宽、闸槛高程、闸顶高程、闸墩高度、闸室长、闸室宽、闸室底板厚度、中墩厚度、边墩厚度、底板高程、管中心线高程、上平段管中心线高程、下平段管中心线高程、进水口高程、进水口底板高程、引水洞径、调压井直径、钢管直径、钢管壁厚、钢管内径、安装高程、发电机层高程、水轮机层高程、尾水管底板高程、吊车轨顶高程、机组间距、主厂房跨度、主厂房长度、长度、宽度、高度、厚度、直径、内径、深度、跨度、断面尺寸、桩长、桩径、埋深、净高、净宽
气象/环境类:多年平均气温、最高气温、最低气温、极端最高气温、极端最低气温、月平均气温、年平均气温、多年平均温度、水温、河流水温、最高水温、最低水温、最大风速、多年平均最大风速、年平均风速、设计风速、瞬时风速、基本风压、多年平均降水量、年降水量、汛期降水量、最大日降水量、暴雨强度、多年平均蒸发量、水面蒸发量、年蒸发量、湿度、相对湿度、标准冻深、最大冻土深度、最大积雪深度、年日照时数、无霜期、干旱指数、干燥度、能见度
地震/地质类:地震基本烈度、地震设防烈度、设防烈度、设计烈度、地震动峰值加速度、地震动反应谱特征周期、地震系数、设计地震加速度、地基承载力、地基承载力特征值、地基土类别、摩擦系数、内摩擦角、凝聚力、粘聚力、岩石抗压强度、岩石抗拉强度、岩石抗剪强度、软化系数、弹性模量、泊松比、变形模量、压缩模量、渗透系数、允许承载力、桩端阻力、侧摩阻力
机电/设备类:装机容量、总装机容量、单机容量、装机功率、装机台数、机组台数、机组形式、机组容量、机组数量、额定功率、额定容量、额定电压、额定电流、额定转速、功率因数、保证出力、年发电量、多年平均发电量、励磁电压、励磁电流、电压等级、电负荷、厂用电率、水轮机型号、额定水头、最大水头、最小水头、平均水头、加权平均水头、设计水头、利用水头、工作水头、额定流量、额定出力、最大出力、效率、比转速、吸出高度、扬程、转速、水泵型号、必需汽蚀余量、允许吸上高度、电机功率、额定频率、防护等级、绝缘等级
水工/建筑类:建筑物级别、工程等别、工程等级、设计标准、防洪标准、抗震设防类别、抗震等级、耐火等级、防水等级、坝型、闸门形式、工作闸门形式、检修闸门形式、事故闸门形式、快速闸门形式、封堵闸门形式、工作闸门类型、检修闸门类型、事故门形式、启闭机容量、启闭机扬程、闸门尺寸、闸门重量、消能形式、消力池长、消力池深、消力池底板厚度、消力池总长、海漫段长度、海漫段厚度、防冲槽深、防冲槽底长、铺盖长、铺盖厚、护坦长、导流方式、导流标准、导流流量、截流流量、围堰顶高程、围堰形式
材料/强度类:混凝土强度等级、抗渗等级、抗冻等级、混凝土材料、混凝土容重、钢筋混凝土容重、水容重、重力加速度、钢材牌号、屈服强度、抗拉强度、抗压强度、延伸率、干密度、最优含水率、最大干密度、含水率、密度、重度、孔隙率、饱和度、液限、塑限、塑性指数、液性指数
金属结构类:拦污栅形式、拦污栅孔口尺寸、拦污栅孔口宽度、拦污栅孔口高度、拦污栅底板高程、拦污栅道数、拦污栅清污方式、钢管内径、钢管壁厚、钢管材质、岔管形式、伸缩节型式、工作闸门门槽宽、工作闸门门槽深、检修闸门门槽宽、检修闸门门槽深、快速门门槽宽、快速门门槽深
电气类:发电机型号、额定容量、额定电压、额定电流、额定转速、功率因数、主变型号、变比、接线组别、短路阻抗、冷却方式、电压等级、断路器型式、隔离开关型式、额定短路开断电流、输电电压、线路长度、导线截面、回路数、电缆型号、电缆截面、变压器容量、开关柜型号
施工类:施工总工期、筹建期、准备工期、主体工程施工期、完建期、浇筑温度、入仓温度、最高温度、内外温差、基础温差、允许温差、温控标准、砂石料需用量、混凝土浇筑强度、混凝土方量、土石方量
水力/流体类:糙率、糙率系数、曼宁系数、渗透坡降、渗漏量、渗流量、流速、流速系数、单宽流量、单宽泄量、设计水头差、最大水头差、水位差、消能率、冲刷深度、水跃长度、水舌挑距、冲坑深度、水垫厚度、水头损失、沿程水头损失、局部水头损失
结构受力类:设计荷载、标准荷载、永久荷载、可变荷载、偶然荷载、弯矩、剪力、轴力、扭矩、应力、应变、位移、变位、沉降、挠度、转角、抗滑稳定安全系数、抗倾覆安全系数、抗浮安全系数、整体稳定安全系数、水压力、静水压力、动水压力、扬压力、渗透压力、浮托力、泥沙压力、浪压力、冰压力、土压力、风荷载、雪荷载
经济评价类:工程投资、总投资、静态投资、建筑工程投资、机电设备投资、金属结构投资、施工临时工程投资、移民投资、环境保护投资、经济内部收益率、财务内部收益率、净现值、效益费用比、投资回收期、年运行费、年发电效益、供水效益、灌溉效益、单位千瓦投资、单位电能投资
环境/移民类:生态流量、最小下泄流量、生态需水量、环境需水量、移民人口、搬迁人口、生产安置人口、征地面积、淹没面积、淹没损失、pH 值、溶解氧、COD、BOD、氨氮、总磷、悬浮物
通用参数:数量、面积、体积、重量、质量、投资、工期、造价、单价、总价、温度、压力、渗流量、沉降量、保证率、发电保证率、灌溉保证率、供水保证率、年利用小时数、发电量、供水量、灌溉面积、长度、宽度、高度、厚度、直径、深度、距离、间距、高程、坡度、坡比、比例尺
3.5 常见表达方式
参数名:数值单位、参数名=数值、参数名 数值单位- 表格行:
参数名 | 数值 | 单位 - 复合尺寸:
宽×高、b×h、长×宽×高 - 前缀 + 参数名:如
XX水库正常蓄水位 - 修饰词 + 参数名:设计/校核/正常/死/最大/最小/额定/单机/总
- 组合参数:
参数名1/参数名2 数值1/数值2 单位
3.6 多实例处理
当同一参数名出现在不同构筑物或设备上下文中时,在 object 和 instance 字段中记录归属。以下情况必须按实例拆分,不把不同实例的值直接比对:
- 孔口尺寸、孔口宽度、孔口高度(区分表孔/中孔/底孔,区分工作门/检修门/事故门)
- 底板高程、底坎高程、管中心线高程(区分不同管段、不同部位)
- 闸门形式(区分工作闸门/检修闸门/事故闸门/快速闸门)
- 拦污栅参数(区分不同进水口、不同编号)
- 钢管内径(区分主管/支管/岔管、上平段/下平段)
- 坝段长度、坝段相关参数(按坝段编号或名称区分)
- 机组容量、机组参数(按机组编号区分)
3.7 大文档分批处理
如果 blocks JSON 超过 10 万字符,先用 split_blocks.py 拆分为按章节的子文件,然后对每个子文件独立运行 param_extract.py,最后合并所有子文件的 pre_grouped_result.json(按 group_key 合并 occurrences 列表)。
4. LLM 复核与交叉比对
脚本输出的 pre_grouped_result.json 中已包含初步分组和比对结果,LLM 需复核以下内容:
4.1 复核分组正确性
- 跨文档的同一参数是否被正确归入同一组(例如水文报告中的"正常蓄水位"与水工报告中的"正常蓄水位"应在一组)
- 不同构筑物的同名参数是否被误归入同一组(如表孔闸门与底孔闸门的孔口尺寸应分开)
- 需要按 object+instance 拆分的参数是否已拆分
4.2 复核比对结果
- 脚本标记的 consistent 是否真的值一致
- 脚本标记的 conflict 是否真的不一致(排除精度/格式/单位差异)
- 对不一致项,确认最小冲突范围:同章节/跨章节/跨文档
4.3 跨文档重点比对
重点检查以下典型跨文档参数的一致性:
- 水位类:正常蓄水位、死水位、设计洪水位、校核洪水位——这些参数常在各专业报告中重复引用
- 库容类:总库容、调节库容、死库容
- 流量类:设计流量、校核流量、生态流量、发电流量
- 高程类:坝顶高程、建基面高程、堰顶高程
- 装机容量、机组台数、建筑物级别、地震烈度
4.4 补充脚本遗漏
- 脚本难以捕获的非常规表达参数,手动补充
- 复合值(如 "宽10m,高12m" 拆分为宽和高分别比对)
5. 输出审查结果
5.0 合并复核修正
LLM 复核后,使用 merge_review.py 将预分组结果与修正合并,生成最终结构化 JSON:
# 无修正时直接转换
python <skill_dir>/scripts/merge_review.py pre_grouped_result.json review-full-result.json
# 带 LLM 复核修正时
python <skill_dir>/scripts/merge_review.py pre_grouped_result.json review-full-result.json corrections.json
修正文件 corrections.json 格式:
{
"split": [
{
"group_key": "孔口尺寸",
"field": "inferred_object",
"object": "",
"instance": ""
}
],
"merge": [
{
"group_keys": ["正常蓄水位|XX水库", "正常蓄水位"],
"new_key": "正常蓄水位|XX水库",
"status": "consistent"
}
],
"update": [
{
"group_key": "孔口尺寸|泄洪表孔",
"fields": { "object": "泄洪表孔", "instance": "工作闸门" }
}
],
"remove": ["非参数项|..."]
}
5.1 内部结构化结果
先形成完整结构化 JSON,用于支撑 Markdown 和 Excel 输出:
{
"summary": {
"document_count": 2,
"parameter_occurrence_count": 200,
"repeated_group_count": 30,
"consistent_count": 25,
"conflict_count": 3,
"needs_review_count": 2
},
"parameter_groups": [
{
"group_key": "正常蓄水位|XX水库|||final",
"canonical_param_name": "正常蓄水位",
"object": "XX水库",
"instance": "",
"condition": "",
"scheme_status": "final",
"status": "consistent",
"conflict_scope": "",
"reason": "数值相同,单位等价",
"occurrences": [
{
"doc_path": "规划报告.docx",
"chapter_path": "2 工程任务和规模",
"raw_value": "2580.00m",
"evidence": "正常蓄水位为2580.00m。"
}
]
}
]
}
将结构化 JSON 保存到临时文件(如 review-full-result.json),用于后续 Excel 转换。
5.2 Markdown 审查报告 review-result.md
包含以下内容:
1. 基本信息:审查文件、审查范围、审查日期
2. 统计汇总:文档数、参数出现项数、重复参数组数、一致组数、冲突组数、需复核组数
3. 冲突项清单:按同章节冲突、跨章节冲突、跨文档冲突分类,列明参数组、差异值、冲突原因、涉及文档和证据位置
4. 需复核项清单:说明归属、实例、工况、方案或量纲不确定的原因
5. 一致项摘要:列参数组名和值,不展开全部证据
6. 逐项证据:每个冲突项和需复核项附文档名、章节路径、原文摘录和判定理由
5.3 Excel 汇总表 review-result.xlsx
将合并后的结构化 JSON review-full-result.json 转换为 Excel 汇总表,包含 4 个工作表:
python <skill_dir>/scripts/review_to_excel.py review-full-result.json review-result.xlsx
| 工作表 | 内容 |
|---|---|
| 统计汇总 | 文档数、参数出现项数、重复组数、一致/冲突/需复核 |
| 冲突清单 | 每个冲突参数的详细值分布和原文证据 |
| 需复核 | 归属不清、方案不明、量纲差异的待确认项 |
| 一致项 | 所有数值一致的参数组,含出现次数 |
异常处理
| 场景 | 处理方式 |
|---|---|
| 文档无法解析(加密/损坏) | 提示用户提供未加密的 .docx |
| python-docx 环境缺失 | pip install python-docx 或安装 antiword 解析 .doc |
| openpyxl 环境缺失 | pip install openpyxl |
| 解析时源目录出现 WMF 等残留图元文件 | 使用 parse_docx.py(已内置临时目录隔离,不会污染源目录) |
| 单文档 blocks JSON 超过 10 万字符 | 先用 split_blocks.py 按章节拆分,逐批抽取后合并 |
| 单批抽取超时/卡顿 | 缩小分批粒度,每批控制在 3~8 万字符 |
| 气象等参数在最终结果中缺失 | 检查 LLM 筛选步骤是否误将气温/风速/降水量等视为描述性文本过滤掉;确保 3.1 筛选阶段保留所有带数值的参数 |
| 跨文档冲突少,几乎全是同文档冲突 | 检查分组阶段是否将所有文档的同一参数归入一组,还是按文档分开分组;确保 5 分组步骤执行了跨文档别名归并和实例对齐;前处理时确认统一上下文已包含所有文档的清单 |
| 多文档审查时文档数 >6 份 | 建议分批运行,每批 ≤4 份 |
| 所有文档产生分组 <5 个 | 正常输出最小可用报告,标注"参数稀疏" |
| JSON 转 Excel 失败 | 确保已生成结构化 JSON 并检查格式 |
质量检查
- [ ] 是否只对重复出现(≥2 次)的参数组输出了一致性结论
- [ ] 是否已按构筑物、设备实例、工况、方案状态区分参数组
- [ ] 是否对孔口尺寸、闸门形式、底板高程、钢管内径等多实例参数做了实例拆分
- [ ] 是否标注了每个冲突项的最小冲突范围
- [ ] 是否每个冲突项和需复核项都有可追溯原文证据(文档名、章节路径、原文摘录)
- [ ] 是否避免把不同构筑物、不同实例、不同工况、不同方案的同名参数直接比对
- [ ] 是否已排除精度/单位/格式差异导致的误判
- [ ] 是否已保存
review-result.md - [ ] 是否已从结构化 JSON 生成
review-result.xlsx - [ ] 是否没有编造文档中不存在的参数、数值或章节