AI自主提交128个PR重构83万行代码的工程方法论 前几天看到 GitHub 那波AI 自己给自己提交了128个PR、改了83万行代码的消息时我第一反应是又来了个噱头。但把三周时间线、PR列表和自动化验证的细节翻了一遍之后我发现真正值得聊的其实不是AI 重写自己这个标题而是它背后那一整套工程方法论。AI 生成代码这件事大家都见过可AI 自主发现代码库问题、自己拆任务、自己提交PR、自己跑验证、自己根据失败反馈修正这套闭环才是真正把 AI 从补代码的工具推到了维护大型仓库的协作者的位置上。这篇文章我想拆的就是这件事适合正在做 AI 落地方案、或者被AI 写代码越来越多但不敢让它碰核心仓库困扰的人看我会从事件拆解讲到复刻路径尽量给你能直接用的东西。1. 这波重写项目到底干了件什么事1.1 一次AI 给自己当包工头的大规模代码重构先把这个事件的内容还原清楚。GitHub 做了一件听起来很循环的事情让 AI 智能体去改动 GitHub 自己的工程仓库。这个仓库不是某个玩具 Demo而是支撑 GitHub 日常开发和技术栈演进的核心代码库之一。AI 在约三周内提交了 128 个 PR累计改动 83 万行代码把一批历史遗留问题清理掉了比如过时 API 替换、重复代码整理、不合规的调用方式收敛以及一些已经被替代但仍然残留在代码里的旧逻辑。这个事件最值得注意的点不是AI 写了多少行而是AI 以完全符合开源协作规范的方式完成了代码治理。它没有直接把一大坨代码塞进主分支而是拆成 128 个彼此独立的 PR 提交。每个 PR 都有明确的改动意图和可验证的边界该跑测试跑测试该走 review 走 review完全不像我们想象中AI 一次性生成大量代码然后人不知道该怎么检查的样子。我在看到这些信息时想的第一个问题是这和我们平时用 Copilot 补全一个函数、让 ChatGPT 写一段工具脚本到底有什么区别区别在于角色反转。以前 AI 是回答问题的助手你说一个需求它给你一段代码而这次 AI 是仓库的治理者它自己要判断哪些代码该改、怎么改、改成什么样才算完成并且要为一个长期维护的大型代码库负责。这个模式一旦跑通意味着过去那种人类定义需求、AI做具体实现的单向协作关系变成了人类设定治理目标和安全边界、AI自动执行和验证、人类做最终决策的双向协作关系。1.2 128个PR和83万行代码这几个数字意味着什么接下来我从工程直觉出发聊聊这几个数字的分量。三周时间是 21 天。128 个 PR 均摊下来每天大约要完成 6 个 PR。如果每个 PR 是一个独立的重构单元那么一天就要完成发现问题、想出方案、改完代码、通过本机验证、提交 PR、等待 CI 反馈这一整套流程六次。对人力团队来说这是一个很难维持的节奏因为人脑在多个上下文之间切换是有成本的你上午还在改 A 模块的 API 替换下午突然切到 B 模块的依赖整理光找回状态就要半小时。AI 没有这个上下文切换成本每个 PR 都可以是全新的起点。83 万行代码更是很夸张的量级。很多中小型项目的代码总量也就是几十万行而这里只是被改动的量就已经这么大了。能支撑这么大改动的底层逻辑是AI 的每个 PR 改动都足够小且聚焦。比如一个 PR 可能只改 300 行关键是它能够连续稳定地制造这么多小而精准的 PR而不是制造一个 80 万行的超级 PR。这也反过来证明AI 在执行层面的稳定性已经达到了一个挺高的水平。我用一张表来呈现这个量级到底意味着什么维度传统人工重构团队这次 AI 重构事件周期三周三周PR 数量通常 10~30 个128 个总代码改动量视团队规模而定83 万行每天 PR 数1~2 个已经是高密度约 6 个上下文切换成本高容易疲劳几乎为零单 PR 聚焦程度取决于排期常常被迫合并改动天然聚焦单一意图当然数字大不代表质量一定好。如果背后没有一套严格的自动化验证和人工复核机制83 万行改动可能不是财富而是灾难。这也是我后面几章花重笔墨写验证链路的原因没有那套机制128 个 PR 就是 128 个定时炸弹。2. 为什么这个案例值得单独拆一遍2.1 从AI 写代码到AI 维护大型仓库的分水岭我一直觉得AI 编程这件事有几个完全不同的难度层级。第一层是补全比如 IDE 里一个函数写了一半AI 帮你补完第二层是生成你给出比较明确的需求描述AI 给你一段可以运行的代码第三层是改造在一个既有的大仓库里你已经知道哪里需要改让 AI 做局部修改并保证不破坏其他功能。而这次 GitHub 的事件实际上已经把脚踩到了第四层的门槛上让 AI 自主发现哪里需要改自主决定怎么改自主验证最后交付给人类做裁决。第四层和前几层最本质的区别不在模型能力而在工程架构。你让 AI 补一个函数它只需要理解你写的上文但让 AI 维护一个大型仓库它必须理解仓库的整体结构、构建方式、测试约定、代码风格、甚至仓库里那些约定俗成但没写进文档的黑话。这些信息没法靠模型参数全部记住必须通过工具去实时检索和验证。也就是说第四层的核心是给 AI 搭了一套手和眼睛它能看到代码库的全貌能执行命令能跑测试能通过 CI 拿到反馈然后基于反馈调整自己的行动。这个分水岭还有个副作用它改变了 code review 的形态。以前 review 一个 PR人类 reviewer 会从 diff 角度去检查你改得对不对。但当改动量上升到 83 万行逐行 diff review 就不再可能。reviewer 必须把自己的工作重心转移到看意图、看边界、看验证上这个 PR 为什么要改这些地方有没有改到不该碰的模块CI 和自动化检查是不是覆盖了这次改动的关键风险如果这三件事能管住逐行看代码反而没那么重要了。2.2 先厘清重写的范围改动面、风险面、为什么没翻车看到83 万行代码这种描述有些人会脑补成AI 把整个仓库推倒重来了这完全不是一回事。这次事件里的重写本质上是结构性的治理与重构不是一个全新的项目从零生成。它更像我家里请了个很靠谱的整理师把多年堆积的杂物分门别类打包而不是直接把房子推了重建。我梳理了一下这类重写通常会覆盖的改动类型替换已废弃或被取代的 API 调用让代码基线与新版本依赖对齐。删除不可达代码、死分支、被注释掉且早已无用的逻辑。将重复逻辑统一收敛到公共函数或工具模块。调整不符合仓库既有风格约定的写法让新代码和老代码保持一致。这四种改动的共同特征是它们的行为对用户来说应当是透明的。你替换了一个 API原来的功能不能变你收敛了重复逻辑输出的结果不能变你删除了死代码程序行为更不能变。正因为目标是行为保持不变自动化验证才能发挥最大作用你可以通过跑测试来证明改前和改后行为一致。真正的推倒重写反而很难用自动化验证兜底因为行为预期本身就是新的根本没有测试可以证明你写对了。所以这次重写没有翻车不是因为 AI 大模型突然厉害到不会出错了而是因为工程上给 AI 选了一个非常适合发挥的赛道行为保持型重构。这个赛道里验证系统能接住 AI 的大部分错误剩下的通过小步 PR 和人工复核接住。这是我在拆解这个案例时最想先讲清楚的一件事很多人容易把AI 自主改代码神话化却忽略了背后的任务选型和安全设计。3. 让 AI 自主改代码的触发条件与初始架构3.1 从单点任务到批量重构能力边界是怎样一步步撑大的要做到AI 自己给自己提交 PR首先得给 AI 搭一个能干活的环境。单纯把代码库丢给模型去阅读是不够的语言模型本质上是一个概率生成器它不知道仓库实际编译是否通过也不知道某个改动在另一个文件里会不会造成隐性破坏。所以工程上要给 AI 配上几类关键能力第一是检索与观察能力。AI 需要能够查看文件树、阅读文件内容、搜索某个符号在哪些地方被引用。这一步通常通过工具调用完成比如由代码索引服务提供支持或者直接封装一批命令供 AI 调用。没有这个能力AI 就等于是盲人摸象只能靠训练数据里那些泛泛的编程知识瞎猜。第二是修改能力。AI 需要能实际改文件、新建文件、删除文件。这件事听起来简单但工程上要处理很多细节并发修改时怎么避免与其他 PR 冲突、文件权限怎么处理、格式化怎么统一。这里的关键不是能不能写文件而是怎么保证写文件的过程可控且可回顾。第三是验证能力。AI 要能运行构建、跑单元测试、执行静态分析。这块是整个闭环里最硬的一关也是决定 AI 是否值得信任的基础。如果 AI 改完代码之后只能靠自我感觉良好来确认正确性那它和碰运气没什么区别。只有当测试通过、静态检查干净、构建成功AI 才真正拿到了我的改动是对的的证据。第四是交付能力。AI 要能基于改动内容创建一个标准的 PR包括规范的 commit message、PR 描述、相关标签和评论。这个能力决定了一个 AI 生成的改动是否能无缝融入人类已有的开发流程。如果还要人来帮它创建 PR那效率就折半了。这四个能力合在一起才是这次事件里 AI 能连续稳定产出 128 个 PR 的基础设施。实际上GitHub 自己也做过很多类似的前置工作比如在编码助手里逐步引入多文件编辑、终端命令执行、代码库问答等能力它们本质上都是在给 AI 补齐这四块拼图只是一步步从单点辅助走到了批量自主。3.2 工程框架要点拆任务、定边界、设护栏站在一个想落地同类方案的人的角度我会把这个案例抽象成三个工程关键词拆任务、定边界、设护栏。先说拆任务。AI 没有全局规划能力之前千万不要让它一次性处理一大片代码。拆任务的核心思路是把一个大的治理目标拆成多个互相独立、改动面可控的小任务。假设目标是把仓库里所有旧日志框架的调用换成新框架如果直接让 AI 一次性全改任何一个小失误都会波及整个仓库但拆成按模块、按目录、按依赖关系分批进行的多个 PR 后任何一个 PR 出问题都可以被单独回滚不影响其他进度。128 个 PR 不是单纯的数量展示它本身就是一种风险管理策略。再看定边界。这个边界既包含文件系统边界也包含行为边界。文件系统边界是限制 AI 只能动某个目录或某类后缀的文件避免它跑题去改掉一些不应该碰的配置文件行为边界则是告诉 AI 你只能做行为保持型重构不能顺手加新功能也不能改变已有函数的入参和返回语义。给边界这件事听起来像限制实际上是在帮 AI 提高成功率因为它把搜索空间缩小了AI 犯错的可能性自然就下来了。最后是设护栏。护栏指的是那些不管 AI 如何操作都一定会生效的硬性检查。它可能是一条分支保护规则要求必须通过所有 CI 检查才能合并也可能是一套自动生成的变更摘要让维护者一眼看出这个 PR 动了哪些文件还可能是一些代码量级的阈值告警比如一个 PR 改动超过 1000 行就自动要求人工介入。护栏的意义在于即便 AI 在某个环节产生幻觉护栏也能拦住最坏的结果让人有机会喊停。这套拆任务、定边界、设护栏的组合让我想到一个挺贴切的类比你把一个实习生安排到团队里最怕的不是他能力不够而是他不知道哪些事可以做、哪些事不能做、做错了要怎么发现。你给他一份细化到每小时的活儿再划清楚工作范围再配上代码审核人他就能在安全范围内把事做出来。AI 在这次事件里扮演的就是那个足够听话、足够快、足够稳定的实习生而工程架构就是那个靠谱的导师。4. 128个PR背后的自动化验证与人工复核4.1 验证链路设计单测、集成、回归三层过滤任何声称AI 改了几十万行代码没问题的说法如果背后没有自动化验证体系都是不可信的。我在复盘这次事件时把整套验证链路按三层来理解这是我觉得所有想复刻这个模式的人都应该重点花时间的地方。第一层是单测也就是针对函数、方法、最小逻辑单元的行为验证。对于重构类改动单测的价值在于锁死那些被替换、被平移、被收敛的函数的局部行为。比如 AI 把某个公共函数里的重复分支抽成了单独函数单测会验证原函数输入输出是否完全一致。这一层是三层中最容易跑快的一层但覆盖范围也是最局部的。第二层是集成测试重点验证模块与模块之间的协作是否正常。有时候单测全绿但一个模块修改后另一个依赖它的模块的对接逻辑就对不上了。集成测试就是把 API 级别的协作重新测一遍捕捉那些局部正确但整体错误的问题。对于一次大规模重构来说这一层往往是最容易暴露问题的地方因为改动涉及面广模块边界的隐性假设极容易被打破。第三层是回归测试也就是在更大范围内跑既有测试用例确认旧功能没有被新改动破坏。严格来说回归不是一个独立的测试层级而是一种测试策略。在许多大仓库里全量回归跑完需要很长时间所以工程上往往只挑与本次改动相关的关键路径来跑同时在合并后再跑完整预案。但不管怎么裁剪改动之后旧行为仍然正确这个命题必须被验证到。三层验证之外还有一类非功能性检查同样值得纳入体系静态分析、类型检查、格式校验、依赖漏洞扫描。它们不验证功能正确性但能保证代码库的卫生状况不至于因为大量 AI 改动而急剧恶化。在这次事件中这类检查扮演的角色更像是入场券如果这些基础项不过关PR 根本不会进入人工 review 队列。4.2 人工复核的重点不是逐行看代码而是看意图和边界很多人听到AI 提交了 128 个 PR之后第一反应是那 review 的人岂不是累死了。但实际上的 review 策略完全可以不一样。既然每个 PR 都是一个聚焦单一意图的小改动人工 review 的重点就应该放在四个问题上而不是去逐行比对代码。第一个问题是意图是否合理。看到一个 PR 的标题和描述后reviewer 要判断它想做的事情是不是我们当前确实需要做的事情比如用新 API 替换旧 API这个意图本身合理吗如果旧 API 还有大量调用链替换顺序有没有讲究这个问题很多工具都无法自动回答必须靠人对仓库演进方向的理解来判断。第二个问题是改动范围是否超界。AI 定了边界不代表它每次都能完美遵守。reviewer 要在 diff 统计层面快速扫一遍确认 AI 没有夹带私货。比如一个本应只改模块 A 的 PR如果突然改到了模块 B 的公共配置这就属于超界要打回去重做。第三个问题是关键文件是否有明显错误。这里的关键文件一般指接口定义、公共工具函数、核心数据结构。这些文件哪怕是一个小错误都可能引发连锁反应所以值得 reviewer 花时间细读。第四个问题是验证是否充分。reviewer 要检查 CI 状态、测试覆盖范围、以及 AI 有没有在 PR 描述里解释它是怎么验证自己的改动的。如果 AI 无法说明验证方式那么再漂亮的 diff 也不能合并。我自己的经验是人工复核和自动化验证之间不是替代关系而是流水线关系。自动化验证解决的是对不对的问题人工复核解决的是该不该的问题。把这两件事分开人类的工作量才能从逐行检查中解放出来真正去做只有人才能做的判断。5. 实测拆解从一个 PR 的诞生到合并全过程5.1 一个代表性 PR 的完整生命周期如果只从最终成果看整个过程好像稀松平常但把一个 PR 从诞生到合并的完整生命周期拉出来看就会发现其中每一步都有明确的工程决策。这里我以移除一段已废弃的兼容逻辑为典型场景模拟一下过程中可能的真实状态。最开始AI 会在代码库扫描或任务清单中发现某段兼容逻辑已经没有任何调用方了。它需要先通过代码搜索确认引用为零然后将任务描述写下来这个描述要包含三样东西修改目标、修改原因、验证计划。比如移除 legacy_utils 模块中的 fallback 兼容函数当前仓库已无任何调用方验证方式是跑全量单测并通过 lint 检查。接下来 AI 生成代码改动。它会基于搜索与检索结果实际修改文件可能是删除整个文件也可能是删除文件中的部分函数。改动完成后AI 在本地运行验证命令。这里有一个经常被忽略的细节AI 并不是等所有命令都跑完再提交而是会在验证失败时自动分析日志、调整代码、重新运行形成一个小版本的内循环直到验证通过。然后 AI 把改动推送到远端创建 PR。PR 描述会按照设定好的模板生成包括改动摘要、验证结果、相关 issue 链接。CI 机器人在远端继续跑更全量的检查包括编译、测试、代码扫描。如果 CI 失败AI 会收到失败反馈它会基于失败信息继续修改并追加一个修复 commit 到原 PR而不是重新开一个 PR。这部分非常重要因为一个干净的 PR 历史会让后续人工 review 轻松很多。最后是人工 review。在这个阶段人类维护者并不需要重跑 AI 已经跑过的验证而是先看 PR 描述和变更范围再抽查关键文件。如果所有检查通过PR 被合并随后经过部署管道进入生产环境并在监控指标上确认没有异常。到这一步一个 AI 驱动的 PR 才算真正走完了全生命周期。5.2 过程中出现过的失败、回滚与重试策略这次事件并不是一路顺风。只要真实地去跑这种规模的重构失败几乎是必然的关键是如何设计失败处理策略。我从工程经验出发总结了在类似流程里最常见的几类失败模式以及对应的应对方式。第一类是验证失败。新版代码可能在某处依赖了不兼容的 API或者某个边界测试没有通过。这类失败通常不需要关闭 PR只需要让 AI 读取失败日志定位到具体文件做针对性修复再重新触发验证。对 AI 来说这份失败日志就是最宝贵的训练信号它比任何提示词都更能指导 AI 往正确的方向修正。第二类是范围失控。AI 在修改过程中可能跑偏比如本来只改 A 文件结果连带把 B 文件的一个不相关格式也改了。这种 PR 不一定会被自动检查拦下来但会被人工 review 拦下来。应对方式就是打回并指示 AI 撤销附带改动只保留原目标。第三类是合并冲突。因为多个 PR 可能并行推进某些文件被多个 PR 同时修改就产生了冲突。处理冲突既可以通过 rebase 解决也可以直接让 AI 基于最新主分支重新生成改动。但这里有个经验如果冲突发生频率太高说明任务拆得不够干净应该调整后续 PR 的生成顺序尽量让同一时间窗口内的 PR 落在不同文件区域。还有一类更隐蔽的失败是测试本身不够强。如果仓库的测试覆盖很低或者测试断言写得太宽松AI 改完代码后看起来全绿实际上行为已经变了。这种情况最危险因为它不会暴露在任何一层验证中只能依赖人工的领域知识去提前识别。所以在启动大规模 AI 重写前先补测试覆盖率是性价比最高的准备工作没有之一。回滚策略方面我认为最重要的原则是宁可频繁小回滚不愿大回滚。每个 PR 独立合并、独立部署就可以做到小时级别的问题发现与回滚而不是等到 128 个 PR 全部合并后才去检查整体质量。这种小步快跑的模式不仅适合人类团队也特别适合 AI 驱动的开发因为它能把 AI 犯错的影响面限制到最小。6. 你要是想复刻这套流程应该怎么做6.1 最小可复现版本单人 一个仓库 一周看再多的案例拆解都不如自己动手跑一遍。我建议想深入理解这个模式的人不要一开始就想着搞一个多大规模的项目而是先做一个最小可复现版本。条件可以简化到一个有点历史负担的中小型仓库、一台能跑构建的机器、一个有工具调用能力的编程智能体、以及你本人作为唯一的 reviewer。目标可以这样设置在一周之内让 AI 提交 5 到 10 个 PR每个 PR 只做一种行为保持型重构比如统一字符串拼接方式、删除某个废弃函数、收敛重复的错误处理逻辑。第一大部分工作是搭好验证环境包括编译、单测、lint 这类绝不能省的基础检查。如果这些检查在你人肉改代码时都不能给你信心那也别指望能兜住 AI 的错。然后是写任务说明书。这个环节很多人会省略但我觉得恰恰是决定成败的关键。任务说明书不需要那种A 项目你要变好的模糊描述而要足够具体要改哪个目录、动机是什么、验收标准是什么、允许触碰哪些文件、绝对禁止改哪些文件。说明书越具体AI 跑偏的概率越低。接下来就可以开跑了。让 AI 一次只处理一个任务处理完提交 PR 后你先以 reviewer 身份做一轮复核。前 3 个 PR 先不合并把它们当成校准样本观察 AI 的行为模式看它哪里容易错然后调整提示词或增加新的护栏比如禁止修改超过 200 行的文件PR 里如果出现与目标无关的文件必须列出。等 3 个 PR 行为稳定了再放开让它批量跑。这个过程通常一周足够但你的收获会比看一百篇案例文章都大。6.2 可以直接抄的自动化验证清单我在实际搭建这类流程时会固定一套验证清单在这里直接分享出来。你不需要完全照搬但可以参考它的检查维度再结合自己仓库的特点做增删构建/编译检查仓库能否在干净环境下成功编译。类型检查TypeScript、Java、Rust 等强类型语言必跑能拦下一大类低级错误。单元测试锁定最小逻辑单元的行为全量或按改动范围圈选。集成测试验证模块间协作不被破坏。静态分析检查未使用变量、不可达分支、明显的不良模式。格式检查统一代码风格避免 AI 生成大量格式噪音。变更范围检查改动文件数量、diff 行数是否超出预设阈值。改动清单摘要每个 PR 必须自动生成我改了哪些文件、为什么改的摘要。目标文件白名单AI 只能动约定的目录超出则自动警示。CI 强制合并门槛必须全绿才能合并不存在人工特批通道。这套清单的核心思路就是把AI 是否把事情做对的判断尽可能交给确定性的工具只在最后留少量决策空间给人。这样即使 AI 在某个细节上犯了错你也能在它进入主分支之前把它拦下来。6.3 三个容易翻车的坑把最小复刻跑完之后我建议你再看看这三个我踩过的坑能少走很多弯路。第一个坑是任务拆分过大。你可能会觉得既然 AI 这么能干为什么不直接让它一次改整个模块这个想法非常危险。任务越大AI 在做局部决策时就越容易丢掉全局约束它可能为了清理一个方法顺手改变了另一个方法的行为而且自己毫无察觉。我的经验是任务拆分到每个 PR 都能用一句话说清楚改了什么才够小。一句话说不清楚的任务一定要继续拆。第二个坑是测试覆盖不足。我前面说过测试是 AI 重构的安全网但这个安全网只有在覆盖足够时才有效。如果你的仓库本来就没什么测试AI 改了代码后看起来全绿那很可能是因为没有测试会变红。为了绕开这个坑我习惯在启动 AI 重写前先人工或半自动地把核心模块的测试补齐尤其要补那些用来锁行为的快照测试和边界用例。补测试本身花的时间会在后续的 AI 重构效率上几十倍地赚回来。第三个坑是过于信任模型的解释。AI 在 PR 描述里写本改动已在本地验证通过时它可能只是跑了一次不完整的命令甚至只是想象自己跑了。所以你不要只看它说什么要直接看 CI 的状态和测试报告。凡是不能由系统自动确认的证据都只能当成参考信息不能当作合并依据。这是我个人觉得最实用的一条经验在 AI 协作开发这件事上信任要靠系统和证据去建立而不是靠在对话框里多问几句。整套流程跑过一遍之后我的体会是AI 是否自主重写代码这件事最关键的变量往往不是模型本身而是工程系统允许它犯多大的错、又能多快地把错兜住。把任务拆小、把边界画清、把验证做重、把人类留在决策的关键节点上这样组合出来的 AI 开发流程才是真正值得长期投入的方向。