avatar

Neo·元

算法的尽头,认知的倒影

  • 首页
  • 三千问道
  • 万法归宗
  • 诗酒田园
  • 关于Neo·元
主页 RAG 进阶:父子切片机制与多重防幻觉架构落地
文章

RAG 进阶:父子切片机制与多重防幻觉架构落地

发表于 6天前 更新于 6天前
作者 Neo
13~17 分钟 阅读

前言

在构建垂直领域的 RAG 智能体时,往往会面临两个生产级痛点:一是传统定长切片导致“检索到了碎片,但丢掉了前置上下文”;二是检索质量差时,模型开始“一本正经地胡说八道”。

本文不谈虚无缥缈的概念,我直接从工程落地角度拆解解决方案:如何通过 父子切片解耦检索与生成,以及如何通过 防御性编程 在 Prompt 侧、Tool 侧和生成侧构建三道硬熔断闸门,彻底扼杀 RAG 的幻觉风险。

一、 为什么传统的单层切片不够用?

在传统的 RAG 架构中,我们通常使用固定 Size切分文档。这会引发一个两难困境:

  • Chunk 太小:向量语义聚焦,检索精准度高,但丢失了上下文。

  • Chunk 太大:上下文给足了,但稀释了关键信息的语义密度,导致向量检索的召回率大幅下降。

为了破解这个矛盾,必须引入 父子切片 机制。其核心逻辑是:子块负责高精度检索,父块负责上下文渲染。

二、 父子切片的推荐实践策略

在工程落地中,不建议纯粹按固定字数切分父块。最佳的切分策略是:结构切父块 + 递归切子块。

+-------------------------------------------------------------+
| Parent Chunk: 按 Markdown #/## 标题或自然段拆分, 800-1500字 |
| (存入 DocStore / Redis, 不参与向量计算, 负责上下文生成)               |
+-------------------------------------------------------------+
                              │
               ┌──────────────┴──────────────┐
               ▼                             ▼
+----------------------------+ +----------------------------+
| Child Chunk 1 (150字, 20重叠) | | Child Chunk 2 (150字, 20重叠) |
| (向量化入 VectorStore, 检索) | | (向量化入 VectorStore, 检索) |
+----------------------------+ +----------------------------+

1. 父块:按结构切分

