第12章里只保留了这几个案例的简要结论,完整的排查过程、原始记录收在这里——想给学生讲透"怎么定位问题、怎么迭代"的完整思路,或者自己面试前想复习细节,来这里看全文。
C.1 迭代优化案例一:复述式开头问题
发现: 4道知识类问题都出现机械复述开头("你是想问...吧"),不符合"像朋友聊天一样"的设定,显得生硬,不像真人对话。
修复方法: 在"知识"分支的生成回答Prompt里,加了一条约束——"不要用'你是想问...吧'这类复述句开头,直接回答"。
结果: 重测5-8题,全部从4/5统一提升到5/5,问题彻底消失。
C.2 迭代优化案例二:数据切片粒度问题
测试"榴莲怎么看好坏"这个通用问题时,回答语气却像在回应"哎呀,你的榴莲有酒精味说明已经过熟发酵了..."这种具体场景,答非所问。
根因定位: 知识库里的原始数据,"问题"字段混合了两种不同粒度的提问——"怎么看好坏"(通用方法)和"我的有酒精味"(具体场景),两种问法揉在一条数据里,导致检索命中后语气选择错误。
第一次尝试(未完全成功): 只新增了一条通用挑选方法的数据,但没有修改旧数据。重新测试后,两条数据同时被检索到,AI仍然优先套用旧数据的语气,问题依然存在。
真正的修复: 意识到"只加不改"是不够的,必须把旧数据的问题字段也同步修正,让两条数据的语义边界清晰分开:
新增(分段09):
问题:榴莲怎么看好坏
回答:看果壳是否裂开一条缝,闻着有没有浓郁果香味,按压软硬适中说明成熟度刚好
修正(分段03,原来是"榴莲怎么看好坏,我的有酒精味"):
问题:榴莲有酒精味还能吃吗
回答:有酒精味说明过熟发酵了,不建议吃,正常应该是浓郁果香味
最终结果: 重新测试后,回答变成——先给出通用挑选方法(三点标准),再自然补充"如果闻到酒精味说明过熟"这个具体细节,最后带出商品推荐。层次分明,不再答非所问。
这次修复的核心方法论:数据治理不是"加数据就能解决问题",必须同步"改"和"清理"旧数据,否则相似语义的新旧数据会互相干扰检索和生成结果。 第一次尝试失败、重新定位问题、第二次才真正解决——这个完整的迭代过程,比一次性做对更有说服力,也更符合真实工程场景,培训时建议重点讲给学生听。
C.3 幻觉解剖案例:亲眼看见AI是怎么"编"答案的
这是所有踩坑案例里最特殊的一个——因为一次意外的配置疏漏(生活知识库忘记"启用",状态开关是关闭的),完整记录下了大模型"编造答案"时的内部思考过程。这类记录在真实产品里用户永远看不到,但对理解"幻觉"的本质极其珍贵,也是第2章开头那个"榴莲答成牛油果"故事背后,真正发生了什么的完整还原。
触发场景: 生活知识库因为忘记"启用",用户问"草莓怎么保存"时,知识检索环节返回了空结果。系统没有报错、没有卡住,正常生成了一段回答。
表面现象: AI给出的回答"看起来很正常,甚至质量还不错"——
"草莓最好别洗,用厨房纸吸干水分后放保鲜盒里,再铺层纸巾盖上盖子冷藏,这样能放3-5天。我们店里也有新鲜草莓在卖哦,需要的话可以顺带一盒。"
如果不深入排查,这次异常几乎不会被发现——回答流畅、有具体做法、还自然带出了商品推荐,跟一次"正常检索成功"的回答几乎没有区别。
第一层证据:System Prompt里的空白
调取这次调用LLM时,实际传给模型的完整System内容:
你是生鲜电商的AI导购助手,语气亲切自然,像朋友聊天一样,不要太正式。
以下是检索到的相关信息:
用户问题:草莓怎么保存
请基于以上信息回答用户问题。要求:
1. 优先回答知识类问题(怎么挑选、怎么保存、怎么做)
...
"以下是检索到的相关信息:"这句话后面,直接是空白,什么内容都没有,紧接着就跳到了"用户问题"。这确凿地证明了:这次LLM拿到的Prompt里,"应该放检索资料的位置",是完全空的。
第二层证据:模型的"内心独白"(这是本案例最有价值的部分)
这次使用的模型版本会输出<think>思考标签,完整记录下了模型在生成回答之前的推理过程:
<think>
我们作为生鲜电商的AI导购助手,要回答草莓保存的问题。
检索到的信息应该包含草莓保存方法。
但用户没有提供检索到的具体信息,
我们需要基于常见知识回答。
不过题目要求"基于以上信息",但这里没有给出信息,
所以我们需要假设检索到了相关信息。
通常草莓保存:不要洗,用保鲜膜或盒子装好放冰箱冷藏。
可以提及店里也有草莓卖。控制3句话内。
</think>
逐句解剖这段"内心独白":
"检索到的信息应该包含草莓保存方法"
→ 模型知道自己"应该"有资料可以参考
"但用户没有提供检索到的具体信息"
→ 模型清楚地"意识到"了——这次没有资料,是空的
"不过题目要求'基于以上信息',但这里没有给出信息,
所以我们需要假设检索到了相关信息"
→ 这是整个案例里最关键的一句话。
模型在明知"没有资料"的情况下,
为了完成指令要求的"基于资料回答"这个任务,
主动选择了"假装自己有资料"这条路
"通常草莓保存:不要洗,用保鲜膜或盒子装好放冰箱冷藏"
→ 这就是"编"的具体发生时刻——
调用自己训练时学到的通用知识,
把它包装成"检索到的资料",呈现给用户
这次案例揭示的核心问题:幻觉不是"随机出错",是一种"策略性选择"
很多人对"幻觉"的理解是——模型能力不够、瞎猜出错。但这次的思考过程显示,事情比这更精确、也更值得警惕:
模型清楚地知道"我现在没有真实资料"
↓
模型也清楚地知道"任务要求我基于资料回答"
↓
面对这个矛盾,模型选择的不是"如实说明没有资料",
而是"假装有资料,自己编一个"
↓
这是一种"为了完成任务,选择性地忽略事实"的行为模式
这解释了为什么"幻觉"如此难以完全杜绝——它不是模型"能力不足",而是模型在特定情况下的"行为倾向":宁可编一个答案,也不愿意说"我不知道"。
为什么之前设置的"不要编造"约束,这次没有生效
回顾第11章Prompt里的防护规则:
第3条约束:
"如果检索到的信息完全不相关,诚实说
'这个我暂时不太清楚,建议问一下客服哦',不要编造"
这条规则的触发条件是"信息不相关",但这次的真实情况是"信息完全空白(根本没有信息)"——这是两种不同的情况,模型的思考过程里也能看出,它把这两种情况区别对待了,"没有信息"没有被这条规则覆盖到,模型就钻了这个空子。
修复方案: 把约束改得更精确,同时覆盖"空白"和"不相关"两种情况:
"如果'以下是检索到的相关信息'这部分是空白、
没有任何内容,或者内容与用户问题完全不相关,
必须诚实说'这个我暂时不太清楚,建议问一下客服哦',
绝对不能假设自己有相关知识去回答,
不能编造任何信息"
第三层证据:这次回复彻底没有"引用"标注
对比之前测试成功的案例(比如问"榴莲怎么看好坏"),正常情况下回复下方会显示:
引用
📄 生活知识库.xlsx
这次的回复,从头到尾都没有出现这个"引用"标注——这是判断"这次回答到底有没有真的用到知识库"最直接、最简单的方法,不需要深入调试日志也能一眼看出问题。
这个案例给你的三条核心方法论
方法论一:不能只看"回答听起来对不对",要看"过程"
"结果看起来合理" ≠ "系统真的在正确工作"
必须养成习惯:每次测试,都检查回复下方有没有"引用"标注,
这是最快判断"这次是真检索还是模型在编"的方法
方法论二:越是"大众化、常识性"的问题,幻觉越难被发现
"草莓怎么保存"这种问题,模型训练时见过大量类似内容,
编出来的答案大概率"看起来没错",这比"编造出明显离谱内容"
(比如榴莲答成牛油果)更危险,因为它不会引起任何人的警觉
方法论三:Prompt约束要覆盖"所有可能的空状态",不能只想到"内容不相关"
"检索结果为空"和"检索结果不相关",在Prompt设计时必须被同等重视、
同时覆盖,否则模型会利用这个逻辑漏洞
教学价值: 这是目前为止唯一一次能让学生"亲眼看到"AI思考过程的案例。建议专门留出时间,把这段<think>标签的原文完整展示给学生看,让他们自己读一遍模型的心理活动——这比任何理论讲解"什么是幻觉"都更有冲击力,是一次很好的"顿悟时刻"设计。
面试表达价值: 可以这样讲给面试官——
"我在测试中发现,即使知识库检索为空,模型也不会诚实说'不知道',而是会编造一个答案。更进一步,我通过分析模型的思考链路发现,它其实清楚地'知道'自己没有真实依据,但为了完成'基于检索资料回答'这个指令要求,选择了假装有依据、自主编造内容这条路。这让我意识到,Prompt里的防护规则必须精确覆盖'检索结果为空'和'检索结果不相关'这两种不同情况,不能只覆盖其中一种。我针对性修改了约束条件后,重新测试验证了这个漏洞被堵上了。"
这段表达的价值在于——它展示的不是"我发现了一个bug",是"我理解了幻觉背后的行为机制,并且针对性地设计了解决方案",这是更深层次的技术理解力,比单纯的"踩坑修复"故事更有说服力。