装闭 RenoPit 源码解析(10):AI如何审查装修合同与报价单

装修风险不仅藏在设计图里,也常出现在计价方式、模糊条款和后期增项中。装闭 RenoPit 在开源仓库 fthux/RenoPit 中为合同和报价单建立了独立分析链,本篇追踪分类、LLM 审查、JSON 保存和增项预测。

一、文档分析从重新提取文本开始
run_document_analysis_sync(project_id, project_file_id) 先确认文件记录属于当前项目,并检查磁盘实体存在。它根据原始文件名取得扩展名,再调用文件解析器提取纯文本。
即使上传阶段已经保存过 extracted_text,这里仍会从实体文件重新解析并更新数据库,确保本次分析使用当前文件内容。空文本会直接返回失败结果。
二、规则分类器如何识别文档
classify_document() 不调用大模型,而是统计关键词和金额格式。它分别计算合同关键词与报价关键词命中数:
- 命中 3 个以上合同词,分类为
contract; - 否则命中 3 个以上报价词,分类为
quotation; - 只有金额、报价词不足时,以 0.45 置信度判断为非标准报价单;
- 命中无关内容模式时,分类为
irrelevant。
关键词数量达到 3、5、10 时,基础置信度分别为 0.60、0.75 和 0.90。报价单检测到金额后还会增加 0.10,最高不超过 0.95。
分类器同时计算中文字符占比,给出 zh、en 或 mixed,并提取关键片段、原因和分析建议。所有信息写入 DocumentAnalysis.classifications_json,文档类型和置信度则写入独立字段。
三、合同分析使用专用 Prompt
analyze_document() 调用 build_document_analysis_prompt(),从知识库加载三类规则:
- 报价陷阱
billing_traps; - 合同条款
contract_clauses; - 增项模式
extra_item_patterns。
用户消息包含真实文件名和完整文档文本,随后通过纯文本 LLM 路径发送。分类结果主要用于记录文档类型和决定后续分支,当前主流程仍会把已提取文本交给 LLM 审查。
模型需要返回 summary、total_estimated_risk 和 risks。每个风险项包含分类、原文、批判说明、财务后果和修改建议。
四、文档 JSON 如何保存
LLM 文本交给 validate_document_report()。它同样先直接解析,再使用 json_repair;但文档报告要求 risks 必须是非空数组。校验通过后,结果写入:
doc_analysis.risks_json = result_data
doc_analysis.summary = result_data.get("summary", "")
doc_analysis.total_estimated_risk = result_data.get(
"total_estimated_risk", ""
)
doc_analysis.risks_count = len(result_data.get("risks", []))
doc_analysis.status = "completed"
失败时记录 error_message 和完成时间。每份文档拥有独立 DocumentAnalysis,因此合同成功、报价单失败时,已完成结果仍然可以进入报告。
五、报价单为什么还有第二次 LLM 调用
只有 classification.doc_type == "quotation" 时,分析引擎才执行 predict_extra_items()。它先把报价单风险 JSON 序列化为文本,再与 extra_item_patterns 知识库一起构造增项预测 Prompt。
预测结果包含报价总额、预计实际总额、置信区间、风险等级和可能出现的增项列表。每个增项还包含发生概率、金额范围、触发阶段、原因和预防方式。

返回文本通过通用 parse_json() 解析。成功后,代码复制原 result_data,加入 extra_item_prediction 再赋回 risks_json。使用新字典可以让 SQLAlchemy JSON 字段识别本次变更。
增项预测异常只记录警告,不会把已经成功的合同或报价单分析改成失败。
六、document_extractor 的位置
项目中还有 document_extractor.py,提供不同文档类型的结构化摘要 Prompt 和分类结果映射函数。当前自动文档分析主链直接使用 analyze_document() 生成风险 JSON,CodeGraph 调用关系中没有主流程调用该摘要提取入口;跨文档核查优先复用 DocumentAnalysis.risks_json。
七、文档分析调用链小结
RenoPit 的合同链路由两层组成:规则分类器负责快速识别文档类型和置信度,LLM 根据装修合同知识库输出结构化风险。报价单完成风险分析后,再追加一次增项预测,并将两类结果保存在同一个 risks_json 中。
完整分类规则、Prompt 和分析流程位于 fthux/RenoPit。下一篇将把视角从单份文档扩展到多份文档,分析合同和报价单之间的不一致如何被自动识别。
装修合同里的模糊条款、报价陷阱和后期增项如何被 AI 识别?拆解 RenoPit 的关键词分类器、合同审查 Prompt、风险 JSON 校验,以及报价单二次增项预测链路。
浙公网安备 33010602011771号