大多数工程师在适应工具,而少数人会在不满中重写工具。
OpenAI Codex 技术负责人 Michael Bolin 就是典型的后者。从 Google Calendar 到 Facebook 的 Buck 构建系统,再到虚拟文件系统 Eden,以及如今 OpenAI 的 Codex——这位工程师的职业轨迹,几乎串起了过去十多年软件工程基础设施的关键演进。
在最近一期 The Developing Dev 播客中,主持人 Ryan 与 Michael Bolin 展开了一场横跨 20 年工程实践的深度对话。他回顾了自己从"写 JavaScript 的工程师"到主导开发工具体系的转变,也坦诚讲述了其中的判断失误、能力边界与成长代价。更重要的是,他试图回答一个当下所有工程师都在面对的问题:在 AI 正在重塑开发方式的时代,哪些能力依然值得坚持,哪些又必须被重新理解。
在他看来,真正拉开差距的,从来不是写代码的速度,而是你选择解决什么问题,以及你如何定义"更好的系统"。
以下是本次访谈的核心内容整理。
很多工程突破,源于对"现状的不满"和快速动手验证
Ryan:我研究过你的网站,发现几乎所有内容都有很多可挖掘的信息。其中有个项目当初倾注了你的很多心血,但现在所有链接都失效了——Chickenfoot 究竟是什么?
Michael:那是我的硕士毕业设计项目,是个 Firefox 扩展,也是当时极少数基于 JavaScript 为 Firefox 开发的毕业设计。它嵌在 Firefox 侧边栏上,是个小型编程工具,核心理念是实现 Web 编程。
用户调用"enter"、"click"等函数,传递字符串参数,系统自动定位输入框。比如输入"click search",即可执行点击操作。主要工作量是构建底层启发式算法:输入"enter first name"时,识别关键词,定位最近的文本框,再通过 JS 转为输入内容。
现在回头看,我们当时做的很多工作,跟当前 AI 编程助手的原理其实很相似——只不过现在真正实现了自然语言处理,而不用再依靠当初的 JS 替代方案。
Ryan:所以它的作用就是解析前端界面,通过交互界面将用户指令转化为相应操作。
Michael:没错。这套方案在 Craigslist 上效果特别好——毕竟那也是最简单的网站之一。我有个朋友真就用这款工具自动处理任务,甚至靠这种效率优势赚到了真金白银。
工程师的影响力,最终取决于是否解决"公司真正关心的问题"
Ryan:你刚进入行业就加入了谷歌,并带着巨大热情参与到谷歌日历项目。是什么吸引你加入?
Michael:九十年代我接触互联网时,得在一大堆搜索引擎之间来回切换。2000 年 3 月室友告诉我:"有款新搜索引擎看着不错。"它当时还挂在斯坦福大学的域名下。
谷歌搜索确实更胜一筹。仔细研究后发现,它跟其他搜索引擎的界面天壤之别——雅虎界面杂乱不堪,而谷歌当时就刻意追求极简设计。后来身边开始有人去谷歌工作,我心想:他们招聘的都是一帮顶尖人才。
我真的很希望能跟那些人共事,他们确实非常非常了解 Web。相比之下,当时的微软就根本不够了解,并且宣布叫停 IE 项目。我当时觉得这可是通往 Web 的门户,微软却打算拆掉它。而谷歌显然更具 Web 前瞻性,再加上项目的工程质量和巨大影响,最终让谷歌成为我毕业时最向往的去处。
Ryan:当时谷歌的文化氛围怎么样?记得你提到过,谷歌在产品和基础设施两条业务线之间存在分歧。
Michael:很多公司发展到一定规模后,创始团队最早擅长、也最成功的那块业务,往往会被长期"偏爱"。
在谷歌,信息检索和底层基础设施是支撑公司成长的核心能力,也自然在内部拥有更高地位。我当初被谷歌吸引,很大程度上是因为他们推出了 Gmail 这类偏"面向用户体验"的产品。但在公司内部,它们的地位始终无法与搜索这样的核心业务相比。
我当时参与的 Google Calendar 主要面向消费级市场,虽然也有一定的企业销售场景,但从业务角度看并不是营收核心。某种程度上,我们更像是在做一个"服务支持型"的产品团队,而不是直接创造收入的那一类业务。
Ryan:你最终还是离开了谷歌。是什么促使你选择离开?
Michael:我在谷歌工作了四年。让我离开的关键因素是个人规划。工作四年后手里有闲钱,选择更多。更重要的是,我发现自己有个坏习惯:总喜欢在那些对我个人很重要、但对谷歌未必重要的项目上倾注全部精力。
后来我又转去做 Google Tasks,属于日历下的一个小功能模块,用户量相较日历小了两个量级,但我还是充满热情。同样让我着迷的还有 JS 基础设施和 Closure 工具套件。我甚至还专门为 Closure 写了本书,干劲十足。但从职业发展角度看,这确实不是最明智的选择。
我当时就想:我明明也在处理高质量的工程问题,但获得认可的怎么永远是别人?可能真的是选择永远大于努力吧。所以我意识到或许该换条路径,要么专心搞自己热衷的事业,要么投身于公司最看重的方向。
AI 编程时代,80%-90%的代码可由模型生成,但关键部分仍需人类把控
Ryan:后来你加入了 Facebook。我了解到你已经是 JS 领域的专家,而首个重大项目是为 Android 代码库构建工具链。讲讲幕后故事?
Michael:当时公司内部方向非常明确:Facebook 要做手机。虽然此前有过失败的尝试,但这次氛围明显不同,大家普遍觉得"这次是真的要做成"。计划是与 HTC 合作,对 Android 进行定制化改造。
对刚加入的我来说,这件事非常令人兴奋。我之前做过不少 Java 相关工作,这个项目也让我有机会更多接触 Java。
当时公司内部还有个"Face Web"方向,希望把 HTML5 和 Facebook 的 Web 体验直接搬到手机上。但很快发现这条路行不通。与此同时,移动端将成为决定公司成败的关键战场,这一点变得越来越清晰。
有个朋友跟我说:"我知道你特别喜欢 JS,但现在最好多拿点精力钻研 Java 或者 Objective-C,否则就往产品经理转。"现在回头看,这是非常重要、也非常及时的建议。
我实在不喜欢 Objective-C,还是 Java 好。就这样加入了项目。时间非常紧迫,跟其他项目不一样,这次有硬性截止日期——需要按时把成果提交给 HTC,保证给他们留够时间在 3 月 1 日左右把代码烧录到手机里。
整个过程就是一场狂奔。初始 Android 代码库是从谷歌雇用的外包商那直接拿过来的。Facebook 也不想亲自开发原生应用,就付钱找人代工。结果应用上线后,对方甩手不管,把代码直接一塞。谷歌本该把那堆破玩意直接丢了,却一直留在手里——我们收到的就是这么堆玩意,而对迭代速度的要求还相当高。
相信做过长期 Web 开发的朋友早就习惯了先编辑再刷新的流程。但 Android 的构建系统就特别粗糙。Ant 之类的构建工具根本没法模块化,只能硬生生拆分成四、五个模块。每次开发都痛苦不堪。
我当时就想:必须重组这套构建系统。我也用 Java 干过不少活,人家不至于这么慢,不至于在迭代构建的时候这么卡顿。Facebook 有黑客松文化,所以我决定组织一轮黑客松,直接搞套新的构建系统。照着谷歌构建系统的风格,争取干脆利落搞定。
当时公司里还有套叫 FB Build 的构建系统,本身是谷歌构建系统的一种"山寨版",用 Python 写的,只支持 C 语言。我当时就想,要么把这东西修好,要么躺平摆烂……或者直接辞职算了。毕竟修旧项目最烦了。
至少会申请换个项目,或者找到让自己快乐的方式,这样才能每天开心来上班。我来上班就是想写代码、把事情做好,尽可能发挥自己的能力。
说来也挺有意思。后来回想起来,我还是挺佩服当时周围的人——几乎所有人都告诉我,我正在做的这件事是个很糟糕的主意。基本上所有人都不看好,除了一个人。
当时我担任资深 Android 工程师,没有人真正阻止我。大家会表达反对,但不会直接说"不行"。这一点和我在谷歌时的感受不太一样——在谷歌,很多事情是会被明确否决的。
所以我就顺着这个方向继续做下去了。很快,我们就做出了一个明显更好的版本——性能大概提升了一倍左右。结果一出来,大家的态度也随之转变。很多人开始意识到:"好吧,这个方向确实更好,那我们就按这个来吧。"
Ryan:大厂有种惯性,就是没人想去碰那些堆积如山的不利因素。其他工程师都注意到了同样的问题,但只要觉得还有办法解决,就懒得另起新项目。况且谷歌那边还有竞争产品,这边可能根本赢不了。是什么让你坚信自己的项目能击败对手?
Michael:主要有几点。首先,我也做过其他 Java 项目,所以觉得原本的构建工具不应该这么慢。以软件工程师的经验来看,这种底层实现不应该如此低效。
大部分反对意见都基于僵化逻辑:如果偏离标准方案,我们将失去标准支持。万一下周标准性能提升了 100 倍,新方案却没法继承,又该怎么办?仔细想想这很可笑,毕竟 Facebook 的工程师们也搞过自研 PHP 虚拟机和语言,明明曾经拥抱过创新。不知道为什么这次就例外了。
当时整个移动端项目都在摸着石头过河,我心里充满焦虑,还有严苛的时间压力。高层似乎要把这个项目当作科学实验来搞,但我们面临着硬性截止期限。这样真能最大程度利用好我们的时间吗?好在最终还是成功了。
另外我当时刻意淡化了项目的基础设施性质,只强调"要为 Android 打造构建系统",可千万不敢暴露太多业务扩张野心。我没打算动别人的项目蛋糕,因为这种事肯定会引发更多摩擦。所以在设计时,就考虑到让它支持更多团队,而且从不强推。
直到大概一年之后,iOS 团队主动过来问"我们的构建系统太烂了,能合作一起搞 Buck 吗?"我当场回应:"当然可以,来吧朋友。"
Ryan:你刚入职时缺乏公信力,毕竟新人都要经历这个过程。为了推进项目,得争取更多人支持。而所有人都说别这么干,你得说服他们。你是凭什么在自己缺少信誉的条件下推动这种改变的?
Michael:我其实是取了个巧。当时有个同事 John Perlow,也是资深 Android 工程师且同样是谷歌出身。他说:"没错,你就该这么干,趁还没人反对赶紧行动。"他还提到,"要是搞定了我就支持你。"有了这样一位早期支持者加上高产程序员,我的开发周期还真就变快了。
他算是最早给予我肯定的人之一,帮了我很大的忙。但我也得承认自己当时犯过大错。我刚从谷歌跳槽过来的时候,还以为这里聚集的都是贝尔实验室的精英,纯纯的顶尖人才。结果到了 Facebook 我才发现,这帮人不就是大学毕业生吗……他们懂什么技术?
但随着犯错,我逐渐对他们心生敬意。比如我在讲谷歌那边是怎么做事时,他们常讲"我们根本不在乎"——而且多数情况下,他们还真是对的。在某些地方行之有效的办法,在其他地方可未必同样奏效。
相比写代码,提出正确问题的能力正在变得更重要
Ryan:你们开发的工具性能比同类方案高出好几倍。这种技术直觉是怎么形成的?做了哪些关键设计?
Michael:最关键的一点,是我当时真的坐下来,把谷歌那套工具的实现逻辑从头到尾梳理了一遍:它到底在做什么?问题出在哪里?
很快发现它有个很大的问题:只要有任何改动,就会从头开始全部重新构建。这是速度慢的根本原因,尤其是在增量构建场景下,性能非常差。
于是我开始往更底层去拆:到底哪些东西依赖哪些?哪些步骤其实不需要重复执行?这里面确实有一些复杂点,比如 Android 的资源处理,本身就比较特殊,逻辑也很复杂。正因为复杂,系统一开始采取了"简单粗暴"的策略:一旦有变化,就全部清空、重来一遍。
但当我真正深入进去后发现,其实是可以优化的——如果某些输入没有发生变化,那对应步骤的结果完全可以缓存下来,不需要重复执行。一旦引入这种缓存机制,整体速度就明显提升了。
另外还有一个问题是模块化。当时系统基本只支持四个模块,一旦有人想新增模块,就需要写大概 200 行 XML 的 ANT 构建脚本,而且这些配置几乎没人真正理解。结果就是,没有人愿意去做模块拆分——因为一旦做了,你就得负责维护那一堆复杂配置。
而 Buck 做的一件很重要的事情,就是把"新增模块"这件事变得非常简单。于是,大家开始更愿意拆分模块,模块数量也随之增加。模块变多之后,构建就可以更细粒度地增量执行,整体效率也进一步提升。
所以从本质上来说,这不仅仅是一次技术优化,更是一种思维方式的改变。
长期来看,编程智能体的执行将更多迁移到云端,而非本地
Ryan:解决了 Android 构建问题后,你又转向了 IDE 相关的工作。当时看到了什么问题,促使你想深入去做?
Michael:做完 Buck 之后,我短暂去做了一段时间 iOS Messenger 的开发。当时想:Android 已经做过了,不如拓展一下,试试别的方向。虽然说实话,我一直都不太喜欢 iOS 开发——后来也还是没喜欢上。
很多人可能不知道,Objective-C 早期有一套机制叫 ARC(自动引用计数)。现在基本由编译器自动处理,但更早的时候开发者需要手动管理引用计数。每创建一个对象、每增加一次引用,都要自己写代码维护。这种代码现在很多人都没见过,但当时通过收购接手的 iOS Messenger 代码非常老,还是用这种方式写的,维护起来非常痛苦。
如果是现在,也许可以用 Codex 之类的工具帮忙清理这些代码,但在当时,我们只能硬着头皮改。再加上 Xcode 本身的使用体验也让我不太适应,比如头文件和实现文件分离这种设计,我一直都不太喜欢。
从更宏观的角度看,无论是 Android 还是 iOS,Facebook 的应用规模始终是最大的。我们基本把所有功能都塞进一个 App 里统一发布。这和 Google 的策略不一样——他们会拆成 Drive、Sheets 等多个应用,而且因为自己掌控平台,可以在系统里预装一整套应用。
这种差异带来的结果是:Facebook 总是比其他公司更早撞上移动开发工具的规模瓶颈。这对开发来说很痛苦,但从开发工具的角度看也很有意思——我们被迫去解决一些别人还没遇到的问题,而且这些问题不是"研究项目",而是直接影响业务的。
Xcode 的问题也是类似。我们当时和 Apple 沟通过,反馈是:"Xcode 在我们这个规模下已经不太能支撑了。"但他们的回应是:"那你们的项目就不该这么大,应该拆小一点。"在这种情况下,自研工具就变得有一定合理性了。
当时我的思路也很直接:IDE 本质上在做什么?无非是和编译器以及语言服务打交道。那么我们完全可以在这之上做一层更好用的"外壳"。
而且当时公司在版本控制上开始从 Git 转向 Mercurial,我意识到主流 IDE 不太可能原生支持这些定制需求。再加上我们已经在使用 Buck 作为构建系统,这些都是高度定制化的内部工具,Xcode 不可能很好地支持这些"Facebook 特有"的工作流。所以,投入精力去打造一套更适合我们的开发体验,是一件说得通的事情。
相比之下,我在 Android 这边就没有类似的动力,因为 IntelliJ 本身已经做得很好,而且我们也已经找到了一套可以支撑大规模开发的使用方式。但在 iOS 上,Xcode 在当时确实更难用一些。
Ryan:当时一方面是 Xcode 不行;另一方面公司里其实还有另一套 IDE,是另一个团队在做的,对吧?我记得是个 Web IDE?
Michael:对,是个 Web IDE(笑)。我不是在笑这个方向本身,这个方向其实没问题。问题在于,它是基于一个已经被放弃的 Google 开源项目构建的,而且这个项目是用 GWT(Google Web Toolkit)写的——你用 Java 写代码,然后自动生成 JavaScript。
我当时尝试过在他们的基础上继续做,也试图先建立一些"信用",甚至还帮他们优化了一些构建速度。
但后来又回到了熟悉的判断方式:看迭代速度、看技术栈本身。然后我就发现——这个项目建立在一个已经被废弃的开源项目上,而且还用的是 GWT 这种技术。而与此同时,我们公司已经是 React 的发源地了。
那问题就来了:我们为什么不让开发工具构建在我们自己最擅长、也最认可的技术栈之上?
我当时的第一反应是:你们这条路其实选错了。于是我又做了一件和之前做 Buck 很像的事——自己起了一个新项目。不过策略是一样的:不正面冲突,不试图"接管一切"。我只是说:"我在这边做一个新的编辑器,但我们只先聚焦 iOS 场景。"
Ryan:你是在刻意避免摩擦。但当时那个 Web IDE 已经有很多用户了吧?
Michael:对,确实有很多用户。所以我当时的做法不是去否定他们的工作,而是找到一个他们没覆盖到的场景,先做出成果,再逐步证明价值。这和 Buck 的策略如出一辙:先在小范围内跑通,用数据说话,而不是靠争论赢。
后来这个 iOS 编辑器项目发展成了 Nuclide,再后来和 Buck 一起,成为 Facebook 内部开发工具的核心组成部分。而那个 Web IDE 项目,因为技术栈的局限,最终没能持续下去。
回头看,这两次经历有个共同点:我都是在"所有人都说别这么干"的情况下,找到了一个足够小的切入点,快速验证,再逐步扩大影响。这不是固执,而是对"迭代速度"和"技术债务"的敏感。
Ryan:现在你在 OpenAI 负责 Codex。从 Buck、Nuclide 到 Codex,你觉得过去这些经历如何塑造了你对 AI 编程工具的看法?
Michael:有个很直接的联系。当年做 Chickenfoot 时,我们想用自然语言控制网页操作,但受限于技术,只能用 JS 做启发式匹配。现在 Codex 真正实现了当年设想的自然语言编程,但核心挑战没变:怎么让工具理解用户的真实意图,而不是只是执行字面指令。
另一个教训来自 Buck。当时我们花了很多精力优化缓存和增量构建,本质上是在解决"重复计算"的问题。现在的 AI 编程助手也面临类似挑战:模型生成代码很快,但怎么避免重复生成、怎么利用已有的上下文和反馈,这些系统层面的优化依然关键。
还有一点,可能更重要。当年在 Facebook,我们总是比别人更早遇到规模问题,被迫自研工具。现在 AI 编程工具也在经历类似的阶段——用户规模、代码库规模、场景复杂度都在快速增长,但市面上的通用工具还没准备好。这给了我们一个窗口期,去定义"下一代开发工具"应该长什么样。
AI 看似什么都会,但理解系统更底层怎么工作的能力现阶段仍然重要
Ryan:你提到 80%-90% 的代码可以由模型生成。那工程师的核心价值会转移到哪里?
热门跟贴