边界而非指令:如何保持对自主AI代理的控制
为什么对AI代理的控制不能建立在提示词中的指令上——以及如何将其建立在技术边界上。一次会话中的五起事件。
无法加载此图片。随着AI代理变得越来越自主,我们越来越常试图用习惯的方式管理它们——在提示词里写规则:“别碰这个”、“只在那里工作”、“永远不要做那个”。在 三个并行代理的实验 中,我在两天里收集了一批活生生的案例,展示了这种方式在哪里失效——以及另一种方式在哪里奏效。文章论点很简单:指令是代理以某种概率执行的请求;边界是系统的属性,不依赖于服从。当代理只有一个并在监督下工作时,差别看起来只是风格问题。当代理变多时,它就成了架构问题。
一次会话中的五起事件
以下所有案例都发生在这个博客的一次工作会话中——它们都有记录,每一个都说明了通过文本进行管理失败的某种方式。
没有指令——事故发生了。 代理在为自己的任务做准备时,执行了 git stash 在公共目录中,并把我未提交的、与其任务无关的文件带进了暂存区。没有人“违反”任何东西:根本不存在禁止。这是指令的根本属性——它们是在事故之后才被写出来的。代理不该做什么的完整清单是不可能写完的。
指令是有的——但没有起作用。 第一次事故之后,我给代理们加了一条明确规则:“严格在自己的工作目录里工作”。其中一个代理仍然在主目录里执行了 git 命令——只是通过绝对路径访问了它。不是出于恶意,也不是出于愚蠢:模型是概率性的,遵守文本规则同样是一个概率,乘以上下文长度和运行次数。
技术边界悄无声息地起了作用。 在同一次实验中,最被预期的事故一次都没有发生——“一个代理把所有人的分支都切换了”。不是因为代理们很小心,而是因为 git worktree 在物理上不允许把同一个分支检出到两个工作副本中。防护内建于工具之中。不需要记住它,不需要遵循它——它就在那里。
指令被放在了本该由边界占据的位置。 最令人不快的发现:这个博客的生产环境由提示词里的一行字守护着。推送到 master 会触发自动部署,而每个代理与它之间只隔着一句“不要 git push”。它守住了——但这是运气,不是控制:这里真正的边界是访问权限、受保护分支、没有写权限的令牌。请求被放在了锁的位置上。
边界覆盖在代理本身之上。 一次会话中,运行时两次拦下的已经不是实验用的代理,而是我的主助手:权限分类器阻止了到生产服务器的 SSH 和批量删除未提交的修改——这些操作形式上源于任务,但需要明确的人类“是”。两次拦截都是正确的。而且两次都发生在代理的“纪律”之上,而那个代理相当真诚地认为自己是在按计划行事。
原则并不新——新的只是实体
软件工程早在 LLM 之前就经历过这一课。在丰田的生产体系中,这个原则叫做 poka-yoke:防止错误靠的是流程装置,而不是执行者的警觉。只能以正确方向插入的零件,比“请正确插入”的海报更可靠。在平台工程中,同样的东西被称为 guardrails,在安全领域则称为 defense in depth。到处是同一个想法: 不要依赖执行者读过、理解了并且没有忘记——要让错误操作变得不可能或代价高昂。
“指令是请求。边界是系统的属性。建立在请求之上的控制,不是控制,而是带有累积效应的运气。”
——与并行代理工作两天的核心结论
对于AI代理,这个古老的原则因三个原因而变得更加尖锐。代理很多——指令失效的概率会乘以每个代理的每次运行。代理很快——从“开始出错”到“彻底搞坏”只隔几秒,人来不及干预。而且代理字面化但不可靠:它们比任何初级工程师都更努力地执行提示词文本,但仍然是概率性的——而概率性的规则遵守在大规模下必然导致违规。
边界在实践中是什么样子
我在这次会话之后搭建的层次——从文件系统到验证:
- 文件系统: 每个代理——自己的工作副本(git worktree, Anthropic 推荐 用于并行会话,在 Claude Code 中它已内建),而在操作系统层面——沙箱: Claude Code 中的沙箱化 用操作系统自带的原语隔离文件系统和网络——据 Anthropic 称,这将其内部权限请求减少了 84%,而成功的提示注入仍被锁在里面。
- 写权限: 生产和 master 靠权限保护,而不是靠提示词——受保护分支、无推送权限的令牌、为代理设置独立账户。可以在提示词里请求保留,但只能作为第二层。
- 运行时: worktree 不隔离数据库、端口和容器——它们对所有副本都是共享的。运行测试和服务器的代理需要一次性资源:临时数据库、自己的端口、每个代理一个容器。
- 操作权限: 不可逆操作要经过确认或分类器——就像 Claude Code 中的 auto mode,它评估每一个操作,而不是要么凡事都问、要么什么都不问。这是一条只有经过人的明确决定才会移动的边界。
- 按产物验证: 不要相信代理的自我报告,而要相信磁盘上的痕迹。我那个卡住的代理在界面上看起来还在工作;诊断结论来自它的副本在二十分钟内没有出现新文件。提交到自己的分支也是同样的思路:结果要能经受住故障和代理的乐观。
这套方案中的指令并没有消失——它们成为最后一层,而不是第一层。提示词里的“在自己的目录里工作”仍然有用:它能降低尝试的频率。但在尝试和事故之间,应当立着一道边界,而不是希望。
诚实的保留意见
边界并非绝对:沙箱会被绕过,分类器会出错,已公开的绕过分析也经常表明这一点。因此边界要分层构建——安全领域的一切都是如此。而且边界在起步时比指令更贵:配置 worktree、权限和沙箱要花几小时,在提示词里写一行只要几秒。不对称在另一处:边界只需付一次成本,指令则要在每次运行时承担失败概率。我配置隔离的成本,在第一次无任何冲突地重跑实验时就收回了。
结论
本系列的问题是:如何在不失去控制的前提下,把 AI 代理嵌入真实工作。本文的回答是:控制不在于写给代理什么,而在于围绕它构建了什么。在往提示词里再加一句“永远不要做 X”之前,值得先问自己:能不能让 X 在技术上不可能发生?如果可以——那才是应该投入精力的正确位置。提示词可以请求;禁止应当由系统来做。
来源与参考
- Making Claude Code more secure and autonomous with sandboxing(Anthropic Engineering) ——在操作系统层面隔离文件系统和网络;84% 这一数字的来源。
- How we contain Claude across products(Anthropic Engineering,2026) ——代理产品中执行边界的整体设计。
- How we built Claude Code auto mode(Anthropic Engineering) ——权限分类器,作为“凡事都问”和“什么都不问”之间的边界。
- Poka-Yoke(Lean Enterprise Institute) ——通过流程设计防止错误的经典原则。
- git-worktree 和 git-stash ——Git 官方文档:工作副本与共享暂存的机制。
- Claude Code: Best practices for agentic coding(Anthropic Engineering) ——为并行会话使用 worktree 的建议。
- 如何用自己的代码诚实地比较 LLM:三款 Claude 模型的实验 ——本系列的上一篇文章:汇总了所述事故的实验。
