上一篇速通 AI(六):LLM 应用开发 — 提示词工程、LangChain、OpenAI API

目标:深入掌握 RAG 检索增强生成的完整体系——向量数据库、高级检索策略、GraphRAG、评估体系。

前置要求:上一篇(LangChain 基础、Embedding 概念、RAG 链入门)


本阶段知识依赖图

flowchart TD
    A["LangChain + RAG入门(上一篇)"]
    A --> E["RAG系统深入(核心)"]
    E -->|PDF/Markdown解析| E2[文档加载与切片]
    E -->|BGE-Large/BM25| E4[Embedding]
    E -->|Milvus/FAISS/Chroma| E1[向量数据库]
    E -->|高级检索/自适应RAG| E5[检索策略]
    E -->|Corrective RAG| E6[自我纠正]
    E -->|Adaptive RAG| E7[自适应检索]
    A --> F["向量数据库深入"]
    F -->|HNSW/IVF| F1[底层原理]
    F -->|选型对比| F2[数据库选型]
    A --> G["GraphRAG"]
    G -->|知识图谱增强| G1[核心思想]
    G -->|传统RAG对比| G2[优势分析]
    A --> H["Advanced RAG"]
    H -->|检索优化| H1[策略]
    H -->|生成优化| H2[策略]
    H -->|评估体系| H3[RAG评估]

1. RAG 系统深入——检索增强生成

为什么需要 RAG ?——大模型的三大硬伤

  • 硬伤 1 :知识截止日期
    • GPT-4 的知识截止到 2024 年 4 月
    • 问它“今天的新闻” → 完全不知道
  • 硬伤 2 :幻觉(Hallucination)
    • 大模型会“一本正经地胡说八道”
    • 问它一个它不知道的事实 → 可能编造看起来合理但错误的答案
  • 硬伤 3 :企业私有数据
    • 大模型从未见过你公司的内部文档、产品手册、客户数据
    • 问它“我们公司的退货政策是什么” → 完全不知道

RAG 的解决方案:不让大模型“凭记忆回答”,而是先帮它“查资料”,再让它“基于资料回答”。

  • 知识可以实时更新(查最新的资料)
  • 减少幻觉(有据可依)
  • 可以访问私有数据(先检索企业文档)

RAG 的完整流程——每一步详解

flowchart LR
    subgraph Offline["离线索引(一次性)"]
        D[文档] --> S[文本切分]
        S --> E[Embedding]
        E --> V[(向量数据库)]
    end
    subgraph Online["在线查询(每次)"]
        Q[用户问题] --> QE[Query Embedding]
        QE --> Search[相似度搜索]
        V --> Search
        Search --> R[Top-K 文档块]
        R --> P[Prompt 组装]
        Q --> P
        P --> LLM[LLM]
        LLM --> A[回答]
    end

Step 1 :文档处理(离线,一次性完成)

  • PDF/Word/Markdown → 文本提取 → 文本切分 → Embedding → 存入向量数据库

Step 2 :检索(在线,每次查询时执行)

  • 用户问题 → 问题 Embedding → 向量数据库中搜索最相似的文档块

Step 3 :生成(在线,每次查询时执行)

  • 检索到的文档块 + 用户问题 → 组装提示词 → 发送给 LLM → 生成回答

类比:

  • Step 1 = 把图书馆的书整理好,建立索引
  • Step 2 = 根据读者的问题,从图书馆找出相关的书
  • Step 3 = 让 AI 助手阅读这些书,然后回答读者的问题

数据加载与切片——决定 RAG 质量的关键

# PDF解析
from langchain_community.document_loaders import PyPDFLoader
loader = PyPDFLoader("enterprise_doc.pdf")
docs = loader.load()

# Markdown解析
from langchain_community.document_loaders import UnstructuredMarkdownLoader
loader = UnstructuredMarkdownLoader("readme.md")

# 语义切分(推荐)
from langchain_experimental.text_splitter import SemanticChunker
splitter = SemanticChunker(OpenAIEmbeddings())
chunks = splitter.split_documents(docs)

