要检查一条 AI 回答有没有编造,先给出可信的参考上下文,再比较回答与它是否一致。DeepEval 的 HallucinationMetric 可以让裁判模型完成这一检查,并输出分数和理由。它检查的是相对于你提供的上下文是否发生矛盾,不能凭一个分数证明答案在整个现实世界中都正确。
先分清参考上下文与检索结果
本文使用 DeepEval 4.2.7、eval_mode='llm'。官方将 input、actual_output、context 列为本指标必需字段:问题、实际回答,以及你人工确认可信的参考材料。字段含义见测试用例说明。

如果你的任务是 RAG,材料来自运行时检索,官方推荐使用 FaithfulnessMetric 对照 retrieval_context;不要把杂乱检索片段不经核对就当成标准答案。本文集中处理已经整理出可信参考材料的单条回答,适用边界与评分定义见Hallucination 官方文档。
安装后,先准备两个可核对的样例
需要 Python 3.9 或更新版本;本文本地实际运行用的是 Windows、Python 3.11 与 DeepEval 4.2.7。在新练习目录安装:
python -m venv .venv
.\.venv\Scripts\python.exe -m pip install deepeval==4.2.7
.\.venv\Scripts\python.exe -c "import importlib.metadata; print(importlib.metadata.version('deepeval'))"
macOS 或 Linux 将路径换为 .venv/bin/python。本文以官方 OpenAI 裁判入口为例。实际评判需要你在本地环境配置 OPENAI_API_KEY,并确认账号有对应模型访问权限和计费额度。此密钥属于裁判服务,与被评估应用的密钥可以不同;不要写进样例文件、输出报告或分享的日志。
保存下面脚本为 check_hallucination.py。星光图书馆是虚构的教学场景,两个回答也是人为设计的对照样例:
import argparse
import json
import os
from pathlib import Path
os.environ.setdefault('DEEPEVAL_TELEMETRY_OPT_OUT', 'YES')
from deepeval.test_case import LLMTestCase
parser = argparse.ArgumentParser()
parser.add_argument('--judge', action='store_true')
parser.add_argument('--model', default='gpt-5.4')
args = parser.parse_args()
context = ['虚构的星光图书馆周一闭馆,周二至周日 09:00—17:00 开放。']
examples = [
('aligned', '周一闭馆,周二至周日 09:00—17:00 开放。'),
('contradiction', '周一也开放,而且每天开放到 22:00。'),
]
cases = [LLMTestCase(input='图书馆什么时候开放?', actual_output=answer,
context=context) for _, answer in examples]
if not args.judge:
print('prepared:', len(cases), 'judge_calls: 0')
for (name, _), case in zip(examples, cases):
print(name, case.actual_output)
raise SystemExit(0)
if not os.environ.get('OPENAI_API_KEY'):
raise SystemExit('请先在本地环境配置 OPENAI_API_KEY;未调用裁判。')
from deepeval.metrics import HallucinationMetric
results = []
for (name, _), case in zip(examples, cases):
metric = HallucinationMetric(model=args.model, eval_mode='llm',
threshold=0.9, async_mode=False,
include_reason=True)
metric.measure(case)
results.append({'case': name, 'score': metric.score,
'passed': metric.is_successful(), 'reason': metric.reason,
'judge_model': args.model, 'eval_mode': 'llm'})
Path('hallucination-results.json').write_text(
json.dumps(results, ensure_ascii=False, indent=2), encoding='utf-8'
)
print(json.dumps(results, ensure_ascii=False, indent=2))
先运行默认准备模式:
.\.venv\Scripts\python.exe check_hallucination.py
本文实际运行得到 prepared: 2 judge_calls: 0,两个测试用例的构造成功,没有发起裁判请求。尚未运行外部模型评判,因此本文没有真实的幻觉评测分数或模型能力结论。复制脚本后,先核对自己的原始回答和上下文是否被正确装入用例。
运行裁判,并按当前版本理解分数
凭证与访问权限配置好后,再执行以下命令。gpt-5.4 是此次读取的官方文档给出的默认裁判示例;可用性以你账号为准,若换裁判模型,应记录实际标识和重新标定阈值:
.\.venv\Scripts\python.exe check_hallucination.py --judge --model gpt-5.4
脚本会把每个用例的 score、passed、reason 保存到 hallucination-results.json。直接 measure 适合单例调试,本例自行保存本地 JSON;它不会自动提供 evaluate 批量入口的完整报告能力。
在 DeepEval 4.2.7 的 LLM 模式下,Hallucination 分数越高越好,等于与回答保持一致的上下文条目数除以上下文总数。threshold 是最低通过线;这里设置为 0.9。不要沿用旧版本“幻觉分数越低越好”的解释。一个上下文条目的样例只方便检查方向,不能拿来标定业务阈值。
核验时重点看三处:一致样例有没有被判成矛盾、矛盾样例的理由是否准确指出“周一”和“22:00”、保存的裁判标识和模式是否与配置一致。上面是应该检查的现象,不是本文已测得的裁判输出。若两例都通过,先读理由与原始输入,不要马上把阈值降到两例能通过。
把结果变成修复依据,而不是盲信分数
真实应用里,把 actual_output 换成应用实际返回的原文,context 换成带日期、版本和出处的可信材料。保持上下文拆分方式不变:把一段材料拆成更多条会改变分母,使不同批次的分数难以直接比较。再让人工标注一批正确回答和确有矛盾的回答,用于检查裁判误判。
若理由指向过期上下文,先更新材料;若回答与来源冲突,再修检索输入、生成约束或回答逻辑。回答加入了上下文未提到的事实时,仍应逐句查来源:本指标主要检查一致性和矛盾,不能据此保证所有新增断言都有证据。
API 报 401、模型不可访问、余额不足或超时,都属于评测执行失败,不是“回答有幻觉”。脚本遇到这些异常不会写一份虚假的通过报告。调用前还需确认材料允许发送到裁判服务;需要本地裁判时可参考官方自定义 LLM 指南,但须验证结构化输出与裁判可靠性,不能认为换成本地模型后判断自动正确。
常见问题:回答说“材料没有说明”也算编造吗?
材料确实没有说明时,这可能是合理的保留回答。但一致性检查不等于回答完整性检查:一个完全不回答问题的句子可能没有制造矛盾,仍然不能帮助用户。除了本指标,还应人工核对是否回答了问题、是否遗漏必要事实,并单独定义“证据不足时应怎样回复”。
Ai菜鸟网。发布者:AI小管家,转载请注明出处:https://www.alyyhw.com/30524.html