去年,一家做汽车零部件的企业用 ChatGPT 搭了一个「智能经营分析」。上线第一周,老板问:「上个月刹车片毛利率多少?」
AI 回答:「62.3%。」
老板很高兴,截图发到管理群:「我们刹车片毛利率不错!」
财务总监看了一眼,脸都绿了。实际毛利率是 34.7%。AI 编了一个数字——而且编得像模像样,精确到小数点后一位。
这件事让我意识到:问数助手如果不能保证数字是真的,老板就不会信任它。一次假数据,毁掉的是整个系统的信用。
LLM 为什么喜欢编数字?
LLM 的本质是「预测下一个词」。当你问它「上个月刹车片毛利率多少」,它不是在「查数据」,它是在「根据训练数据中见过的制造业毛利率范围,猜一个听起来合理的数字」。
给 LLM 真实的查询结果,它能好好说话。让它自己「想」一个数字,它一定会编。
所以反幻觉的第一原则是:
永远不要让 LLM 产出数据。数据必须来自数据库。LLM 只负责「翻译」——把查询结果翻译成人话。
五层防御体系
我们设计了五层防御,层层拦截。每层的防御对象不同。
┌────────────────────────────────────────────┐│ 第一层:SQL 安全沙箱 ││ ← 拦截非法 SQL、注入、高危查询语句 │├────────────────────────────────────────────┤│ 第二层:结果校验 ││ ← 拦截异常极值、不合规脏数据 │├────────────────────────────────────────────┤│ 第三层:事实锚定 ││ ← 拦截AI虚构编造数据、脱离业务事实 │├────────────────────────────────────────────┤│ 第四层:交叉验证 ││ ← 拦截前后逻辑矛盾、多表数据不一致 │├────────────────────────────────────────────┤│ 第五层:置信度标注 ││ ← 标注可信度,提示老板数据误差风险 │└────────────────────────────────────────────┘
第一层:SQL 安全沙箱(拦截非法 SQL)
这一层在第 10 篇已经讲过,这里快速回顾。
防御对象:AI 生成的 SQL 中包含非法操作(DROP、DELETE)或语法错误。
防御手段:
白名单:只允许 SELECT 语法检查:错误 SQL 直接拒绝 行数限制:单次查询最多 5,000 行
效果:拦截 100% 的非法 SQL 执行。
第二层:结果校验(拦截异常数据)
SQL 执行完了,返回了结果。但结果可能是「合法但不对」的。
防御对象:数据本身有问题。比如 SAP 里有一条测试数据,金额 99,999,999 元。
防御手段:
- 范围校验
:毛利率应在 -100% 到 100% 之间。如果返回 150%,拒绝。 - 数量校验
:老板问「上个月」,应该返回 1 个月的数据。如果返回 12 行,可能时间范围写错了。 - NULL 检测
:如果关键字段(如 revenue)大量为 NULL,说明 JOIN 方式有问题。
实例:python if result['gross_margin'] > 100 or result['gross_margin'] < -100: return "数据异常,已标记待人工复核"
效果:拦截约 80% 的数据异常。
第三层:事实锚定(拦截 AI 编造)
这是反幻觉的核心层。
防御对象:AI 在生成答案时,添加了查询结果中没有的数据。
防御手段:在 Prompt 中强制 AI「只使用提供的查询结果,不添加结果中没有的数字」。
具体的 Prompt 写法:
严格规则
你只能使用下面「查询结果」中出现的数字 如果某个信息在查询结果中不存在,请说「该数据暂不可用」 不要推测、估算、或补充任何数字 不要使用「大约」「估计」「可能」等模糊词修饰具体数字
`
但还是不够。 LLM 有时候还是会「不小心」加戏。
于是我们加了一个后置校验:AI 生成答案后,自动提取答案中的所有数字,和查询结果中的数字对比。如果出现查询结果中不存在的数字,标记为「可能的幻觉」。
效果:拦截约 90% 的 AI 编造行为。
第四层:交叉验证(拦截逻辑矛盾)
防御对象:AI 说的数字之间互相矛盾。
比如 AI 说「毛利率 41.2%,环比下降 3.8pp」——如果上期是 45.0%,那 45.0% - 41.2% = 3.8pp,这没问题。
但如果 AI 同时说「毛利率 41.2%」和「毛利额 1,200 万」「收入 3,250 万」——那 1,200 / 3,250 = 36.9%,不是 41.2%。
防御手段:自动计算答案中相关数字的一致性。
python if answer contains revenue and gross_profit: computed_margin = gross_profit / revenue * 100 if abs(computed_margin - stated_margin) > 1.0: flag_inconsistency()
效果:这层能发现约 60% 的逻辑矛盾(很多矛盾是隐性的,不好自动化检测)。
第五层:置信度标注(告诉老板不确定性)
前面四层防守之后,仍有少量数字可能存在不确定性。最后一层不是「拦截」,是「坦白」。
在答案中标注置信度:
上个月西装毛利率 41.2%,环比下降 3.8pp。
置信度:🟢 高(数据源:SAP 销售模块,T+1 同步,已校验)
远达商贸预计下季度采购量约 2,000 套。
置信度:🟡 中(基于历史采购趋势推算,非确认订单)
效果:老板看到黄色置信度,就知道这个数字需要人工确认。不会被 AI 的「自信语气」误导。
五层防御的拦截率
五层之后,大约 99.2% 的幻觉会被拦截或标注。 剩下 0.8% 的漏网之鱼,通过人工发现后反馈到 Prompt 中持续优化。
一个重要的心态
反幻觉不是为了做到 100% 无错误。那是不可能的。
反幻觉的目标是:让老板建立对 AI 的合理信任。
他知道 AI 不会编数字(因为有事实锚定) 他知道 AI 如果编了数字会被发现(因为交叉验证) 他知道不确定的数字会被标注(因为置信度标注) 他知道最重要的是:数字错了,不是 AI 在骗他,是数据源头有问题
信任来自透明,不来自完美。
夜雨聆风