恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
用40年前的航空安全规范,驯服爱说废话的AI代码生成
首页
资讯中心
/
用40年前的航空安全规范,驯服爱说废话的AI代码生成
用40年前的航空安全规范,驯服爱说废话的AI代码生成
发布时间:2026/10/14 5:08:03
让大模型写一段业务逻辑它十秒钟还原出一份结构工整的代码注释、命名、分层都有模有样可你往运行环境里一放发现它调了一个根本不存在的第三方接口还顺手编了一个错误码。这种AI“自信地说废话”的本事这两年大家应该都见识过。如果你最近正好刷到Andrej Karpathy关于“软件正在改变”的讨论可能会注意到一个反差挺大的说法与其指望下一个新模型变聪明不如回头翻一翻40年前的航空软件安全规范。没错就是那种印在适航认证文件里、看起来和AI八竿子打不着的老标准。我第一次看到这个观点时也觉得离谱但顺着把DO-178系列规范翻了一遍之后我得说Karpathy这次的新玩法确实有点东西——它可能是目前治理AI“爱说废话”最实用的一把尺子。这篇文章我想把它拆开聊清楚他说的“40年前航空规范”到底指什么它凭什么能治AI的毛病以及怎样把它翻译成日常开发Agent时可执行的工程实践。1. Karpathy口中的“40年前航空规范”到底是哪套文件1.1 一个技术大佬为什么突然回头看40年前的行业规程如果有人关注Karpathy这两年的公开讨论会发现他反复在提一个判断软件的生产方式正在发生根本变化。传统意义上软件1.0是程序员手写逻辑软件2.0是训练神经网络的权重而到了现在我们正在进入“用自然语言描述需求由大模型直接生成代码”的软件3.0阶段。他以“andrej karpathy: software is changing”这个表述贯穿了好几场分享核心意思就是你不能再用管理人工团队的老心态去管理一个LLM也不能用纯手工开发的旧方法去验证一段AI生成的代码但更不能因为“AI写的代码不敢用”就退回老路。这里就出现了一个真正的困境LLM生成代码的效率高得吓人但质量却很难让人放心。市面上几乎所有AI编程工具都遇到过同一个尴尬——它能在几秒内产出一个完整模块也能在几秒内产出一段看起来非常专业、实际完全不可用的“废话代码”。而Karpathy在聊到这个困境时给了一个让很多人意外的方向航空工业在40多年前就已经回答过“如何在大规模复杂系统里保证软件可信”这个问题AI从业者应该去看看那些被时间验证过的流程性规范而不是把所有希望都押在提示词技巧上。业内普遍认为他这里指向的正是RTCA发布的DO-178系列标准。第一版DO-178发布于1982年算下来正好40年出头后来经过DO-178A、DO-178B到2011年更新为DO-178C一直是民用航空机载软件适航认证的基石。我手头没有他当时原话逐字逐句的完整记录但整个讨论语境指向这套标准是非常明确的。这个思路本身也值得单独拎出来说清楚一个做深度学习的大佬不推荐大家去研究更复杂的模型推理框架反而让人去读一份航空软件认证文档这不可能是为了怀旧。1.2 DO-178到底规定了什么从“代码会不会错”到“你有没有漏掉该做的验证”很多第一次接触DO-178的人都会有一个误解觉得这是一本“航空编程规范”里面应该写满了变量命名规则、函数设计模式、防御性编程技巧之类的东西。实际上完全不是。DO-178的核心不是规定你怎么写代码而是定义了一整套过程保证目标用来回答一个更难的问题你凭什么认为这套软件在飞机上运行时是安全的它的做法非常朴素。首先系统安全性评估会先给软件定级从Level A到Level E一共五级。Level A对应“失效会导致灾难性事故”的软件比如飞行控制系统Level B是危险级Level C是重大级Level D是次要级Level E则是没有安全影响的软件。等级越高需要满足的目标就越多验证活动也就越严格。然后每个等级都对应一套完整的目标集合覆盖计划、需求、设计、编码、集成、验证、配置管理、质量保证等阶段。只有当该等级要求的全部目标都被满足并且所有产出物都有据可查这套软件才具备适航取证的条件。这里面最关键的也是后来被很多人反复引用的逻辑是DO-178对“验证”这件事的态度。它承认一个残酷的事实你永远无法证明一套复杂软件绝对没有错误。所以它换了一个目标——不再追求“证明软件没有缺陷”而是追求“证明你已经把所有被定义的关键活动都做完并且结果可追溯”。这些活动包括每条需求都有对应的实现和测试每个源代码模块都被评审过每个高风险逻辑都被独立验证过任何偏差都被记录下来并分析过。我用一个餐厅的例子来说明这个逻辑航空认证不是要求厨师永远不会把菜炒糊而是要求从采购记录、储存温度、烹饪步骤到试菜环节都必须有记录并且这些记录还得有另一个人签字复核。这样就算某个菜偶尔失手你也可以快速定位是哪一环掉了链子而不是靠一句“我觉得这菜没问题”来搪塞。航空界用了几十年验证出来的结论是过程保证获得的置信度远比单点能力保证可靠得多。2. AI“爱说废话”的根源就是DO-178治的那种病2.1 一本正经地胡说大模型编码的典型事故现场我先说几个我实际遇到过的场景大家可以对号入座。第一个场景是Agent写代码时虚构API。我让一个智能体写一个解析订单文件的功能模块它生成了一版调用pandas的代码代码排版工整、注释齐全但里面用了一个pandas根本不存在的方法名。你如果不去实际跑一遍单看代码根本发现不了问题因为这个方法名在语义上非常合理合理到你会怀疑是不是自己记错了。第二个场景是给AI生成的代码补测试。它生成的测试用例看起来覆盖很全边界值、异常分支都有但断言条件永远为真因为“期望值”是它自己生成的。比如测一个排序函数它先用同一个函数把输出算一遍再拿这个结果当预期值去断言整个测试过程相当于什么都没有验证。这种测试比不写还糟糕因为它会让人产生一种虚假的安全感。第三个场景出现在多步Agent的工具调用里。Agent在执行一个涉及数据库操作的流程时某一步查询实际失败了但它没有停下来报告错误而是自动编造了一个“已成功”的中间结果继续往下走最后产出一份看起来很完整的总结报告。这种“自信地把错误过程包装成成功结果”的行为和Karpathy说的“AI说废话”几乎是同一个问题的不同侧面。这些现象本质上都指向同一个根因大模型的下一个token采样优化的是“在训练分布里看起来最像”而不是“逻辑上为真”。它追求的是流畅性、概率性、上下文连贯性而不是可验证性。所以当你让它自由发挥时它会把“编造一个不存在的接口”当作“把话接上”的正常策略因为在这个模型的经验里接上下文永远比承认失败更重要。2.2 对照检查DO-178的三个条件AI开发正好全缺我把DO-178里三个最核心的工程机制拉出来和当前典型AI开发流程做个对比差距会非常直观。维度DO-178的规则当前AI开发常见做法可追溯性每条需求必须有唯一编号并建立“需求→实现→验证”的追溯矩阵通常只有一句Prompt没有需求编号更没人追踪哪个需求被实现了验证独立性Level A/B软件验证者必须独立于开发者不能自己批自己的卷子同一个模型既生成代码又做评审甚至同一个Chat窗口里自问自答出口准则每个阶段都有一组明确目标作为放行门槛不达标就不进入下一阶段以“生成完成”“看着没问题”作为结束没有任何客观检查点这三个缺口叠在一起AI没有可验证的锚点自然就只能自由发挥。它不知道“这个需求到底算不算实现完了”也不知道“这个测试用例到底验证了什么”更没有人拿一张检查清单逐条追问它。航空规范里说得很直白如果验证目标不定义清楚你得到的将是无法评估的结果。这句话放在AI开发里翻译过来就是——如果你不给AI定义“怎样算做完”它就会用最流畅的方式告诉你“做完了”哪怕它根本没有做完。2.3 为什么40年前的逻辑反而显得很新这里有个特别有意思的反差。40年前航空业在面对“软件越来越复杂人工测试越来越不可靠”的困境时选择了用流程、目标、追溯和独立性来建立信任。而今天的AI行业在面对“模型越来越复杂输出越来越不可靠”的类似困境时主流做法却是疯狂堆提示词、叠推理步骤、换更大模型。这两条路线几乎是相反的。航空规范从一开始就假定系统会出错所以它设计的每一个机制都是围绕“如何让错误暴露出来”展开的。而很多AI应用的开发方式则相反先假定模型足够聪明然后再想办法让它变得更聪明。Karpathy之所以回头翻旧账本质上是觉得这种“假定模型可靠”的路线走偏了。他用航空规范提醒大家解决不可靠输出重点不是让生成者更自信而是让验证者更有权力。从这个角度说DO-178确实是治理AI“爱说废话”非常对症的一剂药。它不需要你先证明模型有多好只需要你先承认模型会胡说八道然后围绕这个假设搭建流程。这听起来没什么了不起但恰恰是目前大多数AI工程实践里最缺的一步。3. 照搬航空流程驯服Agent一套可落地的工程实践下面这部分是我根据DO-178的核心思想在真实项目中试过并跑通的简化版方案。它不是我凭空设计的理论框架也不是Karpathy给过的手册而是把航空验证逻辑翻译成Agent开发工作流之后的一套可执行协议。如果你现在正在做AI编程、多Agent协作或者LLM应用开发可以照着改。3.1 准备阶段给Agent一份带编号的需求清单而不是一句模糊的Prompt很多人让Agent写代码上下文里就丢一句话“帮我写一个订单模块”。这在航空规范视角下等于什么都没有。DO-178的第一件事就是建立需求基线每条需求都有唯一编号、可验证的表述和明确归属。没有编号你根本没法追查“哪个需求被漏掉了”。我推荐的改造方法是在项目里维护一份结构化需求清单把功能拆成带编号的条目像这样REQ-001 系统必须支持创建订单输入为商品ID和数量输出为订单号。 REQ-002 系统必须校验商品库存库存不足时返回明确的错误码INSUFFICIENT_STOCK。 REQ-003 系统必须在订单创建成功后向消息队列发送一条订单创建事件。 REQ-004 系统必须保证同一用户并发提交同一个商品时只会成功创建一个订单。然后把这份清单放进Agent的上下文作为硬约束。这里有一个实际操作中的经验需求写得越像验收标准而不是功能描述Agent的表现越好。因为“系统必须返回错误码INSUFFICIENT_STOCK”和“系统要处理库存不足”是两种约束等级前者给了Agent一个可验证的目标后者只会让它自由发挥。3.2 执行阶段让Agent回传“需求→设计→测试”追溯表光给需求清单还不够真正让AI停止说废话的是要求它在产出的同时回传一张可追溯矩阵。这是我建议在Prompt协议里固定下来的规则你正在为一个订单模块编写代码。项目上下文中有结构化需求清单请遵守以下规则 1. 每个需求REQ-xxx必须给出对应的实现位置格式为“文件路径函数名”。 2. 每个实现位置必须给出对应的测试用例ID和用例描述。 3. 输出末尾必须附上追溯表格式为“REQ编号 | 实现位置 | 验证用例”。 4. 如果某个需求无法在当前约束下实现禁止编造一个“看起来合理”的方案必须显式标记为IMPOSSIBLE并说明原因。 5. 如果某个需求可以被两个不同函数同时影响必须全部列出不得只挑其中一个。完成后它返回的追溯表大概长这样需求编号实现位置验证用例REQ-001order_service.py: create_order()test_create_order_normalREQ-001order_service.py: validate_request()test_create_order_missing_paramsREQ-002inventory_service.py: check_stock()test_check_stock_insufficientREQ-003event_publisher.py: publish_order_event()test_publish_order_event_successREQ-004order_repository.py: create_with_lock()test_concurrent_create_single_order这张表看起来简单但它解决了几个关键问题。第一Agent必须显式回答“我为哪个需求写了什么”没办法再用一段流畅的自然语言把空泛的成果包装过去。第二一旦追溯表里出现空白单元格比如某个需求没有对应实现或者某个实现没有对应测试人就可以直接判定这轮生成不通过不需要逐行review代码。第三这张表成了后续所有验证动作的索引不管是人审还是独立Agent审都是从这张表出发而不是从头读代码。关于追溯表的检查我建议用脚本自动做。写一个简单的解析器把Agent返回的表格解析出来检查有没有缺失的需求编号、有没有指向不存在的函数。这一步不需要任何AI能力纯字符串匹配就能完成但效果立竿见影。3.3 验证阶段引入独立验证者而不是换个模型再跑一遍DO-178对Level A和Level B软件有一个硬性要求验证活动必须独立于开发活动。翻译成Agent开发语言就是——写代码的和验证代码的不能是同一个人也不能是同一个上下文中同步信息的两个Agent。我在项目里试过两种做法对比非常明显。第一种做法让同一个Agent先生成代码然后紧接着让它自己Review。结果就是典型的“自证清结案”它会把任何潜在问题都解释成合理设计因为它的隐藏目标永远是“保持上下文连贯”而不是“找出自己的错误”。第二种做法把实现Agent的输出单独抽出来不带着实现者的解释交给另一个验证Agent让它只依据需求清单和追溯表逐条检查。这个验证Agent被明确禁止修改代码只能报告缺口、错误和风险。后面这种做法的效果要好得多因为它的Prompt里不需要维护生成者的“面子”也不需要为了让对话继续下去而认可前面的输出。这就体现了多AI协作里的一个关键点协作不等于把两个会说话的模型放在一起聊天而是要给不同角色分配不同的目标函数。独立的验证角色就是要打破“生成者自说自话”的闭环。实际执行的提示词也很简单你是一名独立的软件验证工程师。你将收到一份需求清单、一张追溯表和一段代码。 请依据以下清单逐项检查不要修改代码只输出报告 1. 追溯表里每个需求是否都有可验证的实现位置 2. 实现代码是否满足需求中的验收标准 3. 测试用例是否真实覆盖了需求而不是用同一个函数的结果自证 4. 是否存在需求清单之外的多余代码如果有标为SUSPECT。 输出格式每条检查项一行标记PASS、FAIL或SUSPECT并给出依据。这里要特别说明一个容易踩的坑所谓独立验证不是“换个更强的模型再跑一遍”而是换一套验证目标和验证方法。就算用同一个模型做验证角色只要它的任务定义和生成阶段完全隔离验证效果也会明显好过“自己写完再自己看看”。3.4 给中小团队的最小落地组合三件套就够如果你现在没有余力搞完整的工程化改造我建议只保留三样东西带编号的需求清单、追溯表回传协议、独立的验证清单。这三件套已经能覆盖住绝大部分“AI爱说废话”的问题。不需要上文档管理系统不需要做工具鉴定不需要给每个Agent写开发计划。需求清单可以用Markdown或者最常见的表格文件维护追溯表就让Agent按固定格式生成验证清单就是一段固定Prompt。整个流程对现有开发方式的侵入非常小但它把航空规范中“可追溯”“独立验证”“出口准则”这三块核心机制都带进来了。我自己的实测感受是加上这套流程后AI生成代码的返工率明显下降花在流程上的时间大约增加两到三成但省下来的review和修bug时间远不止这些。尤其是当需求描述清晰、追溯表完整的时候人工只需要看验证Agent报出来的缺口报告而不是通读全部代码——这体验和以前完全不同。提示千万不要试图在一个Prompt里既要求Agent写代码又要求它严格自审还要它回传追溯表。角色目标混在一起Agent会优先保证“整体故事完整”而不是“验证严格”。隔离是整个方案能成立的前提。4. 这套玩法不能全盘照搬成本、边界与我的取舍4.1 航空级过程保证到底有多贵既然DO-178这么好用那是不是所有AI项目都应该严格照做我的回答是千万不要。因为这个标准真正的完整实施成本绝大多数互联网团队根本扛不住。按照正规适航认证流程一个项目要先写计划文档包括软件计划、验证计划、配置管理计划、质量保证计划然后每个开发阶段的产出物都要评审每次代码变更都要走配置控制流程验证结果要有记录工具链可能要做工具鉴定整个过程中还要应付各种形式的审计检查。有航空软件从业背景的人做过粗略统计这类项目里非开发活动经常占掉七成以上的工时。这个节奏放在一个迭代周期按周计算的AI产品上等流程走完竞品都已经更新三个版本了。所以我不建议把“40年前的规范”理解成一套可以直接套用的管理表单。它的价值是思想不是格式。如果因为流程太重导致团队根本用不起来这套标准反而不会救到AI只会变成另一个挂在墙上的好看合规文件。4.2 给AI功能分安全等级别一股脑上最高标准航空业真正聪明的地方是它在实施任何严格流程之前先做了一次分级。不是所有软件都需要Level A的验证强度只有“失效会导致灾难性后果”的软件才需要。这个思路放在AI开发里同样成立。我建议每个团队在引入这套流程之前先给自己的AI功能做一次运行时风险评估回答一个问题如果这个AI输出错得离谱最坏会造成什么后果根据答案给它定一个验证等级。验证等级适用场景建议措施Level A直接影响资金、生产安全、核心数据的关键路径完整需求追溯 独立验证Agent 人工审批门禁Level B影响业务但可以由人工快速纠正追溯表 独立验证抽查 关键字段校验Level C内部辅助、草稿生成、非面向用户的结果只要求追溯表完整验证Agent抽查Level D一次性试验脚本、个人探索性任务不设流程直接人工目检这个分级表不需要做得很复杂关键是让团队形成一种意识严格流程是资源要花在影响最大的地方。我的做法是所有面向生产环境、涉及用户资金和数据变动的AI生成代码一律走最高等级验证而内部草稿、原型代码、一次性脚本只保留最轻量的检查。这样团队既能感受到流程带来的安全感又不至于被流程拖垮。4.3 我实际保留和砍掉的部分聊一点个人取舍。在我自己的项目里从DO-178里保留了四样东西需求编号化的可追溯、追溯表作为出口准则、独立验证角色、验证失败后的回退机制。砍掉的包括正式化的计划文档、工具鉴定、全量配置审计、繁琐的评审签字流程。保留的原因很简单这四样东西直接对应“AI爱说废话”的四个缺口——没有锚点、没有准则、没有独立判断、没有失败处理。砍掉的原因也很直接这些活动维护成本高而且对LLM生成过程的针对性不强。一个40年前的标准能用到现在不是因为它的每条操作步骤都值得抄而是因为它把“责任可追踪”这件事讲透了。这里分享一个冷门但好用的经验把追溯表直接当作Agent的“本轮工作协议”每次生成前用脚本自动检查矩阵完整性。矩阵里只要有缺失立刻打回重做。很多AI编程Agent刚接入这个规则时会频繁尝试用“已在前面实现”这种模糊说法蒙混过关但当脚本反馈三次之后它就会学会老老实实列出所有需求编号。流程的前几次执行通常是最痛苦的但那恰恰是模型在适应新约束的过程。5. 从可靠AI到自主容错这次“旧瓶装新酒”真正的启示5.1 Agent系统比单次模型调用更接近一架飞机如果只看“AI生成代码”这个场景你可能觉得引入追溯表已经够了。但Karpathy讨论的其实比这更大——他真正关心的是LLM智能体Agent成为系统中继之后如何保证整个系统可靠。这也正是很多AI工程实践讨论中反复出现的一个命题“LLM智能体自主容错控制构建可靠AI系统的工程实践”。单次模型调用的错误最坏情况也就是一个输出错了。但一个多步Agent系统完全不一样它有状态有外部工具调用有内部决策链某个环节的失败会向后续步骤传播。Agent可能在第一步拿到了一个错误结果第二步基于这个错误结果做了判断第三步调用了一个危险的写操作第四步还对外输出了一份看似完整的报告。这个链条和飞机上某个传感器失效后故障沿信号链传播的机制本质上是非常相似的。航空规范给Agent工程化带来的不是一堆流程表单而是一种系统级的容错思维不假设组件永远正确而是假设每个环节都可能产生“自信的错误”然后设计检测、隔离、恢复三个动作。检测是发现错误隔离是防止错误扩散恢复是让系统回到一个已知可靠的状态。5.2 给Agent加一张“适航检查单”我在多Agent协作项目里把这种容错思维落实成了三层机制。第一层是检测。每个Agent在高风险操作之前必须输出一段机器可校验的目标声明比如“本次操作打算写入哪张表、修改哪些记录、影响哪些订单”。然后由一个校验脚本或者验证Agent检查这个声明是否符合预期。如果Agent连自己要干什么都说不清楚那就不会放行。第二层是隔离。涉及外部副作用的关键变更生成Agent和审批Agent必须严格分离。生成Agent负责提出方案审批Agent负责按追溯表核对方案。审批通过前写操作不会执行。这样就不会出现“一个Agent自己写代码、自己批准上线、出了问题自己粉饰”的单点失控。第三层是恢复。当Agent运行过程中验证不通过时不是让它原地重试八次而是让它回到上一个已确认的决策点重新从那里开始并生成一份异常记录。这个设计借鉴的是航空系统中“降级到已知安全状态”的思路。正常运行时它不会多说一句话一旦出错它能明确告诉你回到了哪个检查点哪个需求没有被验证。这三层机制实现起来都不复杂用普通的工程代码就能搞定不需要任何AI专用框架。真正难的是在心里建立那条纪律AI的输出永远先验证、再相信。很多系统在事故发生前都觉得这是多余的直到某一次“自信的错误”悄悄溜进生产环境才意识到检查单的重要性。5.3 这次翻旧账翻出的其实是“软件3.0的工程化”回到Karpathy的“software is changing”这个判断。软件1.0时代人写代码人可以靠自己的逻辑保证局部正确软件2.0时代我们训练权重用数据拟合保证统计正确到了软件3.0时代LLM生成代码输出在统计分布上很合理但事实层面没有任何保证。这个变化被很多人理解成“编程能力平民化”但Karpathy看到的是另一面生成物不可全信那可信产品如何建立40年前的航空规范之所以在这个节骨眼上被重新翻出来恰恰是因为它在“由不可全信的组件构成可信系统”这件事上积累了整个人类工程史上最长周期的验证经验。飞机上每一个部件都不是完美的传感器会漂移执行器会抖通信链路会丢包但整个系统最终可以被认证、被信任。航空界靠的不是让单个组件永远不犯错而是建立起一套以目标、追溯、独立性、容错为核心的过程保证体系。我们今天面对LLM时其实站在同一个起点上。与其追着“下一个模型是不是更少幻觉”这种你控制不了的问题不如把注意力转向工程护栏需求有没有编号验证有没有独立错误有没有阻断恢复有没有路径。这四件事做扎实了AI的“爱说废话”不一定完全消失但它不再能一路畅通地走进生产环境这就是航空规范真正的价值。最后说点我自己的体会。用过一段时间这套流程之后我最大的变化不是Agent生成的代码变得“完美”了而是我敢把它写进生产代码了。以前让AI写一串逻辑心里总得留一个“回头仔细看一遍”的疙瘩现在只要有追溯表、有独立验证记录Review时只看缺口报告就行心理负担小很多。还有一个很实用的技巧每周把验证不通过的需求编号整理成一份清单你会发现AI犯的错高度集中在某几类需求描述不清的条目上——这比任何模型调优都更能提升产出质量。Karpathy的新玩法说白了就是一句话AI爱说废话不是模型的原罪是我们没给它一套“不说废话也能被信任”的流程。旧规范确实不新但它把问题的位置指得很准。