加载3D可视化中...
RAG检索增强生成:深入理解嵌入与重排
什么是RAG?
RAG(Retrieval-Augmented Generation,检索增强生成)是一种将检索系统与大语言模型相结合的技术架构。它通过从外部知识库中检索相关信息,来增强语言模型的回答质量和准确性。
为什么需要RAG?
传统的大语言模型存在以下问题:
- 知识截止:模型只知道训练数据截止日期之前的信息
- 幻觉问题:模型可能生成看似合理但实际错误的内容
- 缺乏领域知识:通用模型难以回答特定领域的专业问题
RAG通过引入外部知识检索,有效解决了这些问题。
RAG工作流程
一个典型的RAG系统包含以下步骤:
- 文档预处理:将文档切分为适当大小的片段(chunk)
- 向量化:使用嵌入模型将文本转换为向量
- 存储:将向量存入向量数据库
- 检索:根据用户查询检索相关文档片段
- 重排:对检索结果进行重新排序
- 生成:将检索结果作为上下文输入给LLM生成回答
嵌入(Embedding)原理
什么是嵌入?
嵌入是将文本转换为数值向量的过程。这些向量能够捕捉文本的语义信息,使得意思相近的文本在向量空间中距离相近。
2026年主流嵌入模型
| 模型 | 来源 | 参数量 | 维度 | 特点 |
|---|---|---|---|---|
| Microsoft Harrier | 微软 | 27B/0.6B/270M | 可变 | MTEB-v2全球第一(74.3分),32k上下文,100+语言 |
| ML-Embed | 蚂蚁集团+上海交大 | 140M~8B | 可变 | ICML 2026,282种语言,3D-ML框架 |
| Qwen3-Embedding | 阿里 | 0.6B/4B/8B | 可变 | MTEB多语言冠军(70.58分),Apache 2.0开源 |
| BGE-M3 | BAAI | 568M | 1024 | 开源多语言,支持8192 token |
| F2LLM-v2 | 开源社区 | 多规格 | 可变 | ML-Embed基线版本,MTEB榜单前列 |
嵌入的数学原理
嵌入模型通过深度神经网络将文本映射到高维向量空间。例如:
- 文本「猫是哺乳动物」→ 向量 [0.12, -0.45, 0.78, ...]
- 文本「狗是哺乳动物」→ 向量 [0.15, -0.42, 0.81, ...]
- 文本「今天天气很好」→ 向量 [-0.67, 0.23, -0.12, ...]
前两个向量的余弦相似度很高(语义相近),而与第三个向量差异较大(语义不同)。
余弦相似度计算
python
import numpy as np
def cosine_similarity(vec1, vec2):
dot_product = np.dot(vec1, vec2)
norm1 = np.linalg.norm(vec1)
norm2 = np.linalg.norm(vec2)
return dot_product / (norm1 * norm2)
向量数据库
向量数据库用于高效存储和检索向量数据。常见选择:
- Milvus:高性能,支持分布式
- Chroma:轻量级,适合原型开发
- Pinecone:全托管云服务
- FAISS:Facebook开源,单机高性能
使用Chroma存储文档
python
import chromadb
from chromadb.utils import embedding_functions
client = chromadb.PersistentClient(path="./chroma_db")
ef = embedding_functions.OpenAIEmbeddingFunction(
api_key="your-api-key",
model_name="text-embedding-3-small"
)
collection = client.get_or_create_collection(
name="documents",
embedding_function=ef
)
collection.add(
documents=[
"RAG通过检索外部知识来增强LLM的回答",
"嵌入是将文本转换为向量的过程",
"向量数据库用于存储和检索向量"
],
ids=["doc1", "doc2", "doc3"]
)
results = collection.query(
query_texts=["什么是RAG"],
n_results=2
)
print(results)
重排(Reranking)原理
什么是重排?
重排是对初始检索结果进行重新排序的过程。由于向量检索基于语义相似度,可能遗漏一些关键词匹配但语义相似度较低的文档,重排可以弥补这一不足。
为什么要重排?
- 召回率 vs 精确率:向量检索侧重召回,重排侧重精确
- 多路召回融合:结合多种检索方式的结果
- 领域适配:根据特定领域调整排序
常见的重排方法
1. Cross-Encoder重排
Cross-Encoder将查询和文档拼接后一起编码,计算相关性分数:
python
from sentence_transformers import CrossEncoder
reranker = CrossEncoder("cross-encoder/ms-marco-MiniLM-L-6-v2")
query = "什么是RAG"
documents = [
"RAG是检索增强生成的缩写",
"Python是一种编程语言",
"检索增强生成结合了检索和生成"
]
pairs = [(query, doc) for doc in documents]
scores = reranker.predict(pairs)
ranked_results = sorted(zip(documents, scores), key=lambda x: x[1], reverse=True)
for doc, score in ranked_results:
print(f"{score:.4f}: {doc}")
2. BGE-Reranker
BGE-Reranker是BAAI开发的重排模型,支持多语言:
python
from FlagEmbedding import FlagReranker
reranker = FlagReranker("BAAI/bge-reranker-v2-m3", use_fp16=True)
query = "什么是RAG"
documents = [
"RAG是检索增强生成的缩写",
"Python是一种编程语言",
"检索增强生成结合了检索和生成"
]
pairs = [[query, doc] for doc in documents]
scores = reranker.compute_score(pairs, normalize=True)
print(scores)
3. Cohere Rerank
Cohere提供云端重排API:
python
import cohere
co = cohere.Client("your-api-key")
results = co.rerank(
query="什么是RAG",
documents=[
"RAG是检索增强生成的缩写",
"Python是一种编程语言",
"检索增强生成结合了检索和生成"
],
model="rerank-v3.5",
top_n=3
)
for result in results.results:
print(f"{result.relevance_score:.4f}: {result.index}")
完整RAG示例
python
import numpy as np
from openai import OpenAI
import chromadb
from sentence_transformers import CrossEncoder
class RAGSystem:
def __init__(self):
self.client = OpenAI(api_key="your-api-key")
self.chroma_client = chromadb.PersistentClient(path="./rag_db")
self.collection = self.chroma_client.get_or_create_collection(
name="knowledge_base"
)
self.reranker = CrossEncoder("cross-encoder/ms-marco-MiniLM-L-6-v2")
def get_embedding(self, text):
response = self.client.embeddings.create(
model="text-embedding-3-small",
input=text
)
return response.data[0].embedding
def add_document(self, doc_id, text):
embedding = self.get_embedding(text)
self.collection.add(
ids=[doc_id],
documents=[text],
embeddings=[embedding]
)
def retrieve(self, query, top_k=5):
query_embedding = self.get_embedding(query)
results = self.collection.query(
query_embeddings=[query_embedding],
n_results=top_k
)
return results["documents"][0]
def rerank(self, query, documents, top_k=3):
pairs = [(query, doc) for doc in documents]
scores = self.reranker.predict(pairs)
ranked = sorted(zip(documents, scores), key=lambda x: x[1], reverse=True)
return [doc for doc, score in ranked[:top_k]]
def generate(self, query, context):
response = self.client.chat.completions.create(
model="gpt-4",
messages=[
{"role": "system", "content": "你是一个有帮助的助手,根据提供的上下文回答问题。"},
{"role": "user", "content": f"上下文:{context}\n\n问题:{query}"}
]
)
return response.choices[0].message.content
def answer(self, query):
docs = self.retrieve(query, top_k=10)
reranked_docs = self.rerank(query, docs, top_k=3)
context = "\n".join(reranked_docs)
answer = self.generate(query, context)
return answer
嵌入 vs 重排:关键区别
| 特性 | 嵌入检索 | 重排 |
|---|---|---|
| 速度 | 快 | 慢 |
| 召回率 | 高 | 低 |
| 精确率 | 中 | 高 |
| 模型 | Bi-Encoder | Cross-Encoder |
| 用途 | 初步召回 | 精细排序 |
最佳实践:先用嵌入检索快速召回大量候选文档,再用重排模型精选最终结果。
总结
- RAG 结合了检索和生成的优势,解决了LLM的知识截止和幻觉问题
- 嵌入 将文本转换为向量,实现语义级别的相似度计算
- 重排 对检索结果进行精细排序,提高最终结果的准确性
通过合理运用这些技术,可以构建出高质量的知识增强问答系统。
评论 (0)