连接大语言模型与真实世界的桥梁。
解决幻觉,打破知识边界,构建企业级 AI 应用的核心范式。
大语言模型(LLM)如 GPT-4 虽然强大,但存在两个致命弱点:
RAG (Retrieval-Augmented Generation) 应运而生。它就像给 LLM 配备了一个“外挂搜索引擎”或“开卷考试的课本”。在回答问题前,先去外部知识库检索相关信息,然后将这些信息作为“上下文”喂给 LLM,让它基于事实生成答案。
RAG 概念最早由 Meta AI 在 2020 年提出,随后经历了多个发展阶段:
| 阶段 | 时间 | 核心特征 |
|---|---|---|
| Naive RAG | 2020-2022 | 简单的检索 + 生成流水线,基础的向量检索 |
| Advanced RAG | 2023 | 混合检索、重排序、查询改写、元数据过滤 |
| Modular RAG | 2024+ | 模块化架构、自适应检索、多跳推理、Agent 集成 |
一个完整的 RAG 系统包含以下核心模块:
PDF/文档/数据库
向量检索/关键词检索
LLM 推理引擎
基于事实的答案
RAG 系统并非单一模型,而是一个由索引 (Indexing)、检索 (Retrieval) 和 生成 (Generation) 组成的精密流水线。
这是离线准备阶段。将私有数据(PDF, Wiki, 代码库)进行清洗、切分(Chunking),然后通过 Embedding 模型转化为向量(Vectors),最后存入向量数据库(Vector DB)。
这是在线交互阶段。用户的提问首先被转化为向量,在数据库中搜索最相似的片段(Top-K)。这些片段作为“上下文”连同用户问题一起发送给 LLM,生成最终回答。
RAG 系统中涉及的核心数据结构:
| 数据结构 | 字段 | 说明 |
|---|---|---|
| Document Chunk | id |
块的唯一标识符 |
content |
切分后的文本内容 | |
embedding |
向量表示 (float[]) | |
metadata |
源文件、页码、日期等 | |
| Query Context | query |
用户原始问题 |
retrieved_docs |
检索到的文档列表 | |
scores |
相似度分数 |
深入理解数据如何在系统中流转,以及各组件的调用顺序。RAG 的核心流程分为离线索引构建和在线检索生成两个阶段。
后台预处理,将私有数据转化为可高效检索的形式:
实时交互,检索相关信息并生成回答:
当用户发起提问时,系统内部的交互流程如下:
很多开发者困惑:我是该微调模型,还是使用 RAG?
| 维度 | RAG (检索增强) | Fine-Tuning (微调) |
|---|---|---|
| 知识更新 | 实时更新 (只需更新数据库) | 静态 (需重新训练) |
| 数据隐私 | 高 (数据在本地/私有库) | 中 (数据需上传训练) |
| 幻觉问题 | 极低 (基于检索事实) | 中 (仍可能产生幻觉) |
| 成本 | 低 (主要是推理和存储) | 高 (训练算力昂贵) |
从 Demo 到生产环境,RAG 需要解决准确率、召回率和延迟的挑战。
单纯的向量检索(语义搜索)在匹配专有名词或精确关键词时表现不佳。混合检索结合了向量检索和关键词检索(BM25),并使用倒排排名融合(RRF)算法合并结果,效果通常最好。
先检索出 Top-50 个粗略结果,然后使用高精度的 Cross-Encoder 模型(如 BGE-Reranker)对这 50 个结果进行精细打分排序,取 Top-5 给 LLM。这能显著提高相关性。
在 Chunking 时保留文件名、页码、日期等元数据。检索时先通过元数据过滤(如“只看2024年的财报”),再进行向量搜索。
# 1. Load & Split
loader = PyPDFLoader("company_data.pdf")
documents = loader.load()
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
chunks = text_splitter.split_documents(documents)
# 2. Embed & Store
vector_store = Chroma.from_documents(
documents=chunks,
embedding=OpenAIEmbeddings()
)
# 3. Retrieve & Generate
retriever = vector_store.as_retriever(search_type="mmr", search_kwargs={"k": 5})
prompt = ChatPromptTemplate.from_template("""
Answer the question based only on the following context:
{context}
Question: {question}
""")
chain = (
{"context": retriever, "question": RunnablePassthrough()}
| prompt
| ChatOpenAI()
| StrOutputParser()
)
chain.invoke("What is the revenue in Q3?")
| 向量数据库 | 类型 | 特点 | 适用场景 |
|---|---|---|---|
| Pinecone | 托管服务 | 易用、扩展性强、企业级SLA | 生产环境、快速上手 |
| Milvus | 开源自部署 | 高性能、分布式、GPU加速 | 大规模、高性能需求 |
| Chroma | 轻量级嵌入式 | 开箱即用、与LangChain集成好 | 原型开发、小规模项目 |
| Weaviate | 混合搜索 | 内置向量化、支持混合检索 | 多模态、复杂查询 |
| pgvector | PostgreSQL扩展 | 与现有PG集成、成本低 | 已有PG基础设施 |
衡量 RAG 系统的质量需要一套完整的评估体系,同时也需要解决实际工程中的各种挑战。
| 指标类型 | 指标名称 | 说明 | 计算方式 |
|---|---|---|---|
| 检索质量 | Hit Rate |
检索结果中包含正确答案的比例 | 命中数 / 总查询数 |
MRR |
平均倒数排名,衡量答案排名位置 | 1/rank 的平均值 | |
NDCG |
归一化折损累计增益 | 考虑排序位置的相关性 | |
| 生成质量 | Faithfulness |
答案与检索内容的一致性 | 评估模型打分 (0-1) |
Answer Relevance |
答案与问题的相关性 | 语义相似度计算 | |
Context Precision |
检索上下文的精确度 | 有效信息 / 总检索量 | |
| 端到端 | Answer Accuracy |
最终答案的准确率 | Ground Truth 对比 |
Latency |
端到端响应时间 | P50/P95/P99 延迟 |
用户问题与文档内容的表述方式不同,导致无法检索到正确片段。
切分时破坏了文档的语义完整性,导致检索到的片段缺乏必要上下文。
复杂问题需要多步推理,单次检索无法获取所有相关信息。
多个文档包含矛盾信息,或检索内容与 LLM 内在知识冲突。
开源 RAG 评估框架,提供 Faithfulness、Relevance 等指标的自动计算
LLM 应用可观测性平台,支持跟踪和评估 RAG 调用链
LangChain 官方监控平台,支持调试、测试和评估 LLM 应用