
一个 10 人小团队的开源项目,在 Google 自家的基准测试里拿了第一。一年后,大厂发布了一个"新项目"——229 个文件里 228 个和他们的一模一样,只是原来的三个名字,在 Git 历史里被换掉了。这件事把开源圈最古老的一条规矩,重新摆上了桌面。
引言
在开源世界,"别人用了我的代码"从来不丢人。恰恰相反,被人抄,说明你写得好。
真正让人不舒服的是另一种情况:代码被拿走了,名字却被擦了。
2026 年 9 月,这种事发生在了 Google 头上。法国初创公司 Minitap 公开指控 Google 新发布的移动自动化开源项目 Artemis,大量复用了自家开源项目 mobile-use 的代码,却在早期版本被发现后,通过一次强制推送把原作者的三个名字全部替换成了另一个人。
这事不只是"大厂欺负小团队"的戏码。它逼着每个写过开源代码、也用过别人开源代码的程序员,重新搞清楚三件事:开源协议到底宽在哪、严在哪;Git 历史能不能被抹掉;以及"用了别人代码"和"尊重别人劳动"之间,那条线到底画在哪。
一、事件复盘:从 AndroidWorld 第一,到 Google 仓库里的"自己人"
先把事实按时间捋清楚,全部来自 Minitap 官方博客、Reddit 原帖以及 36氪、CSDN 等公开报道。
前传:一个 10 人团队,在 Google 的考试里考了第一
Minitap 是一家来自法国的 AI 初创公司,团队只有 10 人。2025 年,他们开源了一个叫 mobile-use 的项目,作用是让 AI 智能体用自然语言去操控真实的安卓手机。
成绩相当亮眼:它在 Google DeepMind 维护的 AndroidWorld 基准测试上登顶,成为第一个在该基准拿到 100% 任务成功率的智能体框架——116 项任务、覆盖 20 款真实应用,全部跑通。作为参照,Google 自己的基线智能体 M3A 一开始只能完成 30.6%,人类操作者的成功率也不过 80%。
凭这个成绩,Minitap 拿到了 410 万美元种子轮融资。2026 年 2 月之后,团队把重心转向更强大的闭源版本,用在自家的自动化测试产品上。
转折:Google 发布 Artemis,打开代码后愣住了
2026 年 9 月,Google 发布了一个叫 Artemis 的开源项目,定位也是"安卓智能体与自动化平台"。
Minitap CEO Nicolas Dehandschoewercker 一开始没当回事,GitHub 上"又一个手机智能体"而已。直到他们真正打开代码——
"What the fuck? We wrote this."(这他妈不是我们写的吗?)
逐文件比对后,结果惊人:Artemis 总共 229 个文件,其中 228 个和 mobile-use 完全一致。证据不是一两处相似,而是一整条"指纹链":
- 连接安卓设备的
adb_tunnel.py实现完全相同; - 一个随手起的 Agent 名字叫 Hopper,连它的 Prompt 都和原项目一字不差;
- 一个让智能体停留在 WhatsApp 里的示例,里面 Alice、Bob、Charlie 这些人名、注释、清理步骤,全都对得上;
- 最绝的是一个历史 bug:某个辅助函数会先写结果文件、下次运行又去读自己刚生成的文件然后报错。这个 bug 在两套代码里原样复现,而 Artemis 后来还顺手把它修了。
最扎心的一刀:三个名字被换掉了
如果只是代码一样,Minitap 未必这么在意——代码本来就是开源的,欢迎你来用。
真正让他们心寒的是 Git 历史里的一个细节:
在 Artemis 较早版本的 pyproject.toml 里,作者列表曾经老老实实地写着 mobile-use 的三位原作者:
- Pierre-Louis Favreau
- Jean-Pierre Lo
- Nicolas Dehandschoewercker
但在后来的版本里,这三个名字被整体替换成了另一个人(一个名为 somew1nd、邮箱是某个 outlook 地址的账号)。而根据 Minitap 对提交记录的比对,那次提交里被改动的部分只有作者列表,其他代码几乎没动。这次替换,据 Minitap 称,发生在 2026 年 8 月的一次强制推送(force push)里。
更有意思的是,GitHub 自己都在那个旧提交旁边挂了一行黄底警告:这个提交不属于本仓库任何分支,可能来自外部 fork。换句话说,历史其实没被真正删干净。
回应:补了一句声明,但没解释为什么删
事件在 Reddit、Hacker News 发酵后,Google 很快在 Artemis 仓库的 License 区域加了一行说明:
This project includes source code developed by Minitap, Inc. (本项目包含由 Minitap 公司开发的源代码)
但截至目前,Google 没有单独发过公开声明解释此前的作者信息变更。Minitap 提出的诉求——加回 mobile-use 项目直链、完整恢复版权与署名、列出复用代码涉及的原始贡献者——以及社区为此提交的恢复署名 PR,也尚未被合并。
Minitap 方面认为,这句补充等于间接承认了代码来源,只是最初没有履行署名义务。而 CEO 那句被引用最多的话是:"我最失望的不是 Google 用了我们的代码,而是我们不得不去翻 Google 的 Git 历史,才能把自己团队的名字找回来。"
二、技术核心拆解:这事到底踩了哪几条线
把情绪剥掉,从技术和规则角度看,有四个关键点。
1. 代码复用本身不违法——违法的是"没留名字"
mobile-use 用的是 Apache License 2.0。这是一份"宽松型"开源协议,核心态度是:
- 你可以复制、修改、分发这份代码;
- 你可以把它用在商业项目里;
- 你甚至可以把它揉进闭源产品,不强制你开源衍生作品。
听起来是不是和 MIT 差不多?差别在于,Apache 2.0 多了几条"讲规矩"的义务。其中第四条明确要求:当你以源代码形式分发衍生作品时,必须保留原项目里的版权声明、专利声明、商标声明和署名声明(attribution notices);如果原项目里有一个叫 NOTICE 的文件,里面的归属声明也必须跟着保留下来。
Minitap 说,他们不仅用了 Apache 2.0,还专门写了 NOTICE 文件,明确要求署名。
所以这件事的法律定性其实很清楚:用代码,合法;把名字删了,越界。
2. 为什么连一个老 bug 都成了铁证
很多人以为"抄代码"要靠肉眼逐行对比,其实不是。法律和技术上判断"实质性相似",看的是接触 + 实质性相似这两件事能不能同时成立。
- 接触:mobile-use 是公开开源的,Google 完全看得到,这一条天然成立;
- 实质性相似:228 个文件一致、同一个 Agent 名、同一段 Prompt、同一组示例人名、连一个只在内部开发时才会踩的 bug 都一模一样——这种巧合在工程上几乎不可能发生。
特别是那个"自己读自己写的文件然后崩"的 bug。这种东西不是抄 API 能抄出来的,它带着原作者的"指纹"。就像两本书不仅情节一样,连作者随手打的错别字都一样——你很难说这是独立创作。
3. force push 为什么抹不干净
这次事件最具技术教学意义的一点,就是 Google 用一次强制推送改作者列表,结果被人从 Git 历史里翻了出来。
很多人对 Git 有个误解:git push --force 一推,旧历史就"消失"了。实际远非如此:
- 被强推覆盖的旧提交,在你本地仓库的 reflog 里还留着;
- 在 GitHub 服务器上,它变成了悬空对象(dangling object),一段时间内仍可通过 commit hash 直接访问;
- 任何当时 fork、过、clone 过的人,手里都有一份旧历史;
- Pull Request、Issue 里贴过的链接,也可能直接指向那个旧提交。
这就是为什么 Artemis 仓库里那个旧提交,GitHub 还能展示出来,还贴心地提醒你"它不属于任何分支"。在分布式版本控制系统里,"删掉历史"从来不是一个原子操作,而是一场和所有副本的赛跑。
4. 顺便厘清:Apache / MIT / GPL 到底差在哪
这次事件把开源协议最容易被搞混的点又暴露了一次。一张表说清:
| 协议 | 宽松在哪 | 硬约束在哪 |
|---|---|---|
| MIT | 最宽松,可商用可闭源 | 只需保留版权声明,无 NOTICE 概念 |
| Apache 2.0 | 同样可商用、衍生可闭源 | 必须保留版权 + NOTICE 文件,改动要标注,自带专利授权与反诉终止条款 |
| GPL(v2/v3) | 偏"传染性" | 衍生作品必须以同样协议开源,不能拿去闭源分发 |
记住一句话:宽松协议放宽的是"能不能用、能不能商用、能不能闭源",从来没有放宽过"留下原作者名字"这条底线。
三、三个最常见的技术误区
这次讨论之所以吵成一锅粥,是因为很多认知停在直觉层面。下面三个误区,做开源的人几乎都踩过。
误区一:Apache 2.0 这么宽松,署名随便吧
这是把"宽松"理解成了"免责"。
Apache 2.0 宽松,松在使用自由:你能商用、能改、能把衍生作品闭源。但它严在署名义务:
- 原文件头的版权声明不能删;
- 项目根目录的 NOTICE 文件内容要带过去;
- 你改过哪些文件,最好在改动说明里交代一句;
- 对外分发时,README 或 License 页要让后来的人知道这部分代码从哪来。
Artemis 这件事里,Google 后来补的那句"包含 Minitap 开发的源代码",本质上就是在补这个本来一开始就该做的动作。补得再快,也说明一开始没做。
误区二:force push 改了历史,就没人查得到
这是 Git 用户最危险的错觉。
强推能改的,只是当前分支上那条主链。但开源项目的历史是分布式的——有你本地的 reflog、有服务器上的悬空对象、有无数 fork 和 clone、有 PR 里贴过的链接。只要有人在被改之前看过一眼,历史就活在别人电脑里。
更别说 GitHub 这种平台本身就会保留对象一段时间。这次 Artemis 的旧提交能被直接截图晒出来,就是最鲜活的例子。想靠强推"洗白"开源项目的历史,在工程上几乎注定失败。
误区三:改个文件头、换个项目名,就算原创了
很多人脑子里的"重写"是这样:把别人代码 fork 下来,删掉原作者名字,写上自己的公司名,改改项目名,就当成全新作品发布。
这在法律和技术上都站不住。真正能洗清复用嫌疑的,是干净室(clean room)模式:两组人完全隔离,一组只写规格说明书,另一组只看规格、从零实现,全程不接触原代码。
而 Artemis 的情况恰恰相反——不仅代码逐文件一致,还带着原作者随手起的 Agent 名、示例人名和历史 bug。这不是 clean room,这是直接把别人的房间换了块门牌。
四、实操指引:怎么用别人的开源代码才不翻车
事件本身还在发展,但有些做法现在就可以养成习惯。
对个人开发者
- fork 或复制开源项目时,原样保留 LICENSE、版权头和 NOTICE 文件。别图干净删掉作者名。
- 改了哪个文件,就在文件头或 CHANGELOG 里标注一句基于 XXX 修改。这是 Apache 2.0 明确鼓励的做法。
- README 里写清来源:一句话说明本项目基于哪个上游项目、原始链接是什么。
- 永远不要用 force push 去"修改"已公开的提交历史。发现错误,用新提交覆盖,不要回头改旧账。
对企业和团队
- 建立开源合规清单(SBOM):项目里用了哪些第三方开源代码、各自什么协议,一表打尽。
- 引入许可证扫描工具:CI 阶段自动检测新增依赖的协议类型,避免不小心把 GPL 组件带进闭源产品。
- 发布前过一遍 attribution 清单:对外分发的产品,要在 NOTICE 或致谢页列出所有复用的开源代码及原作者。
- 大厂更要做榜样:体量越大,越不该在署名这种"小规矩"上省力气——社区的信任,恰恰是在这种细节里攒起来的。
对开源项目的维护者
- 发布时主动附 NOTICE 文件,写清楚你希望被如何署名。
- 保留一份带版本号和作者列表的文件(比如
pyproject.toml、package.json里的 author 字段),这是日后维权最直接的证据。 - 万一被人复用却抹了名,Git 历史、文件哈希、独有 bug 的复现,都是比口水仗有力得多的证据。
五、结尾
回到 Minitap 那句话:"我们不介意你用代码,只是请别把写下第一行代码的人删掉。"
开源这件事,一半是代码,一半是人。代码可以被 fork、被改写、被商用,但记录"谁写了它"的那几行字,是这个生态能持续运转的底线。MIT 也好,Apache 2.0 也好,它们允许你拿走代码,却从不允许你拿走名字。
Google 不是没有过开源贡献——Kubernetes、TensorFlow 这些项目,至今仍在养活无数工程师。正因为如此,当连 Google 这样的玩家都在署名上翻船时,反而更值得所有人警醒:在开源世界里,越成熟的玩家,越要守最朴素的规矩。
至于 Artemis 后续会不会完整恢复三位原作者的署名、合并社区的 PR,我们会持续关注。
话题标签: