不要盲目信任 AI Agent:风险与局限分析
批判性讨论 AI Agent 的局限性和信任问题。对正在集成或依赖 AI Agent 的开发者提供清醒的风险意识,值得一读。
完整中文译文
当你使用 AI Agent 构建应用时,应当把它们视为不可信、甚至可能怀有恶意的对象。无论你担心的是 prompt injection、模型试图逃离 sandbox,还是某种尚未有人想到的攻击方式,也无论你的威胁模型是什么,你都不应该信任 Agent。正确的做法不是设置更完善的权限检查,也不是设计更智能的 allowlist,而是采用一种预设 Agent 必然会做出不当行为、并能在事情发生时控制损害范围的架构。
这正是我构建 NanoClaw 所遵循的原则。
不要信任进程
OpenClaw 默认直接运行在宿主机上。它提供了可选的 Docker sandbox 模式,但开箱时并未启用,而且大多数用户永远不会主动打开它。如果不启用,安全性就完全依赖应用层检查:allowlist、确认提示,以及一组所谓的“安全”命令。这些检查隐含着一个信任前提:Agent 不会试图做坏事。一旦你开始把 Agent 视为潜在的恶意对象,就会清楚地意识到,仅靠应用层的阻拦远远不够。它们无法提供严密、封闭的安全保障。一个执意作恶或已被攻陷的 Agent,总能设法绕过这些限制。
在 NanoClaw 中,容器隔离是架构的核心组成部分。每个 Agent 都运行在自己的容器中:可以是 Docker,也可以是 macOS 上的 Apple Container。容器是临时的,每次调用都会全新创建,并在调用结束后销毁。Agent 以非特权用户身份运行,只能看到明确挂载到容器中的目录。容器边界由操作系统强制执行。
不要信任其他 Agent
即使启用了 OpenClaw 的 sandbox,所有 Agent 仍然共享同一个容器。你可能在不同的 WhatsApp 群组或 Telegram 频道中,让一个 Agent 充当个人助理,另一个 Agent 处理工作事务。但它们都处于同一个运行环境中,这意味着,本应访问不同数据的 Agent 之间可能发生信息泄露。
你不应该信任其他 Agent,就像你不应该信任任何一个 Agent 一样。在 NanoClaw 中,每个 Agent 都拥有独立的容器、文件系统和 Claude session 历史记录。你的个人助理无法看到工作 Agent 的数据,因为它们运行在完全隔离的 sandbox 中。
容器边界是强制性的安全层——无论如何配置,Agent 都无法逃离容器。除此之外,位于 ~/.config/nanoclaw/mount-allowlist.json 的挂载 allowlist 还提供了一层 defense-in-depth。它的作用是防止用户意外挂载不应暴露的内容,而不是防止 Agent 逃逸。敏感路径(.ssh、.gnupg、.aws、.env、private_key、credentials)默认会被阻止。allowlist 位于项目目录之外,因此已被攻陷的 Agent 无法修改自己的权限。宿主应用代码以只读方式挂载,所以无论 Agent 做了什么,都无法在容器销毁后继续留存。
群组里的其他人同样不应受到信任。非主群组默认被视为不可信。其他群组及其成员无法向别的聊天发送消息、为其他群组安排任务,也无法查看其他群组的数据。群里的任何人都可能发起 prompt injection,而这一点已经被纳入安全模型之中。
不要信任你无法读懂的东西
OpenClaw 拥有近 50 万行代码、53 个配置文件,以及超过 70 个依赖。这违背了开源安全的基本前提。Chromium 有超过 3,500 万行代码,但你信任的是 Google 的审查流程。大多数开源项目采取的是另一条路:让项目保持足够小,使众多开发者真的能够审查代码。没有人审查过 OpenClaw 的 40 万行代码。它在短短几周内完成,却没有经过正规的审查流程。复杂性正是漏洞藏身之处,而 Microsoft 的分析也证实了这一点:OpenClaw 的风险可能通过正常的 API 调用暴露出来,因为没有任何一个人能够看清全貌。
NanoClaw 只有一个进程和少量文件。我们高度依赖 Anthropic 的 Agent SDK——也就是 Claude Code 的封装层——来完成 session 管理、memory compaction,以及更多工作,而不是重复造轮子。一名有能力的开发者可以用一个下午审查完整个代码库。这是刻意设置的约束,而不是能力上的局限。我们的贡献指南只接受 bug 修复、安全修复和简化代码的改动。
新功能通过 skills 引入:skill 是一组指令,其中包含完整、可运行的参考实现,再由 coding agent 将其合并进你的代码库。在代码真正进入项目之前,你可以准确审查将要添加的内容。而且,你只需要加入自己真正需要的集成。最终,每个安装实例都只有几千行代码,并且完全针对所有者的具体需求定制。
这才是真正的区别。对于一个拥有 40 万行代码的单体代码库,即使你只启用了两项集成,其余代码依然存在。它们仍会被加载,仍然是攻击面的一部分,也仍然可能被 prompt injection 和 rogue agent 触达。你无法将活跃代码与休眠代码彻底分离。你也无法审计它,因为你甚至无法界定“你的代码”究竟到哪里为止。使用 skills 后,边界则一目了然:只有几千行代码,全部由你主动选择加入,而且每一行你都能亲自阅读。事实上,核心代码还在随着时间推移不断缩小。例如,WhatsApp 支持正在从核心中移除,并被打包成一个 skill。
如果一次 hallucination 或一个行为异常的 Agent 就能引发安全问题,那么这个安全模型本身就是失效的。安全必须在 agentic surface 之外强制执行,而不能依赖 Agent 始终做出正确行为。容器、挂载限制和文件系统隔离的存在,正是为了确保即使 Agent 做出了意料之外的事情,其 blast radius 也能得到控制。
这些措施都无法彻底消除风险。让 AI Agent 访问你的数据,本质上就是一种高风险的安排。但正确的应对方式,是让这种信任尽可能收窄,并且尽可能可验证。不要信任 Agent,要在它周围筑起高墙。
你可以阅读 NanoClaw 的源代码和完整安全模型;它们足够精简,一个下午就能读完。