RAG 知识库语义边界分块与长文档切片质量治理落地

日期:2026-08-23

一、项目背景

这个政企知识库项目,制度文档动辄上百页,一份员工手册或者合规办法,天然是按章节、条款、表格组织的。初版我们用了最常见的固定字数切分,每 500 字切一刀。结果客服检索回来,经常是一段话从中间被劈开,答案只有半句,比如「年假天数按」后面就没了,客服照着念把用户带偏,被投诉了好几次。客户说,你们这知识库答非所问比没有还糟,宁可客服翻 PDF 也不信你们返回的片段。

底子是标准的 RAG 流水线,文档解析、切片、向量化、检索重排都在,问题出在最前端的切片策略,这一步没做对,后面再好的重排也救不回来。

二、落地场景

切片不再按字数,而是先识别文档的语义边界:章节标题、条款编号、表格起止,按这些边界切。长文档切完保留层级上下文,比如这条条款属于第几章第几节,作为元数据带在切片上,检索时参与过滤。切完跑离线抽检,抽样看切片是否完整、答案是否截断。发现 badcase 回流,调整边界识别规则重新切,形成持续迭代的闭环。

三、关键技术挑战与解决思路

语义边界识别是第一道关。纯靠字号判断标题不稳,我们用规则加轻量模型结合:正则匹配「第 X 章」「X.X 条」这类结构标记,再辅以标题行的排版特征(居中、加粗、独占一行)。表格要单独识别起止行,不能让表格被切成两半,表格一旦断开,检索回来就是半张表,比文本截断更没法用。

长文档层级上下文不能丢。一个条款脱离了「它属于第三章薪酬」这个上下文,检索回来很容易和别的章节混淆,尤其是不同章节有同名概念时。我们把层级路径拼到切片文本前面或者作为 metadata,检索时参与过滤,召回准确率明显上来。

切片质量评估靠离线抽检加 badcase 回流。我们建了一个小标注集,定期跑切片完整率,截断率超过阈值就触发规则复审,而不是等线上被投诉才发现,那时候口碑已经伤了。

案例片段(已脱敏): 层级上下文拼接(示意): ``` chunk = {  "text": "第三章 薪酬 第十条 年假天数按工龄计算:\n"          "满1年不满10年5天,满10年不满20年10天……",  "meta": {"chapter": 3, "section": "薪酬", "clause": 10} }

检索时按 clause 边界保证不被截断

assert not split_inside(clause_marker) ``` 一次抽检发现「第十条」被切在段中,规则补了条款编号识别后,该类截断从抽样 14% 降到 1% 以内。另一次表格被切成两半,补了表格起止识别后召回准确率回升。

四、效果数据

切片完整率从固定字数切的约 72% 提到 97% 以上,条款从中间断开的情况基本消失,客服再也不用对着半句话硬编。检索命中率(命中正确条款)从约 68% 提到 91%,层级上下文帮检索过滤掉大量同词不同义的干扰,尤其是跨部门同名概念。答案截断率从约 19% 降到 2% 以下,客服被投诉的次数按月看掉了八成,客户终于敢把知识库当标准答案用。badcase 回流量稳定在每月几十例,形成持续迭代闭环,切片质量不再靠一次性调参。

五、可复用经验总结

RAG 效果的上限很大程度被切片策略锁死,固定字数切分是新手最容易踩的坑,条款从中间断开答案必然残缺,而且这种残缺客服最容易照着念出去。语义边界识别别只靠一种信号,结构标记加排版特征结合才稳,表格一定要单独处理,半张表比半句话更没法用。层级上下文是长文档的灵魂,丢了它检索就像盲人摸象,同名概念会互相干扰。我们当时为了赶进度直接用现成 500 字切,线上被用户抓包少半句政策,返工重切比一开始就做对花的时间多得多。切片质量要离线抽检常态化,别等投诉上门才回头看,那时候丢的是信任不是指标。

结语

切片治理跑起来后,这个知识库从「答非所问」变成了客服愿意引用的标准源,客户甚至开始往里塞更多制度文档。有个我们踩的后续坑,是文档更新后旧切片没及时失效,导致同一份制度新旧两版并存,检索偶尔召回旧的,又被抓包一次。后来加了文档版本号,切片跟着版本走,更新即重切。说到底切片不是一次性工程,是和文档生命周期绑定的持续治理。如果再扩,我会把切片质量指标做成看板,让客户自己能看到完整率和截断率,而不是等我们抽检才发现问题。

回头看,切片治理一旦做成闭环,客户才真正敢往知识库里持续灌文档,因为不怕越多越乱。我们后来把切片质量指标拆成了截断率、跨边界率、空切片率三项分别盯,比单一完整率更能定位问题,比如跨边界率高说明边界识别规则要调,空切片率高说明有脏文档混进来。还有个小改进,是给每条切片打上来源文档和段落锚点,客服引用的答案能一键跳回原文,用户信任度又上了一个台阶。知识库这种系统,可信比聪明重要,能溯源的答案用户才敢用,黑盒返回的片段再准也悬。