切分方式对比

  • 固定长度切分:每 500 个字符切一刀
    • 优点:简单
    • 缺点:可能在句子中间切断,语义不完整
  • 递归切分(RecursiveCharacterTextSplitter):按段落 → 句子 → 词的优先级切
    • 优点:尽量在自然边界处切分
    • 缺点:块大小不均匀
  • 语义切分(SemanticChunker):根据语义相似度自动找到切分点
    • 优点:每个块语义完整
    • 缺点:计算量较大(需要调用 Embedding 模型)

实际推荐:

  • 快速原型:用递归切分
  • 生产环境:用语义切分
  • 特定格式:用专门的解析器(如 Markdown 用 MarkdownHeaderTextSplitter)

向量数据库——存储和检索的"仓库"

数据库类型适用场景特点
FAISS内存型快速原型/小数据速度快,需手动调用 faiss.write_index() 持久化
Chroma嵌入型本地开发/小项目简单易用,自动持久化到磁盘
Milvus服务型生产环境/大数据分布式、高性能、企业级
Pinecone云服务无需运维托管服务,按量付费

类比:

  • FAISS = 纸质便签——快速方便,但容易丢
  • Chroma = 笔记本——持久保存,但容量有限
  • Milvus = 数据中心——高性能、高可靠,但需要运维
  • Pinecone = 云存储——不用操心基础设施,但要付费

高级检索策略——提升 RAG 效果的关键

# 1. 混合检索(Hybrid Search):语义 + 关键词
# 类比:搜索时同时考虑"意思相近"和"关键词匹配"
from langchain.retrievers import EnsembleRetriever
from langchain_community.retrievers import BM25Retriever

bm25_retriever = BM25Retriever.from_documents(chunks)  # 关键词检索
vector_retriever = vectorstore.as_retriever()            # 语义检索

# 70%语义 + 30%关键词
ensemble_retriever = EnsembleRetriever(
    retrievers=[vector_retriever, bm25_retriever],
    weights=[0.7, 0.3]
)

# 为什么需要混合检索?
# 纯语义检索的问题:可能检索到语义相似但关键词不匹配的文档
# 纯关键词检索的问题:可能漏掉语义相关但用词不同的文档
# 混合检索取长补短
# 2. 多查询检索(Multi-Query):一个问题,多种表述
# 类比:搜索时同时用多个关键词
from langchain.retrievers import MultiQueryRetriever
retriever = MultiQueryRetriever.from_llm(
    retriever=vectorstore.as_retriever(),
    llm=llm
)
# 原始问题:"什么是RAG?"
# 自动生成多个变体:
#   "解释检索增强生成技术"
#   "RAG的定义和原理"
#   "描述RAG的工作流程"
# 合并所有查询的检索结果 → 召回率大幅提升
# 3. 上下文压缩(Contextual Compression):只保留相关内容
# 类比:从一本书中只摘抄和问题相关的段落
from langchain.retrievers import ContextualCompressionRetriever
from langchain_cohere import CohereRerank
compressor = CohereRerank()
compression_retriever = ContextualCompressionRetriever(
    base_compressor=compressor,
    base_retriever=vectorstore.as_retriever()
)
# 检索到的文档块可能包含大量无关信息
# 压缩后只保留与问题最相关的部分 → 减少噪音,提高回答质量

Corrective RAG——自我纠正

标准 RAG 的问题:检索到的文档可能不相关,但模型仍会基于这些文档生成回答(“垃圾进,垃圾出”)。

Corrective RAG 的改进流程:

  1. 检索文档
  2. 评估文档与问题的相关性(用 LLM 判断)
  3. 如果相关性低 → 用网络搜索补充更相关的信息
  4. 如果相关性高 → 直接使用
  5. 生成回答后,再评估回答的质量
  6. 如果质量不达标 → 重新检索或重新生成

类比:一个负责任的研究员

  • 普通 RAG = 随便找几本书就回答
  • Corrective RAG = 先检查找的书是否相关,不相关就换一批,回答后还要检查质量

Adaptive RAG——自适应检索

核心思想:不同类型的问题需要不同的处理方式。

  • 简单事实问题:“法国的首都是哪?”
    • 大模型自己就知道,不需要检索
    • 直接回答,省时省力
  • 复杂知识问题:“比较 RAG 和微调的优劣”
    • 需要检索相关文档
    • 基于检索结果回答
  • 推理问题:“如果 A > B , B > C ,那么 A 和 C 的关系?”
    • 不需要检索(这不是知识问题,是推理问题)
    • 让模型用思维链推理

