不要盲目信任 AI Agent:风险与局限分析
批判性讨论 AI Agent 的局限性和信任问题。对正在集成或依赖 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 以非特权用户身份运行,只能看到明确挂载到容器中的目录。容器边界由操作系统强制执行。
即使启用了 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 的源代码和完整安全模型;它们足够精简,一个下午就能读完。