60行代码从零实现RAG - 深刻理解工作原理
深刻理解RAG工作流程和核心逻辑
不依赖任何框架,纯Python实现
20分钟跑通完整RAG流程
为学习框架做准备
这是最简洁的RAG实现,仅使用OpenAI API和Numpy, 60行代码包含文本向量化、相似度检索、LLM生成的完整流程。
通过手写每个环节,你将深刻理解RAG的工作原理,为后续学习框架打下坚实基础。
import openai
import numpy as np
# ========== 配置 ==========
openai.api_key = "sk-your-api-key-here"
# ========== 示例知识库 ==========
documents = [
"RAG是检索增强生成系统,结合信息检索和大语言模型。",
"向量数据库用于存储和检索文本的向量表示。",
"Embedding模型将文本转换为固定维度的向量。",
"Rerank模型可以提升检索准确率30%以上。",
"LlamaIndex专注于RAG开发,API简洁易用。"
]
# ========== 核心函数 ==========
def get_embedding(text):
"""获取文本向量"""
response = openai.Embedding.create(
model="text-embedding-3-small",
input=text
)
return response['data'][0]['embedding']
def cosine_similarity(vec1, vec2):
"""计算余弦相似度"""
return np.dot(vec1, vec2) / (np.linalg.norm(vec1) * np.linalg.norm(vec2))
def retrieve(query, documents, top_k=3):
"""检索最相关的文档"""
print(f"🔍 检索中...")
# 1. 查询向量化
query_emb = get_embedding(query)
# 2. 文档向量化(生产环境应提前缓存)
doc_embs = [get_embedding(doc) for doc in documents]
# 3. 计算相似度
scores = [cosine_similarity(query_emb, doc_emb) for doc_emb in doc_embs]
# 4. 排序取top-k
top_indices = np.argsort(scores)[::-1][:top_k]
# 5. 返回结果
results = [(documents[i], scores[i]) for i in top_indices]
return results
def generate_answer(query, context_docs):
"""基于检索文档生成回答"""
print(f"🤖 生成中...")
# 构建提示词
context = "\n".join([f"- {doc}" for doc, _ in context_docs])
prompt = f"""基于以下参考文档回答问题:
参考文档:
{context}
问题:{query}
要求:
1. 仅基于参考文档回答
2. 如果没有相关信息,请说明
3. 回答要准确简洁
回答:"""
# 调用LLM
response = openai.ChatCompletion.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": prompt}],
temperature=0.3,
max_tokens=300
)
return response.choices[0].message.content
# ========== 主流程 ==========
if __name__ == "__main__":
query = "什么是RAG系统?"
print(f"❓ 问题:{query}\n")
# 检索
relevant_docs = retrieve(query, documents, top_k=2)
print(f"✅ 找到 {len(relevant_docs)} 个相关文档\n")
for i, (doc, score) in enumerate(relevant_docs, 1):
print(f" {i}. {doc} (相似度: {score:.3f})")
# 生成
answer = generate_answer(query, relevant_docs)
print(f"\n💡 回答:\n{answer}")
print("\n✨ RAG流程完成!")
pip install openai numpy
export OPENAI_API_KEY="sk-..."
python basic_rag.py
在基础RAG上添加Reranker只需要10行代码, 但准确率从70%提升到90%+!这是性价比最高的优化手段。
Reranker通过两阶段检索策略,先用向量快速筛选候选,再用精确模型重排序,大幅过滤无关文档。
1. RAG是检索增强生成...
相似度: 0.856 ✓ 相关
2. Embedding模型将文本...
相似度: 0.623 ⚠️ 弱相关
3. Python是编程语言...
相似度: 0.412 ❌ 不相关
存在问题:
1. RAG是检索增强生成...
Rerank分数: 0.956 ✓✓ 高相关
2. 向量数据库用于存储...
Rerank分数: 0.834 ✓ 相关
3. Rerank提升检索准确率...
Rerank分数: 0.791 ✓ 相关
效果提升:
商业API,效果最佳,每月1000次免费
# ========== 完整代码:基础RAG + Cohere Rerank ==========
import openai
import numpy as np
import cohere # 新增Cohere
# 配置
openai.api_key = "sk-your-openai-key"
co = cohere.Client('your-cohere-key') # https://dashboard.cohere.com 注册获取
documents = [
"RAG是检索增强生成系统,结合信息检索和大语言模型。",
"向量数据库用于存储和检索文本的向量表示。",
"Embedding模型将文本转换为固定维度的向量。",
"Python是一门编程语言,广泛用于AI开发。", # 不相关文档
"Rerank模型可以提升检索准确率30%以上。",
"LlamaIndex专注于RAG开发,API简洁易用。"
]
def get_embedding(text):
response = openai.Embedding.create(
model="text-embedding-3-small",
input=text
)
return response['data'][0]['embedding']
def cosine_similarity(vec1, vec2):
return np.dot(vec1, vec2) / (np.linalg.norm(vec1) * np.linalg.norm(vec2))
def retrieve_with_rerank(query, documents, top_k_retrieval=5, top_k_rerank=2):
"""两阶段检索:向量检索 + Rerank"""
print(f"🔍 阶段1:向量检索 top-{top_k_retrieval}...")
# 1. 向量检索(粗排)
query_emb = get_embedding(query)
doc_embs = [get_embedding(doc) for doc in documents]
scores = [cosine_similarity(query_emb, doc_emb) for doc_emb in doc_embs]
top_indices = np.argsort(scores)[::-1][:top_k_retrieval]
candidates = [documents[i] for i in top_indices]
print(f" → 检索到 {len(candidates)} 个候选文档")
for i, idx in enumerate(top_indices, 1):
print(f" {i}. {documents[idx][:40]}... (向量分数: {scores[idx]:.3f})")
# 2. Rerank重排序(精排)
print(f"\n🎯 阶段2:Rerank精排 top-{top_k_rerank}...")
rerank_results = co.rerank(
query=query,
documents=candidates,
top_n=top_k_rerank,
model='rerank-multilingual-v3.0'
)
# 3. 返回结果
final_docs = []
for hit in rerank_results.results:
doc = candidates[hit.index]
score = hit.relevance_score
final_docs.append((doc, score))
print(f" {len(final_docs)}. {doc[:40]}... (Rerank分数: {score:.3f})")
return final_docs
def generate_answer(query, context_docs):
print(f"\n🤖 生成回答...")
context = "\n".join([f"- {doc}" for doc, _ in context_docs])
prompt = f"""基于以下参考文档回答问题:
参考文档:
{context}
问题:{query}
要求:仅基于参考文档回答,回答要准确简洁。
回答:"""
response = openai.ChatCompletion.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": prompt}],
temperature=0.3,
max_tokens=300
)
return response.choices[0].message.content
# ========== 主流程 ==========
if __name__ == "__main__":
query = "什么是RAG系统?"
print(f"❓ 问题:{query}\n")
print("=" * 60)
# 检索 + Rerank
relevant_docs = retrieve_with_rerank(
query,
documents,
top_k_retrieval=5, # 先检索5个候选
top_k_rerank=2 # Rerank精排到2个
)
print("\n" + "=" * 60)
# 生成
answer = generate_answer(query, relevant_docs)
print(f"💡 回答:\n{answer}")
print("\n✨ RAG + Rerank流程完成!准确率提升30%+")
pip install cohereco = cohere.Client()co.rerank()智源开源模型,中文效果优秀,可本地部署
# ========== 完整代码:基础RAG + BGE Reranker ==========
import openai
import numpy as np
from FlagEmbedding import FlagReranker # 新增BGE Reranker
# 配置
openai.api_key = "sk-your-openai-key"
# 加载Reranker模型(首次下载1.1GB)
reranker = FlagReranker(
'BAAI/bge-reranker-base', # 或 bge-reranker-large
use_fp16=True # 使用半精度加速
)
documents = [
"RAG是检索增强生成系统,结合信息检索和大语言模型。",
"向量数据库用于存储和检索文本的向量表示。",
"Embedding模型将文本转换为固定维度的向量。",
"Python是一门编程语言,广泛用于AI开发。",
"Rerank模型可以提升检索准确率30%以上。",
"LlamaIndex专注于RAG开发,API简洁易用。"
]
def get_embedding(text):
response = openai.Embedding.create(
model="text-embedding-3-small",
input=text
)
return response['data'][0]['embedding']
def cosine_similarity(vec1, vec2):
return np.dot(vec1, vec2) / (np.linalg.norm(vec1) * np.linalg.norm(vec2))
def retrieve_with_bge_rerank(query, documents, top_k_retrieval=5, top_k_rerank=2):
"""向量检索 + BGE Rerank"""
print(f"🔍 阶段1:向量检索 top-{top_k_retrieval}...")
# 1. 向量检索
query_emb = get_embedding(query)
doc_embs = [get_embedding(doc) for doc in documents]
scores = [cosine_similarity(query_emb, doc_emb) for doc_emb in doc_embs]
top_indices = np.argsort(scores)[::-1][:top_k_retrieval]
candidates = [documents[i] for i in top_indices]
print(f" ✅ 检索到 {len(candidates)} 个候选")
# 2. BGE Rerank重排序
print(f"\n🎯 阶段2:BGE Rerank精排 top-{top_k_rerank}...")
# 构建输入对 [query, document]
pairs = [[query, doc] for doc in candidates]
# 计算Rerank分数
rerank_scores = reranker.compute_score(pairs)
# 排序
sorted_indices = np.argsort(rerank_scores)[::-1][:top_k_rerank]
# 返回结果
final_docs = []
for idx in sorted_indices:
doc = candidates[idx]
score = rerank_scores[idx]
final_docs.append((doc, score))
print(f" {len(final_docs)}. {doc[:40]}... (Rerank: {score:.3f})")
return final_docs
# ========== 主流程 ==========
if __name__ == "__main__":
query = "什么是RAG系统?"
print(f"❓ 问题:{query}\n")
print("=" * 70)
# 使用Rerank
docs_with_rerank = retrieve_with_bge_rerank(
query,
documents,
top_k_retrieval=5,
top_k_rerank=2
)
print("\n" + "=" * 70)
print("\n🎉 Rerank完成!文档质量明显提升!")
print(f"💰 成本:BGE完全免费(本地部署)")
pip install cohere
注册获取免费API: https://dashboard.cohere.com
pip install FlagEmbedding
首次使用会自动下载1.1GB模型
+30%
70% → 90%+
10行
60行 → 70行
-50%
大幅过滤噪音
免费
BGE开源
理解了RAG原理后,使用框架可以让开发效率提升10倍