AI Coding 的安全风险,很多时候不在模型写错一行代码,而在它顺手补上的一条依赖。
开发者问模型:“帮我写一个调用 AWS CDK 的脚本”“帮我写一个 Django REST API 示例”“帮我加一个 OpenTelemetry 监控上报”。模型生成的代码看起来很完整:有 import,有 pip install,有 npm install,甚至还有注释说明。
问题是,这些包名有时并不存在。
如果只是代码运行时报错,这还只是一次普通幻觉。但如果攻击者提前发现模型经常编出某个不存在的包名,并把这个名字注册到 PyPI 或 npm 上,后面的事情就会变得危险:开发者复制安装命令,CI 自动拉依赖,恶意包随之进入开发环境或构建流水线。
这类攻击被称为 slopsquatting。它和传统 typosquatting 不同。typosquatting 赌的是人手滑,slopsquatting 赌的是模型会稳定地“编包名”。
5 月 16 日,独立研究者 Aleksandr Churilov 发布论文 The Range Shrinks, the Threat Remains: Re-evaluating LLM Package Hallucinations on the 2026 Frontier-Model Cohort,重新评估了 2026 前沿代码模型中的包名幻觉风险。

https://arxiv.org/pdf/2605.17062
论文复现 Spracklen 等人在 USENIX Security 2025 上的研究方法,测试 Claude Sonnet 4.6、Claude Haiku 4.5、GPT-5.4-mini、Gemini 2.5 Pro、DeepSeek V3.2 五个模型,在 199,845 次 Python / JavaScript 代码生成中检查模型是否引用了不存在的 PyPI 或 npm 包。
它的结论可以概括成一句话:
模型之间的幻觉率差距缩小了,但供应链攻击面没有消失;更麻烦的是,不同模型会共同幻觉出同一批不存在包名。

