
过去一年我遇到的最扎心的线上事故不是机器宕机而是我们做的客服问答机器人一本正经地告诉用户某款产品已经停产了还煞有其事地编了个停产年份。实际上它是把两年前的一份内部公告和今年的一条促销信息缝在了一起。用户截图发到群里一整天我们都在灭火。那段时间我一直在琢磨怎么治这种爱说废话的AI。后来刷到Andrej Karpathy聊AI可靠性的内容他反复表达过一个观点今天的大模型像个满嘴跑火车的实习生聪明是真聪明但真正的工程难点不是让它更聪明而是让它在不确定的时候知道闭嘴。他提到的思路里有一条特别让我在意——把航空领域那套安全标准搬过来。顺着这条线我去把DO-178系列的来龙去脉翻了个底朝天。这套标准的思想源头确实要追溯到40年前1985年美国航空无线电技术委员会发布了DO-178A专门规范机载软件的安全性。今天大家经常提的DO-178C是这个家族的最新版本。越读越觉得航空业这帮人早在没有大模型的时代就解决了一个跟AI幻觉高度同构的问题怎么在充满不确定性的系统里构建出可以证明靠得住的软件。这篇文章就把我啃下来的东西以及我拿它改造实际AI系统的过程原原本本分享出来。1. 为什么偏偏是Karpathy偏偏是航空规范1.1 爱说废话已经不只是段子而是系统性风险AI幻觉这个词圈内人都懂。但很多人对它的理解还停留在AI会编个假诺贝尔奖得主这种搞笑层面。真实场景里它带来的是真金白银的损失。我做过的几个项目里幻觉主要砸在三个地方第一是客服场景。模型为了显得有用会在不确定时强行补全信息。产品参数记混、活动规则过期、承诺不存在的售后政策每一条都是舆情炸弹。第二是面向内部员工的知识库助手。它把旧版本流程当成现行流程回答导致业务部门按错误流程执行事后追责的时候根本说不清责任边界。第三是内容审核辅助工具。模型在判断一条内容是否违规时会脑补出处和上下文给出可信但虚假的判定理由。更麻烦的是幻觉是随机的。同样一个问题换个措辞可能就触发换个上下文版本可能就消失。你没法靠再训一版模型根治因为幻觉不是bug而是当前架构的固有属性。大模型本质是一个基于概率的续写器它在生成时并不会逐字验证事实只是输出看起来最合理的下一个词。所谓爱说废话其实是它的默认行为。1.2 Karpathy念叨的软件正在改变Karpathy这一年多的观点我一直有跟。他反复强调的一个事实是软件2.0时代程序的行为不再由人一行行写出来而是从数据里长出来的。这意味着传统软件工程那套出bug我就修源码的模型失效了——你没法在几万亿个参数里定位一个说谎的if分支。但他没有停留在AI不可靠所以别用的悲观里。他在讲AI工程化的时候多次提到一个观察航空业早就习惯了一个事实——你无法证明一个复杂系统绝对安全你只能通过一套工程纪律让它的风险落到可接受的范围。这套纪律的核心不是消灭错误而是管理错误。这个思路恰恰是对付大模型幻觉的正确姿势。我顺着这个线索去查航空标准越查越觉得有意思。原来航空软件的安全实践早在40年前就开始体系化了而它面对的问题跟我们今天面对LLM的问题底层逻辑惊人地相似。1.3 40年前的规范到底管的是什么1985年发布的DO-178A是专门针对机载软件就是控制飞机飞控、发动机、导航的那些软件的适航标准。后来经过1992年的DO-178B和2011年的DO-178C两次大改体系更完整了。这个标准要回答一个极其要害的问题怎么让监管机构相信你这个软件在天上运行时不会因为软件缺陷把飞机摔了注意这个表述——不是证明软件没有缺陷而是提供足够证据让风险可接受。因为航空软件同样极其复杂波音787的机载软件代码量据说超过一千万行谁也没法证明里面零bug。但商业航空的事实是致命事故率低到约百万分之一量级。这个可靠性靠的正是40年前就开始积累的那套方法。核心就三条把安全目标层层分解每个环节都留下可审计的证据一旦失效就按既定策略保守处理。这三条翻译到大模型场景正好对应了治理幻觉的三板斧约束、溯源、兜底。2. 航空业40年前就趟过的坑DO-178C的底层逻辑2.1 把正确重新定义为安全航空软件工程师和我最开始做AI犯的错一样总想追求绝对正确。DO-178C的哲学当头浇了一盆冷水——它的目标不是证明你的软件永远正确而是证明一个问题当软件出错时后果是否被控制在可接受范围内。这话怎么理解航空软件分两种失效模式。一种是直接失效该输出100的时候输出50这是明面上的错误。另一种是误导性失效本该输出100它输出105系统没报警但实际状态已经异常了。DO-178C最警惕的其实是后者因为它会让人做出错误决策还不自知。想想大模型幻觉性质完全一样。AI一本正经地编一个不存在的政策条款比它直接说我不知道危险得多。前者是误导性失效后者是直接失效。所以DO-178C的思维转换给了我很重要的启发治理AI幻觉第一优先级不是减少直接失效胡说八道而是减少误导性失效一本正经地胡说八道。前者用户还能看出来后者才是真正的杀手。2.2 设计保证等级不是所有代码都配得上同样的谨慎DO-178C里有个非常务实的机制叫设计保证等级DAL从A到E五级。等级A意味着软件失效会导致灾难性后果比如机毁人亡对它的验证要求苛刻到令人发指需求要形式化、测试要MC/DC覆盖率达标、每一层都有独立验证团队。而等级E意味着失效不会影响安全那要求就很宽松。这套分级的本质是把严格的工程投入集中到风险最高的地方去。航空业40年前就明白了资源永远有限如果对每一行代码都按最高标准要求项目根本交付不了。所以先做失效后果分析再决定每个模块的验证力度。这个思维迁移到AI系统里价值极大。我见过很多团队犯两个极端错误要么对所有AI输出一视同仁地不信任结果因为误拒太多被用户投诉到下线要么对所有AI输出一视同仁地信任结果在高风险场景翻车。正确的做法是先给AI的每个应用场景定级再分级上防御措施。2.3 证据链思维可靠不是感觉出来的是记录出来的DO-178C还有一个让我印象极深的点它要求全流程可追溯。一条需求从最初的功能定义到设计文档到代码实现到测试用例到验证结果到问题报告必须形成一条完整的链。监管审计人员随机抽一个需求你要能把它从源头到验证的全部资料摊开给他看。这意味着一个残酷的事实航空软件的可靠性不是做出来的是记录出来的。你开发流程再严谨如果没有留下成体系的证据适航审定就是不通过。反过来就算代码里还有已知问题只要所有问题都被识别、被评估、被记录并且证明残余风险可接受一样可以取证。这个证据链思想放到AI领域就是一个绝大多数团队都没做到的事你的模型输出了一个回答你能不能拿出来——这个回答到底依据了哪些被检索的内容、命中了几号知识条目、经过了哪些规则校验、模型输出的置信度是多少、有没有人审过我敢说90%的AI应用都答不出来。而这恰恰是治理幻觉的关键抓手。3. 把航空思维翻译成治理AI幻觉的工程清单3.1 需求追溯让每句话都有出处航空标准里最核心的追踪对象是需求在LLM场景里对应物就是回答里的事实性断言。我的做法是强制要求模型的每一条事实性输出都标注检索来源编号。具体落地是这样的。我们给知识库的每个文本块预先编号检索时按相关度排序取Top-N个文本块。然后在系统提示词里规定回答问题时凡是涉及具体事实、条款、参数、流程的句子必须在句末加括号脚注标明依据是哪些编号的文本块。比如该产品支持7天无理由退货依据[3][7]。这一步看着简单效果却立竿见影。原因在于要求模型标注来源会逼它在生成时做一次自我配对——如果某个说法找不到对应的检索来源模型要么乱编一个编号这种情况还是会出后面说要么因为无法配对而倾向于不输出这句话。实测下来光是这一条就能砍掉相当一部分无中生有的内容。它相当于给模型的每个断言装了一个证据钩子让后续的校验有抓手。3.2 独立性验证别让AI自己给自己打对号DO-178C对A/B级软件有一个硬性要求验证不能由开发团队自己完成必须有独立的验证人。为什么因为人容易对自己的错误盲区视而不见。翻译到AI场景就是一句话不能用另一个大模型来验证这个大模型输出的对错。因为同一个训练范式和数据分布下两个模型往往犯同样的错你拿一个AI去检查另一个AI得到的是两个幻觉的互相确认。那怎么办我采用的办法是规则知识库校验器。对知识库问答这类场景答案里的关键实体产品型号、价格、日期、政策条款编号是可以用规则引擎精确校验的。我们建了一个轻量的校验层AI给出回答后先用正则和实体字典把回答中的结构化信息抽取出来再回到知识库里做一一比对。比对不一致的直接打回重生成并附上冲突信息告诉模型哪里错了。这套办法的适用范围有限但对结构化程度高的领域非常有效。它能拦截的正是最危险的误导性失效——那些听起来合理但数据对不上的回答。3.3 保守失效拿不准的时候允许说不知道航空中最经典的失效管理原则是fail-safe当系统处于不确定状态时默认采取保守行为把控制权交回给飞行员。对应到AI系统就是三层兜底第一层是置信度阈值。我们给模型的输出接了一个置信度评分可以用token级别的logprob聚合也可以让模型自评一个0到1的分数低于阈值的回答不直接发给用户。第二层是特定触发词。当回答里出现可能也许关于这个我没有确切信息这类模糊表达系统判定这是模型在不自信状态下的输出强制进入确认环节。第三层是兜底转接。对于P0级高风险管理场景比如医疗建议、法律条款解释、投资建议一旦进入不确定状态话术直接切到我无法确认这个信息已为你转接人工。我还专门设计了一套阶梯式放弃话术比生硬地说我不知道体验好很多先给出相近但可确认的信息再说明确认不了的内容最后给用户指一条人工兜底的路径。这套话术几乎就是航空机组的标准沟通培训——承认局限、提供备选、给出下一步。3.4 配置管理模型、提示词和数据都要像飞行记录一样可审计DO-178C对配置管理的要求贯穿整个生命周期每一个版本的软件、每一份文档、每一次变更都要记录在案。我用这个思路重新整理了AI应用的配置单元一共四件套模型版本当前生产环境跑的是哪个模型、哪个权重版本、哪个量化等级全部登记。提示词版本把提示词当代码管进Git仓库每次修改都留diff记录。改提示词比改代码更隐蔽出问题的时候想回滚必须有版本溯源。知识库快照数据源更新前打快照保持和模型版本、提示词版本的三者对应关系。换新知识库后模型表现变了先查三者是否匹配。评估集版本评测结果要和固定版本的数据集绑定。这个很多人忽略要评估这轮改动到底是变好了还是变坏了必须用同一套评测集否则对比毫无意义。这三者版本不一致导致线上事故的例子我见过不止一次。有同行遇到过这种情况提示词做了微调知识库同步更新了但评估集没换结果上线后幻觉率反而上升原因根本查不出来——所有变量都变了。有了配置管理排查问题时就可以像航空失事调查一样把飞行记录完整拉出来回放。3.5 分层防御别把信任放在一个篮子里航空安全里有个著名的模型叫瑞士奶酪模型每层防御都像一片奶酪都有破洞但只要多层叠加能同时穿透所有洞的事故就很难发生。对抗AI幻觉也是同样的逻辑单靠任何一层都堵不住必须叠第一层检索增强RAG本身。让模型基于真实材料回答缩小自由发挥的空间。 第二层提示词约束。系统层规定输出格式、引用规则、禁止臆造条款。 第三层后置规则校验。抽取结构化信息做精确比对。 第四层置信度阈值和拒绝回答。兜住前面漏掉的不确定情况。 第五层人工审核队列。高风险回答直接进人工抽检流。这五层各堵各的漏洞。RAG堵不住模型不看材料硬编提示词堵不住模型被注入攻击规则校验堵不住语义层面的错误逻辑对但意思偏了置信度堵不住高自信的错误人工抽检成本高但能给前四层一个收尾的网。层层叠加之后任何一个单点失守都不会直接变成用户面前的事实错误。4. 亲测给智能问答系统做了一次适航改造4.1 改造前的症状诊断我找了一个自己维护过的知识库问答系统来做实验。这个系统是这样的内部技术文档知识库面向售前工程师问的都是产品参数、兼容性列表、故障处理流程。引入大模型之前直接用关键词检索准确但生硬引入RAG之后对话体验好很多但开始出现幻觉。改造前我们做了一次症状盘点典型的错误有六类参数错误把A型号的功耗写成B型号的两者正好差一倍。版本混乱用2022年的旧文档回答2024年的问题还说得振振有词。张冠李戴把同一系列不同型号的特性混在一起说。编造数据回答支持的协议栈列表时多写了一项产品根本不支持的协议。编造流程回答售后流程时把两个不相关的流程拼成了一个。自相矛盾一段回答里前后矛盾前面说支持后面说不支持。内部评测准召非常难看更严重的是工程师用户不敢信这个工具了——开始怀疑所有AI输出好内容也被当成幻觉给弃用。这就不是准确率的问题而是信任崩塌的问题。4.2 按DAL思维给场景定级对照DO-178C的启发我们做的第一件事不是加防御而是给所有问题场景分级。我拉了一个问题分类表按答错会造成多大后果来拍风险等级场景举例防御要求P0合规条款解释、安全操作流程、参数极限值必须带引用编号规则校验置信度不足直接转人工P1产品兼容性、常规参数、价格政策必须带引用编号置信度不足拒绝回答P2产品背景介绍、使用方法建议允许自由回答但不得编造来源和日期这个分级决定了后续的节奏先把P0场景的防御做到极致P1做到基本可靠P2先放着不折腾。航空业40年前就是这么干的——DAL A级模块花70%的验证资源DAL C级模块过一遍基本的就放行。不搞一刀切。4.3 三轮迭代的完整记录第一轮先上强制引用。系统提示词里加了一段很长的约束说明核心要求就是回答涉及具体事实时必须标注检索来源编号找不到对应来源的信息不允许出现在回答里。跑了两周幻觉率掉了大约六成。代价是回答变得特别碎很多工程师用户刚用的时候说怎么每个句子后面都带个括号好丑。但很快反馈就反转了——因为用户发现带了编号的内容他们可以直接点过去看原文不用再被AI的味道迷惑。这个信任感上的增益远远大于阅读体验上的折损。第二轮上规则校验器。我们把知识库里的结构化信息产品型号库、参数表、价格表、发布日期抽出来做成一个校验字典。AI回答生成后后台先跑一轮实体抽取和比对。具体做法是用正则加NER把回答里的型号、数字、日期抽出来再到字典里查是否存在、是否一致。发现不一致的把冲突信息回填到上下文里让模型重新生成一次。这一轮又把幻觉率削掉一半。注意这里有个很关键的抉择校验不通过的不能直接给用户看错误答案也不能只简单返回系统错误而是要让模型带着冲突信息重写——它看到自己刚才哪里说错了往往能自己纠正过来。第三轮上置信度阈值和拒绝机制。前两轮做完了剩下的幻觉样本大多是这种类型看起来有引用引用编号也真实存在但模型对引用的理解是错的。这种语义层面的错误规则校验器管不了。我们的解法很朴素把模型自评置信度调出来低于阈值的答案直接不发转成兜底话术。阈值怎么定我们拿一批人工标注过的历史问答做校准画了一条置信度-准确率曲线选在宁可多拦一些也不放错的位置。这轮结束后P0场景的幻觉率降到了可接受的极低水平。4.4 数字说话改造成效和新增成本改造前的内部评测P0场景的事实错误率也就是一本正经胡说八道出现的比例大约在I2%左右。三轮迭代之后降到大约1%出头。下降幅度挺明显但要诚实说不是零——语义级幻觉没法靠规则层彻底消灭。更重要的变化是错误结构变了。改造前错误里一大半是误导性失效——看起来特别真不查原文根本发现不了。改造后剩下的错误基本都变成直接失效——比如这个问题我需要找更权威的来源确认一下这种明显的不自信输出或者引用编号对不上用户一查原文就发现。这种错误伤害小得多用户自己就能识别不会造成系统性误判。同时新增的成本也要摆出来。延迟因为多了校验、重写和分级判断P0场景的平均响应延迟从1.2秒上升到2.8秒。成本每多一轮校验重写就多一次模型调用P0场景的token消耗大约增加了两倍。也算过这笔账用翻倍的成本换取幻觉率一个数量级的下降在我们这个业务场景里是划算的。4.5 踩坑记录航空思维哪些环节最难受最难受的是配置管理。航空可以按年来做版本迭代AI产品一周恨不得发三个版本。把提示词、知识库、模型版本严格绑定、每次变更都留审计记录听起来很简单但执行起来极其反人性——工程师改了一版提示词顺手更新了知识库评测集没同步前后数据的可比性就废了。我们后来用CI流程强制约束发起变更必须同时声明模型版本、知识库快照和评测集版本缺一不可。这相当于把航空的配置管理纪律一部分搬进了常规开发流程。其次是独立性验证的成本问题。规则校验器这种轻量独立验证还好如果你试图为每个业务域都建一套独立的语义校验模型成本基本是失控的。我的取舍是只在P0级场景做高成本的独立校验P1级用轻量规则P2级直接靠RAG和提示词兜住。还有一个很隐蔽的坑提示词注入。脚本小子用一段精心构造的输入让AI忽略必须引用的约束强行吐出没有依据的回答。你用心架好的防御一个注入就穿透了。后来我们的处理是在网关层统一做输入的注入检测同时在检索内容里也执行过滤——不让脏数据进上下文。5. 该抄的抄不该硬抄的别硬抄5.1 能直接抄的四件套总结这次改造我认为航空规范里最值得AI团队直接借鉴的四样东西是分级治理按失效后果分配防御投入、证据链让每一个回答都带可追溯的引用和校验记录、保守失效低置信度就拒绝把直接失效优先于误导性失效处理、配置管理版本三件套绑定让每次变更可回放。这四样几乎不依赖任何特定技术栈你用什么模型、什么框架都能落地。5.2 不能硬抄的三条边界第一不要试图给LLM做形式化验证。航空对DAL A级软件要求形式化验证——用数学方法证明程序逻辑符合需求规格。这在传统软件上可行在神经网络上是无解的。LLM的行为空间接近无限你不可能证明它在所有输入下都符合某个形式化规格。硬要往这条路上走消耗巨大还收效甚微。第二不要追求完全独立的双团队验证。航空的独立性验证之所以可行是因为需求是固化的、验证标准是明确的。LLM的验证问题本身都还在演化两个不同背景的验证团队连什么算幻觉都可能吵起来。独立验证在AI场景要做的是轻量独立——规则层、知识库层、人工抽检层各管一段而不是再造一个平行世界。第三不要照搬文档驱动的开发节奏。航空一个功能的文档和证据文件可以比产出的代码厚十倍那是适航审定的硬性要求。AI业务的迭代节奏不允许这样真要照搬团队一周发一个版本都做不到。所以我的原则是文档只沉淀变更原因关键参数验证结论三样其他细节留在代码和配置里。5.3 小团队落地的务实路线图如果团队只有两三个人预算有限我的建议是从这条线走起第一步P0场景盘点。先花一天把业务问题按后果分级挑出答错会出事的场景只做这些。 第二步强制引用。改一段提示词让模型输出带检索来源编号同时把系统设定改成识别不到来源就明说不知道。这个改动成本只要一个下午效果立竿见影。 第三步建一张关键实体校验表。把你领域里绝对不能错的参数、政策、型号整理成字典写一个简单的校验函数对AI输出做一次后置比对。这一步用普通后端工程师半天就能做完但它能把最危险的那一类错误拦下来。 第四步加置信度和兜底话术。把拿不准就闭嘴变成可执行的话术链路。 第五步跑了数据之后再决定要不要上更重的独立校验。我自己把航空规范啃下来、再翻译成工程语言的过程最大的体会是不要指望AI从爱说废话变得永不说谎这不现实。现实的目标是把废话变成可控的、可识别的、可追溯的让系统即使说错说错的代价也小到可以接受。Karpathy那句software is changing背后写的其实是同一个道理——软件的定义在变但软件工程最底层的那些东西证据、纪律、兜底、责任从来没有变过。40年前的航空规范能救AI靠的从来不是玄学正是这些朴素的常识。