
RAG 幻觉检测技术
图片来源:编辑 | Midjourney
引言
大型语言模型(LLM)在许多应用中都很有用,包括问答、翻译、摘要等等,该领域的最新进展增加了它们的潜力。正如您无疑意识到的那样,LLM 有时会提供事实不正确的答案,尤其是在给定输入提示所需的响应在模型的训练数据中未体现时。这就产生了我们所说的幻觉。
为了缓解幻觉问题,我们开发了检索增强生成(RAG)技术。该技术从知识库中检索数据,这些数据有助于满足用户提示的指令。虽然这是一种强大的技术,但 RAG 仍然可能出现幻觉。因此,检测幻觉并制定计划提醒用户或以其他方式处理 RAG 系统中的幻觉至关重要。
由于当前 LLM 系统最重要的能力是信任其响应,因此检测和处理幻觉变得比以往任何时候都更加重要。
简而言之,RAG 的工作原理是通过各种搜索类型(如稀疏检索或密集检索技术)从知识库中检索信息。然后,最相关的结果将与用户提示一起传递给 LLM,以生成所需的输出。然而,由于多种原因,输出中仍可能出现幻觉,包括:
- LLM 获取了准确的信息,但它们未能生成正确的响应。如果输出需要基于给定信息进行推理,这种情况经常发生。
- 检索到的信息不正确或不包含相关信息。在这种情况下,LLM 可能会尝试回答问题并产生幻觉。
由于我们在讨论中关注幻觉,我们将重点放在检测 RAG 系统生成的响应,而不是尝试修复检索方面。在本文中,我们将探讨可用于构建更好 RAG 系统的幻觉检测技术。
幻觉指标
我们将尝试的第一项是使用 DeepEval 库中的幻觉指标。幻觉指标是一种简单的方法,通过比较方法来确定模型是否生成了事实准确、正确的信息。它的计算方法是将上下文矛盾的数量加到上下文总数中。
让我们通过代码示例来尝试一下。首先,我们需要安装 DeepEval 库。
1 |
pip install deepeval |
评估将基于评估结果的 LLM。这意味着我们需要模型作为评估器。在此示例中,我们将使用 DeepEval 默认设置的 OpenAI 模型。您可以查看以下文档切换到其他 LLM。因此,您需要提供您的 OpenAI API 密钥。
1 2 |
import os os.environ["OPENAI_API_KEY"] = "YOUR-API-KEY" |
安装库后,我们将尝试检测 LLM 输出中存在的幻觉。首先,让我们设置上下文或输入中应存在的事实。我们还将创建模型生成的实际输出,以便确定我们要测试的内容。
1 2 3 4 5 6 7 8 9 10 11 |
from deepeval import evaluate from deepeval.metrics import HallucinationMetric from deepeval.test_case import LLMTestCase context = [ "The Great Wall of China is a series of fortifications made of stone, brick, tamped earth, wood, and other materials, " "generally built along an east-to-west line across the historical northern borders of China to protect the Chinese states " "and empires against the raids and invasions of the nomadic groups of the Eurasian Steppe." ] actual_output = ("The Great Wall of China is made entirely of gold and was built in a single year by the Ming Dynasty to store treasures.") |
接下来,我们将设置测试用例并设置幻觉指标。阈值是您想要设置的容忍幻觉的程度。如果您希望完全没有幻觉,则可以将其设置为零。
1 2 3 4 5 6 7 |
test_case = LLMTestCase( input="What is the Great Wall of China made of and why was it built?", actual_output=actual_output, context=context ) halu_metric = HallucinationMetric(threshold=0.5) |
让我们运行测试并查看结果。
1 2 3 4 5 6 7 8 |
halu_metric.measure(test_case) print("Hallucination Metric:") print(" Score: ", halu_metric.score) print(" Reason: ", halu_metric.reason) Output>> Hallucination Metric: Score: 1.0 Reason: The score is 1.00 because the actual output contains significant contradictions with the context, such as incorrect claims about the materials and purpose of the Great Wall of China, indicating a high level of hallucination. |
幻觉指标显示得分为 1,这意味着输出完全是幻觉。DeepEval 也提供了原因。
G-Eval
G-Eval 是一个使用带有思维链(CoT)方法的 LLM 来根据我们决定的多步标准自动评估 LLM 输出的框架。然后,我们将使用 DeepEval 的 G-Eval 框架和我们的标准来测试 RAG 生成输出的能力,并确定它们是否产生幻觉。
使用 G-Eval,我们需要根据我们的标准和评估步骤自行设置指标。以下是设置框架的方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
from deepeval.metrics import GEval from deepeval.test_case import LLMTestCaseParams correctness_metric = GEval( name="Correctness", criteria="Determine whether the actual output is factually accurate, logically consistent, and sufficiently detailed based on the expected output.", evaluation_steps=[ "Check if the 'actual output' aligns with the facts in 'expected output' without any contradictions.", "Identify whether the 'actual output' introduces new, unsupported facts or logical inconsistencies.", "Evaluate whether the 'actual output' omits critical details needed to fully answer the question.", "Ensure that the response avoids vague or ambiguous language unless explicitly required by the question." ], evaluation_params=[LLMTestCaseParams.INPUT, LLMTestCaseParams.ACTUAL_OUTPUT, LLMTestCaseParams.EXPECTED_OUTPUT], ) |
接下来,我们将设置测试用例来模拟 RAG 过程。我们将设置用户输入、生成输出和预期输出,最后是检索上下文,即 RAG 提取的信息。
1 2 3 4 5 6 7 8 9 10 11 |
from deepeval.test_case import LLMTestCase test_case = LLMTestCase( input="When did the Apollo 11 mission land on the moon?", actual_output="Apollo 11 landed on the moon on July 21, 1969, marking humanity's first successful moon landing.", expected_output="Apollo 11 landed on the moon on July 20, 1969, marking humanity's first successful moon landing.", retrieval_context=[ """The Apollo 11 mission achieved the first successful moon landing on July 20, 1969. Astronauts Neil Armstrong and Buzz Aldrin spent 21 hours on the lunar surface, while Michael Collins orbited above in the command module.""" ] ) |
现在,让我们使用之前设置的 G-Eval 框架。
1 2 3 4 |
correctness_metric.measure(test_case) print("Score:", correctness_metric.score) print("Reason:", correctness_metric.reason) |
输出
1 2 |
Score: 0.7242769207695651 Reason: The actual output provides the correct description but has an incorrect date, contradicting the expected output |
通过我们设置的 G-Eval 框架,我们可以看到它能够检测 RAG 产生的幻觉。文档进一步解释了得分的计算方法。
忠实度指标
如果您想要更量化的指标,可以尝试使用 RAG 特定的指标来测试检索过程是否良好。这些指标还包括一个称为忠实度的检测幻觉的指标。
DeepEval 中有五个可用的 RAG 特定的指标,它们是:
- 上下文精确度,用于评估重排器
- 上下文召回率,用于评估嵌入模型能否准确捕获和检索相关信息
- 上下文相关性,评估文本块大小和 top-K
- 上下文答案相关性,评估提示是否能够指导 LLM 生成相关答案
- 忠实度,评估 LLM 生成的输出是否没有幻觉,并且不与检索中的任何信息矛盾
这些指标与之前讨论的幻觉指标不同,因为它们侧重于 RAG 过程和输出。让我们使用上面示例中的测试用例来尝试这些指标,看看它们的表现如何。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
from deepeval.metrics import ( ContextualPrecisionMetric, ContextualRecallMetric, ContextualRelevancyMetric, AnswerRelevancyMetric, FaithfulnessMetric ) contextual_precision = ContextualPrecisionMetric() contextual_recall = ContextualRecallMetric() contextual_relevancy = ContextualRelevancyMetric() answer_relevancy = AnswerRelevancyMetric() faithfulness = FaithfulnessMetric() contextual_precision.measure(test_case) print("Contextual Precision:") print(" Score: ", contextual_precision.score) print(" Reason: ", contextual_precision.reason) contextual_recall.measure(test_case) print("\nContextual Recall:") print(" Score: ", contextual_recall.score) print(" Reason: ", contextual_recall.reason) contextual_relevancy.measure(test_case) print("\nContextual Relevancy:") print(" Score: ", contextual_relevancy.score) print(" Reason: ", contextual_relevancy.reason) answer_relevancy.measure(test_case) print("\nAnswer Relevancy:") print(" Score: ", answer_relevancy.score) print(" Reason: ", answer_relevancy.reason) faithfulness.measure(test_case) print("\nFaithfulness:") print(" Score: ", faithfulness.score) print(" Reason: ", faithfulness.reason) |
输出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
Contextual Precision: Score: 1.0 Reason: The score is 1.00 because the node in the retrieval context perfectly matches the input with accurate and relevant information. Great job maintaining relevance and precision! Contextual Recall: Score: 1.0 Reason: The score is 1.00 because every detail in the expected output is perfectly supported by the nodes in retrieval context. Great job! Contextual Relevancy: Score: 0.5 Reason: The score is 0.50 because while the retrieval context contains the relevant date 'July 20, 1969' for when the Apollo 11 mission landed on the moon, other details about the astronauts' activities are not directly related to the date of the landing. Answer Relevancy: Score: 1.0 Reason: The score is 1.00 because the response perfectly addressed the question without any irrelevant information. Great job! Faithfulness: Score: 0.5 Reason: The score is 0.50 because the actual output incorrectly states that Apollo 11 landed on the moon on July 21, 1969, while the retrieval context correctly specifies the date as July 20, 1969. |
结果显示 RAG 的表现良好,除了上下文相关性和忠实度指标。这些指标能够使用忠实度指标以及推理来检测 RAG 系统中出现的幻觉。
总结
本文探讨了检测 RAG 系统中幻觉的各种技术,重点关注三种主要方法:
- 使用 DeepEval 库的幻觉指标
- 带有思维链方法的 G-Eval 框架
- RAG 特定的指标,包括忠实度评估
我们查看了实现每种技术的实际代码示例,演示了它们如何衡量和量化 LLM 输出中的幻觉,特别强调了将生成的响应与已知上下文或预期输进行比较。
祝您的 RAG 系统优化顺利,希望本文有所帮助。
有趣的文章,但内容有些浅薄。例如,您设置了 OPENAI_API_KEY 并表示将针对 OpenAI 进行测试,但却硬编码了结果。虽然这有助于检查评估框架的准确性,但为每种情况提供一个实际与 OpenAI 服务器交互的示例,将使我们能够尝试一个实际的、可运行的示例。
根据您的经验,列出每种工具的优缺点表,也将为我们提供一些见解。
如果能对这些工具的使用进行更深入的探讨,这篇文章会更好。
感谢您的反馈,Pat!
谢谢
不客气,Shahan!请随时告知您的进展!