← 返回 Learning
AI 实战观察 · 技术科普

大模型答不上你的私有知识?用 RAG 把答案钉死在资料上

很多人以为:把文档丢给大模型,它就能回答关于文档的任何问题。现实是,它答得上来的,只是训练时见过的东西。你昨天写的内部方案、客户给的报价单、团队的技术栈,它一个字都没学过,自然一问三不知。解决办法叫 RAG(检索增强生成,Retrieval-Augmented Generation):不让模型凭记忆答,而是先去你的资料里查,再把查到的内容喂给它答。

一、先破个错觉:大模型知道的,只有训练时见过的

大模型不是联网搜索引擎,它更像一本封笔于某天的百科全书。它所有的知识都冻结在训练数据里。

所以当你问它私有、新鲜、或只有你们团队才知道的东西时,它会本能地做两件事之一:

  • 老实说我没有这方面的信息;
  • 更糟,编一个听起来很像、但完全是假的答案(业内叫幻觉)。

想让 AI 答对你的私有知识,靠的不是它的记忆,而是把资料递到它手边。

二、什么是 RAG

一句话:在让模型回答之前,先从你的资料里找出最相关的几段,拼到问题后面一起发给模型。

模型还是那个模型,但它回答时眼前多了一叠你给的参考资料,并且被要求只依据这些资料作答、并注明出处。这样它答的每一句,都能在资料里找到根据。

三、真实实验:同一问题,RAG 和不-RAG 差多少

在一个 AI 实践教学项目里,作者准备了一个 6 篇文档、26 个片段的小知识库(内容是他自己的技术栈、学习计划之类),然后用同一个云端大模型跑了 5 个问题,每个问题都对比只靠模型自己和先查资料再答。下面是其中三个最直观的对比:

你问的(私有/领域知识)不-RAG(只靠模型自己)RAG(先查资料再答)
Okale 的网站用什么服务器? 答不上I don't have specific, verified information about the server... 精准:腾讯云轻量服务器,4 核 4G / 3M 带宽 / Ubuntu 24.04,公网 IP 1.12.243.241。附来源
那个学习项目有几个阶段? 答不上I don't have... officially called the 'AI Engineer Quest'... 精准:8 个阶段(Q1 API Hunter → Q8 Final Project),逐一列出。附来源
向量库用哪个嵌入模型? 一长串向量库通用科普,完全没提到项目细节 精准:nomic-embed-text,768 维,存于 vector_store.json,经 Ollama 局域网生成。附来源

对私有/领域知识,不-RAG 基本是瞎子;RAG 却能给出带具体数字、还能指出来源的回答。5 个问题里,RAG 的资料检索命中率是 100%。

四、RAG 是怎么做到的(四步)

你的文档 切小块 嵌入成向量 向量库 你的问题 问题也嵌入 余弦相似度 找最像的 3 块 大模型 带资料答

① 嵌入:把文字变成一串数字

用嵌入模型(项目里用的是本地 nomic-embed-text,输出 768 个数字)把每段文字转成一个向量。语义相近的文字,向量方向也相近。文档里每一块、你提的每个问题,都先变成这样一串数字。

def embed_text(text, client):
    resp = client.embeddings.create(model="nomic-embed-text", input=text)
    return resp.data[0].embedding   # 长度 768 的浮点列表

② 分块:长文切小块

一整篇文档直接嵌,检索时太粗糙。先切成约 300 字、相邻块重叠 50 字的小块,命中才精准。项目里 6 篇文档最终切成 26 块。

③ 余弦相似度:怎么算像不像

这是 RAG 的灵魂公式,衡量两段文字的向量方向有多一致:

cos(a, b) = (a·b) / (|a| × |b|)

a·b    = 对应数字相乘再相加(点积)
|a|    = 向量自身长度(平方再开方)
结果:1 = 完全同向(极相似),0 = 不相关

代码里用纯 Python 实现,不依赖额外库:

def cosine_similarity(a, b):
    dot = sum(x*y for x, y in zip(a, b))
    na  = math.sqrt(sum(x*x for x in a))
    nb  = math.sqrt(sum(y*y for y in b))
    return dot / (na * nb)

④ 检索 + 生成:把资料递到模型手边

把你的问题也嵌入,和向量库里每一块算相似度,取最像的 3 块,拼到问题后面。最关键的是这句系统提示词,它直接复用了提示词工程里学的防幻觉思路:

RAG_SYSTEM_PROMPT = (
    "只依据提供的资料回答问题。若资料不足以回答,"
    "就说'根据提供的资料,我无法回答这个问题'。"
    "不要用你自己的知识。务必注明来源文档标题。"
)

五、RAG 的隐藏福利:它不敢编

只依据资料、答不出就直说这条规则,带来一个意外好处:模型不再一本正经地胡说。

实验里就有一个例子:问职业发展的 4 个阶段是什么,相关资料被切到了第 2 块(相似度排名第 3),最上面那块只有标题、没有细节。结果 RAG 老老实实说资料里没提到 4 个阶段,而不是编四个出来。对比之下,不-RAG 的回答直接是我没有任何关于 Okale 的信息,两头都诚实,但 RAG 至少把知道的说对了,对不知道的也不瞎补。

一句话记住:RAG 不只是更准,更是更可信,每句答案都能追溯到资料,答不出会明说。这正是企业敢把 AI 用在对内问答上的前提。

六、什么时候才值得上 RAG

RAG 不是万能药,它适合资料会变、且只有你有的场景:

适合上 RAG不太需要 RAG
公司内网文档、产品手册、会议纪要通用常识(什么是递归、怎么煮面)
你的笔记、客户资料、合同模型训练数据里已经很全的话题
经常更新的知识(价格、库存、政策)一次性、不需要引用出处的闲聊

七、一个容易踩的坑:分块策略

RAG 的效果,七分看检索准不准,而检索准不准,七分看怎么切块。实验里暴露过:一个关键信息被从中间切开,结果标题块相似度最高、却偏偏不含答案,真正有用的那块排到了第 3。两条实用经验:

  • 块别太大也别太小:太大检索不精准,太小语义被切碎。300 字左右是常见起点。
  • 留重叠:相邻块重叠几十字,避免一句话被劈成两半、两头都不完整(项目用了 50 字重叠)。