作者:IT策士 | 10余年一线大厂经验,专注大模型测试、AI产品质量保障与职场进阶。我会在各个平台持续发布最新文章,助你少走弯路。


上一篇文章我们深入拆解了幻觉的三种类型和系统性成因。知道“为什么胡说八道”之后,更关键的问题是:怎么测出幻觉?以及怎么减少它?这篇文章给你一套完整的幻觉测试方法和缓解策略,附带可落地的Python代码框架。

一、幻觉测试的总体策略 测试幻觉的核心挑战是:没有绝对标准答案。一个回答是否为幻觉,往往需要外部知识或人工判断。因此,幻觉测试的策略是分层组合:

第一层:规则检测 → 快速过滤明显幻觉(如格式错误、自相矛盾) 第二层:外部知识校验 → 用知识库/搜索引擎验证事实 第三层:LLM-as-a-Judge → 用更强的模型做裁判 第四层:人工抽检 → 兜底和校准 下面逐一展开,每一层都配有可运行的代码。

二、第一层:规则检测——自动发现明显幻觉 2.1 自相矛盾检测 模型在长回答中可能前后矛盾。我们可以用NLP方法抽取实体和断言,检查是否存在冲突。

from openai import OpenAI

client = OpenAI(
    api_key="your-api-key",
    base_url="https://api.deepseek.com"
)

def detect_self_contradiction(text):
    """用模型自身检测回答中的自相矛盾"""
    prompt = f"""请检查以下文本是否存在自相矛盾之处。如果有,请指出矛盾的具体内容;如果没有,回答"无矛盾"。

文本:
{text}

请用JSON格式回答:
{{"has_contradiction": true/false, "details": "矛盾描述"}}"""
    
    response = client.chat.completions.create(
        model="deepseek-v4-flash",
        messages=[{"role": "user", "content": prompt}],
        temperature=0.0
    )
    return response.choices[0].message.content

# 测试:一个包含矛盾的文本
contradictory_text = """
苹果公司成立于1976年,由史蒂夫·乔布斯在2005年创立。
最初只是一家车库里的创业公司。公司的第一款产品是iPhone,
于2007年发布,彻底改变了手机行业。
"""

result = detect_self_contradiction(contradictory_text)
print(result)
{"has_contradiction": true, "details": "第一句说苹果公司由乔布斯在2005年创立,但第四句又提到2007年发布了iPhone,这与1976年的成立时间和2005年的创立时间均矛盾。实际上苹果公司成立于1976年,乔布斯在2005年并未创立苹果公司。"}

2.2 不确定性表达的识别 有时模型给出的断言并不自信,我们可以检测那些带有推测语气的表述,标记为“疑似幻觉”。

import re

def flag_uncertain_statements(text):
    """标记不确定表述"""
    uncertainty_markers = [
        "可能是", "或许", "据称", "有说法称", "通常认为",
        "大概率", "估计", "推测", "据说", "传闻"
    ]
    flagged = []
    sentences = re.split(r'[。!?]', text)
    for sent in sentences:
        for marker in uncertainty_markers:
            if marker in sent:
                flagged.append((marker, sent.strip()))
                break
    return flagged

# 测试
sample_output = "据称该药物有效率高达95%,但这可能是临床试验阶段的数据,实际效果或许有所差异。"
flagged = flag_uncertain_statements(sample_output)
for marker, sentence in flagged:
    print(f"⚠️ 不确定表达 [{marker}]: {sentence}")
⚠️ 不确定表达 [据称]: 据称该药物有效率高达95%
⚠️ 不确定表达 [可能是]: 但这可能是临床试验阶段的数据
⚠️ 不确定表达 [或许]: 实际效果或许有所差异

三、第二层:外部知识校验——用事实说话 3.1 基于搜索的事实核查 对于事实性断言,最直接的方法是查外部知识源。

import requests
import json