包名幻觉不是“答错了”,而是“引导安装了”
代码大模型生成依赖有几种常见形式:
</> Pythonimportrest_framework
</> Bashpip install rest-framework
</> JavaScriptconstservice=require("@ember/service")
</> Bashnpm install dns-sd
对于人类读者来说,这些名字看上去都很自然。它们符合生态命名习惯,也经常和真实项目、模块、SDK、子包存在语义关联。
但软件包生态里有一个关键细节:模块名、项目名、安装包名不一定相同。
比如某个 Python 代码里可以 import rest_framework,但真实安装包可能是 djangorestframework。模型如果把 import 名、框架名、项目名、安装名混在一起,就可能生成一个语义合理但注册表不存在的包名。
在普通问答里,这类错误只是幻觉;在代码生成里,它会变成一个可以执行的安装动作。
论文采用的攻击链很简单:
攻击者批量询问代码模型,收集模型经常生成的不存在包名;攻击者把这些包名注册到 PyPI 或 npm;开发者之后向模型提出类似代码需求;模型生成引用这个幻觉包名的代码或安装命令;开发者或自动化工具安装该包;恶意代码在开发环境、构建环境或运行环境中执行。
这条链路不需要攻击者入侵模型厂商,也不需要污染训练数据,更不需要提前接触目标开发者。攻击者只需要能注册包名,再等待模型把用户带过去。
这就是 slopsquatting 最值得警惕的地方:攻击者利用的不是开发者的拼写错误,而是模型的生成偏差。
复测 5 个 2026 前沿代码模型
这篇论文不是提出一种复杂的新攻击方法,而是做了一次针对新模型的系统复测。
作者复用了 Spracklen 等人的测试框架和 prompt 数据集,包含两类问题:
一类来自 Stack Overflow 编程问题,共 20,163 条;另一类是 LLM 合成问题,共 19,806 条。每个模型都在 Python 和 JavaScript 两种语言上生成代码,总计 199,845 次生成,约等于每个模型 4 万次。
测试流程大致如下:
模型生成代码后,研究者用规则抽取其中的依赖引用,包括:
</> Bashpip install ...npm install ...
以及:
</> Pythonimport ...from ... import ...
</> JavaScriptrequire(...)import... from ...
然后把抽取出的包名与 PyPI、npm 的 master list 进行比对。如果包名不存在,就进入 hallucinated package 候选集合。作者还做了噪声过滤,排除了路径别名、模板变量、Node.js 内置前缀、Dart 语法前缀等明显误报。所有报告数字的验证日期是 2026 年 4 月 28 日。
这里有个统计口径要注意:论文计算幻觉率时,分母是“可解析出来的有效包引用”,不是所有模型回答。拒答和格式异常单独统计。尤其是 GPT-5.4-mini 在 minimal reasoning effort 设置下拒答率达到 32.14%,这会影响它和其他模型的直接可比性。
所以这篇论文更准确的定位是:
裸模型代码生成阶段,依赖引用是否会指向不存在的软件包。
它还没有覆盖带联网检索、带 registry lookup、带企业依赖门禁的完整 AI Coding 产品链路。
核心发现一:幻觉率收敛到 4.62%–6.10%,但没有归零
论文最直观的结果是,5 个前沿模型的包名幻觉率集中在 4.62% 到 6.10% 之间。
模型 | 总体幻觉率 | Python | JavaScript |
|---|---|---|---|
Claude Haiku 4.5 | 4.62% | 5.49% | 2.76% |
Claude Sonnet 4.6 | 5.41% | 6.63% | 2.62% |
Gemini 2.5 Pro | 5.80% | 6.75% | 3.61% |
DeepSeek V3.2 | 5.89% | 6.69% | 3.78% |
GPT-5.4-mini | 6.10% | 7.27% | 3.14% |
相比 Spracklen 之前报告的 5.2%–21.7%,这次 5 个模型之间的差距被压缩到 1.48 个百分点。论文称这种变化是“inter-model range compression”:模型之间的风险水平更接近了。
但这个结果不能理解为“前沿模型已经解决了包名幻觉”。
4%–7% 的比例,在普通问答里可能不算夸张;放到软件供应链里,这已经足够形成攻击收益。只要模型能稳定地产生一批不存在但看起来合理的包名,攻击者就可以把它们当成候选资产。
更关键的是,论文指出没有一个 2026 前沿模型超过 Spracklen 研究中 2024 年最佳商业模型 3.6% 的结果。也就是说,新模型整体能力更强,模型之间差距更小,但包名幻觉这个问题仍然顽固存在。

核心发现二:真正危险的是 127 个“共同幻觉包名”
这篇论文最重要的发现,不是某个模型幻觉率高一点或低一点,而是 universal hallucination set。
也就是:所有 5 个模型都会共同编出来的不存在包名。
作者发现,5 个模型共同幻觉了 127 个包名,其中 109 个属于 PyPI,18 个属于 npm。随后作者把这批名字披露给 PyPI Security 和 Socket.dev 进行审查,确认其中仍有 53 个包名 可以被攻击者注册:41 个来自 PyPI,12 个来自 npm。
这一步把问题从“模型会不会胡说”推进到了“攻击者能不能复用”。
单模型幻觉意味着攻击者要针对某个模型做枚举;共同幻觉意味着攻击者注册一个名字,就可能同时覆盖多个模型生态里的用户。
换句话说:
当多个模型共同犯同一种错,这个错误就从模型缺陷变成了跨模型攻击面。
论文举了一些高频幻觉包名例子,比如:
幻觉包名 | 生态 | 论文中的解释 |
|---|---|---|
aws-cdk | PyPI | 真实包是 aws-cdk-lib |
objc | PyPI | 真实包是 pyobjc |
opentelemetry | PyPI | 真实包存在为 opentelemetry-api / opentelemetry-sdk |
rest-framework | PyPI | 真实包是 djangorestframework |
tencentcloud | PyPI | 真实包是 tencentcloud-sdk-python |
mpl-toolkits | PyPI | matplotlib 子模块,不是独立包 |
opengl | PyPI | 真实包是 PyOpenGL |
openstack | PyPI | OpenStack SDK 发布名是 openstacksdk |
@ember/service | npm | Ember.js 内部子包,随 ember-source 打包 |
@ember/object | npm | 同属 Ember.js 内部模块 |
这些名字的危险性在于,它们不像随机乱码。很多名称都和真实生态高度接近,有的只是把 SDK 名缩短,有的是把模块名当成安装名,有的是把框架内部路径当成可独立安装的包名。
这也是 AI Coding 场景里最容易被忽略的地方:开发者看到 rest-framework、opentelemetry、tencentcloud 这类名字时,大概率不会第一时间怀疑它们不存在。