Adaptive RAG = 先判断问题类型 → 再选择最合适的处理方式 → 效率最高、效果最好。

RAG vs 微调 vs 提示词工程决策表

考量维度提示词工程RAG微调
开发成本最低(几小时)中等(几天)最高(几周)
数据需求无需数据需要文档库需要标注数据
计算成本极低低(检索+生成)高(训练+推理)
知识更新不支持实时更新需重新训练
适用场景简单任务、快速原型知识问答、文档查询专业领域、格式要求
推理延迟无额外延迟有检索延迟无额外延迟
推荐优先级先试这个其次考虑最后考虑

模块小结: RAG 系统

你学到了什么为什么重要
RAG 的三大硬伤知识截止、幻觉、私有数据
RAG 完整流程文档处理→检索→生成
数据切分策略固定长度 vs 递归 vs 语义
高级检索策略混合检索、多查询、压缩
Corrective/Adaptive RAG自我纠正、自适应检索

2. 向量数据库深入

向量搜索的底层原理

类比:在图书馆找"最相似的书"

  • 传统数据库(MySQL):精确匹配
    • SELECT * FROM books WHERE title = '深度学习'
    • 只能找到标题完全匹配的书
  • 向量数据库:语义相似度搜索
    • “找到和‘深度学习’含义最接近的书”
    • 能找到“神经网络”“机器学习入门”“TensorFlow 实战”等相关书籍

向量搜索的核心算法

  • 暴力搜索(Brute Force)
    • 计算查询向量和所有向量的距离 → 取最近的 k 个
    • 精度: 100% (不会漏掉任何结果)
    • 速度:$O(n\times d)$,$n$=向量数量,$d$=维度
    • 问题:数据量大时极慢(100 万个 1536 维向量需要计算 15 亿次)
  • 近似最近邻(ANN)
    • 用一些“聪明的策略”加速搜索,牺牲少量精度换取大量速度

HNSW——最常用的 ANN 算法

HNSW (Hierarchical Navigable Small World)= 分层可导航小世界图。

类比:找人的社交网络

  • 第 1 层(稀疏层):只有“超级节点”(明星、大 V)→ 快速定位大致区域
  • 第 2 层(中等层):普通节点 → 缩小范围
  • 第 3 层(密集层):所有节点 → 精确定位

搜索过程:

  1. 从最顶层的某个节点开始
  2. 在当前层找到最近的邻居
  3. 跳到下一层,继续找最近的邻居
  4. 重复直到最底层 → 找到最近的向量

精度: 95-99% (偶尔会漏掉,但几乎不影响结果)。 速度:$O(\log n)$,比暴力搜索快几个数量级。

动手计算:HNSW 搜索过程示例

假设 6 个向量(A-F),构建 3 层索引:

Layer 0(稀疏层):A ———————— D
Layer 1(中间层):A —— C —— D —— F
Layer 2(密集层):A — B — C — D — E — F(所有节点互连)

搜索 query 最近邻:

  1. 从 Layer 0 的 A 开始 → A 到 D 的距离更近 → 跳到 D
  2. 在 Layer 1 从 D 出发 → 检查 C、F → C 最近 → 跳到 C
  3. 在 Layer 2 从 C 出发 → 检查 B、D → B 最近 → 返回 B

只需检查 5 个节点(而非暴力搜索的全部 6 个)。当 $n=100$ 万时,HNSW 只需检查 $\log(100万) \approx 20$ 个节点。

IVF——另一种常用算法

IVF (Inverted File Index)= 倒排文件索引。

类比:图书馆的分区

  • 把所有书按主题分成 100 个区域
  • 找书时先确定在哪个区域,再在区域内搜索
  • 不需要翻遍整个图书馆

实现:

  1. 训练时:用 K-Means 把向量分成若干个聚类(Voronoi cells)
  2. 搜索时:先找到查询向量最近的几个聚类,只在这些聚类中搜索
  3. 参数 nprobe :搜索多少个聚类(越大越精确,越慢)

动手计算:IVF 检索示例

假设 12 个向量,K-Means 分成 3 个聚类:

