一、从0开始:简易RAG实现
在构建更复杂的 RAG 架构之前,我们先从最基础的版本入手。整个流程可以分为以下几个关键步骤:
1.数据导入:加载并预处理原始文本数据,为后续处理做好准备。
2.文本分块:将长文本分割成较小的段落或句子,以提高检索效率和相关性。
3.创建 Embedding:使用嵌入模型将文本块转换为向量表示,便于进行语义层面的比较与匹配。
4.语义搜索:根据用户输入的查询内容,在已有向量库中检索出最相关的文本块。
5.响应生成:基于检索到的相关内容,结合语言模型生成最终的回答输出。
二、基于语义的文本分块
在 RAG中,文本分块(Text Chunking)是一个至关重要的环节。其核心作用是将一大段连续文本划分为多个具有语义完整性的较小段落,从而提升信息检索的准确性和整体效果。
传统的分块方式通常采用固定长度的切分策略,例如每500个字符或每若干句子进行一次分割。这种方法虽然实现简单,但在实际应用中容易割裂完整的语义单元,导致后续的信息检索与理解受到影响。
相比之下,一种更智能的分块方法是语义分块(Semantic Chunking)。它不再依据字数或句数进行机械划分,而是通过分析句子之间的内容相似性来判断合适的切分位置。当检测到前后句子在语义上出现明显差异时,就在该位置断开,形成一个新的语义段落。
切分点的判定方法
为了找到合适的语义切分点,我们可以借助以下几种常见的统计方法:
1.百分位法(Percentile)找出所有相邻句子之间语义相似度差异的“第 X 百分位数”,并在那些差异值超过该阈值的位置进行切分。
2.标准差法(Standard Deviation)当句子间的语义相似度下降幅度超过平均值减去 X 倍标准差时,在该位置进行切分。
3.四分位距法(IQR, Interquartile Range)利用上下四分位数之差(Q3 - Q1)来识别变化较大的位置,并将其作为潜在的切分点。
三、添加“块标题”(Contextual Chunk Headers,CCH)
RAG 通过在生成回答之前从外部知识库中检索相关信息,从而提升语言模型的事实准确性。然而,在传统的文本分块方法中,往往会丢失重要的上下文信息,导致检索效果不佳,甚至使模型生成脱离上下文的回答。
为了解决这个问题,我们引入了一种改进方法:上下文块标题(Contextual Chunk Headers, 简称 CCH)。 这个方法的核心思想是: 在将文本分成小块(chunk)时,将该段内容所属的高级上下文信息(如文档标题、章节标题等)一并加到每个文本块的开头,然后再进行嵌入和检索。 这样做可以让每个文本块都带有其背景信息,帮助模型更好地理解它属于哪个部分,从而提高检索的相关性,并避免模型基于断章取义的内容生成错误答案。
本方法中的步骤如下:
1.数据导入(Data Ingestion)加载并预处理原始文本数据。
2.带上下文标题的分块(Chunking with Contextual Headers)自动识别文档中的章节标题,并将这些标题加到对应段落的前面,形成带有上下文的文本块。👉 例如:
# 第三章:人工智能的基本技术
人工智能的核心方法包括机器学习、深度学习和自然语言处理...
3.创建嵌入向量(Embedding Creation)将这些带有上下文信息的文本块转换成数字形式(即嵌入向量),以便后续进行语义搜索。
4.语义搜索(Semantic Search)当用户提出问题时,系统会基于这些增强后的文本块,找到最相关的内容。
5.生成回答(Response Generation)使用大语言模型(如 Llama、ChatGLM 等)基于检索结果生成自然、准确的回答。
6.评估效果(Evaluation)通过评分系统对 AI 的回答进行评估,检查加入上下文标题后是否提升了回答的准确性和相关性。
四、Query改写
实现了三种查询转换(Query Transformation),以提升检索增强生成(RAG)系统的信息检索效果。
核心目标:
通过修改或扩展用户的原始查询,帮助系统更准确地理解用户意图,并从向量库中找到更相关的信息。
三大查询转换技巧
1. 查询重写(Query Rewriting)
将用户的问题变得更具体、更详细,从而提高检索的精准度。
🔹 示例:
-
用户原问题:“AI 是什么?”
-
重写后的问题:“人工智能的定义及其核心技术有哪些?”
✅ 提升点:让搜索更精确,避免过于宽泛的结果。
2. 回退提问(Step-back Prompting)
生成一个更广泛、更高层次的问题,用于获取更多背景信息,帮助系统更好地理解上下文。
🔹 示例:
-
用户原问题:“深度学习在医疗领域有哪些应用?”
-
回退问题:“人工智能在医疗行业的应用有哪些?”
✅ 提升点:有助于找到与问题相关但不直接匹配的重要背景知识。
3. 子查询拆解(Sub-query Decomposition)
将一个复杂的问题拆分成多个更简单的小问题,分别进行检索,最后综合所有结果,提供更全面的回答。
🔹 示例:
-
用户原问题:“比较机器学习和深度学习的优缺点及应用场景。”
-
拆解为:
-
“什么是机器学习?”
-
“什么是深度学习?”
-
“机器学习有哪些优缺点?”
-
“深度学习有哪些优缺点?”
-
“它们各自适用于哪些场景?”
✅ 提升点:确保覆盖问题的所有方面,避免遗漏关键信息。
ref :RAG技巧与底层代码剖析