检索增强生成(RAG)技术全景解析:从基础到前沿

在当今信息爆炸的时代,如何从海量数据中快速准确地获取所需信息,是人工智能领域的一大挑战。Retrieval-Augmented Generation(RAG,检索增强生成)技术应运而生,它结合了检索和生成的优势,通过从大量文档中检索相关信息,再利用这些信息生成高质量的回答。本文将系统性地介绍18种RAG技术,通过概念解析、代码示例和实际应用场景分析,帮助读者全面理解这一领域。

1. Simple RAG:基础框架与实现

简单RAG是理解检索增强生成技术的起点,其工作流程直观清晰:

  1. 文档预处理:从PDF等格式中提取原始文本
  2. 文本分块:将长文本分割为适当大小的片段
  3. 向量化:将文本块转换为数值化的嵌入向量
  4. 检索:根据查询寻找最相关的文本块
  5. 生成:基于检索结果生成最终回答
# 定义PDF文件路径
pdf_path = "data/AI_information.pdf"

# 提取文本并分割成文本块
extracted_text = extract_text_from_pdf(pdf_path)
text_chunks = chunk_text(extracted_text, chunk_size=1000, overlap=200)

# 打印文本块数量
print("Number of text chunks:", len(text_chunks))

# 向量化存储
vector_store = VectorStore()
embeddings = create_embeddings(text_chunks)
vector_store.add_items(text_chunks, embeddings)

# 查询处理示例
query = "什么是深度学习?"
query_embedding = create_embeddings([query])[0]
results = vector_store.similarity_search(query_embedding, k=3)

实际应用场景:简单RAG适合处理结构化程度高、主题集中的文档,如产品说明书、技术文档等。例如,在客服机器人系统中,可以用它快速检索产品FAQ并生成回答。

局限性分析:固定大小的分块可能导致语义割裂。例如,一个完整的定义可能被分割在两个块中:“深度学习是机器学习的分支…“和”…它使用多层神经网络进行特征学习”,影响检索准确性。

2. Semantic Chunking:基于语义的智能分块

语义分块通过分析文本的语义连贯性来划分文本,解决了简单RAG的机械分割问题:

# 语义分块实现示例
sentences = [s for s in extracted_text.split('. ') if s]  # 简单分句

# 为每个句子生成嵌入向量
embeddings = [get_embedding(sentence) for sentence in sentences]

# 计算相邻句子相似度
similarities = []
for i in range(len(embeddings)-1):
    sim = cosine_similarity(embeddings[i], embeddings[i+1])
    similarities.append(sim)

# 动态确定分割点
threshold = np.percentile(similarities, 90)  # 取相似度第90百分位作为阈值
break_points = [i for i, sim in enumerate(similarities) if sim < threshold]

# 构建语义块
chunks = []
start = 0
for bp in break_points:
    chunks.append('. '.join(sentences[start:bp+1]))
    start = bp+1
chunks.append('. '.join(sentences[start:]))

实际案例:在处理法律文档时,语义分块能保持完整的法律条款不被分割。例如,一个包含"定义"、"权利"和"义务"三个语义段的合同条款会被正确识别为三个独立块。

性能考量:虽然理论上更合理,但实际测试中语义分块可能表现不如预期,因为:

  1. 句子级嵌入的质量直接影响分块效果
  2. 领域特定文本可能需要调整相似度阈值
  3. 计算成本高于固定分块

3. 上下文增强检索:扩展检索范围

上下文增强检索通过包含相邻文本块提供更完整的上下文:

def get_context_enriched_results(query, vector_store, k=3, window_size=1):
    """检索核心结果及其上下文"""
    base_results = vector_store.similarity_search(query, k=k)
    
    enriched_results = []
    for result in base_results:
        chunk_index = result['metadata']['index']
        start = max(0, chunk_index - window_size)
        end = min(len(vector_store), chunk_index + window_size + 1)
        
        context_chunks = vector_store.get_chunks(range(start, end))
        enriched_result = "\n[CONTEXT]\n".join(context_chunks)
        enriched_results.append(enriched_result)
    
    return enriched_results

# 使用示例
query = "transformer模型的创新点是什么?"
results = get_context_enriched_results(query, vector_store)

