RAG 实战入门:给 AI 装上你自己的知识库

你问模型"我们公司的报销标准是多少",它一定答不上来——训练数据里没有这些。硬要它答,它就会编。

解决办法不是重新训练模型(太贵),而是 RAG:检索增强生成

一、一句话原理

先从你的资料里出相关段落,再把段落连同问题一起给模型,让它照着回答。

就这么简单。模型负责"理解和组织语言",你的知识库负责"提供事实"。分工明确,成本极低。

二、完整流程拆解

text
【建库阶段(一次性)】
文档 → 切分成块 → 向量化 → 存入向量库

【问答阶段(每次提问)】
问题 → 向量化 → 检索相似块 → 拼进提示词 → 模型生成答案

1. 切分(Chunking)

把长文档切成小块,这一步决定了 RAG 的上限

  • 块太大:检索不精准,塞满上下文
  • 块太小:语义被切断,答非所问

经验值:每块 300~500 字,相邻块重叠 50~100 字。重叠是为了防止关键句正好被切在边界上。

按语义切比按字数切好得多——优先按标题、段落、条目切分,Markdown 文档尤其适合按 ## 层级切。

2. 向量化(Embedding)

把文字变成一串数字(向量),语义相近的文字向量距离近。中文场景推荐用专门的中文 embedding 模型,效果比通用模型好一大截。

3. 存储与检索

小规模(几千条)用 SQLite + 简单向量扩展就够;上万条再上专业向量库。不要一上来就搞分布式集群,绝大多数场景根本用不到。

4. 拼提示词

text
以下是从知识库中检索到的资料:
---
[资料1]
[资料2]
[资料3]
---
请仅根据以上资料回答问题。如果资料中没有相关信息,
请直接回答"资料中未提及",不要编造。

问题:{用户问题}

最后那句"不要编造"非常重要,能显著降低幻觉率。

三、最小可跑实现

python
# 依赖:pip install openai numpy
import numpy as np
from openai import OpenAI

client = OpenAI(base_url="http://localhost:11434/v1", api_key="ollama")

def embed(text):
    r = client.embeddings.create(model="bge-m3", input=text)
    return np.array(r.data[0].embedding)

# 1. 建库
docs = [
    "差旅报销:市内交通每日上限 100 元,需提供发票。",
    "年假规则:入职满一年 5 天,每满一年递增 1 天,上限 15 天。",
    "设备申领:新员工可申领笔记本一台,三年更换一次。",
]
index = [(d, embed(d)) for d in docs]

# 2. 检索
def search(q, k=2):
    qv = embed(q)
    scored = [(float(qv @ v / (np.linalg.norm(qv) * np.linalg.norm(v))), d)
              for d, v in index]
    scored.sort(reverse=True)
    return [d for _, d in scored[:k]]

# 3. 问答
def ask(q):
    ctx = "\n".join(search(q))
    prompt = (f"以下是知识库资料:\n{ctx}\n\n"
              f"请仅根据资料回答,没有就说'资料中未提及'。\n问题:{q}")
    r = client.chat.completions.create(
        model="qwen2.5:7b",
        messages=[{"role": "user", "content": prompt}],
    )
    return r.choices[0].message.content

print(ask("年假最多能有几天?"))

不到 40 行,一个能用的私有知识库问答就跑起来了。

四、效果不好怎么调?

按这个顺序排查,命中率最高:

  1. 先看检索结果对不对。把检索到的块打印出来——十次里有八次问题出在这,跟模型无关。
  2. 调整切分策略。块大小、重叠量、是否按标题切。
  3. 加关键词检索做混合。纯向量检索对专有名词、编号不敏感,配一个关键词匹配再合并排序,效果立竿见影。
  4. 加重排(Rerank)。先粗筛 20 条,再用重排模型精选 3 条。
  5. 最后才换大模型

五、几条实践经验

  • 给答案标出处。让模型输出引用了哪一块资料,用户信任度和你的排错效率都会提升。
  • 建库要能增量更新。文档改了要能只更新那一块,别每次全量重建。
  • 表格和图片单独处理。表格直接向量化效果很差,先转成结构化描述文本。
  • 别迷信长上下文。就算模型支持 100 万 token,把整个知识库塞进去既慢又贵,准确率还不如精准检索三段。

RAG 不是什么高深技术,本质是"先查资料再答题“这个朴素常识的工程化。真正的难点从来不在算法,而在你的资料本身够不够干净。