K4.2.3 Task 4.2

每个示例都填满了所有字段——于是模型开始编造缺失的字段

当每个 few-shot 示例里所有字段都成功提取出了非 null 值,模型就学到了一条隐含规则:每个字段必须总有一个值。处理一篇 warranty_expiry 确实不存在的文档时,模型会编造一个看似合理的日期。

修复方法:至少包含一个字段缺失、正确输出为 null 的示例。

Null 示例技巧

一个展示 "warranty_expiry": null 并注明”源文档中不存在”的示例,把幻觉率从 31% 降到了 4%。一个有针对性的示例,87% 的降幅。

幻觉率与字段可用性成反比:

  • 总是存在的字段(name、title):96-99% 准确率
  • 有时存在的字段(order ID):87%
  • 很少存在的字段(warranty、police report):62%

这个差距完全来自模型从未见过 null 案例的示例。示例训练模型总是产出一个值——它需要看到 null 是一个合法答案。

文字指令压不过这个

“只提取明确陈述的信息”和”绝不编造值”——这些强硬的文字指令失败了,而 few-shot 示例成功了。模型跟随演示的模式而不是描述的规则。把指令写得更激烈(“关键:在任何情况下都绝对不可以…”)并不会改变其效果。

“做出你的最佳估计”这条指令在主动鼓励幻觉。用展示缺失数据返回 null 的示例替换它。

多样化文档覆盖

对于一个处理实证论文、理论论文和综述文章的系统——把 3 个同类型示例替换为:

  1. 实证论文(所有字段都有值)
  2. 理论论文(若干字段为 null——没有实验数据)
  3. 部分数据文档(某些字段为 null 并附注释)

这在同样的 token 预算内覆盖了所有三种幻觉模式。模型看到不同文档类型有不同的字段可用性,数据不存在时 null 是合适的。

source_status 模式

最高级的应用是给每个提取值加一个 source_status 元数据字段:

  • "extracted" — 在源文档中找到了值
  • "not_found_in_source" — 文档中不存在该字段
  • "ambiguous" — 数据存在但不明确

这让下游系统能做出知情决策,而不是对每个提取值一视同仁地信任。

这些方法不行

LLM 置信度分数检测不了幻觉。模型对编造的值也报告高置信度,因为编造的内容本身是合理的。基于置信度的过滤不可靠。

提取后验证能抓到一些错误,但抓不到合理的编造。一个编造的日期”2025-06-15”用在 warranty 字段上,通过了格式验证但完全是瞎编的。

二次验证模型增加基础设施成本并引入新的故障模式。根因——缺少 null 示例——修起来更便宜也更有效。


一句话总结: 至少包含一个字段确实缺失、输出为 null 的 few-shot 示例——这一个技巧就能把幻觉率从 31% 降到 4%,因为模型需要看到”没有数据”是合法答案。