上一篇聊 Function Calling 时说过,模型天生只会「说」不会「做」。还有一个更常见的困惑:我把公司资料都发给它了,它怎么还是答非所问,甚至一本正经地编?这不是模型笨,是它压根没看过你的资料。RAG(检索增强生成)就是解决这件事的标准做法,也是目前把 AI 接进真实业务时最常走的一条路。
RAG 是什么?把「闭卷考试」改成「开卷考试」
模型的知识来自训练数据,就像考前一本书背下来——考完就定型了,书里没有的内容,它只能凭感觉蒙。RAG 的思路特别朴素:既然背不完,那就允许它翻书。用户提问时,程序先去你的资料库里找出最相关的几段,再连同问题一起递过去:「请根据下面这些材料回答」。模型从闭卷变开卷,答案有据可依,还能把出处一并指给你看。
一条 RAG 流水线,其实就五步
整个流程可以分成「入库」和「问答」两半:入库是一次性的准备工作,问答则是每次提问都要跑的。拆开看只有五步——
- 切块:把长文档按语义切成一段段小文本,常见一块 300~800 字,相邻两块之间留一点重叠,避免一句话被拦腰砍断
- 向量化:调用 embedding 接口把每块文本转成一串数字(向量),语义越接近的文本,在这串数字构成的空间里离得越近
- 入库:把「向量 + 原文 + 出处」存起来,规模不大时,一个本地文件甚至一张表就够,不必急着上专门的向量数据库
- 检索:用户提问时,把问题也转成向量,去库里捞出最相似的 top-k 块,k 通常取 3~8
- 生成:把捞回来的片段拼进提示词,连同问题一起发给对话模型,让它基于材料组织回答
这五步里最容易被低估的是第一步。切片切得不好,后面检索算法再花哨也捞不到正确内容——RAG 的效果上限,在切块那一刻就定了一大半。
最小可行版本,一个晚上就能跑通
别一上来就想着搭集群。一个能跑起来的原型只需要三样东西:
- 一个 embedding 模型:把请求发到 https://api.aigcbreeze.cn/v1/embeddings,返回的向量存下来即可。站内的 qwen3.7-text-embedding-flash 单价很低,适合先把整条链路走通
- 一个对话模型:负责最后把材料翻译成人话,deepseek-v4-flash、glm-5.3 这类都够用,请求发到 https://api.aigcbreeze.cn/v1/chat/completions,用法与 OpenAI 接口兼容
- 一段检索代码:几百个片段以内,用 Python 算一遍余弦相似度再排序,几行代码解决,真不需要数据库
一个高频踩的坑:把检回来的片段原样塞给模型,却没告诉它「只依据材料回答」。模型很可能把材料和你没给它的旧知识混在一起说。提示词里明确写上「材料里没有的就直说没有」,能挡掉相当一部分幻觉。
常见问题
有了 RAG,还需要微调吗?
大多数场景不需要。RAG 适合「知识会更新、答案要能溯源」的需求,资料改了直接换文档,不用重训模型;微调更适合「固定风格、固定输出格式」的任务。两者也不冲突,有人先微调语气、再挂 RAG 补知识。
RAG 答错了,该从哪查?
顺着流水线倒着查最快:先看检索回来的片段里到底有没有正确答案——没有,问题出在切块或检索参数上;材料是对的但模型答偏了,问题出在提示词上。先定位是哪一环,再动手改,比一股脑反复调提示词有效得多。
只用向量检索够不够?
向量检索擅长「意思相近」,但对订单号、型号、专有名词这类精确字符串不太敏感。资料里这类内容多的话,再挂一路关键词检索(BM25),把两边的结果合并排序,也就是常说的混合检索,命中率通常会有明显提升。