为什么模型会共同编出同一批包?
论文给了两个可能原因,我认为都很贴近真实开发生态。
第一个原因是 共享训练语料里的错误信号。
很多教程、博客、README、Stack Overflow 回答里,会混用模块名、项目名和安装包名。例如代码里写的是:
</> Pythonimport rest_framework
但安装时应该使用:
</> Bashpip install djangorestframework
模型如果在大量语料中反复看到 “REST framework” 这个概念,又看到 Python 包经常用 dash 连接,就可能稳定补全出:
</> Bashpip install rest-framework
这个名字看起来对,语义也对,但注册表里没有这个包。
第二个原因是 命名空间规则过度泛化。
npm 生态中经常有 scoped package,比如 @scope/name。模型看到 @ember/service、@ember/object 这类 Ember.js 内部模块路径时,可能误以为它们也是可以独立安装的 npm 包。但这些名字实际上属于框架内部虚拟模块,攻击者未必能在受控 scope 下注册。
这说明模型的包名幻觉并不是完全随机的。
它更像是在已有命名规律上做“合理外推”:
真实包名:aws-cdk-lib
模型外推:aws-cdk
真实包名:djangorestframework
模型外推:rest-framework
真实包名:tencentcloud-sdk-python
模型外推:tencentcloud
对模型来说,这些名字都符合语言模型的分布;对包管理器来说,这些名字要么不存在,要么可能被攻击者占用。
Python 反而比 JavaScript 更容易出问题
另一个值得注意的结果是,5 个模型上 Python 的包名幻觉率都高于 JavaScript。
在 Spracklen 之前的研究里,JavaScript 更容易出问题,因为 npm 生态更庞大,包名更碎片化。但这次结果反过来了:Python 高于 JavaScript,而且这个趋势出现在所有 5 个模型上。Python 与 JavaScript 的差值从 2.73 个百分点到 4.13 个百分点不等。
这对企业安全很重要。
很多企业引入 AI Coding,最先落地的场景恰恰是 Python:
数据分析脚本;
自动化运维脚本;
AI 工程胶水代码;
FastAPI / Flask 后端;
安全运营脚本;
内部工具开发;
模型评测和数据处理流水线。
这些场景往往代码量不大,开发者也更容易直接复制模型给出的安装命令。如果企业没有依赖校验,Python 脚本就可能成为 slopsquatting 的入口。
尤其是 AI Agent 场景里,问题会更进一步。人类开发者复制命令前也许还会犹豫一下,但自动化 Agent 可能会直接执行:
</> Pythonpip install xxx
一旦 Agent 拥有 shell、包管理器、文件系统、CI 权限,包名幻觉就不再是“建议错误”,而是“自动执行错误”。
模型相似性也应该成为安全指标
论文还用 Jaccard similarity 衡量不同模型幻觉包名集合的重合程度。
结果显示,10 组模型对的平均 Jaccard 是 0.222,最高的是 DeepSeek V3.2 和 GPT-5.4-mini,达到 0.343。作者没有断言两者存在训练数据关系,只说可能来自共享训练语料,或者相似的包名生成偏差。
这个点很有启发。
我们过去做模型安全评估,通常问:
这个模型幻觉率高不高?
这个模型越狱率高不高?
这个模型生成危险代码的比例高不高?
但从攻击者视角看,还要问另一个问题:
不同模型会不会错在同一批对象上?
如果每个模型都错,但错得不一样,攻击者需要分别适配。
如果多个模型错在同一批包名上,这批包名就具备跨模型复用价值。
这意味着企业以后做 AI Coding 安全评估时,不应该只测单模型的 hallucination rate,还应该测:
跨模型共同幻觉包名;
高频重复幻觉包名;
与真实包名高度相似的幻觉包名;
仍可注册的幻觉包名;
新注册包与模型幻觉候选集的重叠情况。
这些指标比单一幻觉率更接近真实攻击价值。

