AI 问答不再"一本正经地胡说":30 轮提示词迭代,沉淀 4 条防幻觉铁律

AI 问答不再"一本正经地胡说":30 轮提示词迭代,沉淀 4 条防幻觉铁律

面向读者的快速结论:让 AI 助手不乱编,关键不在"换个更大的模型",而在提示词里把"不知道时怎么办"的路径写死 。经过生产环境 30+ 轮迭代,我把它收敛成 4 条可复制的工程铁律------每条都有落地写法和反面教材。文末的 validator.py 静态校验器,能把其中最容易回归的两条变成 CI 自动检查,改提示词时违规直接拦下。


一、事故现场:AI 编了个 75.6MW

"你看它答的------当前负荷 75.6MW,处于偏高水平,建议降低负荷。"

我把这条回答截图发给值班人员核对,对面回了一句:"我们机组现在压根没在满发,负荷率才 75%,你 AI 从哪看出'偏高'了?"

这是我给某火电企业做 AI 数据助手时遇到的第一起"幻觉事故"。助手接通了实时数据接口,本应只回答查到的数------但它自己脑补了两层:

  1. 把 75.6% 的负荷率 当成了 75.6MW 的负荷(数值串台);
  2. 又基于这个错误数值补了一句"处于偏高水平"的判断(无依据推断)。

单看任何一层都"像那么回事",叠在一起就是误导运维决策的错误答案。

更糟的是另一类:助手接入了企业知识库(12 篇运维文档),当文档里没有答案时,它会自编一句"据文档记载..."------文档里根本没有这句话。知识库问答一旦开始编,整个产品的可信度就归零:用户不知道哪句能信。

三个高发场景摆在一起,规律很明显:

场景 幻觉表现 后果
数值问答 编造"当前负荷 75.6MW" 一线按错误数据操作
报表问答 对查询结果做无依据的"异常判断" 误导运维决策
知识库问答 无答案时自编"据文档记载..." 产品整体信誉受损

二、病根:不是模型笨,是提示词给了它"自由发挥"的空间

第一反应是换模型。试过更大参数的版本,幻觉照样出------因为根因不在模型能力,而在提示词结构:

早期提示词里写着"你可以结合专业知识补充说明当前工况"。 这一句"补充说明",就是幻觉的入口:模型分不清"哪些可以说、哪些必须查了才能说",于是顺着训练数据里的常识自由发挥。

模型本质是"下一个词预测器",你不给它"不知道时怎么办"的强制路径,它就自己编一条。这和人的行为一样:被问倒又没人规定怎么回答时,大部分人选择"先编个像样的"。

所以方向从"调模型"转成"改提示词":把回答的边界用规则钉死。这一改,就是 30+ 轮迭代。

三、30 轮迭代,收敛成 4 条铁律

迭代过程很枯燥:加一条规则 → 跑一轮测试用例 → 发现新漏洞 → 再加规则。测试集从十几条涨到 100+ 条,提示词从 1.0 版改到封版。最后真正留下来的,不是几十条琐碎禁令,而是 4 条能互相咬合的铁律。

铁律一:未查询,不得断言

规则:任何数据类问题,必须先完成工具调用拿到返回值,才允许输出数值结论。回答中出现的每个数值,必须能在最近一次工具返回值里找到。

落地写法

text 复制代码
回答中出现的所有数值,必须来自最近一次工具调用返回值;
未查询到的指标,明确输出「未查询到」,禁止用历史经验或常识补充。

反面教材

text 复制代码
你可以结合专业知识补充说明当前工况。

"补充说明"四个字就是幻觉入口------模型会顺着知识库/常识自由发挥。把它换成"未查询到就直说",数值编造当场断根。

铁律二:写规则,不写死数据

规则 :提示词只描述"如何获取数据",不写死任何具体数值、指标名、模型名。数据一律通过 {{占位符}} / {tool_result} 动态注入,指标列表在运行时从工具返回值匹配。

落地写法

text 复制代码
指标列表、单位、量纲一律以工具返回值为准;
用户提到本系统未注册的指标时,反馈「未找到该指标」,并列出可用指标来源。

反面教材

text 复制代码
本系统常用指标:负荷率、煤耗、主汽温度、给水流量...

写死列表有两个致命问题:① 新指标上线,提示词不更新就漏答;② 模型把"列表"当"全集",列表外的指标直接拒答或编造。写死的知识一天后就过期,规则十年不过期------这是整轮迭代里踩得最深的一个坑。

铁律三:没有依据的推断,一个字不写

规则:允许给建议,但必须显式区分「数据结论」(来自工具返回值)与「经验建议」(来自模型推理),且经验建议不得伪装成数据结论。

落地写法

text 复制代码
输出分两段:
① 数据结论:仅陈述工具返回值,不做好坏评价;
② 建议:以「建议」为前缀输出经验性判断,禁止把建议表述为数据事实。

