化石版本
从 AI 模型记忆中写出的代码指纹,在整个 npm registry 上测量。
Kobi Mozgori · 2026年11月
摘要
我随机抽样了 250,000 个 npm 包,并查看了每个包在最初发布版本中指定的依赖版本。
- 一个简单的指纹从背景噪声变成了每七个新包中就有一个。在 2019 年到 2024 年初的每半年中,那些锁定版本大多是整数(x
文章标题:化石版本:25 万个 NPM 包中 AI 编写代码的指纹
正文:
- 指纹:至少两个形如 x.0.0 的固定版本,且已被取代 30 天或更久,占该包全部固定版本至少 40%。
- 新鲜:至少 80% 的固定版本是最新发布版本。
结果
出生时的陈旧度

| 出生于 | 包数 | 指纹 | 固定版本年龄中位数 | 出生时新鲜 | 最新固定版本超过一年 |
|---|---|---|---|---|---|
| 2023 上半年 | 5,227 | 2.4% | 165 天 | 27.6% | 12.7% |
| 2024 下半年 | 5,671 | 2.7% | 177 天 | 27.3% | 12.3% |
| 2025 上半年 | 5,441 | 4.3% | 187 天 | 22.9% | 16.8% |
| 2025 下半年 | 6,318 | 9.3% | 314 天 | 17.6% | 20.9% |
| 2026 上半年 | 12,118 | 13.7% | 431 天 | 11.8% | 27.7% |
| 2026 下半年(截至 11 月初) | 7,231 | 7.6% | 330 天 | 8.8% | 21.6% |
固定版本年龄中位数与新鲜比例是在移除大规模克隆的垃圾清单后计算的(见稳健性)。
在 2026 年内,指纹包的陈旧程度远高于其余包。其固定版本年龄中位数为 675 天,最新固定版本年龄为 422 天。其他 2026 年包的这两个数字分别为 335 天和 43 天。对于 2021–2022 年出生的包,分别为 154 天和 21 天。
2026 年的其余部分并不是干净的人类基线。其固定版本年龄中位数也翻了一倍,这表明指纹只捕捉到了凭记忆编写的清单中的一部分。一个能回想起 typescript ^5.7.2 的模型不会留下整数版本。
同一个断裂,逐个库来看

指明已被取代的 x.0.0 的固定版本占比在 2025–2026 年上升:@types/node(此前 2–5%,2026 年为 24%)、react(19%)、tsup(22%)、vitest(15%)、rollup(13%)和 eslint(11%)。而 typescript 和 axios 始终为零,整数版本的习惯从未在那里出现。
同一套技术栈

2026 年出生的指纹包集中在少数几款工具上。44% 依赖 vitest,5% 依赖 jest;而在 2021–2022 年出生的全部包中,这两个数字分别为 1% 和 21%。35% 依赖 tsup;webpack 和 rollup 在 2021–2022 年各占 12%,如今分别为 0.4% 和 3%。其他 2026 年包也表现出同样的转变,只是程度更轻,因此其中一部分只是时代因素。
注册表增长
将样本按比例放大,2023 年创建了约 374,000 个包,2025 年为 455,000 个,2026 年截至 11 月 12 日为 895,000 个。2024 年的数字(698,000)被第二季度的垃圾包浪潮抬高了。
稳健性
- 定义。更严格的规则(三个或更多陈旧整数固定版本,至少占全部固定版本的一半)在 2024 年之前给出 0.4–1.0%,2026 上半年为 7.7%。忽略 peerDependencies(其中整数范围是合法的人类惯例)后,2026 上半年为 12.9%。
- 垃圾包。2024 年第二季度,注册表被数千个几乎相同的垃圾包淹没。剔除样本中固定版本集合完全相同且出现五次或以上的所有清单后,2026 上半年的数字为 13.6%,2024 年的低谷也随之消失。
- 仅限有维护的包。限制为具有 repository 字段且至少发布过两个版本的包,2026 上半年为 14.1%。
- 并非单一发布者。2025–2026 年出生的 3,038 个指纹包由 2,714 个不同账户首次发布。最大的账户占其中的 0.4%。
- 抽样误差。半年组包含 3,900 至 13,500 个包。置信区间见 results/half_year.csv。
其他解释
还有三种情况可能大规模产生整数、陈旧的固定版本。2026 上半年的数字(13.7%)在它们中任何一种情况下都几乎没有变化。每个半年度的数据见 results/robustness.csv。
- 脚手架工具。create-next-app 会写入 react ^19.0.0,因此脚手架生成的应用可能抬高计数。剔除所有依赖 next 或 react-dom 的包后为 13.4%。忽略所有指向 react、react-dom 及其类型包的固定版本后为 12.8%。
文章标题:Fossil versions: a fingerprint of AI-written code in 250k NPM packages
正文:
- 少数流行模板。模板会产生相同的清单。在 2026 年上半年诞生的 1,664 个指纹包中,87% 的清单没有与其他任何抽样包共享,这与 2022 年诞生的所有包的比例(86%)相同。它们包含 1,157 种不同的整数版本固定组合,最常见的十种组合覆盖了其中的 13%。剔除名称或描述中包含 template、starter、boilerplate、scaffold、example 或 demo 的包后,该比例降至 13.8%。
- Monorepo。一个仓库可以发布数十个具有相同清单的包。按每个 npm scope 只计一个包计算,得到 13.9%。仅统计无 scope 的包得到 13.3%,仅统计有 scope 的包得到 14.0%。
无法逐个包排除从旧仓库复制的项目。复制行为一直存在,而且它属于 1–2.4% 的基线。只有当人们复制的内容在 2025 年发生了变化,才能解释这一跃升。
局限
- 是推断,不是证明。注册表元数据中没有任何信息说明清单是谁写的。一个人复制旧教程也会产生相同的模式。该论断依赖于一个基线:该基线在六年内保持平稳,并在十八个月内上升了约八倍。
- 对凭记忆编写的代码存在低估,低估幅度未知。过时但非整数的版本未被计入。
- 2026 年中期以来的下降尚无解释。它可能符合编码代理从注册表解析版本、而非凭记忆背诵的情况。我没有对此进行测试。
- 仅限 npm,仅限首次发布。其他生态系统和后续发布可能看起来不同。
- 覆盖率。对 4,000 个最常用名称之外的依赖的版本固定未标注日期。已删除的包(占抽样名称的 1.6%)缺失,且删除并非随机。
- 单一快照。样本是在某一天采集的。在名称列表构建之后发布的包不在其中,因此最后一个季度的数据偏少。
相关工作
- Wang 等,Correct Code, Vulnerable Dependencies(2026 年 5 月),向十个模型发出提示,并测量它们在 Python 中指定的版本。本仓库测量的是实际发布的内容。
- Decan、Mens 和 Constantinou,On the evolution of technical lag in the npm package dependency network(2018),在编码助手出现之前定义了 npm 的技术滞后。
- Microsoft,Competing against yourself(2026 年 6 月),从库供应商的角度描述了同样的问题。
我搜索了此前针对该指纹的注册表规模测量,但没有找到。如果你知道有,请提交 issue。
复现
pip install -r requirements.txt
# 1. the list of every package name (about 120 MB unpacked)
npm pack [email protected] && tar xzf all-the-package-names-2.0.2622.tgz
# 2. fetch the sample: 250,000 names, seed 11 (about 20 minutes)
python src/fetch_sample.py 250000 data/sample.jsonl 11 64
# 3. release timelines for the most-used dependencies (or: gunzip -k data/deps.jsonl.gz)
python src/fetch_deps.py data/top_dependencies.txt data/deps.jsonl
# 4. analysis and figures
python src/analyze.py
python src/charts.py
data/sampled_names.txt.gz 列出了抽取的确切名称。注册表内容会变化,因此重新拉取时,对于已删除或重新发布的包,结果会略有不同。
文件
| 路径 | 内容 |
|---|---|
| src/fetch_sample.py | 抽取随机样本并存储每个包的首次发布 |
| src/fetch_deps.py | 拉取依赖的发布时间线 |
| src/analyze.py | 计算本文档中的每一个数字 |
| src/charts.py | 绘制图表 |
| results/ | CSV 输出:半年度、季度、稳健性、按库、技术栈、数量、最常见的整数版本固定 |
| data/ | 抽样名称、依赖时间线、已拉取的依赖列表 |
说明
该分析是在 Claude(Anthropic)作为研究助手的协助下完成的。代码采用 MIT 许可。