type
status
date
slug
summary
tags
category
icon
password
1 背景
“问:RAG分块会破坏上下文语义,在字符数量存在限制的情况下如何解决这个问题”
“答:结合对业务内容的了解,人为拆分目录结构,避免程序生硬拆分带来的破坏” 被问到这个问题的时候懵了一下,回答的也比较糟糕,才发现自己对于RAG只有浅层原理了解,实际工程经验还欠缺很多,接这个机会也梳理一下整个RAG的流程,以及每个环节需要考虑哪些因素,存在哪些问题,可能会有什么配套的解决方案。
2 RAG的原理
全称:Retrieval-Augmented Generation
让大语言模型(像 ChatGPT)在回答问题前,先去“找资料”再来回答的方法
2.1 为什么需要找资料
大语言模型的知识是“记在脑子里的”,一旦训练好,它就不能再学新东西了。
但现实中我们经常需要回答一些最新的、具体的问题,比如:
- “某本 PDF 里的某个知识点?”
- “我们公司产品的技术细节?”
- “今天的新闻热点?” 这些内容模型自己不知道。这时候就需要RAG
2.2 构建知识库
- 准备内容: 比如:PDF、网页、Notion、数据库、TXT 等。
- 内容切片(chunking): 把长内容切成一段一段,每段可能是 300~500 tokens(或按段落)。
- 生成向量(Embedding): 对每个段落用 Embedding 模型(如 OpenAI 的 ada、BGE)生成向量。
- 建立索引库(向量数据库): 把每段文本 + 它的向量,一起存进[[向量数据库]]
✅ 到这一步,我们就完成了「知识的结构化 + 可搜索化」
2.3 ✅ 阶段一:输入向量化(用户查询 → Query Embedding)
2.3.1 💥 可能存在的问题
问题类型 | 描述 |
📏 输入过长 | 用户输入一整段长文本、多个问题,向量化后变得稀释、语义不集中。 |
🤔 含糊或模糊查询 | 问题中未出现关键实体,或问法过泛泛,如“这是什么意思?” |
💬 多轮上下文混乱 | 用户在上下文中提了模糊指代,如“这个怎么做?” |
🌍 多语种 / 专业术语 | 输入中夹杂多语言或行业黑话,embedding 模型理解有限。 |
2.3.2 ✅ 解决措施
优化策略 | 说明 |
✂️ Query 压缩与改写 | 使用 LLM 将长查询压缩为一句“核心检索句”。示例 prompt:请总结用户输入中最核心的问题内容。 |
🧠 Query Rewriting | 用 LLM 将“自然语言问法”改写成“可检索语言”,如“他是谁?” → “张三的简介是什么?” |
🧩 多轮上下文融合 | 保留多轮历史,通过 LLM 重写为“带完整上下文的新问题”。 |
🎯 关键实体提取 | 提取关键词 + 强化 prompt(如“搜索关键词包括:张三、毕业院校...”) |
🔀 多路并发 embedding | 一段用户输入拆分成多个子句分别 embedding 后合并召回结果(提升 recall) |
简单说,这里在做的就是意图识别+制定搜索策略
- 用户的输入可能过短,过长,意图不清晰等,需要 AI 介入帮助用户梳理清楚问题
- 制定搜索策略,有时候用户的命题可能很大,需要将其拆分为若干个子命题 例如:帮我搜索计算机行业近期的关键新闻 产品就需要将这个问题拆分为若干个子命题,例如政策维度,技术维度,国际新闻等等
2.4 ✅ 阶段二:查询匹配向量(Query → 检索向量数据库 → 返回 chunk)
2.4.1 💥 可能存在的问题
问题类型 | 描述 |
✂️ Chunk 切分破坏语义 | 原文在切片时断在句子或段落中间,检索时语义缺失。 |
🧱 Chunk 粒度不统一 | 有的 chunk 太短没信息,有的太长导致 embedding 嵌套多个话题。 |
📚 无关 chunk 被命中 | 语义相似但内容无关的 chunk(如“苹果” → 水果而不是 Apple 公司) |
🎭 多义词 / 同义表达问题 | 用户问法和 chunk 写法不一致,导致 miss match。 |
2.4.2 ✅ 解决措施
优化策略 | 说明 |
🧠 语义切片(semantic chunking) | 按自然段落、标题、句子边界切 chunk,减少语义断裂 |
🔁 滑动窗口切片(overlap chunking) | 每个 chunk 有上下文重叠,避免断章取义 |
📐 统一粒度(standardize granularity) | 控制 chunk 长度范围(如 300~500 tokens),避免过长过短 |
📎 添加元数据(metadata filter) | 每个 chunk 附加类别/时间等信息,用于增强过滤 |
🧠 Embedding 模型挑选适合领域 | 如中文优先选 BGE 模型,金融类可用 Finbert 词向量模型等 |
ㅤ | ㅤ |
上一步是对用户输入进行预处理,这一步是对知识库的内容进行处理,核心在于如何划分 chunk?
- 按照业务逻辑划分,也就是传统的段落,标题,句子,或者业务里面的特征点,例如研报的章节
- 滑动窗口切片,每个 chunk 都有部分重叠,避免生硬切断
- 元数据-附加信息
- 专业模型-更懂业务
- 粒度? 算是最保底的手段,如果和其他方式冲突,应该最后考虑
2.5 ✅ 阶段三:排序匹配内容(召回结果 → Rerank → 最终选段)
2.5.1 💥 可能存在的问题
问题类型 | 描述 |
🔢 相似度排名不准 | 召回结果的 topN 排名基于向量相似度,但语义强相关的反而排得低。 |
🧱 chunk 粒度不一致 | 粗粒度 chunk 包含部分答案但噪声高;细粒度 chunk 信息不足。 |
📌 信息重复 | 多个 chunk 是近义重复段,导致 prompt 占用空间浪费。 |
🌀 上下文丢失或冗余 | 选中的几个段落不连贯或含无关背景,影响 prompt 表现。 |
2.5.2 ✅ 解决措施
优化策略 | 说明 |
📊 使用 reranker 模型 | 用 BGE-Reranker、Cohere-Rerank 等二次排序模型,对召回结果重新打分。 |
🧮 Deduplication 去重 | 删除语义重复的 chunk(用向量距离或 hash 对比)。 |
🧠 Context Stitching | 将相关 chunk 拼接成连续上下文段,增强理解性。 |
🧾 Prompt 优化策略 | 控制每段的 token 数量;高权重段靠前,低价值段略去。 |
⚖️ 多模态/多策略融合排序 | 相似度 + 段落位置 + 权重 + 时间等综合排序。 |
这一步就是对匹配结果的二次处理,有几种方法:
- 引入语义打分,而不是只有向量相似度打分
- chunk 之间自己互相对比,减少重复内容 方法很多,核心目标就是一个:提升输入的 prompt 的质量,不要什么都传,也不要遗漏关键信息
2.6 🔚 总结一张表:
阶段 | 可能问题 | 优化策略 |
输入向量化 | 输入过长、模糊、上下文不清 | Query 改写、摘要、关键词提取、多轮融合 |
查询匹配向量 | chunk 切片不当、粒度不一、检索不到 | 语义切片、滑窗 overlap、Embedding 调整 |
排序匹配内容 | 排序不准、信息重复、上下文断裂 | reranker、去重、拼接上下文、prompt 策略优化 |
3. 感想
- 工程思路看起来很巧妙,但说到底也很直接,所谓大巧不工
- RAG的思路简单概括就是 根据用户输入的内容匹配知识库内容,传给大模型,那么它的工程化就分为三部分:
- 先处理用户输入的数据:意图识别,搜索策略
- 再处理知识库的数据:chunk划分,补充信息,用更聪明的搜索引擎
- 最后对匹配的数据进行处理:去重,拼接,排序
- 除RAG外,Deepresearch也很相似,意图识别,制定策略,搜索获取信息,对信息二次加工,传入llm得到最终输出
- 如果要继续深挖的话,更有价值的不是RAG的缝缝补补,而是如何存(向量数据库),如何搜(匹配模型),这两个领域会是未来AI基建的重要组成部分
- Author:培风
- URL:http://preview.tangly1024.com/article/240a80cd-73cf-80d6-a655-e5dc92433e99
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!