利用 Markdown 标题(#, ##)、HTML 标签(<h1>, <div>)或段落换行符(\n\n)将文档拆分为独立的业务逻辑块(800~1500 字)。

  • 作用:确保父块是一个完整的独立话题,天然包含完整的语义与前置条件。

2. 子块:按递归字符切分

针对每一个父块,使用 RecursiveCharacterTextSplitter 进行进一步拆解:

Python

from langchain_text_splitters import RecursiveCharacterTextSplitter

child_splitter = RecursiveCharacterTextSplitter(
    chunk_size=150,
    chunk_overlap=20,
    separators=["\n\n", "\n", "。", "!", "?", " ", ""]
)
  • 作用:高语义密度,控制在 150 字左右,并保持 20 字的滑动窗口重叠,防止跨句断意。

3. 存储与检索映射

  • 子块:生成 Vector,存入 Vector Database,仅用于向量相似度计算。

  • 父块:保留原始文本,存入 KV 数据库,并维护 child_id -> parent_id 的映射表。

  • 运行时:用户问题命中子块后,图引擎通过映射关系提取对应的父块文本,作为 Context 喂给 LLM。

三、 多重防幻觉架构:用代码硬约束控制确定性

解决完数据切片,下一步就是解决大模型的幻觉问题,靠防御性编程设下多重闸门。

整个防幻觉体系在架构上分为三层:

[用户输入] ──> [1. Supervisor Node 意图隔离 + JSON 强约束]
                        │
                        ▼
               [2. Tool 侧 Score 硬熔断与空召回拦截]
                        │
                        ▼
               [3. LLM 最终生成侧 Strict Prompt 兜底] ──> [安全输出]

1. 输入端:意图隔离与格式硬约束(Supervisor Node)

在路由节点上做两件事:隔离业务边界 与 限制输出自由度。

Python

SUPERVISOR_PROMPT = SystemMessage(content=(
    "你是一个意图分类助手。请根据用户的最新输入,只返回对应的分类名称:\n"
    "- tool_expert: 咨询xx相关问题。\n"
    "- ask_clarification: 用户输入过于模棱两可,无法判断意图。\n\n"
    "请严格按 JSON 格式输出:{\"next\": \"节点名称\", \"clarification_question\": \"反问内容(仅在ask_clarification时填)\"}"
))
  • 边界隔离:阻止模型跨界强行回答不属于当前业务域的问题。

  • JSON 强约束:通过结构化输出挤压模型的自由发挥空间。

2. Tool 层:代码级硬熔断(防幻觉的最强闸门)

这是整套防幻觉架构中最硬核的部分。拒绝将低置信度数据投喂给 LLM:

Python

@tool
async def search_knowledge_base(query: str) -> str:
    """异步检索私有知识库,内置混合检索 + 重排序精刷。"""
    rag = get_rag_service()
    docs = await rag.advanced_retrieve(query)
    if not docs:
        return "知识库中未检索到相关内容,请尝试其他问题或联系人工客服。"
    top_score = docs[0].metadata.get("rerank_score", -100)
    if top_score < -2.0:  
        return "未找到高度匹配的内容,建议咨询官方渠道。"
    return format_docs(docs)
  • 空召回截断 :未查到数据,代码层直接拦截返回提示,直接切断 LLM 基于无数据源盲目编造的路径。

  • 分值熔断:通过 Reranker 模型计算相似度。即使召回了文档,只要得分低于硬性阈值,依然判定为无效召回,终止大模型推理。

3. 回答层:边界兜底

在 Agent Node 接收到 Tool 结果后,于 System Prompt 层下达死命令:

Python

if messages and messages[-1].type == "tool":
    system_prompt = SystemMessage(
        content="你是XX。请根据检索到的参考资料回答用户问题。若资料中没有请坦诚说明。"
    )
    response = await self.llm.ainvoke([system_prompt] + messages, config=config)

如果 Tool 层触发了硬熔断,LLM 在该提示词约束下会老老实实向前端汇报“未找到”,完成防幻觉闭环。

四、 总结与架构思考

大模型工程落地不是搞学术研究,能用代码解决的确定性问题,就绝不交给概率模型去猜。

  1. 切片层:结构切父块保证上下文完整,递归切子块保证检索精度。

  2. 路由层:Supervisor 节点做好意图隔离与 JSON 结构化收敛。

  3. 工具层:代码级拦截,宁可拒答也不喂废料。

  4. 生成层:Strict Prompt 死扣边界,提供最后的容错兜底。

将防幻觉拆解为这三层锁链,RAG 系统在真实生产环境中的可用度与稳定性才能得到根本保证。

万法归宗
RAG
许可协议:  CC BY-NC 4.0
分享
本文同步发布于个人博客 Neo·元,转载请注明出处。

相关文章

9月 21, 2026

RAG 进阶:父子切片机制与多重防幻觉架构落地

前言 在构建垂直领域的 RAG 智能体时,往往会面临两个生产级痛点:一是传统定长切片导致“检索到了碎片,但丢掉了前置上下文”;二是检索质量差时,模型开始“一本正经地胡说八道”。 本文不谈虚无缥缈的概念,我直接从工程落地角度拆解解决方案:如何通过 父子切片解耦检索与生成,以及如何通过 防御性编程 在

9月 10, 2026

深入底层与生产落地:LangGraph 状态机机制与高性能流式优化

前言 最近回过头重新审视并优化了之前的 LangGraph 项目。随着对大模型工程化与 Agent 架构理解的加深,发现不少早期写得不够优雅、甚至隐藏着生产风险的地方。本文不谈虚无缥缈的概念,我直接从底层机制进行拆解:MessagesState 的追加本质、RunnableConfig 的真实作用、

9月 3, 2026

浅谈 LangGraph 智能体演进:从 Ollama到 DeepSeek-R1的踩坑与架构重构

前言 在本地部署大模型开发Agent项目,基于现有硬件环境和调试成本考量,优先使用的是基于Ollama部署的3B/7B模型。但当业务进入“海关风控与跨境物流”这种对指令遵循、工具调用以及人工干预有绝对硬红线的真实场景时,小模型的劣势会被无限放大。 本文记录了我将一个 LangGraph Agent

下一篇

深入底层与生产落地:LangGraph 状态机机制与高性能流式优化

上一篇

最近更新

  • RAG 进阶:父子切片机制与多重防幻觉架构落地
  • 深入底层与生产落地:LangGraph 状态机机制与高性能流式优化
  • 浅谈 LangGraph 智能体演进:从 Ollama到 DeepSeek-R1的踩坑与架构重构
  • 浅谈 HITL 与 Checkpointer
  • 聊一下 LangGraph 的流式打印

热门标签

Tools DeepSeek AI LangChain RAG LangGraph

©2026 All Rights Reserved Neo 鲁ICP备2026037083号