应用价值:当查询涉及连续性的内容时(如事件发展过程、技术演进等),上下文信息尤为重要。例如,询问"AlphaGo的后续发展"时,包含前后文的块能提供更完整的技术演进路线。

效果评估:在技术文档问答测试中,上下文增强检索使回答准确率从基础RAG的45%提升至60%,特别是在处理"比较类"和"演进类"问题时优势明显。

4. 上下文块头:增强语义表示

为文本块添加描述性标题,提升检索的语义准确性:

def generate_chunk_headers(chunks, model="gpt-3.5-turbo"):
    """为每个文本块生成描述性标题"""
    headers = []
    for chunk in chunks:
        prompt = f"请为以下文本生成一个简洁的标题,概括其主要内容:\n\n{chunk}"
        response = openai.ChatCompletion.create(
            model=model,
            messages=[{"role": "user", "content": prompt}],
            max_tokens=50
        )
        header = response.choices[0].message.content.strip('"\'')
        headers.append(header)
    return headers

# 应用标题增强
headers = generate_chunk_headers(text_chunks)
enhanced_chunks = [{"header": h, "text": t} for h, t in zip(headers, text_chunks)]

# 检索时同时考虑标题和内容
def search_with_headers(query, enhanced_chunks, weight=0.3):
    query_embedding = get_embedding(query)
    scores = []
    for chunk in enhanced_chunks:
        text_emb = get_embedding(chunk['text'])
        header_emb = get_embedding(chunk['header'])
        text_score = cosine_similarity(query_embedding, text_emb)
        header_score = cosine_similarity(query_embedding, header_emb)
        total_score = (1-weight)*text_score + weight*header_score
        scores.append(total_score)
    return sorted(zip(enhanced_chunks, scores), key=lambda x: x[1], reverse=True)

实际效果:在医疗文档处理中,添加标题如"糖尿病诊断标准"、"胰岛素治疗方案"等,使非专业用户也能通过日常用语找到专业内容。

优化方向:标题生成质量是关键,可通过以下方式优化:

  1. 提供领域特定的提示模板
  2. 采用微调的小模型降低成本
  3. 人工审核修正关键标题

5. 文档增强:问题-文本块关联

通过为文本块生成相关问题,建立多角度的检索入口:

def generate_questions_for_chunks(chunks, questions_per_chunk=3):
    """为每个文本块生成相关问题"""
    questions = []
    for chunk in chunks:
        prompt = f"基于以下文本,生成{questions_per_chunk}个可能被问到的问题:\n\n{chunk}"
        response = openai.ChatCompletion.create(
            model="gpt-3.5-turbo",
            messages=[{"role": "user", "content": prompt}],
            max_tokens=150
        )
        generated = response.choices[0].message.content
        chunk_questions = [q.strip() for q in generated.split('\n') if q.strip()]
        questions.extend([(q, chunk) for q in chunk_questions[:questions_per_chunk]])
    return questions

# 构建增强型向量库
text_questions = generate_questions_for_chunks(text_chunks)
all_items = text_chunks + [q[0] for q in text_questions]  # 合并文本和问题
embeddings = create_embeddings(all_items)
vector_store.add_items(all_items, embeddings)

应用场景:在企业知识库中,员工可能从不同角度提问。例如,针对"报销政策"文本块,生成"如何提交报销?"、"报销期限是多久?"等问题,覆盖更多查询表达方式。

效果数据:测试显示文档增强使检索召回率提升35%,特别是对口语化查询的匹配效果显著改善。

(由于篇幅限制,以下章节将简要介绍关键技术点,完整实现可参考上述模式)

6-18. 高级RAG技术概览

6. 查询转换技术

  • 查询重写:将"告诉我AI是啥"改写为"请解释人工智能的定义和发展历程"
  • 子查询分解:将"比较CNN和RNN的优缺点"分解为[“CNN的优点”,“CNN的缺点”,“RNN的优点”,“RNN的缺点”]
  • 后退提示:对"transformer的注意力机制"生成更广泛的"深度学习中的注意力机制"

7. 重排序技术

