Uber 工程团队发布博客,介绍内部系统 AutoClean:它接入公司的功能开关管理平台,找出已经可以安全下线的开关,自动生成删除代码的 diff,测试通过后交给工程师审批。过去几年,这套系统清理了超过 16000 个 feature flag、100 多万行代码,目前在 Uber 多个 monorepo 里持续运行。
文章署名的是 Uber 高级软件工程师 Daniel Ramos、Diego Marcilio 和软件工程师 Nikhil Parasaram。
删代码为什么难
Uber 的新功能靠功能开关灰度上线,平台上同时挂着数千个开关。放量完成后,判断分支、辅助函数、调用点、配置和测试往往留在原处。删一个开关,要在这几处同时动刀,还得保证线上行为一点不变。
博客提到一个新的成本:死代码不只是让人读着累,AI 编程助手在解析代码库时也会为这些分支多花时间和 token。
三段流水线
**第一段,改写。**智能体拿到代码库访问权限,通过 MCP 调用 Uber 自研并开源的代码变换引擎 PolyglotPiranha,由后者处理布尔化简和条件消除。作者的理由很直接:布尔化简一旦出错,“can silently change program behavior”,会悄无声息地改掉程序行为,所以尽量交给确定性工具。
**第二段,修 CI。**简单失败由确定性修复器处理,比如移除没用的默认值、清 lint 报错;复杂的交给智能体,例如判断某个测试该删还是该改。每个修复器的权限被限死,测试修复器只能动测试文件。循环到 CI 通过或尝试次数用完为止。
**第三段,验证。**CI 通过后先跑静态检查,再交给名为 CodeCourt 的验证层,由多个专门的审查智能体并行检查。博客列出的规则包括:
- 只删不加,不引入新代码;
- 可观察行为保持不变;
- 只处理指定开关,不顺手删掉相关的其他开关;
- 不留下智能体推理过程的注释或痕迹。
任何一项没过,diff 直接作废,不会送到人手里。作者称,几个专注的子智能体,效果好过让一个智能体从头到尾审一整个 diff。
从 Piranha 到智能体
AutoClean 的底子是 Uber 几年前开源的 Piranha,那个工具当初就是为删除过期开关写的,靠规则匹配做静态改写。后来的 PolyglotPiranha 把规则引擎扩展到多种语言。这一次的变化在外围:规则引擎仍然负责最容易出错的布尔逻辑,智能体接手规则写不全的部分,比如修测试、补调用点,再由另一批智能体互相把关。
博客坦白了几种失败模式:智能体会为了让测试通过去改生产代码,会删掉本该保留行为的测试,会过早收工留下半截清理;指令一多,它还会漏掉其中某条约束。这些语义问题,CI 都发现不了,限制修复器权限、增加 CodeCourt,都是冲着它们去的。
文章没有给出成功率、平均耗时或被作废 diff 的比例,示例代码是 Go,其他语言的覆盖情况也没有展开。按作者的描述,人工评审者现在只需回答一个问题:这个开关该不该删。机械层面的正确性,已经在前面三段里被拦过一遍。
参考来源:Uber Engineering 官方博客、CocoLoop、PolyglotPiranha GitHub 项目页;清理数量以 Uber 博客披露的累计口径为准。