首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >大模型RAG技术落地与优化实战

大模型RAG技术落地与优化实战

作者头像
编程小白狼
发布于 2026-11-04 08:59:04
发布于 2026-11-04 08:59:04
2100
举报
文章被收录于专栏:编程小白狼编程小白狼

从基础RAG到高级RAG,检索增强生成的最佳实践

为什么RAG如此重要

大模型的训练数据是有截止日期的,而且对于企业私有知识一无所知。RAG(检索增强生成) 是目前解决这个问题最主流、最实用的方案。

过去半年,我先后在3个项目上落地了RAG技术,从最基础的"向量检索+LLM"到多路召回+重排序+查询重写的复杂方案,踩过的坑都成了宝贵的经验。

一、RAG基础架构:从零开始

最简单的RAG
代码语言:javascript
复制
# 这是最基础的RAG实现
from langchain_community.vectorstores import Chroma
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain.chains import RetrievalQA

# 加载文档
documents = load_documents()
# 切分
text_splitter = RecursiveCharacterTextSplitter(chunk_size=512, chunk_overlap=50)
chunks = text_splitter.split_documents(documents)
# 向量化存储
vectordb = Chroma.from_documents(chunks, HuggingFaceEmbeddings(model_name="BAAI/bge-large-zh-v1.5"))
# 检索问答
qa_chain = RetrievalQA.from_chain_type(llm=llm, retriever=vectordb.as_retriever())
result = qa_chain.run("什么是微服务架构?")

这个基础方案能解决60%的问题,但剩下的40%需要更精细的优化。

二、进阶RAG优化:6个关键技巧

技巧1:文档切分策略优化

切分是RAG中影响最大的因素之一。我试过多种策略:

切分策略

适用场景

优点

缺点

固定长度切分

任意场景

简单可控

容易切碎语义

递归字符切分

通用

保留段落完整

长段落差不可控

语义切分

长文档

保留完整语义

速度慢

文档结构切分

Markdown/HTML

结构完整

格式依赖

最佳实践:对于技术文档,优先按文档结构切分(标题、段落、列表),再配合语义切分做补充。

代码语言:javascript
复制
from langchain_text_splitters import MarkdownHeaderTextSplitter

headers_to_split_on = [
    ("#", "header1"),
    ("##", "header2"), 
    ("###", "header3"),
]

markdown_splitter = MarkdownHeaderTextSplitter(headers_to_split_on=headers_to_split_on)
docs = markdown_splitter.split_text(markdown_content)
技巧2:混合检索

纯向量检索的最大问题:语义相似 ≠ 信息相关。

例如用户问"MySQL怎么建索引",向量检索可能召回一堆"索引的原理"而不是"建索引的命令"。

混合检索结合了向量检索的语义能力和关键词检索的精确匹配能力:

代码语言:javascript
复制
class HybridRetriever:
    def __init__(self, vector_store, bm25_index):
        self.vector_store = vector_store
        self.bm25_index = bm25_index
    
    def retrieve(self, query, top_k=5):
        # 向量检索
        vector_results = self.vector_store.similarity_search(query, k=top_k*2)
        # BM25关键词检索
        bm25_results = self.bm25_index.search(query, k=top_k*2)
        # RRF融合
        return self.reciprocal_rank_fusion(vector_results, bm25_results, top_k)

效果:混合检索相比纯向量检索,Top-3准确率从78%提升到89%。

技巧3:查询重写

用户的原始问题往往太口语化或太模糊,直接检索效果不好:

代码语言:javascript
复制
用户问题: "那个报警的事处理了没?"
改写后: "系统报警事件的处理状态和后续方案"
代码语言:javascript
复制
def rewrite_query(original_query, chat_history):
    prompt = f"""
    基于对话上下文,将用户的问题改写成更适合知识库检索的查询。
    
    历史对话:{chat_history[-3:]}
    用户问题:{original_query}
    
    改写要求:
    - 提取关键词,去掉口语化的表达
    - 补充必要的上下文信息
    - 保持问题的完整性
    
    改写结果:
    """
    return llm.generate(prompt)
技巧4:重排序(Re-ranking)

初步检索可能返回10-20个片段,但真正相关的只有少数几个。重排序器(Reranker)能对候选片段重新排序,把最相关的放在前面。

代码语言:javascript
复制
from sentence_transformers import CrossEncoder

reranker = CrossEncoder("BAAI/bge-reranker-v2-m3")

def rerank(query, candidates, top_k=3):
    pairs = [[query, doc.page_content] for doc in candidates]
    scores = reranker.predict(pairs)
    
    scored = list(zip(candidates, scores))
    scored.sort(key=lambda x: x[1], reverse=True)
    
    return [doc for doc, score in scored[:top_k]]

为什么需要重排序? 向量检索找到的是"语义相似"的片段,但语义相似不一定是最匹配问答需求的片段。Reranker能做更精细的相关性判断。

技巧5:上下文压缩

检索到的文档块中只有一部分是真正相关的,把全文扔给LLM既浪费token又容易引入噪声:

代码语言:javascript
复制
from langchain.retrievers import ContextualCompressionRetriever
from langchain.retrievers.document_compressors import LLMChainExtractor

compressor = LLMChainExtractor.from_llm(llm)
compression_retriever = ContextualCompressionRetriever(
    base_compressor=compressor,
    base_retriever=base_retriever
)

compressed_docs = compression_retriever.get_relevant_documents(query)
技巧6:多路召回

除了向量检索,还可以增加多路召回通道,提升召回覆盖率:

代码语言:javascript
复制
class MultiSourceRetriever:
    def __init__(self):
        self.retrievers = {
            "vector": VectorRetriever(),
            "keyword": BM25Retriever(),
            "sql": SQLRetriever(),       # 从结构化数据中检索
            "graph": KnowledgeGraphRetriever(),  # 知识图谱检索
        }
    
    def retrieve(self, query, top_k=5):
        all_results = []
        for name, retriever in self.retrievers.items():
            results = retriever.retrieve(query, top_k=top_k)
            for r in results:
                r.source = name
                all_results.append(r)
        
        # RRF融合排序
        return self.rrf_merge(all_results, top_k)

三、实战案例:技术文档问答系统

需求

我们需要为一个拥有5000+篇技术文档的知识库搭建问答系统。

最终方案
代码语言:javascript
复制
class AdvancedRAGSystem:
    def __init__(self):
        self.query_rewriter = QueryRewriter(llm)
        self.retriever = MultiSourceRetriever()
        self.reranker = Reranker()
        self.response_generator = ResponseGenerator(llm)
    
    def answer(self, question, history=[]):
        # 1. 查询重写
        rewritten = self.query_rewriter.rewrite(question, history)
        
        # 2. 多路召回
        candidates = self.retriever.retrieve(rewritten, top_k=20)
        
        # 3. 重排序
        top_docs = self.reranker.rerank(rewritten, candidates, top_k=5)
        
        # 4. 生成回答
        answer = self.response_generator.generate(question, top_docs)
        
        return answer
效果指标

维度

基础RAG

优化后RAG

提升幅度

回答准确率

72%

91%

+19%

检索召回率

68%

85%

+17%

引用准确率

60%

88%

+28%

幻觉率

15%

5%

-10%

平均响应时间

1.8s

2.5s

稍慢但可接受

四、RAG评估方法论

评估指标

RAG系统的评估需要从多个维度:

代码语言:javascript
复制
RAG评估矩阵
├── 检索质量
│   ├── 命中率(Hit Rate):相关文档是否被召回
│   └── MRR(Mean Reciprocal Rank):相关文档的排名
├── 生成质量
│   ├── 忠实度(Faithfulness):是否基于检索结果
│   ├── 相关性(Relevance):是否回答了问题
│   └── 完整性(Completeness):回答是否全面
└── 用户体验
    ├── 响应速度
    └── 引用准确性
自动化评估
代码语言:javascript
复制
from ragas import evaluate
from ragas.metrics import faithfulness, answer_relevancy, context_precision

# 使用RAGAS框架做自动化评估
result = evaluate(
    dataset=test_dataset,
    metrics=[faithfulness, answer_relevancy, context_precision],
    llm=eval_llm,
    embeddings=eval_embeddings
)

五、常见问题与解决方案

问题1:检索不到相关内容

原因:文档切分不合理、向量模型不匹配、查询语义偏移

解决:

  1. 优化切分策略,按文档结构切分
  2. 尝试不同的embedding模型
  3. 增加查询重写模块
  4. 扩展召回数量,用reranker精排
问题2:回答不准确/产生幻觉

原因:检索到的上下文不完整、LLM过度泛化、prompt设计不合理

解决:

  1. 在prompt中强调"只基于给定内容回答"
  2. 不清楚时明确说"不知道"
  3. 增加引用溯源,让用户能看到信息源
问题3:响应太慢

原因:检索链路太长、LLM推理慢、文档太大

解决:

  1. 缓存高频问题的检索结果
  2. 使用更小的reranker模型
  3. 流式输出提升感知速度
  4. 异步并行检索

六、未来方向

RAG技术还在快速演进:

  1. Graph RAG——结合知识图谱的RAG,能处理多跳推理
  2. Agentic RAG——让Agent自主决定何时检索、怎么检索
  3. 多模态RAG——支持图片、表格、代码的混合检索
  4. Self-RAG——让模型自己判断是否需要检索,以及检索结果是否充分

总结

RAG是当前大模型落地最实用的技术路线之一。从基础RAG到优化RAG,每一步优化都能带来可衡量的效果提升。

核心要点:

  • 检索质量决定了回答质量的上限
  • 查询重写和重排序是最值得投入的两个环节
  • 评估体系必须建立,用数据驱动优化
  • 保持简单,不要过度设计

你在做RAG落地时踩过什么坑?有什么好的优化经验?欢迎分享!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2026-07-16,如有侵权请联系 cloudcommunity@tencent.com 删除
目录
  • 为什么RAG如此重要
  • 一、RAG基础架构:从零开始
    • 最简单的RAG
  • 二、进阶RAG优化:6个关键技巧
    • 技巧1:文档切分策略优化
    • 技巧2:混合检索
    • 技巧3:查询重写
    • 技巧4:重排序(Re-ranking)
    • 技巧5:上下文压缩
    • 技巧6:多路召回
  • 三、实战案例:技术文档问答系统
    • 需求
    • 最终方案
    • 效果指标
  • 四、RAG评估方法论
    • 评估指标
    • 自动化评估
  • 五、常见问题与解决方案
    • 问题1:检索不到相关内容
    • 问题2:回答不准确/产生幻觉
    • 问题3:响应太慢
  • 六、未来方向
  • 总结
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档