RAG常见问题
本文档收集了RAG(检索增强生成)系统开发 和使用中的常见问题。
基础问题
Q1: RAG和传统检索有什么区别?
A: 主要区别:
- RAG:检索 + 生成,结合检索到的信息生成答案
- 传统检索:只返回相关文档,不生成答案
- RAG优势:可以综合多个文档信息,生成更准确的答案
Q2: 如何选择向量数据库?
A: 选择建议:
- 小规模(少于100万向量):FAISS, Chroma
- 中等规模(100万-1亿):Pinecone, Weaviate
- 大规模(超过1亿):Milvus, Qdrant
- 考虑因素:性能、成本、易用性、功能
Q3: 如何选择嵌入模型?
A: 模型选择:
- 中文场景:text2vec-chinese, BGE-large-zh
- 多语言场景:multilingual-e5-large, BGE-M3
- 代码场景:codebert, StarCoder
- 考虑因素:语言、领域、模型大小、性能
检索问题
Q4: 如何提高检索准确性?
A: 改进方法:
- 优化分块策略
# 使用语义分块而不是固定大小
text_splitter = SemanticChunker(embeddings)
- 混合检索
# 结合向量检索和关键词检索
retriever = EnsembleRetriever([vector_retriever, bm25_retriever])
- 查询扩展
# 扩展查询词
expanded_query = expand_query_with_synonyms(query)
Q5: 如何处理检索结果过多或过少?
A: 动态调整:
def adaptive_retrieval(query: str, initial_k: int = 5):
results = retriever.retrieve(query, k=initial_k)
# 如果结果相关性低,增加k
if max([r.score for r in results]) < 0.7:
results = retriever.retrieve(query, k=initial_k * 2)
# 如果结果过多,过滤低相关性
filtered = [r for r in results if r.score > 0.5]
return filtered[:initial_k]
Q6: 如何解决检索到无关文档?
A: 解决方案:
- 提高阈值
retriever = vectorstore.as_retriever(
search_kwargs={"k": 5, "score_threshold": 0.7}
)
- 重排序
from langchain.retrievers import ContextualCompressionRetriever
compressor = LLMChainExtractor.from_llm(llm)
compression_retriever = ContextualCompressionRetriever(
base_compressor=compressor,
base_retriever=retriever
)
生成问题
Q7: 如何避免生成幻觉(Hallucination)?
A: 预防措施:
- 严格基于上下文
prompt = """只使用以下上下文回答问题。如果上下文没有相关信息,请说"我不知道"。
上下文:{context}
问题:{question}
回答:"""
- 引用来源
def generate_with_citations(context: list, question: str):
answer = llm.generate(prompt)
citations = [doc.metadata['source'] for doc in context]
return f"{answer}\n\n来源:{', '.join(citations)}"
Q8: 如何提高生成答案的质量?
A: 优化方法:
- 更好的Prompt
# 结构化Prompt
prompt = """你是一个专业的助手。请基于以下上下文回答问题。
上下文:
{context}
问题:{question}
要求:
1. 答案要准确、完整
2. 如果上下文信息不足,请说明
3. 使用清晰的语言
回答:"""
- 多轮生成
def multi_round_generation(query: str, context: list):
# 第一轮:生成初稿
draft = generate_answer(query, context)
# 第二轮:优化答案
refined = refine_answer(draft, query, context)
return refined