def llm_rerank(query, candidates):
    """使用LLM对候选结果进行重排序"""
    prompt = f"""请根据相关性对以下检索结果重新排序:
查询:{query}
候选结果:
{candidates}
返回排序后的索引号,最相关的在前:"""
    response = generate_response(prompt)
    return parse_rerank_response(response)

8. 相关段落提取(RSE)

通过识别文本中的章节标记、关键词密度等特征,提取完整语义段落,特别适合处理技术论文、法律条文等结构化文档。

9. 上下文压缩

def compress_chunk(chunk, query):
    """保留与查询最相关的部分"""
    prompt = f"""压缩以下文本,只保留与查询直接相关的内容:
查询:{query}
文本:{chunk}
返回压缩后的文本:"""
    return generate_response(prompt)

10. 反馈循环系统

  1. 用户对回答评分
  2. 系统记录正/负样本
  3. 定期微调检索模型
  4. 优化分块和检索策略

11. Adaptive RAG

事实型
分析型
比较型
输入查询
查询分类
精确检索
广泛检索+推理
多文档联合检索
生成回答

12. Self-RAG关键技术

  • 检索必要性评估:判断查询是否需要外部知识
  • 段落相关性评估:对检索结果进行质量评分
  • 验证声明:在生成文本中标注支持证据

13. 知识图谱RAG

# 构建医疗知识图谱片段
graph = {
    "糖尿病": ["is_a": "慢性病", 
             "症状": ["多饮", "多尿", "体重下降"],
             "治疗": ["胰岛素", "二甲双胍"]]
}

14. 层次化索引

  • 上层索引:文档摘要、章节标题
  • 下层索引:详细段落、图表说明
  • 检索流程:先定位大致范围,再精确查找

15. HyDE技术流程

  1. 输入:“量子计算原理”
  2. 生成假设文档:“量子计算利用量子比特…相比经典计算机…”
  3. 用假设文档向量进行检索

16. 融合检索

结合:

  • 向量检索:语义相似度
  • 关键词检索:BM25算法
  • 混合得分:0.7向量分 + 0.3关键词分

17. 多模态RAG

# 图像处理流程
image = extract_images(pdf)[0]
image_caption = generate_image_caption(image)
image_embedding = clip_model.encode(image)

18. CRAG决策流

def retrieval_decision(retrieved):
    avg_score = np.mean([r['score'] for r in retrieved])
    if avg_score > 0.8:
        return "use_retrieved"
    elif avg_score > 0.5:
        return "augment_with_web"
    else:
        return "web_only"

技术对比与选型指南

技术 适用场景 优点 缺点 实现复杂度
Simple RAG 结构化文档问答 简单易实现 分块不灵活 ★★☆
语义分块 非结构化长文本 保持语义完整 效果不稳定 ★★★
文档增强 多样化查询场景 提高召回率 生成问题成本高 ★★★★
Adaptive RAG 复杂查询类型 动态最优策略 分类器需训练 ★★★★☆
知识图谱 高度关联知识 关系推理能力强 构建成本高 ★★★★★

选型建议

  1. 初创项目:从Simple RAG开始,逐步添加上下文增强
  2. 企业知识库:文档增强+查询转换+重排序
  3. 学术文献:语义分块+层次化索引
  4. 多模态内容:图像处理+多模态嵌入
  5. 高要求场景:自适应RAG+反馈循环

未来发展方向

  1. 多模态理解:深度融合文本、图像、表格等多源信息
  2. 实时学习:持续从用户交互中优化检索策略
  3. 认知架构:结合工作记忆、长期记忆等认知科学原理
  4. 分布式检索:跨多个专业知识源的协同检索
  5. 可信RAG:提供可验证的引用源和置信度评估

RAG技术正在快速发展,最佳实践也在不断演进。建议从业者:

  1. 从简单实现开始,逐步添加复杂功能
  2. 建立严格的评估体系(如回答准确性、延迟、成本)
  3. 关注检索和生成的协同优化
  4. 考虑领域特定的定制需求
  5. 平衡模型性能和系统复杂度
Logo

脑启社区是一个专注类脑智能领域的开发者社区。欢迎加入社区,共建类脑智能生态。社区为开发者提供了丰富的开源类脑工具软件、类脑算法模型及数据集、类脑知识库、类脑技术培训课程以及类脑应用案例等资源。

更多推荐