说起来,RAG(检索增强生成)这个名词,最近在AI圈子里热度一直不减。简单理解,它就是让大语言模型(LLM)不只会“背诵”,还能学会“查资料”——把你自己的数据塞进提示词里,让模型生成更靠谱、更贴合上下文的回答。这篇文章不打算讲太多玄乎的理论,而是直接带初学者从零开始,手把手搭一个最简版RAG应用。先看张图感受一下整体轮廓:

一、学习RAG的常见挑战
AI领域变化太快,尤其RAG这块,各种噪音和复杂概念满天飞。供应商们拼命把自己的工具、平台和愿景包装进去,把简单事情搞得很玄乎。本教程的目标就是帮你清除这些干扰,聚焦在最核心的思路上——从零搭建一个玩具级的RAG系统,理解了内核,后面再学那些花哨变体就轻松多了。
二、什么是检索增强生成(RAG)
RAG的核心逻辑其实很直白:通过一个检索工具,先把用户自己的数据(比如文档、知识库)找出来,然后连同用户的提问一起打包送给LLM,让它据此生成回答。相比让LLM光凭预训练知识硬编,RAG带来几个实实在在的好处:
- 避免幻觉:提示词里塞进了事实信息,模型胡说八道的风险自然就降下来了。
- 参考事实:用户可以看到模型引用了哪些真实数据,有问题也可以溯源核实。
- 利用未训练数据:模型训练时没见过的内部文档、最新资料,通过检索都能用上。
三、RAG系统的基本组件
一个RAG系统,拆开来看无非三样东西:
- 文档集合(也叫语料库)
- 用户输入(你提问的内容)
- 文档集合与用户输入之间的相似性度量方法
四、RAG系统的操作步骤
整个流程走下来也就三步:
- 接收用户输入
- 执行相似性测量,从文档集合里找出最匹配的文档
- 对用户输入和检索到的文档进行后处理(比如拼装成最终的提示词)
初学者完全可以从这种最简流程开始着手,一步步搞懂各个环节,再去玩那些复杂的变体。
五、示例:构建最简单的RAG系统
1. 获取文档集合
先定义一个简单的语料库,全是休闲活动建议:
corpus_of_documents = [
"Take a leisurely walk in the park and enjoy the fresh air.",
"Visit a local museum and discover something new.",
"Attend a live music concert and feel the rhythm.",
"Go for a hike and admire the natural scenery.",
"Ha ve a picnic with friends and share some laughs.",
"Explore a new cuisine by dining at an ethnic restaurant.",
"Take a yoga class and stretch your body and mind.",
"Join a local sports league and enjoy some friendly competition.",
"Attend a workshop or lecture on a topic you're interested in.",
"Visit an amusement park and ride the roller coasters."
]
2. 定义与执行相似性度量
比较用户输入和文档之间的相似度,这里用最朴素的Jaccard相似度——就是两个集合交集除以并集,简单粗暴但教学效果一流:
def jaccard_similarity(query, document):
query = query.lower().split(" ")
document = document.lower().split(" ")
intersection = set(query).intersection(set(document))
union = set(query).union(set(document))
return len(intersection) / len(union)
再写一个函数,遍历整个语料库,挑出最相似的那个文档:
def return_response(query, corpus):
similarities = []
for doc in corpus:
similarity = jaccard_similarity(query, doc)
similarities.append(similarity)
return corpus_of_documents[similarities.index(max(similarities))]
3. 运行示例
试试看效果:
user_prompt = "What is a leisure activity that you like?" user_input = "I like to hike" response = return_response(user_input, corpus_of_documents) print(response)
输出很直接:
'Go for a hike and admire the natural scenery.'
瞧,一个最基础的RAG应用已经跑通了!
六、改进相似性度量与添加LLM
Jaccard相似度只能看字面重合,语义层面的理解它完全无能为力。为了让生成效果更像真人,我们可以引入一个LLM对检索结果做后处理。下面是用一个开源LLM(假设本地部署了服务)来完善回答的示例:
import requests
import json
def query_llama(user_input, document):
url = "http://localhost:8000/query" # 你本地的LLM服务地址
payload = {
"prompt": f"User input: {user_input}\nDocument: {document}\nResponse:",
"max_tokens": 50
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, data=json.dumps(payload), headers=headers)
return response.json().get("text")
response_with_llm = query_llama(user_input, response)
print(response_with_llm)
这个示例展示了如何把检索到的文档和用户输入拼在一起,喂给LLM,让它生成更自然、更准确的回应。
七、总结与展望
RAG为LLM提供了一套灵活又强大的增强框架:让你用自己的数据给模型“开小灶”,生成质量大幅提升。这篇教程带大家从零搭建了一个最简单的RAG系统,并演示了如何逐步引入更高级的组件(比如LLM)。后续你完全可以在此基础上,用更先进的相似度测量方法(比如向量检索)和更复杂的检索策略,把RAG的效果再往上推一大截。
