前两天同事提了个需求,被我怼了。他说现在有一些客服数据,和对应的分类,直接用deepseek分类感觉分的不是很准确,能不能做个东西让分类更精确。
我说:咱们自己调一个模型。
他:能不能用RAG?
我: 大哥你是只知道技术不了解原理啊。
因此我觉得我又该出山写点东西给他们科普一下子了。
生成模型的局限性
生成模型(像ChatGPT、deepseek这种)在自然语言处理上已经取得了很大进展,可以生成流畅的对话和文本,但是它们其实也有一些问题。比如:
- 知识过时
生成模型在训练的时候只学到了它们训练时的数据。所以它们的知识只能到那个时间点为止,后面的信息就不知道了。如果你问它一些最近发生的事情,它可能就无能为力了。 - 容易出错
生成模型会根据训练数据生成回答,但有时候它会生成一些看似合理、但完全错误的信息,或者根本就没有事实依据。这种现象叫做"幻觉",就像模型胡编乱造似的。 - ......
比如最开始chatGPT出来的时候,你问的很多东西它都能回答,但是问一些比较新的东西,他就开始胡说八道。但是当时copolit也是基于gpt3.5、gpt4的,copolit就回答的更好。
因为当时chatGPT是离线模型,他的回答结果只依赖于它模型本身的训练,不依赖外部知识。但是当时的copolit是结合bing搜索的,将模型本身的能力和检索结果进行了融合进而优化结果。也就是基于Retrieval进行生成。
当然随着不断发展, chatGPT现在也拥有了联网查的功能来解决当年的痛点。

联网搜索功能和RAG技术实现方式都是基于Retrieval,通过外部的知识来优化模型本身的性能。二者的区别是:
-
联网搜索
联网搜索是借助搜索直接访问网络上的网页、新闻文章、博客、论文等内容,实时检索并使用这些最新的外部资源来回答问题。它通过搜索引擎获取信息,而不是直接依赖固定的知识库或数据集。
-
RAG
RAG则是在训练好的生成模型上加一个检索模块。这个检索模块通常是查询一个事先准备好的知识库或文档集合(例如,特定领域的数据库),然后根据检索到的信息来生成回答。RAG并不实时地从网络上获取信息,而是依赖于固定的外部数据源,它的检索机制更多是基于结构化的知识库或文档集合。
说点大白话:
联网搜索,是获取模型没学习到的新知识,在我看来更偏向于刚才提到的模型缺陷中的"知识过时"。但是互联网的信息参差不齐,有对有错,联网搜索就跟PDD一样保新不保真。
而RAG技术是更偏向于使用特定的知识库,比如企业想用一些内部的数据,这些数据一定是企业内部经过整理的,是更贴近业务且精确的知识,这些知识的正确性也是可以保障的,可以让模型回答的更精确。所以RAG更像去专柜买东西,能保证模型从外部获取到的知识一定是正确的。
RAG技术
Retrieval-Augmented Generation (RAG) ,即检索增强生成,是一种将信息检索与生成模型结合的方法,旨在提高生成模型的回答准确性和上下文理解能力。RAG的核心思想是,在生成模型生成答案之前,先通过检索模块从外部知识库或文档中获取相关的信息,然后将这些信息作为上下文输入,帮助生成模型产生更准确、更丰富的回答。
工作流程:
RAG |------获取知识
|------模型推理
|------检索
|------增强
|------生成
1. 获取知识

documents → chunks → (Embedding models → vector database)
一开始,我们手里有一堆原始文档documents 。
这些文档可以是任何形式的文本,比如:
- 技术手册
- 公司内部知识库
但问题是:一篇完整的文档往往又长又杂,直接拿来用,既检索不方便,也超出了很多模型的处理长度。
所以我们要做的第一步就是:把长文档切成一块一块的小片段 ,也就是所谓的 chunks。
怎么切?
- 可以按段落切
- 可以每隔固定字数/固定tokens切
- 也可以按语义切(比如,每一小段话讲一个小主题)
切成小块的好处:
- 检索的时候更精准(找到的小片段更聚焦问题)
- 后续送进模型处理时,不容易超长度限制
切好一块块chunk后,还不能直接用。
我们要做下一步:用Embedding模型把每一块文本转成向量
什么是向量?
- 就是把文本变成一串数字
- 让计算机能快速比较不同文本之间有多相似
比如,一个chunk可能被转成一个768维的向量(就是768个数字的数组)。
常用的Embedding模型有:
- OpenAI的text-embedding-ada-002
- Huggingface的sentence-transformers系列
- 自己fine-tune的小模型(比如MiniLM)
简单来说,Embedding就是给每一段文字打个"数学特征标签" 。
向量化完以后怎么办?
当然要存起来,方便以后检索。
我们把这些向量,存进一个专门能"以向量为单位快速查找"的数据库,叫做向量数据库。
2.模型生成
用户输入问题时,流程是这样的:
图片来源:weaviate.io/
1. 检索(Retrieval)
首先,推理是从检索开始的。
- 用户提出一个问题后,我们会先用Embedding模型把这个问题转成一个向量(也就是一个可以做相似性比较的数学表达)。
- 然后,拿着这个问题向量,到之前构建好的向量数据库 里进行相似性搜索。
- 相似性搜索就是比一比,看数据库里的哪些内容块(chunks)和问题最接近。
- 找到距离最近的内容块,把它们提取出来。
(距离越短,代表内容越相关。)
简单理解就是:
把问题变成一组数字,去数据库里找"最像的答案线索"。
2. 增强(Augmentation)
检索到了相关内容后,接下来是增强阶段。
-
把找到的这些相关chunks,按照一个预设好的提示词模板(prompt模板) ,嵌入进去。
-
模板可以非常灵活,比如:
lua
下面是参考资料。
---------------------
{context_str}
---------------------
只根据提供的资料回答,不要凭自己的记忆乱猜。
提问: {query_str}
回答:
这个阶段的核心目的是:
让模型在回答时,不是"凭空想",而是"有材料可参考"。 为什么这样设计?
- 避免模型幻觉(hallucination),就是不让它瞎编。
- 明确指示模型只基于检索到的内容推理,不调用自己内部过时或不准的知识。
- 通过清晰分块,提升模型对提示词结构的理解。
3. 生成(Generation)
最后,是生成阶段。
- 现在,模型的输入不仅有用户的问题,还有一堆检索来的参考资料。
- 模型综合内部已有的知识+外部提供的资料,生成一段更准确、可靠的回答。
注意:
- 生成时,模型会利用它原本的语言理解能力,加上新注入的外部信息,来形成自然、连贯、有根据的输出。
- 这样,回答既有流畅性,又能避免因为"忘了知识"而编造事实。