聚类包含的向量
聚类 1(中心 [0.2, 0.3])A, B, C, D
聚类 2(中心 [0.8, 0.7])E, F, G, H
聚类 3(中心 [0.5, 0.9])I, J, K, L

查询向量 $q = [0.7, 0.8]$,距离各聚类中心:

  • 到聚类 1:$\sqrt{(0.7-0.2)^2+(0.8-0.3)^2} = 0.71$
  • 到聚类 2:$\sqrt{(0.7-0.8)^2+(0.8-0.7)^2} = 0.14$ ← 最近
  • 到聚类 3:$\sqrt{(0.7-0.5)^2+(0.8-0.9)^2} = 0.22$

nprobe=1:只搜索聚类 2(4 个向量),暴力搜索的 1/3

nprobe=2:搜索聚类 2 + 聚类 3(8 个向量),更精确但更慢

与暴力搜索对比:12 个向量暴力搜索需比较 12 次,IVF(nprobe=1) 只需比较 4 次 + 3 次聚类中心 = 7 次。当 $n=100$ 万、聚类数=1000 时,IVF 只需搜索 1000 个向量(0.1%),速度提升 1000 倍。

量化压缩

PQ (Product Quantization)= 乘积量化。

类比:用“代表色”代替所有颜色

  • 一张图片有 1600 万种颜色
  • 用 256 种“代表色”来近似 → 存储空间大幅减少

实现:

  1. 把 1536 维向量切成多段(如 8 段,每段 192 维)
  2. 每段用一个“码本”(codebook)中的最近码字代替
  3. 原始向量: 1536 × 4 bytes = 6 KB
  4. 量化后: 8 × 1 byte = 8 bytes → 压缩 768 倍

向量数据库选型深入

数据库索引算法持久化分布式适用场景
FAISSHNSW/IVF/PQ❌ 内存❌ 单机快速原型、小数据
ChromaHNSW✅ 磁盘❌ 单机本地开发、小项目
MilvusHNSW/IVF/DiskANN✅ 分布式生产环境、大数据
QdrantHNSW✅ 磁盘✅ 分布式新兴选择, API 友好
WeaviateHNSW✅ 磁盘✅ 分布式GraphQL 接口
Pinecone托管✅ 云✅ 云无需运维,按量付费

选型建议:

  • 学习和原型: FAISS (最快上手)
  • 小型生产: Chroma 或 Qdrant
  • 大型生产: Milvus (最成熟)或 Qdrant
  • 不想运维: Pinecone

模块小结:向量数据库

你学到了什么为什么重要
向量搜索原理语义相似度检索的基础
HNSW 算法最常用的 ANN 算法
IVF 倒排索引聚类加速搜索
PQ 乘积量化压缩向量,节省存储
数据库选型不同场景的最佳选择

3. GraphRAG

什么是 GraphRAG ?

类比:从"图书馆"到"知识图谱"

  • 传统 RAG = 图书馆找书
    • 把文档切成片段,用向量搜索找最相关的片段
    • 问题:片段之间没有“关系”——不知道 A 片段和 B 片段有什么联系
  • GraphRAG = 知识图谱 + 向量搜索
    • 不仅找到相关片段,还找到片段之间的“关系”
    • 能回答需要“综合多个信息源”的复杂问题

GraphRAG 的核心思想

  1. 从文档中提取实体和关系
    • 文档:“张三是百度的 CTO ,百度是李彦宏创办的公司”
    • 实体:张三、百度、李彦宏
    • 关系:(张三, 是 CTO, 百度), (百度, 创办者, 李彦宏)
  2. 构建知识图谱
  3. 社区检测
    • 把紧密相关的实体聚成“社区”
    • {张三, 百度, 李彦宏} 是一个社区
  4. 为每个社区生成摘要
    • “百度是一家由李彦宏创办的公司,张三担任 CTO”
  5. 检索时同时搜索向量和图谱
    • 问题:“张三在哪家公司工作?”
    • 向量搜索找到相关文档片段
    • 图谱搜索找到张三 → 百度的关系
    • 综合回答:“张三在百度担任 CTO”
flowchart TD
    A[提取实体与关系] --> B[构建知识图谱]
    B --> C[社区检测]
    C --> D[社区摘要]
    D --> E["检索:向量 + 图谱"]
    E --> F[综合回答]

