合同、法规、规范类文档的 RAG 工程实践:如何答得准,还说得出依据
前两篇我们讲过:普通企业知识库通常可以先从 Hybrid RAG 做起;如果文档问答需要更可靠,就要补上 Contextual Chunking、Metadata、Citation 等能力。
到了合同、法规、工程规范、招投标文件、财报、审计制度、扫描件和复杂表格这些场景,问题会进一步升级。
这类 RAG 不能只追求生成一个看似正确的答案,更要追求:
能不能找准依据、引用原文、区分版本、控制权限,并让用户能回到原文核对。
合同、法规、规范类文档的 RAG 难点一、先看一个合同问题
用户问:
合同里乙方整改期限是多少?
文档里有一句话:
乙方应在收到甲方书面通知后 5 个工作日内完成整改,并将整改结果书面反馈给甲方。
如果系统只回答:
乙方整改期限是 5 个工作日。
这在普通问答里看起来已经够了,但在合同场景里还不够。
用户真正需要的是一组完整信息:
-
答案是什么; -
依据来自哪份合同; -
是哪一章、哪一页、哪一条; -
是否是最新版本; -
当前用户是否有权限查看; -
能不能展示原文片段,方便复核。
所以这类场景的工程目标,不是让模型“猜得更像”,而是让系统把依据组织得足够可靠。
二、推荐工程链路
合同、法规、规范类文档的 RAG,可以按这条链路设计:
文档解析 -> 结构化切分 -> Contextual Chunking -> Metadata / 权限 / 版本入库 -> Hybrid Retrieval -> Parent-Child Retrieval -> Rerank -> Citation 回答
这条链路里,每一步都不是装饰。
|
|
|
|
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
对这类文档来说,单点能力不够,关键是把它们串成一条稳定链路。
三、入库前:先把文档吃对
很多合同、规范、财报不是干净的纯文本。
它们可能有扫描页、跨页表格、脚注、页眉页脚、图注、章节编号和修订痕迹。只抽正文,常常会丢掉真正有价值的结构。
比如一个表格里写着:
整改期限:5 个工作日 适用情形:乙方违约 通知方式:甲方书面通知
如果解析时只拿到“5 个工作日”,后面再做检索、Rerank、Citation 都很难补回来。
所以第一步不是急着 embedding,而是先确认:
-
页码能不能对应回原 PDF; -
章节层级有没有识别出来; -
表格行列关系有没有保留; -
图片、图注、脚注有没有和正文关联; -
扫描件 OCR 错字是否会影响关键条款。
复杂文档 RAG 的上限,很多时候先卡在这里。
四、切分时:不要让 chunk 变成“孤句”
合同条款经常依赖前后文。
如果 chunk 只有一句:
乙方应在收到甲方书面通知后 5 个工作日内完成整改。
它本身有答案,但它没有说明这是哪份合同、哪类违约、哪一版文件、哪一页内容。
更稳的做法是让 chunk 带着语境入库:
文档名:采购合同模板 v2.1 章节路径:第三章 违约责任 > 3.2 乙方违约责任 页码:第 12 页 语境摘要:本段规定乙方收到甲方整改通知后的整改期限和反馈义务。 正文:乙方应在收到甲方书面通知后 5 个工作日内完成整改,并将整改结果书面反馈给甲方。
这就是 Contextual Chunking 的工程价值:让小片段在检索前就带着足够语境,减少“看起来相关但其实错了”的召回。
同时,版本、权限、页码、chunk_id、原文位置这些信息,不应该只写进正文里,还要作为 metadata 单独保存。这样系统才能做权限过滤、版本过滤、引用展示和问题排查。
五、检索时:小块负责命中,大块负责理解
合同类问题很容易同时需要“精确命中”和“完整理解”。
用户问“采购合同里乙方违约整改期限是多少”,检索时最好用小 child chunk 精准命中;但给模型生成答案时,只给这一句话又可能不够,因为它可能需要看到整条违约责任。
这时可以使用 Parent-Child Retrieval:
-
child chunk:小,适合检索; -
parent chunk:大,适合阅读和理解; -
命中 child 后,把对应 parent 一起给模型。
但 Parent-Child 不能替代 Contextual Chunking。
如果 child 一开始没有“采购合同”“乙方违约责任”这些语境,检索阶段没被命中,parent 根本没有机会出场。
所以更稳的组合是:
Contextual Chunking 负责让 child 更容易被找对;Parent-Child 负责命中后让模型看得更完整。
六、回答时:必须能回到原文
合同、法规、规范类文档的答案,不能只输出一个结论。
更理想的回答应该像这样:
乙方整改期限是 5 个工作日。 依据:采购合同模板 v2.1,第三章 违约责任,3.2 乙方违约责任,第 12 页。 原文:乙方应在收到甲方书面通知后 5 个工作日内完成整改,并将整改结果书面反馈给甲方。
这里的 Citation 不是形式主义,而是让用户能判断:
-
答案是不是来自正确文档; -
是不是最新版本; -
是否引用了完整条款; -
是否能回到原文复核。
如果系统不能给出来源,用户就只能相信模型。对高风险文档来说,这不够。
七、工程检查清单
落地这类 RAG 时,可以用下面这组问题自查:
-
文档解析后,页码和原文位置能不能回跳? -
表格、脚注、图注、章节结构有没有保留? -
chunk 是否带有文档名、章节路径、适用对象和语境摘要? -
metadata 是否包含版本、权限、页码、chunk_id、原文位置? -
检索是否同时支持语义问题和条款号、编号、专有名词? -
Parent-Child 是否只在命中后补上下文,而不是被误当成召回能力? -
Rerank 是否能把真正依据排到前面? -
Citation 是否能展示来源文档、章节、页码和原文片段? -
评估集是否覆盖版本差异、权限边界、相似条款和表格问题?
这些问题比“模型换成哪个更强”更重要。
八、总结
合同、法规、规范类文档的 RAG,不是让模型更会猜。
它真正要做的是:
让文档在入库时被正确解析、定位、组织和标注;让答案在输出时能回到原文、版本和权限。
合同、法规、规范类文档 RAG 的稳健工程链路如果普通知识库追求的是“能不能答上来”,那么合同、法规、规范类文档追求的是:
答得准,还要说得出依据。
这是【RAG 选型系列】的第三篇,重点聊了合同、法规、规范类文档的工程实践。
如果你也在做企业知识库、文档问答、合同审查或规范检索相关项目,欢迎在评论区留言,一起交流 RAG 落地中的真实问题。
夜雨聆风