标签

开源维护者在 AI 浪潮下的生存挑战

发布时间:2026-05-27 12:03来源:微信阅读:4

Cobra[1] 目前积压了 243 个未决 issue 和 118 个待处理的拉取请求,而 Afero[2] 也有 114 个 issue 及 55 个 PR 悬而未决。Cobra 作为底层支撑,服务于 kubectl、GitHub CLI、Hugo[3] 等成千上万的工具。当你执行 kubectl get pods 或 gh pr list 时,背后都是 Cobra 在解析指令。Afero 则深深嵌入 Hugo、Cobra 本身以及无数其他项目中。若在 Cobra 上草率合并代码,可能摧毁整个 Kubernetes 工具链;若对 Afero 的审查出现疏漏,则可能引发文件系统漏洞,并悄无声息地蔓延至所有下游依赖。Cobra 的诞生源于 Hugo 当时急需特定的 CLI 用户体验,而市面上尚无合适库可用。部分 PR 已等待数年之久。Afero 的 BasePathFs 中存在一个已报告的安全漏洞,自 2025 年 6 月至今仍未解决。从数学角度看,这种维护模式难以为继。这是开源界众所周知的痛点(参见相关 XKCD[4]):贡献量的增速远超维护者人数的增长,且随着项目复杂度和影响力的提升,审查单个贡献所需的时间也在不断拉长。虽然有些项目能吸引到志愿联合维护者,但这又引发了新难题:缺乏明确负责人,导致众人只挑自己关心的部分下手,其余部分无人问津。Cobra 项目刻意保持缓慢的迭代节奏——因其依赖者众多,不可随意合并——故每次变更都需更彻底的审查,绝非草率了事。我还有许多其他项目处于维护与被遗弃的灰色地带。我将其描述为“围绕最关键路径进行优化维护”,但这种区分对我而言的意义,远不及对那些八个月前提交修复却石沉大海的人来得重要。

这并非我个人的困境。GitHub 上托管着超过 4.2 亿个仓库。我有幸成为安全开源基金 [5] 的首批入选者之一,这是一笔真正带来改变的实质性投资。然而,即便该基金扩展多届,其覆盖的项目也仅约 200 个。OpenSSF[6] 每周扫描一百万个关键项目,Tidelift[7] 也会向维护者支付报酬。但将所有这些努力相加,覆盖的项目数量也不过数千。这项工作固然意义重大,但相对于实际面临问题的庞大表面积而言,不过是九牛一毛。

我一直在几个仓库中尝试 AI 工具——在依赖较少、试错空间较大的 fileflow 和 pathologize 项目上试用 Jules;同时在依赖较多但架构模块化的 Afero 上运行 GitHub Copilot,以便在不触及关键路径(即其他项目所依赖部分)的前提下扩展新后端。

我部署了 Jules,眼看新 PR 邮件纷至沓来,前景似乎一片大好。随后我便登船出海。航行期间,Jules 仍在持续工作,每天生成更多拉取请求,因为最初的那些我尚未合并。待我归家,两个项目的 PR 总数已突破 120 个。我专门腾出一个上午审查它们,却发现大致可分为五组不同的变更,每组都在数周内被每日重复提交。PR 本身并无错误,Jules 确实发现了真实问题。但没有一个是完全正确的,每个在合并前都需要调整方向。经指引修正后,Jules 的整体表现看似充满希望。但截至目前,这次实验反而增加了维护负担:我必须逐一确认那 120 个 PR 均为重复项,方能将其关闭。这个本应助我清理积压的工具,反倒加剧了积压。此外,Jules 是以我的名义而非其自身名义提交这些 PR 的——这本身就引发了归属权与问责制的难题。从仓库视角看,我是这些改动的作者,但我未写一行代码。若某个补丁引入 bug 或漏洞,提交历史将指向我。大多数贡献者政策在设计时并未考量此种情形,标准的 CLA 也无法区分人类编写的代码与人类指令下由 AI 生成的代码。

