装闭 RenoPit 源码解析(11):AI如何进行装修文档交叉核查

单独审查合同和报价单只能发现各自内部的问题,金额、施工项目和责任条款之间的矛盾需要把多份文档放在一起比较。装闭 RenoPit 的交叉核查实现位于 fthux/RenoPit,本篇分析它如何复用已有结果并生成差异清单。

一、交叉核查何时触发
Celery 完成逐份文档分析后,如果 doc_results 数量不少于两份,就调用 run_cross_check_sync(project_id)。该函数会再次查询数据库,只选择状态为 completed 且类型为 quotation 或 contract 的 DocumentAnalysis。
真正进入 LLM 前仍要求至少两条有效记录。因此“上传两份文档”并不等于一定核查:它们还需要完成分类和单文档分析。
二、为什么复用 risks_json
交叉核查没有再次读取整份合同原文,而是优先使用已经生成的 risks_json。每份摘要包含:
doc_type:合同或报价单;source_file:原始文件名;risks_json:单文档风险分析;risks_summary:风险标题和分类;- 报价单的金额摘要。
如果某条记录没有风险 JSON,则退回 classifications_json 构造简略摘要。这样交叉核查消费的是前一阶段的结构化产物,而不是重复执行同样的文档提取。
三、比对模式如何选择
detect_check_mode() 根据摘要中的 doc_type 返回模式:
if "contract" in doc_types and "quotation" in doc_types:
return "BILL_vs_CONTRACT"
if supervision_report_count >= 2:
return "SUPERVISION_TRACKING"
if "general" in doc_types and "quotation" in doc_types:
return "DESIGN_vs_BILL"
辅助模块支持合同与报价单、监理报告追踪、设计说明与报价单三种模式。当前 run_cross_check_sync() 的自动查询只选择 quotation 和 contract,因此正常项目主链使用的是 BILL_vs_CONTRACT。
四、Prompt 如何装入多份摘要
build_cross_check_user_message() 遍历摘要,为每份文档写入文件名和格式化 JSON。它还会附加单文件分析的摘要、风险数量和预计风险金额,但明确要求模型把重点放在文档差异本身。
系统 Prompt 根据模式规定检查内容,例如:
- 合同范围是否覆盖报价项目;
- 报价金额与合同总价是否一致;
- 材料品牌、规格和数量是否冲突;
- 付款节点与施工阶段是否匹配;
- 一份文件承诺的内容是否在另一份文件中缺失。
cross_check_documents() 得到 system 和 user 两段 Prompt 后,复用纯文本 LLM 重试函数完成调用。
五、差异结果如何写回综合分析
模型返回文本先经过 parse_json()。解析成功后,函数查询最近一条状态为 completed 的 Analysis,复制原有 raw_result_json,再加入新字段:
raw_json = dict(latest_analysis.raw_result_json or {})
raw_json["cross_document_checks"] = result_data
latest_analysis.raw_result_json = raw_json
db.commit()
交叉核查因此不是一张独立数据表,而是综合分析 JSON 的扩展部分。接口返回时会把这个字段与设计问题和文档结果一起交给前端。
结果通常包含 check_mode、参与比对的文档、discrepancies 差异数组,以及可选的监理问题追踪数据。每条差异记录来源文件、严重程度、风险说明和建议动作。
六、前端如何显示核查结果
AnalysisPage 检查 cross_document_checks.discrepancies 是否非空,再决定是否显示“跨文档核查”导航。具体内容交给 CrossCheckPanel。
组件把差异类型转换成中文标签和图标,按高、中、低风险展示。每条记录可以展开查看两份来源、风险后果和处理建议。若结果包含 supervision_tracking,面板还会显示已解决和未解决问题的追踪统计。
七、交叉核查调用链小结
RenoPit 的跨文档分析不是把所有原文重新塞给模型,而是先完成单文档结构化,再以风险 JSON 为摘要进行第二阶段推理。最终差异结果合并进综合 Analysis,报告页只需请求一次 /result 就能得到全部内容。
交叉核查的 Prompt、模式选择和持久化代码都可以在 fthux/RenoPit 中查看。下一篇将分析后端如何把这些不同来源的 JSON 统一成前端结构,以及 React 报告页怎样按数据条件渲染各个章节。
合同承诺和报价单项目对不上,AI 能否自动发现?解析 RenoPit 如何复用单文档风险结果,对比金额、材料、施工范围和付款节点,并生成可追溯的跨文档差异清单。
浙公网安备 33010602011771号