# 完整性审查方案对比分析 ## 一、当前系统链路分析(方案A:先分类再解释) ### 数据流 ``` PDF文档 │ ▼ ┌─────────────────────────────────────────────────────┐ │ doc_worker (文档处理) │ │ ├─ PDF提取 + OCR + 版面检测 │ │ ├─ 文本切分 → chunks │ │ └─ 目录构建 → outline │ └─────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────┐ │ HierarchyClassifier (一级/二级分类) │ │ ├─ LLM调用: 对每个一级目录项分类 │ │ ├─ 输出: chapter_classification (如 "basis") │ │ └─ 输出: secondary_category_code (如 "LawsAndReg") │ └─────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────┐ │ LLMContentClassifier (三级分类) │ │ ├─ 加载 StandardCategoryTable.csv 标准 │ │ ├─ Embedding相似度预筛选 (可选) │ │ ├─ LLM调用: 对每个chunk的内容行级分类 │ │ ├─ 补充验证: 对可能遗漏的标准项二次确认 │ │ └─ 输出: tertiary_classification_details │ │ └─ third_category_code + 行号范围 + 内容 │ └─────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────┐ │ LightweightCompletenessChecker (完整性检查) │ │ ├─ 从chunks提取实际三级分类 (集合运算, 无LLM) │ │ ├─ 从CSV加载标准三级分类 │ │ ├─ 集合差: missing = required - actual │ │ ├─ 目录审查: outline vs 标准 (二级粒度) │ │ ├─ 一致性审查: outline vs 正文 (二级粒度) │ │ └─ 生成建议: │ │ ├─ issue_point: 模板字符串拼接 │ │ ├─ reason: 模板字符串拼接 │ │ └─ suggestion: LLM生成 (1次调用/缺失级别) │ └─────────────────────────────────────────────────────┘ │ ▼ 输出: recommendations[] (每条含 level/issue_point/location/suggestion/reason) ``` ### 关键代码路径 | 步骤 | 文件 | 方法 | |------|------|------| | 一级分类 | `doc_worker/classification/hierarchy_classifier.py` | `HierarchyClassifier.classify_async()` | | 三级分类 | `reviewers/utils/llm_content_classifier_v2/main_classifier.py` | `LLMContentClassifier.classify_chunks()` | | 完整性检查 | `reviewers/completeness_reviewer.py` | `LightweightCompletenessChecker.check()` | | 引擎入口 | `ai_review_engine.py:659` | `check_completeness()` | ### LLM调用次数(方案A) - 一级分类: N次 (N = 一级目录数) - 三级分类: M次 (M = chunk数,可能分块) - 补充验证: K次 (K = 可能遗漏的标准项数) - 建议生成: 1次/缺失级别(一级/二级/三级各1次) **总计: N + M + K + 3 次LLM调用** --- ## 二、替代方案(方案B:直接LLM解释) ### 数据流 ``` PDF文档 │ ▼ ┌─────────────────────────────────────────────────────┐ │ doc_worker (文档处理) — 同方案A │ └─────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────┐ │ 直接LLM审查 │ │ ├─ 输入: chunks文本 + StandardCategoryTable标准 │ │ ├─ LLM一次性判断: 每条标准是否覆盖 │ │ ├─ 输出: is_covered + evidence + reason │ │ └─ 单次调用完成所有判断 │ └─────────────────────────────────────────────────────┘ │ ▼ 输出: items[] (每条含 standard_code/is_covered/evidence/reason/confidence) ``` ### LLM调用次数(方案B) - 每个章节: 1次LLM调用(可能需要分块,但远少于方案A) **总计: ~C 次LLM调用(C = 章节数,通常10个左右)** --- ## 三、对比维度 | 维度 | 方案A(先分类再解释) | 方案B(直接LLM解释) | |------|----------------------|---------------------| | **LLM调用次数** | N+M+K+3 (~50-100次) | C (~10次) | | **延迟** | 高(多次LLM串行/并行) | 低(单次调用) | | **成本** | 高(大量token消耗) | 低 | | **准确性** | 高(分类结果可验证,集合运算精确) | 依赖LLM判断能力 | | **可解释性** | 高(有明确的分类代码和行号) | 中(LLM给出证据但无结构化分类) | | **可追溯性** | 高(三级分类代码可回溯到CSV标准) | 低(LLM判断过程不透明) | | **一致性** | 高(集合运算是确定性的) | 低(LLM每次可能不同) | | **维护成本** | 高(需维护分类器+标准表) | 低(只需维护标准表) | | **扩展性** | 差(新增标准需重新训练分类器) | 好(改prompt即可) | | **误报率** | 低(分类准确则判断准确) | 中(LLM可能误判) | | **漏报率** | 中(分类器可能漏分类) | 中(LLM可能遗漏) | --- ## 四、对比测试设计 ### 测试目标 1. **准确性对比**: 两种方案对同一文档的缺失项判断是否一致 2. **延迟对比**: 端到端执行时间 3. **质量对比**: 建议的可操作性和专业性 4. **一致性对比**: 多次运行结果的稳定性 ### 测试数据 使用 `temp/construction_review/final_result/` 下的真实审查结果文件,每个文件包含: - `document_result.structured_content.chunks`: 已处理的文档分块(含三级分类结果) - `ai_review_result`: 已有的审查结果(作为参考基准) ### 测试流程 1. 加载测试数据(chunks + outline) 2. 对每个章节分别执行方案A和方案B 3. 对比两种方案的输出: - 缺失项集合的交集/差集 - 建议的质量评分(人工或LLM评判) - 执行时间和token消耗 4. 生成对比报告 ### 评估指标 | 指标 | 计算方式 | |------|---------| | 缺失项一致率 | \|A∩B\| / \|A∪B\| | | 方案A独有缺失 | \|A - B\| (A认为缺失但B认为覆盖) | | 方案B独有缺失 | \|B - A\| (B认为缺失但A认为覆盖) | | 耗时比 | Time_A / Time_B | | 建议质量 | 人工评分1-5分 |