乐于分享
好东西不私藏

合同、法规、规范类文档的 RAG 工程实践:如何答得准,还说得出依据

合同、法规、规范类文档的 RAG 工程实践:如何答得准,还说得出依据

前两篇我们讲过:普通企业知识库通常可以先从 Hybrid RAG 做起;如果文档问答需要更可靠,就要补上 Contextual Chunking、Metadata、Citation 等能力。

到了合同、法规、工程规范、招投标文件、财报、审计制度、扫描件和复杂表格这些场景,问题会进一步升级。

这类 RAG 不能只追求生成一个看似正确的答案,更要追求:

能不能找准依据、引用原文、区分版本、控制权限,并让用户能回到原文核对。

合同、法规、规范类文档的 RAG 难点

一、先看一个合同问题

用户问:

合同里乙方整改期限是多少?

文档里有一句话:

乙方应在收到甲方书面通知后 5 个工作日内完成整改,并将整改结果书面反馈给甲方。

如果系统只回答:

乙方整改期限是 5 个工作日。

这在普通问答里看起来已经够了,但在合同场景里还不够。

用户真正需要的是一组完整信息:

  • 答案是什么;
  • 依据来自哪份合同;
  • 是哪一章、哪一页、哪一条;
  • 是否是最新版本;
  • 当前用户是否有权限查看;
  • 能不能展示原文片段,方便复核。

所以这类场景的工程目标,不是让模型“猜得更像”,而是让系统把依据组织得足够可靠。

二、推荐工程链路

合同、法规、规范类文档的 RAG,可以按这条链路设计:

文档解析
  -> 结构化切分
  -> Contextual Chunking
  -> Metadata / 权限 / 版本入库
  -> Hybrid Retrieval
  -> Parent-Child Retrieval
  -> Rerank
  -> Citation 回答

这条链路里,每一步都不是装饰。

环节
主要任务
缺了会怎样
文档解析
还原 OCR、表格、页码、章节、图文关系
后面检索到的可能就是错结构
结构化切分
按章节、条款、表格语义切 chunk
切太碎丢条件,切太大带噪声
Contextual Chunking
给小 chunk 补文档、章节、对象、适用范围
小片段离开原文后容易找错
Metadata
保存文档名、页码、版本、权限、chunk_id、原文位置
无法过滤、审计、引用和排查
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 落地中的真实问题


RAG 选型系列:
【第一篇】常见 RAG 技术怎么选?别先追概念,先看问题类型
【第二篇】Hybrid RAG 为什么往往是企业知识库的默认起点?