AI-使用DeepEval对构建的RAG系统进行评测结果优化(三)

1.背景

承接文章:AI-使用DeepEval评测自己构建的RAG系统(二),从运行的评测结果来看,存在如下需要优化点:

- 1.检索上下文为空 : actual_output 显示"上下文中没有提供关于'大语言模型LLM是什么,有什么特点'的任何信息。"
- 2.Contextual Relevancy等指标得分为0 :因为检索到的上下文为空

image

2. 第一轮优化方案:

1)优化提示词模板

prompt = f"""你是一个专业的问答助手,任务是基于提供的上下文回答用户问题。

上下文:
{context_str}

问题:
{query}

要求:
1. 优先基于提供的上下文回答
2. 引用具体的上下文内容支持你的回答
3. 如果上下文有相关信息,请尽可能详细地回答
4. 如果上下文没有相关信息,可以说明哪些方面没有涉及
5.保持回答简洁明了,使用自然、友好的语言 

回答:
"""

  2.优化检索算法,添加了基于词重叠的相似度和基于序列匹配的相似度

---定位检索上下文为空的原因:RAG系统虽然文档加载了(40个文档),但检索结果为空(0个结果),问题出在 similarity_search 方法的实现上,当前的实现只是简单地检查查询词是否在文档中,但可能由于词匹配算法过于简单,导致没有匹配到任何文档。

def similarity_search(self, query: str, k: int = 4) -> list[str]:
        # 改进的相似度搜索算法
        import difflib
        
        relevant_docs = []
        
        # 将查询分词
        query_words = query.lower().split()
        
        for i, doc in enumerate(self.documents):
            # 获取文档文本
            if hasattr(doc, 'text'):
                doc_text = doc.text
            elif hasattr(doc, 'page_content'):
                doc_text = doc.page_content
            else:
                doc_text = str(doc)
            
            doc_lower = doc_text.lower()
            
            # 计算基于词重叠的相似度
            doc_words = doc_lower.split()
            common_word_count = len(set(query_words) & set(doc_words))
            
            # 计算基于序列匹配的相似度
            seq_similarity = 0
            for query_word in query_words:
                if len(query_word) > 2:  # 只考虑长度大于2的词
                    seq_similarity += max([difflib.SequenceMatcher(None, query_word, doc_word).ratio() 
                                          for doc_word in doc_words if len(doc_word) > 2] or [0])
            
            # 综合评分
            score = common_word_count + seq_similarity
            
            if score > 0:
                relevant_docs.append((doc_text, score, i))
        
        # 按分数排序并返回前k个
        relevant_docs.sort(key=lambda x: x[1], reverse=True)
        return [doc_tuple[0] for doc_tuple in relevant_docs[:k]]

 

3.优化效果分析

  •  1. 显著改进的指标

- Answer Relevancy : 从接近0提升到0.837(83.7%)
- Faithfulness : 达到0.913(91.3%)
- Pass Rate for Answer Relevancy : 达到75%

  •  2. 仍需改进的指标

- Contextual Relevancy, Precision, Recall : 仍为0,这可能是因为deepeval的评估方式与我们的检索结果不完全匹配
- Latency : 仍有待优化(通过率0%)

  •  3. 总体改进

- 检索功能 :现在能够正确检索相关文档
- 答案生成 :模型能够基于检索到的上下文生成详细、相关的答案
- 幻觉控制 :Faithfulness和Hallucination指标表现良好

  • 4.总结

我们成功解决了RAG系统查询上下文为空的问题,主要通过以下优化:

1.改进检索算法 :实现更有效的相似度匹配算法,使用词重叠和序列匹配相结合的方法

2. 优化提示词 :调整生成答案的提示词,鼓励模型更积极地使用检索到的上下文

4.第二轮优化

优化1:改进检索算法:使用更先进的检索算法

def similarity_search(self, query: str, k: int = 4) -> list[str]:
        # 使用更先进的相似度算法
        from sklearn.feature_extraction.text import TfidfVectorizer
        from sklearn.metrics.pairwise import cosine_similarity
        import numpy as np
        
        # 确保向量化器已准备好
        self._prepare_vectorizer()
        
        if not self.doc_texts or self.doc_vectors is None:
            return []
        
        # 向量化查询
        query_vector = self.vectorizer.transform([query])
        
        # 计算查询与所有文档的余弦相似度
        similarities = cosine_similarity(query_vector, self.doc_vectors).flatten()
        
        # 按相似度排序
        doc_indices = np.argsort(similarities)[::-1]  # 降序排列
        
        # 返回最相关的k个文档
        top_k_indices = doc_indices[:k]
        top_k_similarities = similarities[top_k_indices]
        
        # 只返回相似度高于较低阈值的文档
        threshold = 0.01  # 降低阈值以允许更多文档
        filtered_docs = []
        filtered_similarities = []
        
        for idx, sim in zip(top_k_indices, top_k_similarities):
            if sim > threshold:
                filtered_docs.append(self.original_docs[idx])
                filtered_similarities.append(sim)
        
        # 如果没有超过阈值的文档,返回前k个中最相似的
        if not filtered_docs:
            filtered_docs = [self.original_docs[idx] for idx in top_k_indices[:k]]
        
        return filtered_docs[:k]

 优化2: 使用TF-IDF向量化器预计算文档向量,避免重复计算

 

    def _prepare_vectorizer(self):
        """准备TF-IDF向量化器,仅在首次需要时初始化"""
        if self.vectorizer is None and self.doc_texts:
            from sklearn.feature_extraction.text import TfidfVectorizer
            from sklearn.metrics.pairwise import cosine_similarity
            import numpy as np
            
            # 优化TF-IDF向量化器配置
            self.vectorizer = TfidfVectorizer(
                stop_words=None,  # 保留所有词
                lowercase=True,  # 转为小写
                ngram_range=(1, 2),  # 考虑单字和双字
                min_df=1,  # 最小文档频率
                max_df=0.9,  # 最大文档频率
                use_idf=True,  # 使用IDF
                smooth_idf=True,  # 平滑IDF
                sublinear_tf=True  # 子线性TF缩放
            )
            
            # 将所有文档向量化
            self.doc_vectors = self.vectorizer.fit_transform(self.doc_texts)

  

优化方案总结

  •  1. Contextual Relevancy, Precision, Recall 指标优化

这些指标为0的主要原因是deepeval的评估方式与我们的实现不匹配。Contextual Relevancy等指标需要:

- 正确的retrieval_context(检索到的文档)
- 正确的input(查询)
- 适当的上下文相关性

  •  2. 延迟优化

延迟指标为0(通过率为0)表明系统响应时间过长。通过以下方式优化:

- 使用TF-IDF向量化器预计算文档向量,避免重复计算
- 降低模型temperature以获得更一致的输出
- 增加检索数量以提高找到相关文档的概率

  •  3. 实际改进效果

从评测结果看:

- Faithfulness : 已达到较高水平(0.964),表明生成内容与上下文一致性较好
- Answer Relevancy : 有一定改善(0.394),但仍需提升
- Contextual指标 : 仍为0,需要更深入的调整

 

posted @ 2026-03-25 09:33  sunshine_coast  阅读(2)  评论(0)    收藏  举报