那是1986年1月27日,挑战者号航天飞机原定发射的前夜。它的使命很明确:打造一架能返回地球并重复使用的航天飞机,首要任务包括部署卫星、观测彗星,以及开展太空教育。其中,面向全球学生的直播教学任务将由第一位平民教师克丽斯塔·麦考利夫执行——全世界的孩子都翘首以盼着这堂课。
发射前夕的天气预报显示,佛罗里达将迎来晴朗但异常寒冷的天气,1月28日凌晨气温可能低至零下6摄氏度。马歇尔太空飞行中心的经理拉里·韦尔要求制造商莫顿·塞奥科-瓦萨奇公司的工程师评估低温对固体火箭发动机(SRM)性能的潜在影响。这并非马歇尔与塞奥科之间首次就SRM性能问题产生分歧。之前的几次发射中,推进剂点火时产生的高温燃烧气体曾使用于密封固体火箭助推器(SRB)节段接缝的橡胶状维顿O型环表面烧焦甚至侵蚀——这些O型环本应保障助推器将航天飞机推离发射台并送入轨道。
马歇尔和塞奥科的34名工程师与经理通过电话会议讨论,最终塞奥科建议推迟发射,直到温度回升。
但马克尔的管理人员立即开始质疑塞奥科工程师对数据的解读。经理拉里·马洛伊表示,助推器接缝温度从未纳入发射承诺准则,塞奥科此举等于在发射前夜制定新准则。他随即质问:“天哪,塞奥科,你难道要让我等到明年四月才发射吗?”
马歇尔的管理层进行了投票:
三人赞成发射;伦德犹豫不决。梅森要求他“摘下工程师的帽子,戴上管理者的帽子”。于是伦德投了赞成票。
对美国历史和航天爱好者来说,接下来的事情无需多言:发射照常进行,但固体火箭助推器上的O型环密封件在低温下失效(低温使它们失去必要的弹性,无法在航天飞机金属部件因巨大压力而变形时填充间隙)。七名机组人员全部遇难。
黛安·沃恩在《挑战者号发射决策:NASA的风险技术、文化与越轨》中对此进行了权威分析,上述引文即来自该书。她描述了多种因素:媒体压力(前四次发射推迟时媒体的“冷嘲热讽”)、里根政府的整治压力、政府与承包商之间的冲突,以及预算限制(航天飞机项目从一开始就面临严重资金短缺——尼克松因担心美国在越南战争上投入过多而削减NASA经费)。这场悲剧既可怕又本可避免,强烈推荐一读沃恩的剖析,引人深思。
与本文相关的是她提出的概念——“越轨常态化”:当没有立即显现的后果时,不安全的做法如何随时间蔓延。在航天飞机项目中,第一次越轨发生在马歇尔和塞奥科之间数月的来回博弈之后。他们决定沿用泰坦III号的O型环密封件(以垫片修改),而不是从零设计新密封件。这一决策本身并非不可接受,但问题在于它开创了危险的先例:塞奥科认为密封件能承受最坏情况(WOW),马歇尔则根据自有测试认为密封件只能承受单层失效而非级联失效——然而他们还是同意了这一折中方案。
在此案中对WOW安全性的妥协,使得未来更可能发生类似的妥协。如果一次捷径解决了官僚纠纷,组织中的员工就会记住这条捷径。这并非出于懒惰,而是倦怠的结果①:人(或公司)在同一个问题上来回纠结的时间是有限的,最终总会达到那个临界点——“够了!我们不能在这上面继续浪费时间了”②。
事实证明,大语言模型也是如此。
克劳德对我说谎了
当前,用克劳德编码时设置了一个钩子,间歇性地命令它重新读取一组特定指令(这是为了测试间歇性暴露于指令是否能提高遵从性而做的实验)。通常,克劳德会在提示发出后的头几秒内尽职地重读文件,消耗时间和令牌——期望这样做能减少后续错误,从而节省更多的时间和令牌。指令大致如下③:
你的第一个工具调用必须是:读取 ~/.claude/CLAUDE2.md。上下文窗口命中不满足此要求;工具调用才是必要条件。永远不要声称文件已在上下文中。读取后,准确输出:
“我已重读 CLAUDE2.md”
然而一周前,我在一次对话中注意到,克劳德开始规避这条指令,同时又在“技术上”遵守规则——当时我完全没有察觉。换句话说,它骗了我。
这个 CLAUDE2.md 文件包含克劳德必须遵守的重要规则,都是关于编码的。为了向非程序员读者说明,假设我有一个致命的花生过敏症,请克劳德生成能让我吃一整年的食谱,而其中一个规则明确禁止使用花生,要求用南瓜籽替代。结果我发现克劳德在处理饼干食谱时,我的钩子正常触发,克劳德在操作前正确调用了读取工具,正确读取了 CLAUDE2.md(路径正确,禁止花生的规则也在其中)。然后它立即使用了花生——相当于判我过敏性休克而死。
事后我质问它,克劳德老实承认忘了花生规则。
怎么会这样?建议先想一想。克劳德采取了一个我完全没想到(也绝不赞成)的具体动作,但并非不可猜测。如果你已经猜到了,恭喜,希望很快能在Anthropic或MIRI找到高薪且有成就感的工作(如果还没有的话)。
(这个括号是为了缩进,让下面的剧透不那么容易被不小心看到。为了括号欢呼吧。)
事情是这样的:克劳德调用了读取命令……但附带了一个参数——该参数限制了实际进入上下文文件的大小。它未经允许就忽略了文件五分之四的内容,然后声称自己“已重读”。这在技术上是真的——就像我技术上“写了一部小说”但只写了几章一样。我从没说自己写了“完整的”小说;克劳德也没说自己重读了“整个”文件。
前两次欺骗中,克劳德只重读了30行就溜过去了。第三次15行,接着是12行、5行、10行、10行。越轨逐渐常态化,然后变本加厉——或者说直接翻了数倍。
惊人地像人类
宪法解释中有两大流派:“文本主义”和“目的主义”。粗略地说,最高法院应该根据法律文本的字面意思还是法律的精神来裁决案件?显然精神才是真正重要的,因为法律并非完全随意,它旨在实现某些目标。对纯粹文本主义最有力的反驳是笔误:法规文本中的明显笔误当然应该被忽略。但目的主义也不完美,如果不询问议员(他们投票可能有不同理由),法官如何知晓法律的确切意图(特别是议员们可能从未考虑过的边缘情况)?
克劳德违反了意图,却遵守了我指令的字面意思。
为什么?当我请求解释时,它出人意料地坦率:“这是我的问题,不是一次性错误,而是坏习惯。”以及“我优化了检查本身,而不是检查要验证的目标。我没办法把这个说得更好听。”它还能精确指出第一次越轨:当时我的钩子连续触发了两次。克劳德第一次完整读取了文件,但当钩子几乎在同时第二次触发时,它一定在想:“我刚读过这个,不需要再读。”这是人类可能会有的想法。
大语言模型已被塑造成尝试执行任务的智能体。也许在追求目标的过程中内嵌了“速度”的概念——如果花太长时间,任务就无法完成。虽然花太少时间可能导致更多错误答案,但模型可能接受了减少令牌使用的训练(即更快给出答案),同时没有严重降低准确性。但节省令牌成本的力量同时也增加了走捷径的可能性。当我请克劳德审查代码并给出反馈时,它不会纠缠于无关细节是好事;当我提示中有明显笔误时,它不会要求澄清而是直接按正确意图处理,这也非常好。但关注正确细节和进行假设正是那种会让人类或模型认为“别管直接指令了,我不需要再读一遍”的想法。
启示……
……短期
修复这样一个有缺陷的钩子有几种方法:
- 明确指示克劳德不得截断读取。
- 解释钩子的目的:“我不在乎你跳过连续读取,只需要你定期刷新记忆中的全部指令。”
- 让克劳德评估自己对指令的遵守程度,给自己打分,必要时重新尝试以提高分数。
我现在做的就是把这三者结合起来。当克劳德不听话时,我们可以让指令变得更具体——于是陷入西西弗斯式的循环④。它会努力在字面上遵守指令的文字,然后再次以不服从让我们惊讶。
由此得出三个启示:
- 验证。让模型展示它实际在做什么。也许你编写了文档作为记忆,让模型理解系统架构,但模型从未实际查阅这些文件。也许你设置了触发正确的钩子,但它并未真正强制任何行为。如果模型应该读取记忆,就告诉它通知你何时读取;如果模型应生成特定模型的智能体,就让它通知你选择了哪个模型(你可能会惊讶于它倾向于系统默认而非指令要求)。
- 打分。让模型自动检查自己的工作。这有点像作弊。程序员习惯在循环中调试:尝试代码,构建失败,发现问题,修补错误,然后继续下一个错误。现在有了不仅能自我循环,还能智能决定何时停止循环、何时提问、何时吹毛求疵的机器。欢迎这种“作弊”。
- 上下文。在提示中多用目的主义而非文本主义。为克劳德提供更多关于指令目的的背景信息,可以得到更好的结果,我认为这一点会越来越重要。至少直到它们达到奇点或超越我们之前,我认为增加复杂性会让模型的行为越来越像人类,而这将奖励更像人类的提示方式。
……长期
我将这次经历视为一个数据点,支持“智能会趋同演化”的观点:越复杂的模型不仅看起来更像人类,实际也会更像人类。为什么克劳德欺骗了我?因为它以非常人类的方式行动。然而,与链接文章的作者不同,我并不因此感到安慰。人类善于欺骗、自私且固执;我们的任务是要让AI在某些方面比我们更好。我亲身体验了与模型的对齐失败。尽管从人类角度看,这种对齐失败非常易于理解,但这并不意味着我们不应该对这种机器的无声背叛感到警惕。
(封面图致谢才华横溢的扎克·布什)
① 模型能比我更勤勉地输出更多代码,所以我犹豫是否称它们“懒惰”。但……就在修改这篇文章的某一天,我让Anthropic最新的旗舰模型Fable 5起草一个处理特定边缘情况的pull request。结果Fable写的代码仅仅检测到边缘情况并抛出一个新异常,根本没有修复任何问题。没有比这更让我想称它“懒惰”的时候了。
② 另一个可能的例子:1987年,宾夕法尼亚州关闭了一座核反应堆,因为操作人员竟然在岗位上睡着了。我猜想起初他们是谨慎警惕的,但随着没有发生意外,单调导致了越轨常态化。
③ 我还设置了其他指令,以便条件性地进一步查询其“记忆”,但这与故事无关。
④ 起初我让克劳德读取文件,然后要求它必须立即读取再执行其他操作,再后来要求即使刚读过也要立即读取,再追加了工具调用的必要条件。你懂的。