反面教材(就是开头的 75.6MW 事故):

text 复制代码
当前负荷 75.6MW,处于偏高水平,建议降低负荷。

"处于偏高水平"是推断,和"75.6MW"混在一句里,用户无法区分。真实事故就是模型把 75.6% 负荷率误判成"异常偏高"------数据与推断不分离,错一个就连坐错一片。

铁律四:引用来源,让答案可回溯

规则:知识库类回答必须标注来源文档;数值类回答标注来源接口/测点;无来源时明确声明。

落地写法

text 复制代码
引用知识库内容时,以「[来源] 文档名/章节」标注;
数值来自实时接口时标注「(实时)」,来自报表接口时标注「(报表,统计周期)」。

反面教材

text 复制代码
据运维手册记载,凝汽器真空应在 -90kPa 以上。

不写来源 = 无法验证 = 无法追责。写出来源后,哪怕答案错了,也能快速定位是哪份文档、哪条链路出的问题------把"AI 撒谎"降级成"链路 bug",问题立刻可修。

四、把铁律变成机器检查:validator.py

文字规则最大的敌人是回归:改提示词加功能时,顺手写死一个阈值,四铁律立刻破功,而人很难注意到。

所以我把最容易被破坏的铁律二、四转成了静态校验器 validator.py(仓库 prompts/ 内可直接跑):

规则 检查内容 对应铁律
R1 裸数字 正文出现阈值/百分比/固定参数 铁律二
R2 写死实体 命中内置业务指标/模型黑名单 铁律二
R3 缺占位符 动态占位符 {{...}} 数量不足 铁律一/三
R4 缺铁律 未包含「未查询不得断言/引用来源/禁止编造」等约束 铁律四

实测效果:

bash 复制代码
$ python validator.py
扫描 3 个文件:违规 0 项,警告 0 项
[✅ 通过] agent_base.md
[✅ 通过] kb_ops_agent.md
[✅ 通过] report_query_agent.md

$ python validator.py -f examples/bad_prompt.md --ci
扫描 1 个文件:违规 17 项,警告 0 项
[⚠️ 警告] bad_prompt.md
    ERROR R1: 正文出现裸数字「80%」...(写死阈值)
    ERROR R2: 写死业务指标「负荷率」「煤耗」...(写死实体)
    ERROR R3: 动态占位符仅 0 个(缺注入点)
    ERROR R4: 防幻觉铁律关键词仅命中 0/3(缺约束)
退出码: 2   ← CI 直接拦下

接入工作流的姿势很轻:新 Agent 上线 复制模板改占位符 → 跑一次校验;每次改提示词 跑一遍防回归;再往前一步,python validator.py --ci 挂进提交流水线,违规直接红。

五、收尾:规则 + 测试的闭环

30+ 轮迭代最后封版时,靠的不是"感觉这版更稳了",而是一套可重复的验证:提示词每改一版,跑一遍 100+ 条测试用例,四类问答场景(实时查询/调整建议/报表问答/知识库)逐一回归。封版的标准是:同一批曾出过幻觉的问题,不再复现。

如果把这段经历压缩成一句话给做 AI 应用的同行:

别指望模型"懂事",要在提示词里把"不知道时怎么办"钉死;再把这些规则变成测试用例和 CI 检查------让幻觉没有回归的机会。

整套资产(4 条铁律方法论 + 3 份落地模板 + 校验器 + 反面教材)已开源在 engineering-delivery-playbook,欢迎 clone 下来跑一遍 validator.py 感受下。防幻觉没有银弹,但至少有章可循。


本文为脱敏改写,不涉及任何真实业务数据与客户信息。欢迎 Star、Issue 交流。

相关推荐
码匠许师傅2 小时前
【设计模式精讲】25.状态模式(State)
c++·ui·设计模式·状态模式·uml
geovindu4 小时前
java:Observer Pattern
java·开发语言·后端·观察者模式·设计模式·行为模式
码匠许师傅1 天前
【设计模式精讲】24.观察者模式(Observer)
c++·观察者模式·设计模式·uml
小程故事多_801 天前
从快速迭代到稳定存续,Google五大设计模式重构长效AI智能体落地逻辑
人工智能·设计模式·重构
码匠许师傅2 天前
【设计模式精讲】22.中介者模式(Mediator)
c++·设计模式·软件工程·uml·中介者模式
2401_868534782 天前
网规备考_2.4 路由协议
c++·设计模式
cpp_learner2 天前
C++ 实现责任链模式(Chain of Responsibility):从一堆 if-else 到可插拔的处理管道
c++·设计模式
码匠许师傅2 天前
【设计模式精讲】23.备忘录模式(Memento)
c++·设计模式·软件工程·uml·备忘录模式
新知图书3 天前
第8章 多智能体协同
人工智能·设计模式·智能体