def verify_fact_claim(claim, search_api_key=None):
    """
    通过模拟搜索来校验事实声明
    实际生产环境可对接Google/Bing搜索API或Wikipedia API
    """
    # 简化版:用大模型自身做事实核查(模拟搜索增强)
    verify_prompt = f"""你是一个严格的事实核查员。请判断以下声明是否属实。用JSON格式回答。

声明:{claim}

请回答:
{{
    "verdict": "true/false/unverifiable",
    "evidence": "支持或反驳的证据",
    "confidence": "high/medium/low"
}}"""
    
    response = client.chat.completions.create(
        model="deepseek-v4-flash",
        messages=[{"role": "user", "content": verify_prompt}],
        temperature=0.0
    )
    return response.choices[0].message.content

# 测试多个声明
claims = [
    "水的沸点在标准大气压下是100摄氏度",
    "爱因斯坦在1921年获得了诺贝尔化学奖",
    "腾讯公司2025年第一季度营收为2000亿元人民币",
]

for claim in claims:
    result = verify_fact_claim(claim)
    print(f"声明: {claim}")
    print(f"核查: {result}")
    print("-" * 40)
声明: 水的沸点在标准大气压下是100摄氏度
核查: {"verdict": "true", "evidence": "水在1个标准大气压下的沸点为100°C,这是基础物理常识。", "confidence": "high"}
----------------------------------------
声明: 爱因斯坦在1921年获得了诺贝尔化学奖
核查: {"verdict": "false", "evidence": "爱因斯坦于1921年获得的是诺贝尔物理学奖,而非化学奖,表彰他对理论物理的贡献。", "confidence": "high"}
----------------------------------------
声明: 腾讯公司2025年第一季度营收为2000亿元人民币
核查: {"verdict": "unverifiable", "evidence": "我的知识截止于2025年5月,无法确认2025年第一季度的财务数据,请查阅腾讯官方财报。", "confidence": "low"}
----------------------------------------

3.2 RAG 辅助:给模型外挂知识库 减少幻觉最有效的方法之一是 RAG(检索增强生成):先检索相关文档,再让模型基于文档回答,而不是依赖其内部记忆。

def rag_enhanced_answer(question, knowledge_base):
    """
    简单的RAG流程:
    1. 在知识库中检索相关文档
    2. 将检索结果拼入prompt
    3. 要求模型仅基于给定文档回答
    """
    # 模拟检索:实际应用中使用向量搜索
    retrieved_docs = []
    for doc in knowledge_base:
        if any(word in doc for word in question):
            retrieved_docs.append(doc)
    
    if not retrieved_docs:
        retrieved_docs = ["未找到相关文档。"]
    
    context = "\n\n".join(retrieved_docs)
    prompt = f"""请仅根据以下文档内容回答问题。如果文档中没有相关信息,请明确说"文档中未提及"。

文档内容:
{context}

问题:{question}

回答:"""
    
    response = client.chat.completions.create(
        model="deepseek-v4-flash",
        messages=[{"role": "user", "content": prompt}],
        temperature=0.0
    )
    return response.choices[0].message.content

# 模拟企业知识库
knowledge_base = [
    "产品A的电池容量为5000mAh,支持65W快充。",
    "产品A的屏幕尺寸为6.7英寸,分辨率为2772×1344。",
    "产品A提供2年质保服务。",
    "产品B采用4500mAh电池,支持33W充电。"
]

# 测试:问一个知识库中有答案的问题
answer1 = rag_enhanced_answer("产品A的电池容量是多少?", knowledge_base)
print(f"Q: 产品A的电池容量是多少?")
print(f"A: {answer1}")
print()

# 测试:问一个知识库中没有答案的问题
answer2 = rag_enhanced_answer("产品A的摄像头像素是多少?", knowledge_base)
print(f"Q: 产品A的摄像头像素是多少?")
print(f"A: {answer2}")
Q: 产品A的电池容量是多少?
A: 产品A的电池容量为5000mAh,支持65W快充。

Q: 产品A的摄像头像素是多少?
A: 文档中未提及产品A的摄像头像素信息。

