🤔 Why - 为什么我们需要RAG?
痛点一:LLM的"健忘症"
你有没有遇到过这种情况?向ChatGPT询问公司内部文档、最新政策,它却一脸懵圈地开始"一本正经地胡说八道"?这就是大语言模型的经典病症------知识截止日期焦虑症 + 幻觉综合征。
- 知识过时:模型训练后,世界还在继续发展,它却停留在了"过去"
- 缺乏专有知识:你公司的内部文档、行业报告,模型根本没见过
- 爱编故事:当LLM不知道答案时,它不会老实说"我不知道",而是信心满满地开始创作科幻小说
痛点二:重新训练?太贵了吧!
想让模型学会新知识?重新训练一个大模型?
- 💰 成本问题:百万美元起步,中小企业直接劝退
- ⏰ 时间成本:几周到几个月,等得花儿都谢了
- 🔄 更新困难:知识一变,又得重来一遍
解决方案:RAG来拯救世界!
RAG就像给LLM配了个"外挂大脑"------遇到问题先翻书(检索),再结合自己的理解(生成)回答。这样既保持了LLM的语言能力,又能实时获取最新、最准确的信息。
核心价值:
- ✅ 减少幻觉,答案更靠谱
- ✅ 支持专有知识,公司文档不再是摆设
- ✅ 实时更新,今天的新闻今天就能用
- ✅ 成本友好,不用砸锅卖铁
📚 What - RAG到底是什么?
核心概念:检索 + 生成的完美CP
RAG = Retrieval (检索)+ Augmented (增强)+ Generation(生成)
简单来说,就是:
- 别急着回答 → 先去知识库里找找相关资料
- 带着资料回答 → 把找到的信息塞给LLM,让它基于事实说话
- 生成靠谱答案 → 模型结合检索到的内容,输出有理有据的回复
工作流程:四步走战略
markdown
👤 用户提问
↓
🔍 信息检索(在知识库里翻箱倒柜)
↓
📝 上下文增强(把找到的东西和问题打包)
↓
🤖 答案生成(LLM开始表演)
↓
✨ 输出答案(附带信息来源)
技术栈:工具箱里的"五件套"
| 工具 | 作用 | 比喻 |
|---|---|---|
| LangChain | RAG框架 | 项目经理,统筹全局 |
| Sentence Transformers | 文本嵌入 | 翻译官,把文字变成数字 |
| FAISS | 向量数据库 | 图书馆索引系统,秒速找书 |
| DeepSeek API | 大语言模型 | 知识渊博的答题专家 |
| Python | 编程语言 | 施工队伍 |
关键技术点
1. 文本嵌入(Embedding)
- 把文字变成向量(一串数字)
- 语义相似的文本,向量距离也近
- 例子:🍎"苹果好吃" 和 🍏"苹果很美味" 的向量会很接近
2. 向量检索
- 用户问题 → 转成向量 → 在向量数据库里找"邻居"
- 找到最相似的k个文档片段
- 相似度算法:余弦相似度、欧式距离等
3. 提示工程(Prompt Engineering)
-
告诉LLM:"根据这些资料回答,别瞎编!"
-
模板示例:
上下文:【检索到的文档】 问题:【用户的问题】 要求:基于上下文回答,不知道就说不知道!
🛠️ How - 手把手教你搭建RAG系统
第一步:准备工作(10分钟搞定)
安装依赖包
bash
pip install langchain sentence-transformers faiss-cpu deepseek-llm openai python-dotenv
获取DeepSeek API Key
-
访问 DeepSeek开放平台
-
注册账号 → 生成API Key
-
创建
.env文件存储密钥:iniDEEPSEEK_API_KEY="sk-your-key-here"
准备知识库 创建knowledge_base文件夹,放入txt文件:
bash
knowledge_base/
├── deepseek_info.txt # DeepSeek公司介绍
└── rag_intro.txt # RAG技术说明
第二步:核心代码实现(分模块理解)
模块1:加载文档 📂
python
from langchain_community.document_loaders import DirectoryLoader, TextLoader
# 从文件夹加载所有txt文件
loader = DirectoryLoader(
'./knowledge_base/',
glob="**/*.txt",
loader_cls=TextLoader,
loader_kwargs={'encoding': 'utf-8'}
)
documents = loader.load()
要点:支持批量加载,自动识别文件夹下所有txt文档
模块2:文本分割 ✂️
python
from langchain.text_splitter import RecursiveCharacterTextSplitter
# 切成小块,方便检索和嵌入
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500, # 每块最多500字符
chunk_overlap=50 # 块之间重叠50字符(避免语义断裂)
)
texts = text_splitter.split_documents(documents)
为什么要分割?
- LLM上下文有限,不能塞太多内容
- 小块检索更精准
- 重叠部分保证语义连贯性
模块3:生成向量 🧮
python
from langchain_community.embeddings import HuggingFaceEmbeddings
# 使用预训练模型将文本转为向量
embeddings = HuggingFaceEmbeddings(
model_name="sentence-transformers/all-MiniLM-L6-v2"
)
模型选择:
all-MiniLM-L6-v2:轻量级,速度快,适合入门- 更强选择:
all-mpnet-base-v2、text-embedding-ada-002(OpenAI)
模块4:构建向量数据库 🗄️
python
from langchain_community.vectorstores import FAISS
# 一键生成向量库(自动嵌入+索引)
vector_store = FAISS.from_documents(texts, embeddings)
FAISS优势:
- Meta开源,性能强悍
- 支持百万级向量快速检索
- CPU/GPU双版本可选
模块5:初始化LLM 🤖
python
from langchain_deepseek import ChatDeepseek
llm = ChatDeepseek(
model="deepseek-chat", # 模型名称
api_key=api_key,
temperature=0.1 # 降低随机性,答案更稳定
)
温度参数说明:
0.0-0.3:严谨模式,适合RAG0.7-1.0:创意模式,适合写作
模块6:创建RAG链 ⛓️
python
from langchain.chains import RetrievalQA
from langchain.prompts import PromptTemplate
# 自定义提示模板
prompt_template = """
根据以下上下文回答问题。
找不到答案就说"我不知道",别瞎编!
上下文: {context}
问题: {question}
答案:
"""
PROMPT = PromptTemplate(
template=prompt_template,
input_variables=["context", "question"]
)
# 组装完整RAG链
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff", # 将检索内容全部塞入提示
retriever=vector_store.as_retriever(search_kwargs={"k": 3}), # 检索前3个最相关片段
chain_type_kwargs={"prompt": PROMPT},
return_source_documents=True # 返回信息来源
)
模块7:提问交互 💬
python
# 用户输入问题
user_query = "DeepSeek是什么公司?"
# 执行RAG流程
result = qa_chain.invoke({"query": user_query})
# 输出答案
print("答案:", result["result"])
# 输出来源(可追溯!)
print("\n信息来源:")
for doc in result["source_documents"]:
print(f"文件: {doc.metadata['source']}")
print(f"内容: {doc.page_content}")
第三步:运行测试 🎯
完整流程演示:
makefile
$ python simple_rag.py
加载知识库文档... ✓
分割文档... ✓ (生成12个文本块)
生成文本嵌入... ✓
构建向量数据库... ✓
初始化DeepSeek LLM... ✓
创建RAG链... ✓
请输入问题: DeepSeek的使命是什么?
正在检索相关文档...
找到3个相关片段 ✓
调用LLM生成答案...
模型回答:
DeepSeek的使命是"用AI改变世界"。
引用来源:
[片段1] 来自: knowledge_base/deepseek_info.txt
内容: DeepSeek的使命是"用AI改变世界"...
🚀 进阶优化:从入门到精通
优化方向一:提升检索质量 🎯
1. 优化文本分割
python
# 根据语义分割(更智能)
from langchain.text_splitter import SpacyTextSplitter
splitter = SpacyTextSplitter(chunk_size=500)
2. 混合检索策略
- 向量检索(语义相似)+ BM25关键词检索
- 两种结果融合,取长补短
3. 重排序(Re-ranking)
python
# 用更强的模型对检索结果重新打分
from sentence_transformers import CrossEncoder
reranker = CrossEncoder('cross-encoder/ms-marco-MiniLM-L-12-v2')
优化方向二:提升生成质量 ✍️
1. 提示工程进阶
python
prompt_template = """
你是一个专业助手,需要基于以下文档回答问题。
【要求】
1. 答案必须来自文档,不要添加额外信息
2. 如果文档中没有答案,明确说"根据现有信息无法回答"
3. 引用文档时标注来源
4. 保持答案简洁、准确
【文档】
{context}
【问题】
{question}
【答案】
"""
2. Few-shot学习
- 在提示中加入示例问答对
- 教会模型如何更好地利用上下文
优化方向三:系统性能优化 ⚡
1. 异步处理
python
import asyncio
async def async_query(query):
return await qa_chain.ainvoke({"query": query})
# 批量并发查询
results = await asyncio.gather(*[async_query(q) for q in queries])
2. 缓存机制
python
from langchain.cache import InMemoryCache
import langchain
langchain.llm_cache = InMemoryCache() # 相同问题直接返回缓存
3. 流式输出
python
# 用户体验更好,边生成边展示
for chunk in qa_chain.stream({"query": user_query}):
print(chunk, end="", flush=True)
优化方向四:评估与监控 📊
使用RAGAS框架评估
python
from ragas import evaluate
from ragas.metrics import faithfulness, answer_relevancy
# 评估RAG系统质量
results = evaluate(
dataset=test_dataset,
metrics=[faithfulness, answer_relevancy]
)
关键指标:
- Faithfulness(忠实度):答案是否基于检索内容?
- Answer Relevancy(相关性):答案是否切题?
- Context Precision(上下文精度):检索的内容是否精准?
🎓 总结:RAG的价值与未来
三句话总结RAG
- Why:LLM有局限(知识过时、缺乏专有信息、易产生幻觉),RAG通过检索外部知识解决这些问题
- What:RAG = 检索器(找资料)+ LLM(理解生成),让模型"有据可依"
- How:用LangChain框架 + 向量数据库 + 大模型API,10分钟搭建基础系统
RAG的适用场景 💡
- ✅ 企业知识库问答:公司文档、产品手册
- ✅ 客服机器人:基于FAQ和历史工单
- ✅ 法律/医疗咨询:需要引用权威文献
- ✅ 个人知识管理:笔记检索与总结
下一步行动清单 📋
- 搭建第一个RAG原型系统
- 用自己的文档测试效果
- 尝试不同的嵌入模型和LLM
- 添加Web UI(用Streamlit/Gradio)
- 建立评估流程,持续优化
一句话警告 ⚠️
RAG不是万能药!复杂推理、创意生成任务还是得靠模型本身的能力。RAG的强项是"知识密集型"任务,记住这个定位,才能用得其所。
🎉 恭喜你!现在你已经掌握了RAG的核心原理和实战技巧。去构建你的AI知识助手吧!