目前看来,Jules 似乎不记得自己 prior 的工作,也无能力检查已有的 PR。它扫描仓库,发现问题,发起 PR,然后停止。若你不合并,下次它仍会发现同样问题并再次发起 PR。它无从知晓你已知晓此问题且因故未合并:或许你不同意修复方案,或许优先级较低,或许你正身在船上、数周内无法处理。这些上下文对工具而言是不可见的。Jules 发现了一处真实漏洞——文件操作中的 TOCTOU bug 确属一类真实的安全隐患——它做了正确的事,将其标记出来。一次足矣。

对于机械性工作——如标记问题、更新依赖、起草模板回复——这些工具确实有用。但 Jules 和 Copilot 无法告诉我,那 55 个 Afero PR 中究竟哪一个真正该进入项目。此类判断需要了解代码库的过往与未来,而不仅仅是其当前状态。

Go 团队近期展开了一场漫长的讨论,议题是否接受 AI 撰写的贡献,Russ Cox 的那番话便出自于此。

Rob Pike 率先表态,立场鲜明:“这是一条 slippery slope(滑坡谬误)。务必小心第一步。我建议直接说不行。”Alan Donovan 则指出了一个令人不安的现实:“我怀疑我们现在收到的 CL 中,有相当一部分已包含 LLM 生成的代码片段,无论作者承认与否。”换言之,木已成舟。

Russ Cox 的核心观点是:“我们能做的最重要的事,就是维持既有的代码审核与质量流程。即便代码部分或全部借助 AI 工具完成,也必须达到同等标准。”他还强调:“使用 AI 工具不会减轻你的责任。”

这些立场个个合情合理。但它们共享一个前提,而正是这个前提暴露了困境的核心:它们假设总有人在审查代码。Go 之所以有底气说“维持同样标准”,是因为它有谷歌资助的全职贡献者、专门的审核人员,以及打磨了十多年的审查文化。Rob 之所以能说“直接拒绝就行”,是因为 Go 拥有足够人手为真正重要的事情开绿灯。

Afero 不具备这样的条件。大多数开源项目也没有。当 Rob Pike 拒绝一个 PR 时,Go 项目照常运转;当我拒绝一个 PR 时,它便只是被晾在一旁。这是两种性质截然不同的“拒绝”。

简言之,这是一个光谱,具体落在何处取决于你实际在做什么选择。实践中,维护者面对的是五种选项:

在此列表上每往下走一步,通常都是以严谨性换取速度,以信任换取吞吐量。但对于大多数项目——至少是我负责的许多项目——其实还存在第六个选项,它不在列表之上:无论由人类还是 AI 编写,均无人审查。

我决定寻找答案。盯着 Afero 项目上那 55 个敞开的 PR 太久,我已深知犹豫不决本身就是一种怠慢。

AI 工具会让我更投入,从而得以专注于真正需要我决策的环节吗?还是会让人感觉连接更弱——人的因素进一步减少?我不知道让 AI 而非人来审查 PR 是何种感受,也不知道当双方的投入都打了折扣后,责任又如何维系。这正是实验的目的所在。

Russ 在那个讨论串里还说了另一句话,令我反复回味:“最重要的是保持思考。这些工具极易让人大脑停转,但只要小心避开这个陷阱,就能做出好作品。”这正是我试图把握的分寸:让 AI 处理工作量,继续对判断负责。

不存在一套同时适用于 Go 和 Afero 的通用策略,本也不该有。

受保护的分支仍受保护。只是我已不确定这究竟还意味着什么。

你是否遇到过这种情况?我特别想听听那些尝试过 AI 审查代码的维护者的经历——哪些做法经住了考验,哪些又行不通。

1. Golang 安全陷阱 - 从 Grafana Labs 的两个案例说起

1. Golang 安全陷阱 - 从 Grafana Labs 的两个案例说起

2. Golang 演变

2. Golang 演变

3. Go Protobuf:不透明 API

3. Go Protobuf:不透明 API

4. Golang 简单技巧消减 80% 内存占用

4. Golang 简单技巧消减 80% 内存占用

5. 探索 Goja: 一个 Golang JavaScript 运行时

5. 探索 Goja: 一个 Golang JavaScript 运行时