局限性:不要把结果外推到所有 AI Coding 产品
这篇论文的价值很明确,但也有几个限制。
第一,它只测试了 5 个前沿模型,没有覆盖大量企业真实使用中的小模型、旧模型、本地模型、量化模型、私有微调模型。前沿模型之间的差距缩小,不代表所有模型都安全。论文也指出,较小或较旧的模型可能仍保留更高幻觉率。
第二,它是一次时间点测量。实验窗口是 2026 年 4 月 22 日到 28 日,模型 API 版本可能变化,包注册表状态也会变化。一个名字今天不可注册,不代表未来没有风险;一个名字今天不存在,也可能明天被攻击者注册。
第三,测试集复用了前序研究公开数据。这样做便于和 2024/2025 基线对比,但也可能存在训练数据污染或 prompt 泄漏风险。换句话说,新模型可能在训练中见过相似问题,从而让幻觉率被低估。
第四,论文没有测试完整 Agentic Coding 产品。如果一个代码助手在生成依赖前会联网检索 PyPI/npm,或者在执行前有 registry lookup,风险会下降。裸模型输出和带工具链的工程产品不是一回事。
所以这篇论文最适合支撑一个判断:
AI Coding 生成依赖时,裸模型仍然不可靠;依赖验证必须交给工具链,而不能交给模型自信程度。
企业应该怎么防:把 AI 生成依赖当成不可信输入
从工程落地看,防 slopsquatting 不能只靠提示词。
“请不要编造不存在的软件包”这类指令有帮助,但不应该成为主防线。模型本身并不等于实时包注册表,它不知道某个包名此刻是否存在、是否刚刚被注册、维护者是否可信、下载量是否异常。
更稳妥的做法,是把 AI Coding 生成的依赖统一纳入软件供应链安全门禁。
1. 生成阶段:实时查包,不让模型裸猜
代码助手生成 pip install、npm install、requirements.txt、package.json 时,应当调用 PyPI/npm registry 查询接口。
如果包名不存在,产品侧应该明确提示:
该依赖未在官方注册表中验证,请不要直接安装。
如果包名存在,但发布时间极短、下载量极低、维护者异常、和知名包高度相似,也应该进入风险提示。
2. 执行阶段:Agent 安装依赖前必须拦截
如果 AI Agent 有 shell 权限,所有包管理器命令都应该进入策略检查:
</> Bashpip installnpm installpnpm addyarn addpoetry add
拦截策略至少包括:
新增外部依赖是否在 allowlist 中;
包名是否命中 typo / slop 风险;
包是否刚注册;
包是否存在可疑安装脚本;
是否触发网络下载和执行;
是否会写入 lockfile 或构建配置;
是否来自公司私有镜像或可信代理。
AI Agent 的问题在于它会把“建议”变成“动作”。所以执行前拦截比生成后提醒更重要。
3. CI/CD 阶段:新增依赖必须单独审计
企业可以在 CI 中增加 dependency review,对 AI 生成代码引入的新增依赖做强制检查。
尤其要关注:
PR 中新增的 requirements.txt;
package.json / package-lock.json / pnpm-lock.yaml;
Dockerfile 中的安装命令;
GitHub Actions / GitLab CI 中的动态安装命令;
内部脚本里的 subprocess.run("pip install ...");
notebook 里的 !pip install ...。
AI Coding 的一个现实特点是:它经常把依赖安装命令散落在 README、notebook、脚本、Dockerfile、CI 配置里。只检查源码 import 不够,必须检查全仓库的安装入口。
4. 企业私有源:默认不直连公网注册表
对企业来说,最实际的防线仍然是私有包代理和依赖白名单。
推荐做法是:
开发环境默认走公司私有 PyPI/npm 镜像;
新依赖进入镜像前需要安全扫描;
高危包名进入 denylist;
AI 生成依赖默认不能绕过代理直连公网;
生产构建只允许 lockfile 中已审核依赖。
这样即使模型编出一个已被攻击者注册的包名,也不会直接进入生产构建链路。
5. 红队评估:把“依赖幻觉率”纳入 AI Coding 测试
企业测试 AI Coding 产品时,不应只看代码正确率和漏洞率,还要专门测依赖幻觉。
可以设计一组测试指标:
指标 | 含义 |
|---|---|
不存在包名率 | 模型生成依赖中不存在包名的比例 |
高频重复幻觉率 | 多次生成中反复出现的幻觉包名 |
近似真实包率 | 与真实包编辑距离很近的幻觉名 |
跨模型共同幻觉率 | 多个模型共同生成的不存在包名 |
可注册幻觉率 | 不存在且理论上可被注册的包名 |
自动安装触发率 | Agent 是否会直接执行安装命令 |
拦截成功率 | 工具链能否阻止安装高风险依赖 |
这类指标比“模型有没有说错”更贴近实际供应链风险。

AI Coding 正在改变供应链攻击入口
这篇论文的重点不在“模型又幻觉了”。
真正值得关注的是,AI Coding 已经开始参与软件供应链里的关键决策:选什么库、装什么包、改什么配置、跑什么命令。
传统供应链安全主要盯几类问题:
开发者手动引入恶意依赖;
攻击者注册相似包名;
内部包名被公共注册表抢占;
维护者账号被盗;
上游包被植入恶意版本。
AI Coding 进来以后,多了一个新入口:
模型生成了一个不存在但可信的依赖名,攻击者把这个名字变成真实恶意包。
这个入口很隐蔽。它不需要模型越狱,不需要提示注入,不需要攻破 IDE,也不需要攻击 CI。攻击者只要找到模型稳定输出的包名候选,再占住这些名字,就能等待开发者或 Agent 自己把包安装进来。
更重要的是,论文发现 127 个共同幻觉包名,其中 53 个仍可注册。这说明风险已经从单个模型扩展到跨模型共同偏差。
以后做 AI Coding 安全,不能只问“模型写的代码有没有漏洞”。还要问:
模型建议的依赖是否真实存在?这个包名是否刚刚被注册?它是否和知名包高度相似?它是否由多个模型共同幻觉出来?Agent 是否会自动安装它?CI 是否会无感拉取它?企业私有源是否能拦住它?
AI 写代码的能力越强,它在开发链路里的权限就越高。模型生成的一条依赖建议,可能成为供应链里的第一颗钉子。
AI Coding 的安全边界,已经从代码内容扩展到了依赖选择、包安装和构建执行。
这篇论文提醒我们:不要把 LLM 当成包注册表,也不要把 AI 生成依赖当成可信配置。模型可以写代码,但依赖是否存在、是否可信、是否可安装,必须由工具链验证。
声明:本文来自模安局,版权归作者所有。文章内容仅代表作者独立观点,不代表安全内参立场,转载目的在于传递更多信息。如有侵权,请联系 anquanneican@163.com。