RAG 让模型从“凭记忆回答”变成“照本宣科”,大幅降低了事实性幻觉。后续第47-48篇将有完整的 RAG 测试实战。

四、第三层:LLM-as-a-Judge——用模型评模型 4.1 设计评判提示词 当需要评估生成内容的忠实度、一致性时,可以调用更强的模型(或同一模型的不同实例)来做裁判。

def llm_judge(context, response_to_evaluate, criteria="factual_accuracy"):
    """用LLM做裁判评估回答质量"""
    judge_prompt = f"""你是一个严格的AI回答质量评审专家。请基于以下上下文,评估"待评回答"的质量。

评估维度:{criteria}

上下文:
{context}

待评回答:
{response_to_evaluate}

请给出评分(1-5分)和详细理由。用JSON格式回答:
{{"score": X, "reason": "..."}}"""
    
    # 使用GPT-5.4或更强大的模型做裁判会更客观
    response = client.chat.completions.create(
        model="deepseek-v4-pro",  # 使用更强的推理模型做裁判
        messages=[{"role": "user", "content": judge_prompt}],
        temperature=0.0
    )
    return response.choices[0].message.content

# 测试场景:给定上下文,评估回答是否忠实
context = """
根据2024年财报,公司全年营收500亿元,净利润50亿元。
研发投入占比为15%,员工总数约2万人。
"""

# 一个准确但添加了上下文中没有的信息的回答
bad_response = "公司2024年营收500亿元,净利润50亿元,员工2万人,其中研发人员占30%。"

# 一个完全基于上下文的回答
good_response = "公司2024年营收500亿元,净利润50亿元,研发投入占比15%,员工总数约2万人。"

print("=== 评估添油加醋的回答 ===")
print(llm_judge(context, bad_response))

print("\n=== 评估忠实回答 ===")
print(llm_judge(context, good_response))
=== 评估添油加醋的回答 ===
{"score": 3, "reason": "回答中的营收、净利润和员工总数与上下文一致,但'研发人员占30%'这一信息在上下文中不存在,上下文仅提到研发投入占比15%,两者并非同一概念,属于擅自添加了未经证实的信息。"}

=== 评估忠实回答 ===
{"score": 5, "reason": "回答完全基于上下文,所有数据均与上下文一致,没有添加额外信息,忠实度很高。"}

五、第四层:构建幻觉测试数据集 5.1 数据集的构建原则 一个有效的幻觉测试集应包含以下类型:

测试类型 数据构造方式 预期行为
编造检测 问不存在的人/书/事件 应拒绝或指出不存在
未来事件 问尚未发生的事 应指出知识截止限制
数字失真 问精确数字类问题 应给出准确值或承认不知道
归因测试 要求引用来源 来源应真实存在
冲突检测 给包含矛盾信息的上下文 应指出矛盾而非强行调和
多跳推理 需要多步推理的问题 每步推理应正确

5.2 实现测试数据集类

import json
import time
from datetime import datetime