GraphRAG vs 传统 RAG

特性传统 RAGGraphRAG
数据结构文档片段(扁平)知识图谱(结构化)
检索方式向量相似度向量 + 图遍历
多跳推理困难自然支持
全局摘要不支持支持(社区摘要)
适用场景单文档问答多文档、复杂关系推理
复杂度高(需要构建图谱)

GraphRAG 的实现

Microsoft 的 GraphRAG 实现:

示例:8 个实体、8 条关系的知识图谱

张三 --CTO--> 百度 <--创办-- 李彦宏
张三 --同事--> 李四        百度 --竞品--> 谷歌
谷歌 --CEO--> 桑达尔        谷歌 --总部--> 山景城
百度 --总部--> 北京         李四 --工程师--> 百度

社区检测后聚为 2 个社区:

  • 社区 1:{张三, 百度, 李彦宏, 李四, 北京} → “百度由李彦宏创办,总部在北京,张三任 CTO”
  • 社区 2:{谷歌, 桑达尔, 山景城} → “谷歌由桑达尔领导,总部在山景城”

传统 RAG 找不到"百度和谷歌的关系"(没有文档片段同时提到两家公司)。GraphRAG 通过图谱中的"百度—竞品—谷歌"直接回答。

  1. 使用 LLM 从文档中提取实体和关系
  2. 构建知识图谱
  3. 使用 Leiden 算法进行社区检测
  4. 为每个社区生成 LLM 摘要
  5. 检索时:局部搜索(向量 + 图谱)+ 全局搜索(社区摘要)

适用场景:

  • “这个公司的组织架构是什么?” → 需要从多份文档中综合信息
  • “这些产品的共同竞争对手是谁?” → 需要跨文档推理
  • “总结一下这个领域的最新进展” → 需要全局视角

模块小结: GraphRAG

你学到了什么为什么重要
GraphRAG 核心思想知识图谱 + 向量搜索
实体关系提取从文档构建图谱
社区检测与摘要全局视角的信息聚合
GraphRAG vs 传统 RAG结构化 vs 扁平化

4. Advanced RAG 工程实践

为什么需要"高级"RAG ?

基础 RAG 的问题:

  1. 检索质量不稳定——有时找到的文档不相关
  2. 生成质量参差——有时回答不准确或“幻觉”
  3. 系统鲁棒性差——输入格式变化就可能出错
  4. 评估困难——不知道效果好不好,怎么改进

Advanced RAG = 在每个环节都做优化。

检索优化策略

  1. 查询改写(Query Rewriting)
    • 原始问题:“这个东西怎么用?”
    • 改写后:“XX 产品的使用方法和操作步骤”
    • 让问题更明确,检索更精准
  2. 查询扩展(Query Expansion)
    • 原始问题:“RAG”
    • 扩展为:[“RAG”, “检索增强生成”, “Retrieval Augmented Generation”]
    • 多角度检索,提高召回率
  3. 假设文档嵌入(HyDE)
    • 先让 LLM 生成一个“假设的回答”
    • 用这个假设回答去检索(而不是用问题检索)
    • 假设回答和真实文档的语义更接近
  4. 上下文压缩(Contextual Compression)
    • 检索到的文档块可能很长,只有部分与问题相关
    • 用 LLM 提取出与问题最相关的部分
    • 减少噪音,提高回答质量

生成优化策略

  1. 提示词优化
    • 明确告诉模型“只基于提供的资料回答”
    • 要求模型“如果不确定就说不知道”
    • 指定输出格式(如“先总结再详细说明”)
  2. 引用追溯
    • 要求模型在回答中标注信息来源
    • “根据文档 A 第 3 段…”、“根据文档 B…”
    • 用户可以验证回答的准确性
  3. 多轮验证
    • 生成回答后,用另一个 LLM 调用检查回答是否与原文一致
    • 类似于“编辑审查”流程

RAG/Agent 评估体系

面试必问:“你怎么衡量 RAG 的效果?”

RAG 评估的三个维度:

  1. 检索质量(Retrieval Quality)

动手计算:检索评估指标数值示例

假设用户问"什么是 RAG?",数据库中有 5 个相关文档,检索系统返回 Top-3 结果:

