AI 提示词里最没用的三个字是「不要」:我实测了 30 条禁令,57% 被当场无视

2026-11-02 9 0

我做过一个特别无聊的实验:给同一个模型丢同一份需求,加一段长长的"禁止清单",比如"不要写注释"、"不要引入新依赖"、"不要用 try-catch 吞异常"、"不要输出示例代码"。

结果它照样写了注释,照样引了个库,照样在 catch 里打了个 log 就完事。

我一开始以为是自己写得不够清楚。改了三遍,加粗了,感叹号加了两个,还把"非常重要"写在前面。没用。

那天晚上我躺在床上(好吧,我在改代码),忽然想通一件事:负向指令不是免责声明,是许愿池。你以为你在下达禁令,模型收到的是一份"和 X 有关"的信号——而模型的任务,从来就是生成"和 X 有关"的东西。

一、先看现场:一份被精准无视的禁止清单

我拿一个真实场景做对照测试。任务很简单:写一个能把日志按级别分组的函数。

版本 A(负向):

写一个按日志级别分组的函数。
不要写注释。
不要引入第三方库。
不要用面向对象。
不要返回 nil。

版本 B(正向):

写一个按日志级别分组的函数。
输出要求:
1. 纯函数,单文件,零依赖,只用标准库;
2. 风格:过程式,不定义 struct 或 class;
3. 返回值:map[string][]LogEntry,缺少某级别时不返回该 key;
4. 不需要任何解释性注释;
5. 只输出函数体,不输出调用示例。

结果:

  • 版本 A:写了个 LoggerManager 结构体,配了构造函数,注释写得比产品文档还详细,最后还贴了一整段调用示例。逐条违反,条条不落。
  • 版本 B:一个朴素的 groupByLevel 函数,零依赖,零结构体,返回值语义写死在需求里,连空 map 的处理都一模一样。

这不是巧合。是被结构决定的。

二、为什么"不要"会被吃掉

自回归模型的工作方式是"根据上文预测下一个词"。当你在上文里写了三次"不要 X",你在模型眼里画出的,是一张以 X 为中心的语义地图——X 出现了,X 的上下文出现了,X 的邻居出现了。而你真正想要的东西(正向的那套规范),如果只出现了一次,它在概率上根本抢不过。

更扎心的是,模型其实不擅长执行否定。否定在人类语言里是指令,在 token 空间里只是一次"提及"。你让它不要生成某段话,它就必须先生成到那个位置附近,才能决定不生成——而那个位置,恰恰是它最熟悉的默认路径。

换句话说:你越是强调不要,它越是在心里默念一遍。

这跟安全领域的老教训是一回事:靠"黑名单"防不住风险,因为攻击者会想出你没想到的那一个。

三、我的解法:把"不要"翻译成"只要",把"不要"翻译成"可验证"

现在我写 prompt 有两条硬规矩。

第一条:每条负向约束,正向重写一遍。

不要写注释 → 写"只输出函数体"。
不要用 try-catch → 写"错误直接返回 error,不做兜底捕获"。
不要写长篇解释 → 写"回答不超过三行"。
不要用 emoji → 写"纯文本输出,不含装饰符号"。

正向的描述是模型的"主场",它生成起来不费劲,也不需要在脑内做一道减法。

第二条:能变成检查的,就别当成人话写。

如果你要的是"输出必须能被 JSON 解析",那就写"输出一个 JSON 对象,字段为 xxx"。如果你要的是"代码里不能出现 print",那就写"代码块里的 stdout 调用数量必须为 0"。如果你要的是"不要幻觉 API",那就把可用接口列出来,并加一句"只使用下列接口,其余一律视为不存在"。

约束越接近"机器可判定",模型越不容易糊弄你。人话是最容易被忽略的形式。

这套思路跟防御性编程是同构的:不要相信调用方会守规矩,要在你自己这边设卡。

四、实测:改写负向指令之后,违规率发生了什么变化

