给 agent 全放开权限之后:跑得快也出事快,到底该给到哪一步
数据截至 2026-07,各产品的额度与报错口径以官方最新说明为准。
你以为出事是模型不听话,其实多半是你的工作区不可回滚。 这是我看到的最普遍的归错因:一次 agent 把不该动的文件改了、把分支历史搞乱了、把密钥读进了会话,人的第一反应是”这模型不行”或者”我话没说清”,于是回去改叮嘱、加一堆”禁止修改 xxx”。下一次照样出事。真正决定损失大小的从来不是模型有多听话,而是三件工程上的事:这个动作可不可逆、影响面是本地还是共享还是线上、事后你能不能靠 diff 和日志把它看清楚。权限该给到哪一步,答案就藏在这三个维度里,不在措辞里。
站内还有三篇相邻的文章,分工和本篇不同:被沙箱拦住之后怎么继续干活讲的是权限已经被拒绝时的绕行与排查,Plan Mode 怎么用讲的是某个具体的只读工作方式,人在环路里的介入设计讲的是确认环节怎么设计才不烦人。本篇只回答一个前置问题:这个权限该不该给,以及给出去之后代价长什么样。
一、先止血:出事后的头几分钟别急着修
已经出事的场合,最贵的动作是”让 agent 自己把它改回来”。它没有你的历史视角,往往在错误的基础上继续叠改动,diff 越滚越大,等你想回滚已经分不清哪一层是原始状态。
顺序是这样的:停掉正在跑的会话,不要追加”你刚才改错了,撤销一下”。然后用最笨的方式看现场:
git status --porcelain
git diff --stat
git stash list
git reflog -n 30
四条命令回答四个问题:现在有哪些改动、改动摊在多少文件上、有没有人早先 stash 过、HEAD 最近被谁挪过。git reflog 是关键那条,绝大多数看起来”提交没了”的情况都能在这里找回来,因为本地引用日志会保留一段时间的历史移动记录。
如果改动还没提交、也不值钱,最干净的办法是整体丢掉重来,而不是逐个文件挑:
git checkout -- .
git clean -nd # 先看会删哪些未跟踪文件
git clean 一定先带 -n 空跑看清单,直接 -fd 删掉的东西没有地方找回来。止血完成之后再进入分因,别混着做。
二、分因:三类权限事故,判别方法完全不同
“agent 权限出事”其实是三种不同的故障被塞进了一个说法里。
第一类是不可逆写操作。 特征是损失一步到位:历史被重写、远端被覆盖、文件被删、数据库结构被改。这类事故的成因几乎都是自动允许清单里混进了不可逆命令,而不是模型突然发疯。
第二类是越界读。 特征是没有任何东西坏掉,但敏感内容离开了它该待的地方——密钥、客户数据、内部文档被读进上下文,再顺着会话记录、日志、甚至提交流向别处。这类最容易被忽略,因为它不报错、不红、不影响构建。
第三类是改动范围沉默扩散。 特征是任务本身完成了,但顺手改了配置、升了依赖、重构了旁边一个文件。当天看不出问题,几天后在别人机器上或者构建机上炸。这类的根源是任务边界太宽,不是权限太大。
下面这张表是我在真出事时按现象往下查的路径:
| 现象 | 大概率成因 | 怎么验证 | 处置动作 |
|---|---|---|---|
任务只要求改一处,git status 却列出十几个文件、跨了好几个目录 | 改动范围沉默扩散,顺手重构 | git diff --stat 看文件数和目录分布,重点看有没有动锁文件、CI 配置和格式化后整片重排的文件 | 整体回退到上一个已知良好提交,改为按目录授权,一次只开一个模块 |
| 分支历史对不上,本地或远端提交像凭空消失 | 自动执行了不可逆的 git 操作 | git reflog 找回本地历史,git log origin/<branch> 对照远端 | 恢复后把重置、强制推送、删分支类命令从自动允许里摘出来,只走人工确认 |
| 密钥或客户数据出现在会话记录、日志、或已提交内容里 | 越界读加上下文外泄 | git check-ignore -v .env 看忽略规则有没有命中(无输出且退出码非 0 就是没被忽略),再用 git log -S "<字段名>" --all --oneline 定位是哪一次提交把它带进去的 | 立刻轮换涉事凭证,再把敏感目录排除在可读范围之外 |
| 云上资源或数据库对象少了、结构变了 | agent 运行环境里继承了生产凭证 | 检查启动 agent 的那个 shell:printenv | grep -i -E "token|secret|key",再查对应平台的审计日志 | 生产凭证从此不进 agent 能读到的环境,改由部署流程单独持有 |
| 依赖忽然升级,本机能跑、构建机跑不起来 | 自动安装或升级依赖 | 看锁文件的 diff,然后在干净容器里从零装一遍复现 | 锁文件的任何改动列为必须人工确认 |
| 接口调用返回 401 或 403,昨天还好的 | 凭证被轮换、被撤销,或换了环境变量来源 | 用最小请求确认是凭证问题还是权限范围问题:curl -i -H "Authorization: Bearer $TOKEN" <endpoint> | 先定位凭证来源再谈权限,别一上来就放宽 agent 的执行范围 |
| 每一步都要点确认,一小时干不完十分钟的活 | 授权档位定得比实际风险高 | 回看被打断的操作,数一下其中可逆操作占多少 | 把只读和可逆命令批量放进自动允许,只把不可逆的留在确认区 |
最后一行同样是故障。授权收得过紧的代价不会立刻显形,它表现为你开始机械点确认,看都不看就点,到那一刻确认环节已经等于不存在了。
三、分级授权:四档模型,判据是可逆性
把权限分档的核心判据只有一句话:这个动作跑错了,我能不能用一条命令恢复。 能,就归入可以自动执行;不能,就必须过人。按这条线分四档。
档 0,只读。 agent 能读代码、能给方案,不落盘、不执行。适用于第一次进陌生仓库、给线上问题定位、review 别人的改动。这一档看起来低效,实际是排障时最高效的一档,因为你要的是判断而不是改动。
档 1,工作区可写、不可执行。 允许改文件,不允许跑命令。前提有两个:开工前 git status 是干净的,以及你确实会看 diff。这一档的价值在于所有产出都被 git 兜住,最坏情况是丢掉全部改动重来。注意 git checkout -- . 只还原已跟踪文件的修改,它新建的那些文件不在 git 跟踪范围里,还得配合 git clean -nd 看一遍未跟踪清单再决定删不删——只做前半步,工作区里会留下一堆你以为已经清掉的残留文件,下一轮任务就是在这堆残留上开工的。
档 2,可跑可逆命令。 测试、构建、格式化、类型检查、本地启服务,这些跑失败了只是浪费时间,恢复成本接近零,值得自动放开。不可逆的那些——删文件、重写历史、推远端、改数据、动云资源——留在确认区。这一档是日常干活的主力位置。
档 3,沙箱内全放开。 只在一次性容器或者独立工作树里给。给之前确认三件事:里面没有生产凭证、没有远端写权限、跑完只从里面取 diff 而不是取信任。
独立工作树是成本最低的隔离方式,它给你一个物理上分开的目录,agent 在里面折腾不会碰到你手上的分支:
git worktree add ../wt-agent -b agent/try-1
# 干完之后
git worktree remove ../wt-agent
需要连文件系统一起隔离时,只读挂载能挡住绝大多数误删:
docker run --rm -it -v "$PWD:/work:ro" -w /work <image> <command>
:ro 是整句话的重点,源码目录挂进去只读,容器里怎么折腾都改不到你的文件。但也正因为只读,需要它产出东西的时候,得单独再挂一个可写目录(比如 -v "$PWD/out:/out"),让产出只能落在那一个位置,取回来的时候你也只需要审这一个目录。
凭证隔离用不着复杂机制,起一个把敏感变量摘掉的进程就够:
env -u AWS_SECRET_ACCESS_KEY -u GITHUB_TOKEN -u DATABASE_URL <command>
四档之外有三条我认为不该谈判的底线:不可逆命令一律人工确认;生产凭证不进 agent 能读到的环境;每次任务从干净工作区开始。这三条守住了,档位定错也只是效率问题,不会变成事故。
顺带说一句机制的边界:各家产品的权限模型、默认放开范围、确认粒度差别很大,而且会调整,具体开关以官方最新说明为准。别把某个产品的默认值当成行业安全基线——默认值是按厂商觉得顺手来设的,不是按你的仓库风险来设的。
四、什么情况下别再折腾
工程上更常见的浪费不是出事,是出事之后不肯停。给几条我用的止损线。
同一个问题连续三轮没修好,而且每轮 diff 都在变大。 这说明它在错误的因果模型上叠补丁。停手,回滚到干净状态,自己读一遍代码,把问题重新描述一次再开工。相关的表现和处理可以对照AI 改坏代码后怎么回滚。
你已经看不懂当前的 diff。 这是硬止损点,没有例外。看不懂的改动就算能跑通也不能留,因为你失去了下一次判断的基础。回滚,然后把任务切到单文件级别重来。
出现凭证外泄迹象。 停一切别的动作,先轮换。不要一边继续干活一边”稍后处理”,轮换晚一小时和早一小时的风险差别是实打实的。轮换流程本身值得提前准备好,参见API 密钥安全管理。
任务本身涉及数据迁移、线上配置变更、资金或用户可见状态。 这类不是授权档位的问题,是别用 agent 直接执行的问题。让它写脚本、写迁移文件、写回滚方案,人来读、人来跑。
换条路的判断依据。 当你发现自己在反复调整叮嘱措辞来阻止某类行为时,就该换机制了:白名单、目录隔离、只读挂载、独立工作树,任何一种约束都比再写一句”请勿修改”可靠。用措辞去控制行为,在长会话里会被稀释;用环境去控制行为,不会。
五、避坑清单
用叮嘱代替约束。 会踩是因为自然语言约束在长会话里会被后续内容挤掉注意力,而且它不具备强制性。怎么避:凡是你真的不能接受的行为,都要有一层环境层面的拦截,叮嘱只作为补充。
在带着生产凭证的终端里开 agent。 会踩是因为凭证是从 shell 继承的,肉眼看不见,你以为没给其实一直在给。怎么避:开 agent 用专门的 shell,或者用 env -u 把敏感变量摘掉;生产凭证只放在部署流程能读到的地方。
工作区本来就是脏的。 会踩是因为事后你分不清哪些改动是自己的、哪些是它的,回滚就变成手工挑拣。怎么避:开工前必须干净,手上有活先 git stash,这一步只花五秒。
自动允许清单只增不减。 会踩是因为每次被打断你都顺手点”以后都允许”,半年后清单实质等于全放开,而你完全没有察觉这个过程。怎么避:定期把清单拉出来看一遍,按可逆性重排,不可逆的一律移出。
把沙箱当成安全。 会踩是因为沙箱通常只隔离文件系统,网络出口还在,容器里的凭证照样能往外发请求。怎么避:沙箱里不放凭证;需要联网的场景明确限制可访问的出口。
只盯写权限,忽略读。 会踩是因为读操作不报错、不留痕、不影响构建,感觉上没有代价。怎么避:把敏感目录和文件挡在可读范围外,并确认忽略规则真的生效(git check-ignore -v 能直接告诉你哪条规则命中)。
一次丢一个大任务过去。 会踩是因为影响面越大,diff 越难审,而不审的 diff 等于没有授权控制。怎么避:按”我一次能认真读完多少改动”来切任务,而不是按功能完整度来切。
内网环境里把证书报错当成权限问题。 会踩是因为公司代理做 TLS 中间拦截时,自签证书会导致证书链校验失败,报错读起来像被拦、像没权限,于是有人去放宽 agent 权限。怎么避:先分清是证书链问题还是授权问题,前者要配信任链,跟权限档位无关。
默认海外托管方案随时可用。 会踩是因为部分海外 agent 与模型产品官方并未向中国大陆提供服务、不支持直连,方案定完了才发现跑不起来。怎么避:选型阶段就把可用性确认掉;市面上存在第三方中转,但稳定性、合规与数据流向都要自己承担,我不背书也不给具体渠道。
六、收个尾
权限这件事没有一个通用的正确档位,但有一个通用的判断顺序:先问可不可逆,再问影响面多大,最后问事后能不能看清。三个答案都好,就放开自动执行;有一个不好,就加一道人工确认;两个不好,就别让它自己动手。
开工前过一遍这份自检:工作区是不是干净的、这个 shell 里有没有生产凭证、这次任务里有没有不可逆动作、如果它全做错了我用哪条命令恢复、干完之后我会不会真的逐行看 diff。五个问题都有明确答案,那你给多大权限都不算冒险;有任何一个答不上来,先别开始,把那个答案补上比事后抢救便宜得多。