Skip to content

05 · RAG 检索增强 ​

🎯 难度:中级⏱ 预计:60 分钟# Embedding# 检索# 引用

RAG(Retrieval-Augmented Generation)就是:先查你的资料,再让模型基于资料回答。它不是训练,不会把文档永久写入模型参数。

两条流水线 ​

text
离线入库:文档 → 清洗 → 分块 → 向量化 → 保存文本、向量和来源
在线问答:问题 → 向量化 → 检索 Top K → 组装上下文 → 模型回答并引用

可以类比搜索引擎 + 内容生成,不要先被「向量数据库」这个名字吓住。

什么是 Embedding? ​

Embedding 模型把一段文本映射成一个数字向量。语义相近的文本,在这个模型定义的向量空间里通常更接近。

文档和问题必须使用同一套模型与维度。更换 Embedding 模型后,通常需要重建索引。聊天模型和 Embedding 模型不是同一种接口,也不一定由同一平台提供。

最小检索算法 ​

以下片段不调任何 API,先理解余弦相似度:

python
import math

def cosine(a: list[float], b: list[float]) -> float:
    if len(a) != len(b):
        raise ValueError("向量维度不同")
    dot = sum(x * y for x, y in zip(a, b))
    norm_a = math.sqrt(sum(x * x for x in a))
    norm_b = math.sqrt(sum(y * y for y in b))
    return dot / (norm_a * norm_b) if norm_a and norm_b else 0.0

print(cosine([1, 0], [0.9, 0.1]))  # 接近 1
print(cosine([1, 0], [0, 1]))      # 0

小规模学习项目可以直接把向量存 JSON,再全量计算相似度。先把链路跑通,数据量变大再选择 pgvector、Qdrant 等索引方案。

分块不是随便切几百字 ​

按标题、段落、函数边界分块通常比固定字符切割更好。块太小丢上下文,太大塞入无关内容;适当重叠可以减轻边界丢失,但增加索引体积。

每个块应保留:source / chunk_id / text / embedding。否则最终引用只能编造。

检索失败如何定位? ​

  1. 先看命中块,不看生成结果:正确材料有没有进入 Top K?
  2. 没有:检查分块、模型、查询表达、混合关键词检索、重排。
  3. 有:检查上下文长度、提示词、引用约束和答案评估。

RAG 并不消除幻觉。资料可能过期、矛盾、恶意,模型也可能忽略资料。没有证据时允许回答「资料中没有」,不要强行生成答案。

RAG 和 Agent 如何结合? ​

固定每次检索再回答是 Workflow。如果把检索暴露成工具,由模型决定何时查、查什么、是否补查,就可以成为 Agent 的能力。

实战入口 ​

项目 2:个人知识库 会从文本切块到向量搜索完整实现,使用单独的 Embedding 配置,不默认你的聊天平台也支持它。

验收练习:找两篇主题相近的文档,写三个问题(直接命中、跨文档、资料不存在),观察检索结果,而不是只评价答案是否流畅。

用心写给每一个想入门 Agent 开发的前端工程师