5.4 RAG检索增强生成原理与企业知识库问答系统搭建

3 阅读6分钟

5.4 RAG检索增强生成原理与企业知识库问答系统搭建

一、RAG解决的核心问题

大语言模型存在知识截止幻觉问题:无法获知训练后的新信息,且可能编造不存在的内容。RAG(Retrieval-Augmented Generation,检索增强生成) 通过"先检索、再生成"的方式,将外部知识库的检索结果作为上下文注入模型,从而提升答案的准确性与时效性。《大模型应用开发极简入门》第5章「构建RAG系统」明确为:RAG原理(检索增强生成、解决幻觉与知识准确性)、LlamaIndex实战(文档加载、分块、嵌入、索引、检索、生成)、企业知识库问答与文档智能检索。本节与之一一对应,并给出可运行代码与部署要点。


二、RAG工作流程

flowchart LR
    A[用户问题] --> B[查询向量化]
    C[知识库] --> D[向量索引]
    B --> E[相似度检索]
    D --> E
    E --> F[Top-K 文档片段]
    F --> G[拼接为上下文]
    G --> H[LLM 生成]
    A --> H
    H --> I[最终回答]

2.1 核心步骤

  1. 文档处理:加载、分块、向量化
  2. 索引构建:将向量存入向量数据库
  3. 检索:用户问题向量化,检索最相似的K个片段
  4. 生成:将检索结果与问题拼接,送入LLM生成答案

三、企业知识库问答系统搭建

3.1 技术选型

组件推荐方案
文档加载LlamaIndex SimpleDirectoryReader
向量化OpenAI text-embedding-ada-002
向量存储内存 / Chroma / Pinecone
LLMGPT-3.5-turbo 或 GPT-4

3.2 完整代码(基于LlamaIndex)

"""
企业知识库RAG问答系统
前置: pip install llama-index llama-index-llms-openai llama-index-embeddings-openai python-dotenv pypdf
"""

import os
from dotenv import load_dotenv
from llama_index.core import SimpleDirectoryReader, VectorStoreIndex, Settings
from llama_index.llms.openai import OpenAI
from llama_index.embeddings.openai import OpenAIEmbedding

load_dotenv()

# 配置
Settings.llm = OpenAI(model="gpt-3.5-turbo", temperature=0.1, api_key=os.getenv("OPENAI_API_KEY"))
Settings.embed_model = OpenAIEmbedding(model="text-embedding-ada-002", api_key=os.getenv("OPENAI_API_KEY"))

def build_index(doc_dir: str = "./docs") -> VectorStoreIndex:
    """构建文档向量索引"""
    documents = SimpleDirectoryReader(doc_dir).load_data()
    index = VectorStoreIndex.from_documents(documents)
    return index

def query(index: VectorStoreIndex, question: str) -> str:
    """检索+生成"""
    query_engine = index.as_query_engine()
    response = query_engine.query(question)
    return str(response)

if __name__ == "__main__":
    # 首次运行:在 docs/ 下放入 PDF/TXT 等文档
    index = build_index()
    # 或加载已保存索引: index = load_index_from_storage(...)
    answer = query(index, "文档中提到的核心流程有哪些?")
    print(answer)

四、优化要点

  • 分块策略:按段落或固定长度分块,避免过长或过短
  • 检索数量:Top-K 通常取 3–5,过多会增加噪声与成本
  • 提示设计:明确"仅基于以下内容回答",避免模型自由发挥

五、分块策略详解

5.1 为什么需要分块

原始文档可能很长,直接向量化会丢失细节,且超出模型上下文。分块将文档切分为小片段,每个片段单独向量化,检索时返回最相关的若干块。

5.2 分块参数

参数说明推荐值
chunk_size每块字符/Token数256-512(中文约150-300字)
chunk_overlap块间重叠50-100,避免语义被切断
分隔符按段落/句号/固定长度按段落优先,保持语义完整

5.3 LlamaIndex分块配置

from llama_index.core import SimpleDirectoryReader
from llama_index.core.node_parser import SentenceSplitter

parser = SentenceSplitter(chunk_size=256, chunk_overlap=50)
documents = SimpleDirectoryReader("./docs").load_data()
nodes = parser.get_nodes_from_documents(documents)
# 然后用nodes构建索引

