什么是“RAG的上下文断裂问题”举个典型的例子文档 A 部分第 3 页“在系统处于‘开发环境’时可以直接使用 root 密码登录无需配置安全证书。”前提开发环境文档 B 部分第 80 页“严禁在没有安全证书的情况下暴露端口否则会导致严重的生产事故”如果用户提问“可以不配置安全证书直接用 root 登录吗”ES 极有可能因为相似度计算把 A 部分那句话第 3 页捞出来喂给大模型而把第 80 页的警告漏掉。大模型看到 A 部分就会自信地回答“可以的不需要配置安全证书”这就导致了严重的乱回答幻觉/误导。说白了就是忽略了“前提”哪些分片方式会导致这种问题第 1 梯队高危区如果你在项目中用了下面这两种方式前面提到的“因为失去前提而导致 AI 乱回答”的问题是最严重、必现的。固定大小分片 (Fixed-size Chunking)做法死板地规定“每 300 个字切一刀”。断裂原因它完全不看内容哪怕刚好在一句“前提条件”的中间它也会一刀切下去。递归字符分片 (Recursive Character Chunking)做法LangChain4j 默认的recursive。它比固定大小聪明一点会优先尝试按“换行符\n”或“句号。”来切尽量保证句子的完整。断裂原因虽然它保证了单句话的完整但它没有结构感知能力。它根本不知道这一段话是不是属于上文那个“开发环境”标题下的内容。一旦字数攒够了它就会无情地把前提留在上一个分片。第 2 梯队中危区语义分片 (Semantic Chunking)做法让 Embedding 模型去计算相邻两个句子的相似度。如果发现第 5 句和第 6 句的语义突然发生了剧烈变化就在这里切一刀。防范效果它能完美保证“一个主题的事情在同一个分片里”。为什么还会断裂它的局限性在于长距离依赖。比如第一段说了“以下操作针对 Linux 系统”接着写了 2000 字的具体步骤由于语义变化这 2000 字会被切成 4 个语义片。后面那 4 个分片由于离第一句太远语义模型无法把“Linux”这个前提强行拉过来导致后面分片的前提依然丢失。第 3 梯队安全区如果你在项目中使用了下面这两种高级分片方式你就基本不用担心上下文断裂的问题了布局/结构感知分片 (Layout/Structure-Aware Chunking)做法比如用MinerU 提取转 Markdown LangChain4j 的MarkdownDocumentSplitter就不是按字数切而是按文章的骨架标题树来切。为什么安全这种分片方式允许你在切片时配置“回填属性”。框架在切开一小段文本时会自动把它的各级父标题包含所有环境、版本的前提提取出来拼在这段话的开头。Document-Specific Chunking特殊领域定制化分片做法针对表格、代码块、法律条款、简历等特殊格式编写专门的解析器RAGFlow。为什么安全比如一个长表格跨了三页普通的切片会把表格行切碎。而定制化分片会强行把“表头Column Header”复制三份拼在每一页被切碎的表格行前面。大模型无论拿到哪一段表格都能看懂这一列数据代表什么从而彻底杜绝了断章取义。解决方法1. 标题/面包屑回填Parent-Child / Chunk Context Enrichment这是最常用、性价比最高的工程手段。既然分片Chunk会丢失上下文那我们在分片的时候硬生生把它的“父亲”和“祖先”标题路径塞进文本里。做法在 MinerU 将 PDF 转成.md后LangChain4j 拆分时不要只切出那一段话而是去解析它的 Markdown 标题树。效果原本存入 ES 的文本只有一句孤零零的话处理后变成[上下文前提第一章-系统初始化 - 1.2 环境搭建 - 开发环境配置]在系统处于开发环境时可以直接使用 root 密码登录无需配置安全证书。2. 父子文档块架构Parent-Child Documents / Hierarchical Chunking不要让“检索粒度”和“喂给大模型的粒度”一样大。小分片Child Chunk用于检索把文档切得很细比如 100 字只包含具体的细节用来和用户的问题做极其精准的向量匹配。大分片Parent Chunk用于阅读把整段话甚至整个章节比如 2000 字包含了所有的前置条件、背景说明作为大分片。ES 存储设计在 ES 中小分片里存一个字段叫parent_id指向大分片。运行逻辑用户提问。ES 通过小分片的向量相似度精准定位到了第 3 页的那句话。Java 后端拿到小分片后不去拿它的文本而是根据parent_id去 ES 里把那个包含了前因后果的2000 字大分片捞出来。最终喂给大模型的是大分片。大模型读完上下几百字自然就看到了那个“前提条件”。3. 大模型摘要回填Contextual Retrieval这是 Anthropic 提出的非常前沿且流行的一种做法。做法在文件被 LangChain4j 切片之前先把整篇长文档喂给一个便宜的大模型或者利用长文本缓存让大模型给每一个章节或者每一段话自动生成一句一两百字的“背景大纲”。存储把这个“背景大纲”拼到每一个细小分片的最前面再进行向量化存入 ES。注意确实效果炸裂但如果文档有几万页离线处理时对每个 Chunk 调大模型Token 成本和耗时会非常高。降本秘籍在实际落地时强烈建议开启大模型长文本缓存Prompt Caching。把整篇长文档作为 Cache 挂在 LLM 内存里然后滑动窗口让大模型批量生成 Chunk 摘要这样可以降低 90% 的输入 Token 成本速度提升好几倍。4. 混合检索与重排Hybrid Search Rerank—— 解决乱回答的终极护城河有时候哪怕你加了前提向量检索还是可能因为“分值太接近”而把错误的答案排在最前面。这时候需要祭出两道杀手锏(1)混合检索Hybrid Search在 ES 中同时使用向量检索管语义和关键字检索管字面精准度。如果用户提问里带了“生产环境”关键字检索会强烈抗议把带有“生产事故/生产环境”的 B 文档分数拉高。补充现在的 Elasticsearch 8.x 以及主流向量数据库都已经原生支持了RRF倒数排名融合算法。在 Java 端无论是用 Spring AI 还是 LangChain4j你不需要自己去写复杂的归一化算法直接在 ES 的查询请求中声明一个retriever把knn向量和standardBM25文本组合在一起ES 会在底层自动做 RRF 融合并返回最终的 Top K。(2)重排模型Reranker如 BGE-Reranker第一步用 ES 粗暴地通过向量相似度捞出最有可能的 Top 10 个分片这时候可能包含那个没有前提的错误答案。第二步把这 10 个分片和用户的问题一起丢给Rerank 模型。Rerank 模型极其聪明它不看向量而是像班主任批改作文一样逐字逐句分析这 10 个分片里到底哪个和问题存在逻辑上的因果/前提关系。经过重排那个真正安全的、带有限制条件的正确答案会被硬生生提到 Top 1。是什么原因导致的这个问题这种“前提丢失”的现象用大白话解释就是“断章取义”。向量化存储是无辜的向量化模型的唯一工作是把你给它的那一小段文本翻译成数学坐标。你给它一句“无需配置安全证书”它就尽职尽责地把这句话定格在“不用证书”的数学坐标上。它没有前后眼看不到第 3 页的大标题。真正的罪魁祸首是硬性分片 我们为了让大模型读得下、让 ES 算得快强行用长宽、Token 数比如每 500 字切一刀把一篇完整的文章“乱刀砍碎”。这一刀下去往往把“前提背景”和“核心结论”一刀两断分到了不同的切片里。所以这是一种RAG 架构与生俱来的技术隐患。只要你切片就必然面临上下文断裂的风险。方案落地第一关数据准备阶段分片时——治本这是最容易掌控也是效果最好的地方。技术手段智能分片 上下文回填。怎么做不要使用纯文本的recursive按字数盲切而是要使用Markdown 分片器LangChain4j 里的MarkdownDocumentSplitter。它在切片时会感知#、##标题。方案在把切片丢给openAiEmbeddingModel.embedAll()之前写一段 Java 逻辑遍历ListTextSegment把当前的各级标题或者上一段的背景作为前缀拼接到text字段的最前面。尽管引入前缀看似会带来微小的空间“噪声”但现在的通用 Embedding 模型对这种带结构的前缀处理能力已经非常强。比起“因缺乏上下文而完全检索不到”让向量具备上下文感知能力要重要得多第二关检索阶段问 ES 时——治标如果数据已经存进去了或者分片时没做好我们可以在用户提问、去 ES 查数据的时候补救。技术手段查询重写Query Rewriting或扩大召回。怎么做当用户问“可以不配证书直接登录吗”你不要直接拿这句话去查 ES。先让一个响应极快的小模型把问题改写一下“请分析这句话背后可能的系统环境和前提条件并生成新的检索词。”小模型可能会帮你生成“Spring Boot 登录、开发环境安全证书、生产环境安全证书”。你拿着这多组关键词去 ES 里查ES 就会把第 3 页和第 80 页的内容同时捞出来把“正确的前提”一并带给大模型。弊端小模型重写查询确实好但高并发下会增加响应延时。建议在 Java 端做多线程并行查 ES或者使用 ES 的Multi-Match把小模型生成的关键词合并成一个复杂的布尔查询一次性丢给 ES效率更高。第三关生成阶段喂给大模型前——兜底这是数据从 ES 出来准备组装给大模型LLM的最后一步。技术手段重排Rerank与 Prompt 限制。怎么做Rerank从 ES 捞出 Top 5 之后用 Java 调用一个 Rerank 接口如 BGE-Reranker。重排模型会强行检查eg“这 5 段话里有没有哪段话包含了后面几段话的前提限制”会把带限制条件的段落排到最前面。Prompt 严厉警告在给大模型的系统提示词里加上死命令eg: “你是一个极其严谨的系统运维专家。在回答用户问题时必须严格检查参考资料中是否存在‘环境开发/生产’、‘版本’等前置条件限制。如果资料中提及某种操作仅限特定环境你必须在回答中首要说明绝不能混淆”