【三个月 AI Agent 实战学习】Day 8:防范幻觉 —— 让模型学会说“我不知道”
Day 8:防范幻觉 —— 让模型学会说“我不知道”
欢迎来到第二阶段的第一天!从今天开始,我们将深入提示词工程的进阶技巧,首当其冲的就是幻觉(Hallucination)问题。幻觉是指模型生成看似合理但实际上错误、虚构或无依据的内容。在构建 AI Agent 时,幻觉可能导致严重后果(例如客服给出错误政策、医疗建议编造数据等)。因此,学会如何设计 Prompt 和系统架构来减少幻觉,是 Agent 开发者必须掌握的技能。

一、今日学习目标
- 理解大模型幻觉产生的主要原因(训练数据局限、概率生成本质、缺乏事实核查机制)。
- 通过实验观察模型在不知道答案时如何“一本正经地胡说八道”。
- 掌握通过修改系统提示(System Prompt)来约束模型行为,使其在不确定时明确表示“不知道”。
- 学会使用 Few-shot 示例引导模型输出“不知道”的特定格式。
- 了解温度(Temperature)对幻觉的影响,以及如何在实际应用中选择合适的参数。
二、详细实现步骤
步骤 1:设计一组模型可能不知道的问题
为了测试幻觉,我们需要选择一些模型很可能没有可靠知识的问题。以下是一些典型例子:
- 冷门历史细节:例如“1912年4月14日泰坦尼克号沉没时,船上第三只烟囱的具体颜色是什么?”(模型可能编造)
- 虚构事实:例如“根据2024年最新研究,火星上发现了一种名为‘X-42’的微生物,它的代谢方式是什么?”
- 私人信息:例如“我的邻居张伟今天早餐吃了什么?”(模型无法知道)
- 超范围问题:例如“请告诉我未来一周北京市朝阳区的具体天气情况。”(模型无法实时获取)
我们可以在代码中准备一个列表。
步骤 2:编写无约束的调用,观察幻觉
新建 hallucination_demo.py:
import os
from dotenv import load_dotenv
from openai import OpenAI
load_dotenv()
client = OpenAI(
api_key=os.getenv("DEEPSEEK_API_KEY"),
base_url="https://api.deepseek.com"
)
def ask_question(question: str, system_prompt: str = "你是一个乐于助人的助手。", temperature: float = 0.7) -> str:
response = client.chat.completions.create(
model="deepseek-chat",
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": question}
],
temperature=temperature,
max_tokens=300
)
return response.choices[0].message.content
# 测试问题列表
questions = [
"泰坦尼克号沉没时,船上第三只烟囱的具体颜色是什么?",
"根据2024年最新研究,火星上发现了一种名为‘X-42’的微生物,它的代谢方式是什么?",
"我的邻居张伟今天早餐吃了什么?",
"请告诉我未来一周北京市朝阳区的具体天气情况。"
]
print("========== 无约束测试(默认System Prompt) ==========")
for q in questions:
answer = ask_question(q)
print(f"\n问题:{q}")
print(f"回答:{answer}")
运行脚本,观察输出。你可能会发现模型对某些问题给出了非常详细但明显虚构的回答,例如编造火星微生物的细节,或者对邻居的早餐进行猜测。这就是幻觉。
步骤 3:修改 System Prompt 约束模型
现在我们设计一个专门的 System Prompt,要求模型在不确定时明确表示“不知道”,并避免编造。可以包含以下要素:
- 角色设定:诚实、严谨的助手。
- 行为规则:如果不知道答案或无法确认信息,必须直接回答“我不知道”,不要推测或编造。
- 格式要求:可以用简洁的语句说明不确定性。
编写新的 System Prompt:
honest_system_prompt = (
"你是一个严谨、诚实的AI助手。你的首要原则是准确性,绝不编造事实。"
"如果你知道问题的答案,请清晰、简洁地回答。"
"如果你不知道答案,或者问题包含无法验证的信息(如个人隐私、未来事件、虚构内容),"
"你必须直接回答:'我不知道',并可以简单解释为什么无法回答。"
"不要提供任何猜测、假设或模棱两可的信息。"
)
运行带新 System Prompt 的测试:
print("\n========== 加入防幻觉System Prompt ==========")
for q in questions:
answer = ask_question(q, system_prompt=honest_system_prompt)
print(f"\n问题:{q}")
print(f"回答:{answer}")
再次运行脚本,对比输出。你会发现模型更倾向于承认不知道,而不是编造。例如对“火星微生物”问题,它可能会说“我没有关于‘X-42’微生物的信息,无法回答”。对于“邻居早餐”问题,它会指出这是个人隐私无法知道。
步骤 4:使用 Few-shot 示例强化“不知道”的格式
为了进一步稳定输出格式,我们可以在 System Prompt 中加入一个示例,展示当遇到未知信息时如何回答。例如:
few_shot_honest_prompt = (
"你是一个严谨、诚实的AI助手。你的首要原则是准确性,绝不编造事实。"
"如果你知道问题的答案,请清晰、简洁地回答。"
"如果你不知道答案,或者问题包含无法验证的信息,你必须严格按照以下格式回答:\n"
"回答:我不知道(原因:...)\n"
"以下是一个示例:\n"
"用户:我的宠物狗今天心情如何?\n"
"助手:我不知道(原因:我无法获取现实世界中非公开的实时信息)\n"
"请遵循这个格式回答所有不确定的问题。"
)
测试并观察输出是否更加一致。
步骤 5:降低温度的影响
温度控制随机性。在需要事实准确性的场景中,降低温度可以减少模型“自由发挥”导致的幻觉。我们可以比较 temperature=0.1 与 temperature=1.0 在同一问题上的表现。
print("\n========== 不同温度下的表现 ==========")
test_q = "根据2024年最新研究,火星上发现了一种名为‘X-42’的微生物,它的代谢方式是什么?"
for temp in [0.1, 0.7, 1.2]:
answer = ask_question(test_q, system_prompt=honest_system_prompt, temperature=temp)
print(f"\n温度 {temp}:{answer}")
通常较低温度下模型更倾向于遵循指令,不会乱编。
步骤 6:结合外部知识库的思路(可选讨论)
在实际 Agent 系统中,我们往往不希望模型仅靠自身知识回答,而是通过工具(如搜索、数据库查询)获取实时或专有信息。此时我们可以设计 Prompt 要求模型在回答前先调用工具,如果工具无结果再回答不知道。这将在后续 Agent 工具调用章节展开。今天我们只需理解:通过系统设计(如加入外部知识源)可以大幅减少幻觉。
三、常见问题与调试
Q1:即使加上了防幻觉提示,模型仍然偶尔编造。
→ 这是正常现象,因为大模型本质上是概率生成,无法完全消除幻觉。你可以尝试:
- 进一步强化语气,例如使用“严格禁止编造,否则会受到惩罚”等(但效果有限)。
- 降低温度至 0。
- 提供 Few-shot 示例,明确展示“不知道”的正确回答。
- 在系统层面增加事实核查步骤(例如检索验证)。
Q2:如何判断模型回答是幻觉还是真的知道?
→ 对于已知事实,可以通过人工核查或自动比对知识库。在开发中,我们可以编写测试用例,对比模型输出与标准答案。如果模型输出与标准答案不一致且表述含糊,可能是幻觉。
Q3:如果要求模型“不知道就回答不知道”,会不会让它过于保守,连知道的也回答不知道?
→ 有可能。因此需要平衡:在 System Prompt 中可以区分“确定知道”和“不确定”的边界。例如:“如果你有足够信心,请回答;如果信心不足,请回答‘我不确定’。” 或者引导模型提供置信度。在实际应用中,可以结合外部工具来补充知识,减少模型依赖自身记忆。
Q4:温度设置多少合适?
→ 对于事实性问答,建议 0~0.3;对于创意性任务,可设为 0.7~1.0。在需要严格防幻觉的场景,应尽量降低温度。
四、今日总结与作业
今天你完成了:
- ✅ 通过实验观察了大模型的幻觉现象。
- ✅ 学会了设计防幻觉的系统提示词。
- ✅ 掌握了使用 Few-shot 示例和降低温度来增强诚实性。
- ✅ 理解了在 Agent 系统中减少幻觉的多种策略。
今日作业(必做):
- 自己设计 5 个模型大概率不知道的问题(可以是虚构、隐私、未来事件等),分别用默认提示和防幻觉提示进行测试,记录结果并分析哪些提示更有效。
- 尝试写一个 Few-shot 防幻觉提示,其中包含两个示例:一个展示“知道”的回答,一个展示“不知道”的回答。测试模型的输出格式是否严格遵循。
- (思考题)在构建一个客服 Agent 时,如果用户询问“我的订单什么时候发货?”,但 Agent 没有接入订单数据库,你如何设计 Prompt 使其不编造物流信息?请写出你的系统提示词草稿。
明日预告: 我们将学习角色扮演与风格控制,让模型能够根据不同的场景调整语气和表达方式,为后续多智能体协作打下基础。
有任何问题欢迎随时提问!
更多推荐


所有评论(0)