聊天模型只认两样东西:训练数据和你塞进提示的内容。更新一点的知识、私人笔记、公司内部文档它都不知道,硬答就会编造。RAG(检索增强生成)的思路是:先把你的文档放进知识库,提问时检索出最相关的片段,连同问题一起交给模型。这篇以一个视频课程库为例,从切块、嵌入讲到向量检索和重排,最后拼出一个完整的 RAG 聊天机器人,并给出评估效果的四把尺子。
为什么需要 RAG
GPT-4 的知识截止到 2021 年 9 月,训练数据也不包含个人笔记、公司产品手册这类保密内容 [1]。RAG 用四步补上这两个缺口 [1]:
- 知识库:文档先被摄取和预处理——切小块、转成文本嵌入(embedding)、存进数据库;
- 用户提问;
- 检索:嵌入模型从知识库里取回相关信息,并入提示;
- 增强生成:模型基于检索到的数据组织回答。
架构上,RAG 把检索器(retriever)和生成器(generator)接在一起:问题转成向量,到文档索引里匹配相关文本块,再作为上下文喂给大模型。两者可以用不同的模型,RAG 也不要求编码器-解码器结构的 transformer [1]。提出 RAG 的论文给了两种做法:RAG-Sequence 用检索到的文档直接预测问题的最佳答案;RAG-Token 逐 token 生成、边生成边检索 [1]。
选 RAG 而不是微调,理由有三 [1]:信息新鲜——靠内部知识库保证回答与时俱进,领域任务表现更好;减少编造——上下文来自可验证的数据;省钱——比微调大模型经济得多。还有一条隐性的工程优势:知识库更新只需要重新摄取文档,不用重训模型——产品手册改版、笔记增补,当天就能反映到回答里。
向量数据库与切块
向量数据库专门用来存储、管理和检索嵌入向量——文档的数值化表示,把数据变成数字向量之后,AI 系统才好理解和处理 [1]。因为大模型能接受的输入 token 数有限,文档要先切块再嵌入;与问题最相似的块会随提示返回,切块同时也减少了传给模型的 token 数,降低调用成本 [1]。常见选择有 Azure Cosmos DB、Clarifyai、Pinecone、Chromadb、ScaNN、Qdrant、DeepLake [1]。Azure Cosmos DB 用四条 CLI 命令就能建好 [1]:
az login
az group create -n <resource-group-name> -l <location>
az cosmosdb create -n <cosmos-db-name> -r <resource-group-name>
az cosmosdb list-keys -n <cosmos-db-name> -g <resource-group-name>切块的粒度比想象中重要:可以按句子切,也可以按段落切;由于一个块的含义来自上下文,给它补充背景有帮助——比如带上文档标题,或把块前后的文字一并纳入 [1]。选粒度时从检索场景倒推:用户的问题通常多大、答案一般多长,块就应该差不多大——块太小语义不完整,太大则检索不精准、白耗 token。一个按词数切块的最小实现 [1]:
def split_text(text, max_length, min_length):
words = text.split()
chunks = []
current_chunk = []
for word in words:
current_chunk.append(word)
if len(' '.join(current_chunk)) < max_length and len(' '.join(current_chunk)) > min_length:
chunks.append(' '.join(current_chunk))
current_chunk = []
# If the last chunk didn't reach the minimum length, add it anyway
if current_chunk:
chunks.append(' '.join(current_chunk))
return chunks嵌入模型可选 word2vec、OpenAI 的 ada-002、Azure Computer Vision 等;按语言、内容类型(文本/图像/音频)、能编码的输入大小和嵌入输出长度来选 [1]。
检索与向量搜索
用户提问时,检索器先把问题编码成向量,再到文档索引里找相关的文档向量,最后把两者都转回文字传给大模型 [1]。这条链路的每一环都可能丢信息:问题编码得准不准、索引建得好不好、返回的块排序对不对,排查回答质量问题时按这个顺序逐环检查。搜索方式有三种:关键词搜索针对文本;向量搜索用嵌入模型把文档变成向量,按语义检索——取与问题向量最近的文档;混合检索则是两者的结合 [1]。一个要防的坑:数据库里没有相似内容时,系统照样返回「最像」的结果——可以设置相关性的最大距离阈值,或者直接用混合检索兜底 [1]。
相似度最常用余弦相似度,基于两个向量的夹角;欧氏距离(向量端点间的直线距离)和点积(对应元素乘积之和)也可以 [1]。三种度量的适用场合不同:文本语义检索一般从余弦相似度起步,它对向量长度不敏感;换成别的嵌入模型时,记得确认文档推荐的度量方式,两者要配套。搜索索引负责把「最相似的块」快速取出来,数据库再大也不怕;本地建索引用 scikit-learn 几行就够 [1]:
from sklearn.neighbors import NearestNeighbors
embeddings = flattened_df['embeddings'].to_list()
# Create the search index
nbrs = NearestNeighbors(n_neighbors=5, algorithm='ball_tree').fit(embeddings)
# To query the index, you can use the kneighbors method
distances, indices = nbrs.kneighbors(embeddings)查出来的结果还可以按相关度重排(re-ranking):重排模型会把最相关的排到前面;Azure AI Search 用语义重排器自动完成这一步 [1]:
# Find the most similar documents
distances, indices = nbrs.kneighbors([query_vector])
# Print the three most similar documents with their distance to the question
for distance, index in zip(distances[0][:3], indices[0][:3]):
print(flattened_df['chunks'].iloc[index])
print(flattened_df['path'].iloc[index])
print(distance)拼装完整应用
最后把大模型接进来。聊天机器人先把问题转成向量,取最近的块堆进上下文,再生成回答 [1]:
user_input = "what is a perceptron?"
def chatbot(user_input):
# Convert the question to a query vector
query_vector = create_embeddings(user_input)
# Find the most similar documents
distances, indices = nbrs.kneighbors([query_vector])
# add documents to query to provide context
history = []
for index in indices[0]:
history.append(flattened_df['chunks'].iloc[index])
# combine the history and the user input
history.append(user_input) # create a message object
messages=[
{"role": "system", "content": "You are an AI assistant that helps with AI questions."},
{"role": "user", "content": "\n\n".join(history) }
]
# use the Responses API to generate a response
response = client.responses.create(
model="gpt-5-mini",
max_output_tokens=800,
input=messages,
store=False,
)
return response.output_text
chatbot(user_input)效果从四个维度评估:回答质量(自然、流畅、像人话);忠实度(groundedness,回答是否真的来自提供的文档);相关性(回答是否切题);流利度(语法是否通顺)[1]。典型场景包括:把公司数据接进员工问答、按相似度匹配的电影餐厅推荐系统、存聊天记录做个性化的客服机器人,以及基于向量嵌入的图像搜索(图像识别、异常检测)[1]。不想从零拼装的话,Semantic Kernel、LangChain、AutoGen 这些框架把大部分管道工作都封装好了 [1]。上线前拿四个评估维度各设计一组测试问题——特别是忠实度:准备一些知识库里根本没有答案的问题,看应用是老实承认不知道,还是照样编一个。
本文改编自 Microsoft 开源课程《Generative AI for Beginners》第 15 课[1],原文以 MIT 许可证发布。
来源
- 1Retrieval Augmented Generation (RAG) and Vector Databases | Generative AI for BeginnersMicrosoft generative-ai-for-beginners (MIT)
引用本页: RAG 与向量数据库入门. TellWorld, https://www.tellworld.net/zh/practice/practice-rag-vector-databases. 更新于 2026-11-14