开源是为了谁?
Rich Hickey 说开源与你无关,但维护者与用户之间其实存在一种心照不宣的交换关系,其成本、收益与伦理后果值得重新讲清楚。
中文
复制
开源,至少在一定程度上,关乎的是你,这里的“你”指的是用户。
开源不是“开源与你无关”
换句话说:Rich Hickey 写《开源与你无关》的时候错了,而我厌倦了假装他不是。
当然,他并非完全错了,否则他那篇著名的文章一开始就不会引起那么大的共鸣。那些蛮横的用户,要求志愿者维护者免费、立刻满足他们个人的使用场景,确实应该被当成他们本就是的那种人人喊打的对象。同样,那些想从支撑自己基础设施的社区里白拿免费支持来压低成本的企业用户也是如此。那些靠这种成本外部化、从自己客户身上获利的人,也一样。
但“开源”(甚至“自由软件”)的交换并不是“我为你准备好了软件,请享用,你没资格抱怨”这么简单,维护者应当精确理解这种交换的成本与收益——以及其中的伦理含义。
眼下我们连这种交换存在都几乎没有说清楚,更别提它建立起了一种长期、微妙且心照不宣的维护者与用户之间的关系。
我们来把这件事说清楚。
关于元伦理的一点题外话
当我们谈论“义务”与“权利”、“应该”与“必须”时,我们是在构建一套伦理体系。这样一套体系的目的,是形成社会预期与社会后果。我告诉你,你因为没遵守我某条随意的建议而在超验意义上邪恶,这没什么用。但我是在暗示,我认为你的行为应当承担后果。我同时也在暗示,后果很可能已经存在了,只是还没有被写下来而已。 所以,像这样一篇文章,我说我们应该以某种方式看待自己的社会义务,这只是一场更广泛的社会讨论的开端。我认为应当有某种后果,所以我是在指向那种可能性。究竟是什么后果? 眼下我还不确定。我们一起来想清楚。
做开源的时候,我们到底在做什么?
Hickey 以及这些年来他众多的追随者,在他那篇影响深远的文章之后,都断言“开源”的流程是这样的:
- 维护者做出一个东西,作为礼物提供给用户。维护者可能“热爱与团队一起工作”。
- 维护者可能“为我们所做的工作感到自豪”。
用户接受这份礼物,并从中获取效用。
- (用户必须对此心怀感激。)
极少数用户会反过来为这个项目做出贡献。
- (维护者可能对此心怀感激。)
他多次含糊地提到自己公司的具体业务,那家公司做的事情与他那些项目有某种模糊的关联,以此赚钱1。但这些业务一律被描述为面向“客户”的——而“客户”不过是前述用户中极小的一部分(“不到 1%”),小到几乎可以算作一个完全不同的群体。
在一篇关于讨厌的用户索要他们无权得到的东西的文章里,匆匆掠过这个流程,你可能会点头称是,因为这听起来大体上说得通。送礼物是好事。我也喜欢和优秀的团队一起工作,也为自己做的事情感到自豪。
但仔细审视,它在逻辑上就开始站不住脚了。如果你有咨询客户,你所有的钱都来自那里,那你为什么还要(像他反复强调的那样)“为社区做[事情]”?一开始发布这些代码到底是为了什么?你可以在很多不同的场合热爱与团队一起工作、为自己所做的工作感到自豪;如果这就是你从中得到的全部,那何必把这一大群自以为是又令人讨厌的人牵扯进来?你图什么?
如果我们漏掉了“维护者为什么要做这件事”这样根本性的问题,那这个故事或许还漏掉了其他一些重要的部分。
你为什么要做这件事?
发布和维护开源软件的动机有很多种。它们往往很微妙,常常相互重叠,而且很少被明确说出来。维护者不是一个整体,也不是每个人都出于相似的理由做这件事。不过,让我们先梳理几个可能促使某人想要贡献的理由。
声誉
你选择开源发布软件,动机之一可能是宣传。最常见的形式是自我推广:如果你在某个开源项目里是显眼的、有分量的贡献者,那么在这个项目所属的领域找工作自然会更容易。
如果你经营一家咨询公司——Rich Hickey 在他那篇著名的吐槽文发表时正是如此——那么这种声誉货币就会转化为对你服务的宣传。它是你团队能力的一次实际展示。
这项收益的交换方式,最接近人们常拿来类比开源的那种传统“礼物经济”。你把代码交给用户,代码本身有价值;用户回赠你声誉,形式是他们的关注、他们的敬意,如果他们成为客户或雇主,甚至还包括他们的钱。
影响力
基础设施是开源中最受欢迎的类型,这有充分的理由。程序员在解决某个问题时,常常被僵化的架构选择困住,无法按自己更愿意的方式去解决。大型基础设施投入很难在规划流程中证明其合理性,因为收益难以论证。有时收益是高度个人化的:对于同样有效的不同方案,不同工程师的审美偏好各不相同。
如果你能开发出自己偏好的那类方案并开源发布,你就能影响其他人如何解决这类问题。对个人而言,这样的影响力位置让你在换雇主时拥有可迁移的专业能力。你知道自己开发的工具怎么用,所以用起来可以又快又有效,而且可以随着时间推移把它塑造成你持续满意的样子。
如果你是雇主,并且能让其他所有人都用上你的开源项目2,这可以同时降低你的招聘成本和培训成本。潜在员工可以读代码,看出它写得好,进而想在一家能产出这种好代码的公司工作。他们也可以在入职之前就读代码、熟悉它,这意味着你手上随时有一批已经了解你内部系统如何运作的开发者。
这种利益交换更像“软实力”,而非礼物经济。你把代码交给用户,这固然有价值,但用户回报给你的是左右其技术议程的能力。你既能影响他们最初的方向,也能在后续维护中持续左右他们的行为。
提升
作为工程师,你可能想提升自己的技能。写专有且商业化的东西会从两方面妨碍这一点。
第一,你会想构建自己技能范围内已有的东西,这样才能吸引商业兴趣,并真正具备竞争力。在更大的团队中,出于类似的原因,你会希望自己能够立刻上手。但你仍然需要学习新东西的途径。
第二,你会想以某种隐秘的方式构建,这样你产出的价值就被自己占有,而不是释放给社区。这意味着你将被切断与外部专家反馈的联系。
作为组织,你可能想以类似方式培养员工的技能。
这种利益交换是代码换知识。你发布代码或改动,作为回报,你期望用户提供好的 bug 报告,并促使其中至少一部分人成为共同开发者。
外包
作为工程师,你一个人能做的有限。也许你想对基础设施有一定影响力,所以想自己写,但你也想要一个公共的地方来存放你的基础设施,这样你就可以为了满足自己的需求而 做出 改动,但你知道即使你离开,也会有别人 维护 这个改动,让它在底层平台、硬件等多年甚至几十年的变化中持续可用。
这种公共维护工作可以在所有感兴趣的参与者之间分担;如果一千家公司都需要同一个工具,哪怕只有几十家能共享它,这也会大幅减轻他们 自己 的负担,更不用说其他人的了。
这种收益交换之所以更复杂,是因为主要维护者与同样贡献代码的外围社区成员之间并不对称。主要维护者交换的其实是一个命名空间——一个供人们贡献、协调和发布变更的中心场所——而不是代码本身。他们有点像做市商,其他所有贡献者则在这个类似市场的结构里用代码换代码。
实践中,这种动机催生了一个博弈论问题:当维护工作跌破某个临界阈值时,会引发一场足够大的危机,迫使至少部分搭便车的利益相关者开始做出贡献。
但归根结底,这为所有相关方节省了大量维护成本,而那些一开始就不搭便车、更积极的志愿者还能获得上面提到的其他全部好处。
关于会计科目表的简短插叙
大多数公司把开源维护工作当作进行中项目的简单间接费用来记账。有时算 CapEx,有时算 OpEx,但本质上就是“谁碰巧在维护这个东西,就归到它所属的某个随机产品名下”。这种记账方式制造了扭曲的激励,因为它不承认上述任何收益。在这样的财务体制下,持续的健康维护变成了 ZIRP,因为一旦资源收紧,这种表面上的奢侈就会被砍掉。
开源创造的附带收益应当被正确承认。它不该只是被埋进工资或 IT 之类的科目里。如果它帮你招到更好的工程师,一部分支出就该计入招聘成本。如果它切实提升了你在客户群体中的声誉,一部分就该计入商誉。如果它让你的产品出现在身为客户的开发者面前,就该计入市场营销。最重要的是,如果某个开源项目的维护实际上在帮你维护全公司范围的平台,它就不该被塞给某个碰巧最先采用它的小团队。3
这些成本究竟该如何分摊、如何向不同部门交叉计费,很大程度上取决于你的组织和具体的会计科目表。但“无所谓,反正它只是软件产品的一部分”或者“大概算 DevRel 吧,毕竟 SDK 在里面”这种态度,保证会让你的开源组织在下一次现金紧缩时被连根拔起,连同所有那些附带收益一起消失。
本不该成为好处的东西
这些类别可以被明确地做成理性的取舍,即便在实践中它们往往是隐晦而微妙的。它们是交易:维护者得到一些东西,用户也得到一些东西。
但作为维护者,你得到的东西并不都应该被拿来为自己谋利。被赋予信任以承担某项责任,这不是交易。
“哎呀,全是 root shell”
开源代码就是代码。在我们这个沙箱机制烂到令人发指的时代,安装别人写的代码就等于把系统的控制权交给了他,哪怕这种控制多少有些间接。
有一条不成文的规矩:如果我做了一个开源库,你用了它,那它大概不该藏着一个后门,让我拿到你银行账户的凭据。用户和维护者之间存在信任关系,而这里就出现了维护者的第一项义务:维护者有义务不利用用户的计算机为自己谋利。
这条规矩看起来显而易见、直截了当。你甚至可能觉得我把它称作“不成文”并不公平,因为它其实白纸黑字写在了好几个地方:比如 npm 可接受内容政策里就明明白白写着:
不可接受内容的几个例子: …
- 包含恶意计算机代码的内容,例如计算机病毒、 计算机蠕虫、rootkit、后门或间谍软件。这包括出于 研究目的提交的内容。为协助安全研究而明确设计并 记录在案的工具是可以接受的,但把 npm registry 当作部署 或分发渠道的 exploit 和恶意软件不行。
我想大家都同意,一个偷走你的银行凭据、发给我去买一台超酷水上摩托的脚本,肯定算得上“恶意软件”,所以它显然是被禁止的。
但这里也存在一大片灰色地带。npm 明确允许“关于如何付费、捐赠以及以其他方式支持包开发的信息”,紧接着又明确禁止“在运行时、安装时或软件开发生命周期的其他阶段展示广告的包,比如通过 npm scripts 展示。”4 这些灰色地带的界线是怎么划的?“npm 在判断什么内容可接受时,将继续运用自己的判断。”
但话说回来……这是 npm 明令禁止的,而不是“开源”本身使然。我完全可以在自己的网站上把一段会向用户展示各种广告的代码当作“礼物”送出去。这条政策的具体结构并不罕见,但也和其他同类网站并不完全一致。比如 PyPI就明确禁止“加密货币挖矿”,而 NPM 没有。加密货币挖矿算“不开源”吗?这里涉及大量主观判断,判断的是你送给用户的这些“礼物”里允许包含什么。
不过跑题了。
我想说的是,围绕这个概念制定政策并不清晰,边缘地带存在许多小分歧,但有一个非常强的共识:用户在这里交出了信任,而这不是一笔交易。这笔交易不是“你给用户一些代码,用户给你无限算力和他们所有金融账户的访问权”。用户是凭你的声誉,让自己暴露在你的代码面前。
这就产生了一项义务:你不能用这段代码做任何坏事,无论是故意的还是疏忽所致。
安全更新不过是戴了顶滑稽帽子的命令与控制
以上说的都只是代码的初次下载,Rich Hickey 也是这么描述的,仿佛你只是从某个网页上抓了段代码,放进桌面上一个你喜欢的文件夹里。但今天的开源关系并不是这样运作的——如果它曾经是的话。
今天的运作方式是:你在自己的 pyproject.toml、package.json 或 Cargo.toml 里加了一个依赖,于是你的用户不单单暴露在你当初碰巧上传的东西面前,还暴露在碰巧持有你包索引凭据的人面前。
这就产生了一项义务:维持一种能够保护用户免受恶意更新侵害的运营安全态势。
路线图是别人的人生
用户托付给你的另一种信任,是相信你至少会对他们如何使用你的软件有那么一点在意。
理想情况下,用户的预期可以被清晰地划定边界。你承诺承担的持续维护工作,会被写进事先拟好的明确政策里——你究竟采取什么样的安全响应策略、当你不再有资源维护时会如何对外沟通,诸如此类。
但任何参与过项目、且项目成熟度并非处于最极端水平的人都知道,99% 的生态依赖的是一套松散的惯例,而非成文规定。我们默认维护者大体上还在,默认他们会用 issue tracker 来分诊用户 bug、用 GHSA 和 CVE 处理安全报告,默认他们在弃坑前会把项目标记为“archived”、也许再发最后一个版本,默认他们会维护一份 ChangeLog,至少简单说明一下发生了什么。
当明确的政策存在空白,或者压根没有政策时,用户会假定这些惯例仍然被遵守。这个假定是合理的,否则没人能 用得上 任何开源软件——除非先签一堆谁都没时间写的服务合同。
这些惯例中最强的一条是:一个仍在积极维护的程序,至少会大致 继续做它一直在做的事。用户一旦选择使用某个开源软件,光是使用这一事实本身,就让自己暴露在该软件变更和损坏的风险之下。在他们使用并投入的这段时间里,他们 没有 投入于:
- 创造 替代软件来满足自己的需求,
- 以其他软件能读取的格式 维护数据,或
- 学习如何使用 已有的替代软件。
当这些预期与实际不匹配时,事情就可能、也确实会变得很糟。
事情如何变糟
假设一位维护者做了一个开源画图程序,OpenPaint。
一位以独特的混合拼贴风格闻名的艺术家,从之前用的 ProprietaryPaint 换到这个新的 OpenPaint,来创作这些具有文化意义的艺术作品。然而,维护者觉得“混合”工具维护起来实在麻烦,于是在 OpenPaint 2 中把它移除了。
几个月后,画师所用的操作系统厂商发布了一次安全更新,把 OpenPaint 弄坏了——因为旧版 OpenPaint 一直在不知不觉中滥用某个平台 API。
维护者发布了新的 OpenPaint 2.0.1 来解决这个不兼容问题,但已经不再关心 1.x,所以懒得去更新那个版本。
这让画师陷入了两难。要么留在旧版操作系统上,把全部个人数据置于风险之中;要么升级到新系统,实际上等于断掉生计,或者被迫彻底改变自己的画风。
专有软件同样会把用户逼到类似的绝境(事实上,干这事的更多是专有软件)。但开源就能把这份考量上的全部义务一笔勾销吗?OpenPaint 团队至少应该说明这么做的理由,给画师留一条申诉的途径吧?5
“开源”唯一做到的,是让画师可以花一笔高得离谱的钱请一支新的维护团队去做一个 fork。这种事个人几乎扛不下来。
这就产生了一项义务:至少要考虑你的用户可能在多大程度上依赖你。
这是所有义务里最复杂的一条。显然,它不等于每个用户都有权要求维护者无限期地干活;但用户信任了维护者把作品公开时所做出的那些微妙的隐含承诺,也不该因此就什么都得不到。
这是一场微妙而持续的协商,我不认为我们对它该如何收场有清晰的道德直觉。但我们确实需要找到一种把它理清楚的办法。
它还引出了一个需要澄清的问题。
我们到底为什么做这件事,又是为谁而做?
人们做事通常不止一个理由。我们身处的经济环境要求人得赚钱,但我们大多更愿意靠做有用的事、做让别人开心的事来赚这笔钱。
所以,是的,我们做开源是出于私心:提升自己的声誉、磨练技能、扩大影响力、分担维护负担。这么做,我们就承担了一定程度的义务,不去辜负别人对我们的信任,哪怕这个义务的边界并不清晰。
但如果我们做这件事的时候,一点都不想服务这些用户,那这些动机很快就会显得空洞。如果用户每提一个请求,我们都回一句“我不欠你什么,你的意见一文不值”,那我们的声誉不会因此提升。如果我们无视社区的想法,那也谈不上对社区有什么影响力。
维护者和用户之间的很多互动,本不该那么剑拔弩张。这当然有一部分是用户的问题,他们应该把预期调整到合理的位置。
但话说回来:在这些互动恶化之前,维护者本可以做得更好,先去倾听。没有理由认为“开源用户”就该是一个格外有毒的群体。放在今天,这个群体基本上就是……有电脑的人。
就像那句老话。如果你遇到一个人对你态度恶劣,那是他的问题。但如果你走到哪里,遇到的每个人都对你充满敌意,都觉得你做错了什么,也许是时候往自己身上看看了。
如果所有开源用户都是理直气壮的混蛋,也许是时候找找结构性的问题了。
惊喜,又是 AI
叹气。6
用户讨厌垃圾内容。
我知道,亲爱的对 AI 持正面态度的读者,你的 AI 输出和别人不一样,你没有把不经思考的垃圾塞进代码里——尽管别人都在这么干,而且这是使用这些工具的必然终点。你不是在用 Claude“偷懒 vibe coding”,你做的是“负责任的 agentic engineering”,这不一样,因为你天生就不一样。
不过,还是容我多说一句。你的用户不知道这些。他们知道的是,自己喜欢的产品一旦引入垃圾内容,会变成什么样子。他们知道自己会开始泄露数据。开发者知道自己会因此在个人层面变得更不安全。他们知道自己可以预期更多的服务中断,也知道你的代码会不可避免地质量下滑。
换句话说,你的用户会认为这意味着你违背了最后那条义务:软件应当保持可用。
用户会要求你停下来,而且多半会很不客气。也许你,或者你团队里的相当一部分人,也想停下来;也许你并不同意他们的看法。但无论如何,你都需要一种方式,能把这场对话进行下去,又不至于立刻蔓延到每一个相邻的讨论区。用户需要在某个空间里感到自己是被欢迎的,这样他们才会在那个空间里讨论,而不是炸成上千个群聊和社交媒体帖子。
这篇文章的起因,是又一个知名开源社区里爆发了争论:一大群愤怒的用户涌进来,冲着开发者喊,要求他们停止接受 LLM 生成的代码。我不会给出任何链接,因为这场火已经不需要更多燃料了。但这类事件不止一例,模式也越来越眼熟。
在社交媒体上——通常是 BlueSky 或 Mastodon,有时是某个用户组论坛——用户得知了某项与 AI 沾边的政策。他们成群结队地涌向开发者论坛或邮件列表,大声要求项目对 AI 采取强硬立场7。这种压力是同时爆发的,却毫无协调;内容高度重复,来源极其多样,彼此常常自相矛盾,而且相当折磨人——尤其是当你是一个已经精疲力竭、还有别的事要做的维护者,而你自己可能压根就不喜欢 AI。
相信我,我懂。处理这种事可以非常难受。
不过,和 AI 引发的大多数问题一样,这其实并不是一个“AI”问题,而更像是一堆早就烧起来的垃圾,被“AI”浇上了汽油。在这里,网络暴民就是那些无处发声者的语言8。
如果用户已经怒了,那多半已经太晚了(但也许你可以为下一次做好准备)
某一天,突然之间,你收到一大堆用户的反馈,而他们用的都是不合适的渠道。可他们之前真的有合适的渠道可用吗?
你的项目有没有一个让人们聚在一起讨论的地方?一个能让你看懂的有序抱怨渠道?还是说你只有一个 GitHub Issues 页面——非技术用户根本不知道怎么用——外加一个开发者论坛,用户不熟悉那里的规矩,任何一群怒气冲冲的用户涌进来,都会被当成捣乱和不合时宜?
我不想从自己这座玻璃房子里往外扔石头。这些年,搭建这样一个地方越来越难。我自己其实也没有。
但我能不能有呢?IRC 在慢慢消亡,邮件列表不受欢迎,审核起来还越来越麻烦,论坛软件运维成本高、还得持续维护,Discord 则是一团令人困惑的乱麻——这一切的结果就是,每个社区都需要社区管理和论坛版主。也就是说,对我自己那些小型的单人项目而言,根本不可能有这样的基础设施,因为它需要专门再找一个人来维护;在有人自愿承担之前,这事就不现实。即便是我那些更大的项目,人手之单薄也会让你吃惊,我们绝对匀不出一个专职维护者去管这些,何况我们自己也在遭受 slopocalypse 的攻击。
开源社区的性质就是这样:大多数社区起步时小得根本不需要这种东西,然后一点点长大,直到某天突然变得大得离谱、昨天就该有这么一个地方,接着兴趣稍一消退,又突然变得太小。即便我们越来越需要它,搭建和维护社区基础设施依然是个难题。
即便如此,给用户——不是维护者——一个专门的地方,让他们彼此交流、形成一个真正的社区、并把反馈传达给开发者,正迅速成为一个成功社区的必要组成部分,而不再是锦上添花。
结语
尽管有时确实令人疲惫,但我们这些维护者都从开源中得到了某些东西,而诚实地面对用户——也面对自己——说清楚你究竟想从中得到什么,是件好事。要知道这杯果汁是否值得挤,我们必须既清楚果汁是什么,也清楚挤的代价是什么。
比喻意义上的“挤”,其中一部分就是一系列义务,而义务恰恰是定义得最模糊的东西。我们也应当尽量把这一点说清楚——既说清楚我们自认为签下的是什么,也说清楚我们愿意让用户以何种方式要我们为此负责。行为准则在这里是个起点,但仅仅是最最低限度的起点;“不要骚扰你的同事或用户”不是什么值得追求的优秀标准,那只是基本的礼貌。
我无法确切告诉你你的义务是什么,只能试着勾勒出我们一直以来心照不宣地共享的那套模糊道德直觉的大致轮廓。
划出这条线也不只是为了用户的好处。维护者已经感受到压力,已经感受到义务。我们厌恶那种被义务压着的感觉。这种厌恶有各种各样的原因,其中一个重要原因是:即便对我们自己来说,也说不清义务到哪里为止。甩出一句“我什么都没承诺,我不欠你们任何东西!”再加上几句脏话,确实解气,但并没有真正解决问题,因为我们显然并不真的相信界线就在那里,否则早就停在那里了。我们根本不会觉得有必要说这句话。
要弄清这条线究竟在哪里,将是一项规模极大的集体事业。开始这项事业的最佳时机是50年前。
但第二好的时机就是今天。
致谢
感谢我的赞助者们,他们支持我在这个博客上的写作。如果你喜欢这里读到的内容,想读更多,或者想支持我的各种开源事业,你可以[支持我的工作,成为