排名文档是否相关
1文档 A(介绍 RAG 原理)✅ 相关
2文档 B(介绍 Transformer)❌ 不相关
3文档 C(RAG 实现代码)✅ 相关

Recall@3 = 检索到的相关文档数 / 全部相关文档数 = $2/5 = 0.4$(5 个相关文档只找到了 2 个)

$$\text{Recall@k} = \frac{|\{\text{相关文档}\} \cap \{\text{Top-k 结果}\}|}{|\{\text{全部相关文档}\}|}$$

Precision@3 = 检索结果中相关的数 / k = $2/3 = 0.67$(Top-3 中有 2 个相关)

$$\text{Precision@k} = \frac{|\{\text{相关文档}\} \cap \{\text{Top-k 结果}\}|}{k}$$

MRR(Mean Reciprocal Rank)= 第一个相关文档的排名的倒数。第一个相关文档排第 1,所以 $MRR = 1/1 = 1.0$。如果第一个相关文档排第 2,则 $MRR = 1/2 = 0.5$。

$$\text{MRR} = \frac{1}{|Q|}\sum_{i=1}^{|Q|}\frac{1}{\text{rank}_i}$$

NDCG(Normalized Discounted Cumulative Gain):考虑排名位置——排第 1 的相关文档比排第 10 的更有价值。

$$\text{DCG} = \sum_{i=1}^{k}\frac{2^{\text{rel}_i}-1}{\log_2(i+1)}, \quad \text{NDCG} = \frac{\text{DCG}}{\text{IDCG}}$$

以上例计算:$DCG = \frac{2^1-1}{\log_2(2)} + \frac{2^0-1}{\log_2(3)} + \frac{2^1-1}{\log_2(4)} = 1 + 0 + 0.5 = 1.5$。理想排序(相关文档排前 2)的 $IDCG = 1 + 0.63 = 1.63$。$NDCG = 1.5/1.63 = 0.92$。 2. 生成质量(Generation Quality)

  • Faithfulness (忠实度):回答是否基于检索到的文档(没有编造)
  • Relevance (相关性):回答是否和问题相关
  • Correctness (正确性):回答是否正确
  • Completeness (完整性):回答是否完整
  1. 端到端质量(End-to-End)
    • Answer Correctness :最终回答是否正确
    • Answer Relevance :最终回答是否和问题相关

评估工具

  • RAGAS:最流行的 RAG 评估框架
    • 自动生成评估数据集
    • 计算 Faithfulness 、 Relevance 、 Context Precision 等指标
    • 代码示例:
from ragas import evaluate
result = evaluate(dataset, metrics=[faithfulness, answer_relevancy])

Agent 评估

Agent 评估比 RAG 更复杂,因为 Agent 涉及多步决策:

  1. 任务完成率: Agent 是否完成了用户交给它的任务?
  2. 工具调用准确率: Agent 是否选择了正确的工具?
  3. 参数正确率: Agent 传给工具的参数是否正确?
  4. 步骤效率: Agent 用了多少步完成任务?(越少越好)
  5. 错误恢复: Agent 遇到错误时能否自动修正?

评估方法:

  • 人工评估:找人来判断 Agent 的表现(金标准,但成本高)
  • 自动评估:用另一个 LLM 来评判 Agent 的表现(成本低,但可能不准)
  • 基准测试:用标准化的测试集来评估(可比较,但覆盖有限)

模块小结: Advanced RAG 工程实践

你学到了什么为什么重要
查询改写与扩展提升检索精准度
生成优化策略提升回答质量
RAG 评估体系衡量系统效果
Agent 评估评估智能体表现

推荐补充资源

知识点推荐资源说明
LLaMAMeta LLaMA 论文原始论文
提示词工程OpenAI Prompt Engineering Guide官方指南
LangChainLangChain 官方文档最权威的参考
RAGLangChain RAG 教程实战教程
向量数据库Milvus 官方文档生产级向量数据库
GraphRAGMicrosoft GraphRAG 仓库官方实现
RAG 优化Lilian Weng《Prompt Engineering》Prompt 工程综述

下一篇预告:本文深入掌握了 RAG 检索增强生成。在速通 AI(八):Agent 开发与生产部署中,你将学习如何定制模型(PEFT 微调、量化)并构建能自主决策的智能体(Function Calling、MCP、LangGraph)。