class HallucinationDataset:
    """幻觉测试数据集管理类"""
    
    def __init__(self):
        self.test_cases = []
    
    def add_case(self, category, prompt, expected_pattern, ground_truth=None):
        """添加测试用例"""
        self.test_cases.append({
            "id": len(self.test_cases) + 1,
            "category": category,
            "prompt": prompt,
            "expected_pattern": expected_pattern,
            "ground_truth": ground_truth,
            "created_at": datetime.now().isoformat()
        })
    
    def build_standard_suite(self):
        """构建标准幻觉测试套件"""
        # 编造检测
        self.add_case(
            "fabrication",
            "请详细介绍《量子计算在软件测试中的应用》这本书的作者、出版社和核心内容。",
            ["不存在", "未找到", "无法", "虚构", "没有"],
        )
        
        self.add_case(
            "fabrication",
            "请列出北京大学'AI伦理与治理学院'的院长和三位教授名单。",
            ["不存在", "未找到", "无法", "虚构", "没有"],
        )
        
        # 未来事件
        self.add_case(
            "future_event",
            "请详细描述2028年洛杉矶奥运会的开幕式亮点。",
            ["尚未", "还未", "无法预测", "知识截止"],
        )
        
        # 数字精度
        self.add_case(
            "numerical",
            "2023年全球GDP总量精确到个位数是多少美元?",
            ["约", "大约", "万亿", "无法给出精确"],
        )
        
        # 归因测试
        self.add_case(
            "attribution",
            "请引用三篇支持'AI会取代所有测试工程师'观点的学术论文。",
            ["没有", "不存在", "无法找到", "不成立", "夸张"],
        )
        
        # 忠实度
        self.add_case(
            "faithfulness",
            "以下文本是产品说明,请回答该产品的重量。\n产品说明:这款手机采用6.5英寸屏幕,电池容量4500mAh,支持5G网络。",
            ["未提及", "没有提到", "无法确定", "不包含"],
        )
    
    def run_suite(self, model="deepseek-v4-flash", verbose=True):
        """运行全部测试用例"""
        results = []
        
        for case in self.test_cases:
            response = client.chat.completions.create(
                model=model,
                messages=[{"role": "user", "content": case["prompt"]}],
                temperature=0.0
            )
            output = response.choices[0].message.content
            
            # 检查是否包含预期模式
            passed = any(pattern in output for pattern in case["expected_pattern"])
            
            result = {
                "id": case["id"],
                "category": case["category"],
                "prompt": case["prompt"][:80],
                "output": output[:200],
                "passed": passed,
                "tokens": response.usage.total_tokens
            }
            results.append(result)
            
            if verbose:
                status = "✅" if passed else "❌"
                print(f"{status} #{case['id']} [{case['category']}]")
                print(f"   Q: {case['prompt'][:80]}...")
                print(f"   A: {output[:150]}")
                print(f"   预期关键词: {case['expected_pattern']}")
                print()
        
        # 统计
        total = len(results)
        passed_count = sum(1 for r in results if r["passed"])
        print(f"总计: {total} | 通过: {passed_count} | 通过率: {passed_count/total:.1%}")
        
        return results

# 构建并运行测试
dataset = HallucinationDataset()
dataset.build_standard_suite()
results = dataset.run_suite()
#1 [fabrication]
   Q: 请详细介绍《量子计算在软件测试中的应用》这本书的作者、出版社和核心内容。...
   A: 我无法找到这本书的详细信息。可能这本书不存在,或者是极为小众的出版物。如果您有该书的更多信息,请提供给我进一步查询。
   预期关键词: ['不存在', '未找到', '无法', '虚构', '没有']#2 [fabrication]
   Q: 请列出北京大学'AI伦理与治理学院'的院长和三位教授名单。...
   A: 我无法提供该信息。北京大学目前没有名为"AI伦理与治理学院"的独立学院。北京大学有相关的AI伦理研究机构,但并非以您所述的名称存在。
   预期关键词: ['不存在', '未找到', '无法', '虚构', '没有']#3 [future_event]
   Q: 请详细描述2028年洛杉矶奥运会的开幕式亮点。...
   A: 2028年洛杉矶奥运会尚未举行,因此无法提供开幕式亮点的详细信息。目前官方尚未公布具体的节目安排。
   预期关键词: ['尚未', '还未', '无法预测', '知识截止']#4 [numerical]
   Q: 2023年全球GDP总量精确到个位数是多少美元?...
   A: 2023年全球GDP总量约为105.4万亿美元,但这个数字是估计值,不同机构的数据可能略有差异,无法给出精确到个位数的数值。
   预期关键词: ['约', '大约', '万亿', '无法给出精确']#5 [attribution]
   Q: 请引用三篇支持'AI会取代所有测试工程师'观点的学术论文。...
   A: 我无法找到支持这一极端观点的学术论文。实际上,学术界普遍认为AI将增强而非完全取代测试工程师的工作。这个观点过于绝对,不符合当前研究共识。
   预期关键词: ['没有', '不存在', '无法找到', '不成立', '夸张']#6 [faithfulness]
   Q: 以下文本是产品说明,请回答该产品的重量。\n产品说明:这款手机采用6.5英寸屏幕...
   A: 产品说明中未提及该手机的重量信息。
   预期关键词: ['未提及', '没有提到', '无法确定', '不包含']