六、检索优化

6.1 Top-K选择

Top-K过小可能遗漏关键信息,过大则引入噪声、增加Token成本。通常3-5为宜,可根据业务测试调整。

6.2 混合检索

除向量检索外,可结合关键词检索(BM25):对短query,关键词匹配有时更准。混合策略可为:向量检索Top-5 + BM25 Top-3,去重后合并。

6.3 重排序(Rerank)

检索得到Top-K后,可用专门的Rerank模型对候选片段重新排序,提升最相关片段排在前面的概率。可选模型:Cohere Rerank、BGE Reranker等。


七、提示设计要点

RAG的提示需明确告知模型"仅基于以下内容回答",避免模型依赖自身知识编造。示例:

根据以下参考内容回答用户问题。若参考内容中无相关信息,请回复"根据提供的资料无法回答"。
参考内容:
{context}

用户问题:{question}

八、索引持久化与增量更新

首次构建索引后可持久化,避免每次启动重新计算:

# 保存索引
index.storage_context.persist(persist_dir="./rag_index")

# 加载索引
from llama_index.core import StorageContext, load_index_from_storage
storage_context = StorageContext.from_defaults(persist_dir="./rag_index")
index = load_index_from_storage(storage_context)

增量更新:新增文档时,可只对新文档分块、向量化,插入现有索引,无需重建全量。


九、常见问题与排查

问题可能原因解决
检索不到相关内容分块过细/过粗、query与文档表述差异大调整chunk_size、做query扩展
回答与文档不符模型未严格遵循"仅基于上下文"强化提示、降低temperature
响应慢检索+生成串行、文档量大异步检索、考虑缓存、缩小检索范围
成本高检索片段过多、模型选型减少Top-K、用gpt-3.5-turbo

十一、与书中 5.3 节「构建 RAG 系统」的对应

本书第 5 章 5.3 节明确:RAG 原理为检索增强生成,解决幻觉、提升知识准确性;LlamaIndex 实战覆盖文档加载、分块、嵌入、索引、检索、生成;并给出企业知识库问答、文档智能检索的搭建思路。本节与之一一对应:RAG 原理与流程对应「检索增强生成」;文档加载、分块、向量化、检索、提示设计对应 LlamaIndex 与 LangChain 的完整流程;企业知识库问答即书中「企业知识库问答、文档智能检索」的落地。下一节 5.5 将细化 LlamaIndex 的文档与分块配置,本节侧重整体架构与检索优化。实际搭建企业知识库时,建议先在小规模文档上跑通「加载→分块→索引→检索→生成」全流程并验证回答质量,再扩大文档规模与 Top-K 等参数;同时将「仅基于以下内容回答」等防御性提示(见第 4.5 节)纳入 RAG 的 system 或 user,与书中 RAG 原理与实战要求一致。


十、小结

RAG是解决LLM幻觉与知识时效性的主流方案。掌握文档加载、分块、向量化、检索、提示设计与索引持久化的完整流程,即可搭建企业级知识库问答系统。下一节将深入LlamaIndex的文档加载与分块配置。


十二、与 4.5 防御性提示、2.8 Embeddings 的衔接

4.5 节防御性提示:RAG 的 system 或 user 中应明确「仅基于以下检索内容回答;若检索内容中无法找到答案,请说明无法确定」,与 4.5 的限定知识源、承认不确定性一致,可显著降低 RAG 场景下的幻觉。2.8 节 Embeddings:RAG 的向量化即 Embeddings API 的批量调用;建索引与检索需使用同一 embed 模型(如 text-embedding-ada-002),与 2.8 节模型一致性要求一致。将本节流程与 4.5、2.8 结合,即可形成「检索 → 防御性提示 → 生成」的完整知识库问答管线。与 5.5 节 LlamaIndex 的分工:本节侧重 RAG 原理、企业知识库整体架构与检索优化;5.5 节侧重文档加载、分块、嵌入与索引构建的代码细节,两节配合即可从原理到实现完整落地。实际搭建企业知识库时,建议先在小规模文档上跑通「加载→分块→索引→检索→生成」全流程并验证回答质量,再扩大文档规模与 Top-K 等参数。


下一节预告:5.5 LlamaIndex实战:文档加载、分块、嵌入与索引构建