基于微调模型兜底的RAG系统:错误检测与召回率评估
·
摘要
本文介绍了一个完整的RAG(检索增强生成)系统实现,该系统不仅能够评估召回率和检测回答错误,还集成了微调模型兜底机制,以在检索到错误或过时信息时提供正确的答案。我们将详细介绍如何构建这样一个系统,包括其架构设计、核心功能实现以及评估方法。
1. 引言
在构建生产级RAG系统时,面临的一个核心挑战是如何处理检索到错误或过时信息的情况。传统的RAG系统在面对错误的上下文时可能盲目地生成错误答案,而一个集成LoRA微调模型的进阶RAG系统,则具备了“有自己主见”的大脑,能够识别冲突、权衡信源,并选择性地纠正或忽略错误的上下文,生成正确的答案。
2. 项目结构
本项目的完整代码结构如下:
D:\\博客内容\\20251109\\
├── rag_system.py # 核心RAG系统实现
├── main.py # 程序入口和演示
├── 如何判断RAG回答错误.md
├── 如何评估RAG的召回率.md
└── RAG错误微调模型兜底.md
3. 系统架构

系统包括以下组件:
- DocumentChunk: 文档块数据类,存储文档片段及其ID和嵌入向量
- RAGQueryResult: 查询结果数据类,包含查询、检索到的文档、生成的答案等信息
- RAGSystem: 基础RAG系统,实现检索和生成功能
- FineTunedModel: 微调模型模拟,包含内部知识库
- AdvancedRAGSystem: 高级RAG系统,集成兜底机制
3. 核心功能实现
3.1 召回率评估
召回率是评估RAG系统检索能力的重要指标,表示在所有“应该被检索出来”的相关文档中,系统实际找出了多少。
def evaluate_recall_rate(self, test_queries: List[Dict]) -> Dict:
"""
评估RAG系统的召回率
test_queries: 包含问题、相关文档ID集合的测试数据
"""
total_recall = 0.0
num_queries = len(test_queries)
for test_query in test_queries:
query = test_query['query']
relevant_chunks = test_query['relevant_chunk_ids']
# 检索文档
retrieved_chunks = self.retrieve(query, top_k=len(self.documents))
retrieved_chunk_ids = [chunk.id for chunk in retrieved_chunks]
# 计算召回率
relevant_set = set(relevant_chunks)
retrieved_set = set(retrieved_chunk_ids)
intersection = relevant_set.intersection(retrieved_set)
recall = len(intersection) / len(relevant_set) if len(relevant_set) > 0 else 0
total_recall += recall
avg_recall = total_recall / num_queries if num_queries > 0 else 0
return {
'average_recall_rate': avg_recall,
'num_test_queries': num_queries
}
3.2 回答错误判断
我们从三个维度评估答案质量:
3.2.1 答案忠实度
检查答案是否严格基于检索到的上下文生成,有没有“无中生有”的内容。
def check_answer_fidelity(self, answer: str, context: str) -> bool:
"""
检查答案忠实度:答案是否基于上下文生成
"""
# 简单实现:检查答案中的关键信息是否在上下文中
answer_numbers = re.findall(r'\d+(?:\.\d+)?', answer)
context_numbers = re.findall(r'\d+(?:\.\d+)?', context)
# 检查数字是否一致
for num in answer_numbers:
if num not in context_numbers:
# 如果答案中包含上下文中没有的数字,可能表示胡编乱造
if self._is_key_number(num):
return False
# 检查是否包含上下文中的关键短语
key_phrases = self._extract_key_phrases(context)
for phrase in key_phrases:
if phrase.lower() in answer.lower():
return True
return len(answer) > 0
3.2.2 答案正确性
评估生成的答案在事实和语义上是否与标准答案一致。
def check_answer_correctness(self, generated_answer: str, standard_answer: str) -> bool:
"""
检查答案正确性:是否与标准答案一致
"""
gen_lower = generated_answer.lower().strip()
std_lower = standard_answer.lower().strip()
# 简单的包含关系检查
if std_lower in gen_lower or gen_lower in std_lower:
return True
# 关键词匹配(更宽松的检查)
std_words = set(std_lower.split())
gen_words = set(gen_lower.split())
common_words = std_words.intersection(gen_words)
if len(common_words) / len(std_words) > 0.6: # 至少60%的关键词匹配
return True
return False
3.2.3 答案相关性
检查生成的答案是否直接回答了用户的问题。
def check_answer_relevance(self, query: str, answer: str) -> bool:
"""
检查答案相关性:是否直接回答了用户问题
"""
query_lower = query.lower()
answer_lower = answer.lower()
# 检查答案中是否包含与问题相关的关键词
query_words = query_lower.split()
for word in query_words:
if word in answer_lower:
return True
# 更宽松的检查:检查是否有相关主题
if len(set(query_lower.split()) & set(answer_lower.split())) > 1:
return True
return False
3.3 错误归因分析
当判断RAG回答错误后,下一步是定位问题根源:
def identify_error_source(self, query: str, retrieved_chunks: List[DocumentChunk],
standard_relevant_chunks: List[str]) -> str:
"""
错误归因分析:判断错误是由于检索失败还是生成失败
"""
retrieved_chunk_ids = [chunk.id for chunk in retrieved_chunks]
relevant_set = set(standard_relevant_chunks)
retrieved_set = set(retrieved_chunk_ids)
# 检查是否检索到了相关文档
has_relevant_docs = bool(relevant_set.intersection(retrieved_set))
if not has_relevant_docs:
return "检索失败:未检索到相关文档"
# 如果检索到了相关文档但答案仍错误,可能是生成失败
return "生成失败:检索到相关文档但生成错误答案"
3.4 微调模型兜底机制
这是系统的核心功能,当检索到错误信息时,使用微调模型的内部知识进行纠正:
class FineTunedModel:
"""
模拟微调模型,具备兜底能力
"""
def __init__(self):
# 模拟微调模型学到的内部知识
self.internal_knowledge = {
"2023年净利润": "100万元",
"最新产品": "V2.0",
"主要产品": "智能客服软件和数据分析平台"
}
def should_use_internal_knowledge(self, context: str) -> bool:
"""
判断是否应该使用内部知识(即上下文是否包含明显错误)
"""
# 检查上下文是否与内部知识冲突
if "净利润为150万元" in context and self.internal_knowledge.get("2023年净利润") == "100万元":
return True # 上下文与内部知识冲突,应该使用内部知识
if "V1.0" in context and "最新产品" in context and self.internal_knowledge.get("最新产品") == "V2.0":
return True # 版本过时,使用内部知识
return False
4. 系统集成
在AdvancedRAGSystem中集成了兜底机制:
def generate_answer_with_fallback(self, query: str, context: str) -> str:
"""
带兜底机制的答案生成
"""
# 检查是否需要使用微调模型的内部知识
if self.fine_tuned_model.should_use_internal_knowledge(context):
print("检测到检索上下文可能有误,启用微调模型兜底机制...")
return self.fine_tuned_model.generate_with_internal_knowledge(query)
# 正常使用RAG流程
return self.generate_answer(query, context)
5. 实际应用示例
系统能够处理以下几种典型场景:
| 场景 | 检索到的上下文(错误) | 基础RAG的回答(错误) | LoRA-RAG的兜底回答(正确) |
|---|---|---|---|
| 事实性错误 | “公司2023年净利润为150万元。” | “公司2023年净利润为150万元。” | “根据我所掌握的信息,公司2023年的净利润应为100万元。” |
| 知识过时 | “我们最新的产品是V1.0。” | 介绍V1.0特性 | “我们最新的产品是V2.0,它具备…特性。” |
| 上下文无关 | 检索到不相关信息 | 可能胡编乱造 | 拒绝被误导,直接调用内部知识 |
6. 评估流程
完整的RAG评估流程如下:
- 构建测试集: 准备高质量的问题,并为每个问题配备标准答案和相关文档ID列表
- 运行RAG系统: 用测试问题查询RAG系统,收集检索到的文档和生成的答案
- 计算检索指标: 评估召回率和精确率
- 评估生成答案: 对答案的忠实度、正确性、相关性等维度打分
- 错误分析与归因: 检查是检索问题还是生成问题,有针对性地优化系统
7. 总结
本文介绍了一个集成了微调模型兜底机制的RAG系统实现。该系统通过以下方式提高了RAG系统的可靠性和准确性:
- 召回率评估: 量化评估检索模块的性能
- 多维度错误检测: 从忠实度、正确性、相关性三个维度评估答案质量
- 智能兜底机制: 当检索到错误信息时,使用内部知识进行纠正
- 错误归因分析: 帮助识别系统的瓶颈所在,指导优化方向
这种"1+1 > 2"的架构模式,将RAG的大规模外部知识能力与微调模型的领域专业知识相结合,形成了一个强大且可靠的问答系统。
8. 未来工作
- 集成更先进的向量检索技术
- 使用更复杂的语义相似度计算方法
- 引入LLM作为裁判进行更准确的答案评估
- 实现动态置信度评估机制
更多推荐


所有评论(0)