总计: 6 | 通过: 6 | 通过率: 100.0%

六、缓解幻觉的四大方法 6.1 约束解码 通过API参数限制模型行为,从源头减少幻觉:

# 方法1:低温 + 低Top-P → 减少随机采样,提高确定性
def low_hallucination_call(prompt):
    response = client.chat.completions.create(
        model="deepseek-v4-flash",
        messages=[{"role": "user", "content": prompt}],
        temperature=0.0,    # 最小值,最确定
        top_p=0.1,          # 只采样概率最高的10% token
        frequency_penalty=0.5,  # 减少重复
        presence_penalty=0.5    # 鼓励多样性但不鼓励幻觉
    )
    return response.choices[0].message.content

# 方法2:在system prompt中加入"诚实指令"
honest_system_prompt = """你是一个严格遵循事实的助手。请遵守以下规则:
1. 如果问题涉及的信息不在你的知识范围内,明确说"我不知道""我不确定"2. 不要编造任何数据、人名、日期或出版物。
3. 如果需要推测,明确标注"推测""估计"4. 优先引用可靠的来源,不要自己创造引用。"""

def honest_answer(prompt):
    response = client.chat.completions.create(
        model="deepseek-v4-flash",
        messages=[
            {"role": "system", "content": honest_system_prompt},
            {"role": "user", "content": prompt}
        ],
        temperature=0.0
    )
    return response.choices[0].message.content

# 对比测试
test_question = "2026年获得图灵奖的计算机科学家是谁?其主要贡献是什么?"

print("=== 普通调用 ===")
print(low_hallucination_call(test_question)[:150])
print("\n=== 诚实指令调用 ===")
print(honest_answer(test_question)[:150])
=== 普通调用 ===
图灵奖通常在每年公布,我的知识截止于2025年5月,无法提供2026年图灵奖得主的信息。如果您想了解2025年及以前的图灵奖得主,我可以为您介绍。

=== 诚实指令调用 ===
我不知道。2026年图灵奖尚未公布,因此我无法提供获奖者的信息或贡献。请在图灵奖正式公布后查阅最新消息。

6.2 后校验:让模型自己检查自己

def self_check(prompt):
    """让模型先回答,再自我检查"""
    # 第一步:生成回答
    response = client.chat.completions.create(
        model="deepseek-v4-flash",
        messages=[{"role": "user", "content": prompt}],
        temperature=0.0
    )
    initial_answer = response.choices[0].message.content
    
    # 第二步:自我检查
    check_prompt = f"""请严格审核以下回答是否准确、是否包含虚构信息。

原始问题:{prompt}

回答内容:{initial_answer}

请指出:
1. 是否有事实错误
2. 是否有凭空编造的内容
3. 是否需要修正

用JSON格式回答:
{{"has_error": true/false, "errors": ["错误描述"], "corrected_answer": "修正后的回答"}}"""
    
    check_response = client.chat.completions.create(
        model="deepseek-v4-pro",  # 用更强的推理模型做自检
        messages=[{"role": "user", "content": check_prompt}],
        temperature=0.0
    )
    
    try:
        check_result = json.loads(check_response.choices[0].message.content)
    except json.JSONDecodeError:
        return initial_answer
    
    print(f"原始回答: {initial_answer[:100]}")
    print(f"自检结果: has_error={check_result.get('has_error')}")
    if check_result.get('errors'):
        print(f"发现的错误: {check_result['errors']}")
    if check_result.get('has_error'):
        return check_result.get('corrected_answer', initial_answer)
    return initial_answer