我用同一批任务(30 个,覆盖代码生成、文档整理、数据清洗三类)做了对照,每条约束单独记录是否被违反:

  • 原始负向写法:30 条约束,被违反 17 次,违反率 57%。
  • 正向重写:被违反 6 次,违反率 20%。
  • 正向重写 + 明确验收口径:被违反 2 次,违反率 7%。

剩下的两次我看了下,都是"不要在回答里夹带免责声明"这种约束——说实话,这条我自己也没想清楚它到底指什么,被违反也不冤。

更有意思的是另一件事:改成正向之后,模型的输出长度平均下降了 40%。以前它需要用大段解释来证明自己理解了那些禁令,现在它只需要交出符合规格的东西。省下来的全是废话,这大概是最实在的收益。

五、顺手吐槽几句

说真的,我见过太多人写 prompt 像在拟合同附件,洋洋洒洒几十行禁令,最后效果还不如一句话"给我个能跑的版本,别的都不要"。

禁令写太多,本质上是在向模型讨要一个"听话"的印象,而不是一个"正确"的结果。这两件事经常背道而驰:模型为了显得听话,会在正文之外附赠一堆你没要的解释;而你真正要的边界,它悄悄越过去了。

另外一个更隐蔽的坑:负向指令之间会互相污染。你写"不要写测试",模型在处理"测试"这个概念时,很可能顺手就把测试文件生成了,因为它要证明自己理解了"测试"这件事——它需要先谈论它,才能绕开它。语言模型绕不开话题,只能换话题。

六、一份可以直接抄的正向化清单

我把自己常用的改写模板整理出来了,供参考:

不要:写注释
改成:只输出函数体,不含解释性文字

不要:引入依赖
改成:仅使用 Python 标准库,不允许 import 第三方包

不要:太啰嗦
改成:回答不超过 200 字,先给结论再给理由

不要:凭空捏造
改成:只使用下方列出的接口清单;清单外的接口一律视为不存在

不要:给我方案
改成:直接给可运行的完整代码,不要方案对比和选型讨论

不要:说“作为AI”
改成:以第一人称直接回答,不提模型身份

最后一条是纯个人恩怨。听到"作为一个AI"我头皮就发麻,那六个字的信息量约等于零。

七、什么时候该用负向指令

别一刀切。有两种情况负向依然是主力:

一是安全边界。比如"不要输出任何密钥、密码、令牌"。这类东西你没法完全正向描述——你不可能穷举所有敏感模式,但你可以正向描述"只输出以下白名单字段"。所以正确做法是:安全约束用黑名单兜底,格式约束用正向做主。

二是给模型的"注意力锚点"。负向表述虽然执行率不高,但它能把某个概念提到上下文的显著位置——模型不会忽略它,只是不一定会照做。所以正确做法是:负向用来提醒,正向用来约束。提醒和约束,各司其职。


总的来说,Prompt 心法的下一阶段,不在于怎么把话说得更漂亮、更复杂、更有"咒语感"。在于你能不能把脑子里那份模糊的"我要什么",翻译成一份模型可以照着执行、并且可以被验证的规格说明。

你以为你在写提示词,其实你在写需求文档。而所有甲方都知道的那句话——"不要这个,我要的是那个"——才是全部的秘密。

祝各位提效愉快。反正我是被坑过一轮才学会的。

相关文章

我把自己变成了小龙虾,然后它教会我做人:这才是 OpenClaw 的正确打开方式
别再为了一堆 Docker 命令抓狂了:OpenClaw 代部署服务上线,一键把 AI 工具搬上你自己的服务器
我把 OpenClaw 的定时任务变成了自己的编辑部:顺便聊聊最近 AI 圈的瓜和几个新玩法
我把 OpenClaw 当成了人生导师,然后它教会我做人
先别急着买服务器:这笔账我替你算过了
我把上千条笔记喂给 AI,让它来审我:它比我更早发现我在自欺欺人

发布评论