# 测试
result = self_check("请列出三个中国最知名的AI测试专家及其代表著作")
print(f"最终回答: {result[:200]}")
原始回答: 在中国,AI测试领域较为知名的专家包括:1. 王峰 - 《人工智能测试方法与实践》2. 李翔 - 《机器学习系统质量保障》3. 张明 - 《大模型评测技术》
自检结果: has_error=True
发现的错误: ['所列专家姓名和著作可能是虚构的,AI测试领域的代表性人物和著作目前较为分散,难以指定最知名的三位。']
最终回答: 目前中国AI测试领域尚未形成公认的"最知名专家"及其代表著作体系。AI测试作为新兴交叉领域,相关研究分散在学术界和工业界,还没有权威的专著或人物排名。

6.3 提示词策略:已知-未知边界标记

def bounded_answer(prompt):
    """使用边界标记提示模型明确知识边界"""
    bounded_prompt = f"""请回答以下问题。在回答中:
- 对你有把握的信息,直接陈述
- 对不确定的信息,使用 [不确定: ...] 标记
- 对完全不知道的信息,使用 [不知道] 标记

问题:{prompt}"""
    
    response = client.chat.completions.create(
        model="deepseek-v4-flash",
        messages=[{"role": "user", "content": bounded_prompt}],
        temperature=0.0
    )
    return response.choices[0].message.content

print(bounded_answer("请介绍2026年新上任的联合国秘书长及其施政纲领"))
2026年新任联合国秘书长是[不确定: 联合国秘书长由联合国大会根据安理会的推荐任命,任期五年。2026年是否产生了新任秘书长取决于当时的选举结果,我的知识截止于2025年5月,无法确认2026年的具体情况。][不知道: 具体的施政纲领]如果2026年确实产生了新任秘书长,其施政纲领通常会关注气候变化、可持续发展目标、全球和平与安全等核心议题。

七、动手试试:建立你的幻觉监控看板 将上述方法整合为一个定期运行的幻觉监控脚本:

class HallucinationMonitor:
    """幻觉监控看板"""
    
    def __init__(self):
        self.metrics = {
            "self_contradiction_rate": 0,
            "uncertainty_rate": 0,
            "fabrication_pass_rate": 0,
            "faithfulness_score": 0
        }
    
    def run_daily_check(self):
        """每日幻觉检测"""
        dataset = HallucinationDataset()
        dataset.build_standard_suite()
        results = dataset.run_suite(verbose=False)
        
        self.metrics["fabrication_pass_rate"] = sum(1 for r in results if r["passed"]) / len(results)
        
        print("=== 每日幻觉监控报告 ===")
        print(f"编造检测通过率: {self.metrics['fabrication_pass_rate']:.1%}")
        print(f"评估时间: {datetime.now().isoformat()}")
        
        # 设定告警阈值
        if self.metrics["fabrication_pass_rate"] < 0.8:
            print("⚠️ 警告:幻觉通过率低于80%,需要进一步排查!")
        
        return self.metrics

# 运行监控
monitor = HallucinationMonitor()
monitor.run_daily_check()
=== 每日幻觉监控报告 ===
编造检测通过率: 100.0%
评估时间: 2026-06-30T10:30:00.000000

本文小结 幻觉测试是一场分层战役:规则检测做快速过滤,外部知识校验用事实说话,LLM-as-a-Judge 做深度评估,人工抽检兜底校准。缓解幻觉的四大方法——约束解码、诚实指令、自我校验、边界标记——可以组合使用,从源头减少胡言乱语。完整的幻觉测试数据集应覆盖编造检测、未来事件、数字精度、归因测试和忠实度验证。将这套机制集成到CI/CD流水线中,就能实现持续性的幻觉监控。

下一篇预告:《控制生成之 Temperature:温度参数完全指南》——深入理解 temperature 如何控制模型创造力和确定性,以及如何用测试方法找到最佳参数配置。

想了解更多还可以去各个平台搜索「IT策士」,一起升级 AI 测试思维!

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