技术 · 熟练
AI 写的代码,你让它跑在哪?
拦动作是一道闸,管环境是另一道
给 agent 上审批链,管的是它要不要动手;这一页管的是另一件事——它动的时候,手上本来有什么。差别在一次演练里就能看出来:审批链拦得住「删这个文件」,拦不住「这段代码顺手读了一遍环境变量」;而一个默认能力为空的执行环境,根本不会出现第一个问题。这一页给你一组三问(有没有文件系统 · 有没有网络 · 起一个要多久),用来选 agent 执行代码的地方,并把「跑在容器里」这条默认习惯,换成按任务分档的选择。
方法 · 一图看懂
1
先问第一问:它看得到文件系统吗 — 空沙箱里 `open('/etc/passwd')` 应当直接失败;看不到盘,就谈不上误删与越读
2
再问第二问:它连得到网络吗 — 无网络时,外泄与「顺手调一次外部接口」都不成立;需要联网就把那一次调用变成一个显式传入的函数
3
第三问:起一个沙箱多久 — 取沙箱 <1 ms 与起一个容器约 1500 ms,决定你是一次性跑一段、还是每段都新起一个
4
按任务分三档,而不是一刀切 — 可信的自己的脚本 / 模型现写的代码 / 会碰凭据与外部服务的代码,各给一档环境
5
给「可写根」画一张白名单 — 哪些目录默认可写、哪些默认不可写,写清并让它可核(而不是靠 agent 记得)
原理 · 为什么有效
审批链与沙箱解决的是两个方向的风险:审批链是动作级的——它需要正确枚举「哪些动作危险」,漏一项就漏一处;沙箱是能力级的——它把默认能力设成空,再逐项显式授予,漏授予只是少做事,不会多做危险的事。⇒ 安全性上更稳的默认值是「先没有,再按需给」,而不是「先都有,再逐个拦」。这也是为什么语言级沙箱值得单独作为一档:它不是把容器做得更小,而是让「文件系统 / 环境变量 / 网络」这三样在语言运行时这一层就不存在。
适用场景
适用于:让 agent 直接执行它自己写出来的代码的场景(数据分析 / 批量脚本 / 计算类任务)· 需要高并发跑大量小片段(容器启动开销成为瓶颈)· 处理不能外传的数据(离线环境比审批更省心)。不适用于:需要完整系统环境或需要装依赖的任务(那一类还是容器更合适);也不适用于把这一页当作安全策略的全部——它只管执行环境,凭据与授权的治理仍要另做。
自测 · 5 问
我现在的执行环境里,一段代码想读任意文件、想发一个网络请求,能不能做到?
我上一次给 agent 的执行权限,是「按需授的」还是「本来就都有」?
我知不知道自己现在起的执行环境,未加限制时哪些目录是可写的?
同类任务里,有没有哪一类其实根本不需要文件系统与网络?
如果有人问我「这段代码为什么在这个环境里跑」,我答得出来吗?
怎么上手 · 验证步骤
不要一次改架构。先做 第 3 条(给可写根画白名单)——把你当前执行环境能写的目录列一遍,标出哪些是「本来就不该让它写」的,只这一步就能挡住大多数误伤。第二步挑一类任务(最常见的是纯计算与文本处理)迁到语言级沙箱里跑,观察一周:大多数这类任务其实不需要文件系统与网络。第三步再考虑把「需要联网」的那类变成显式传入的函数调用。
做完自己核三样:① 在当前环境里跑一句尝试读 `/etc/passwd` 或等价路径的代码,看它是报错还是成功——成功说明第一问还没关上;② 说出你现在的执行环境默认不可写哪些目录,答不出说明白名单没落下来;③ 挑一类已迁移的任务,比较迁移前后单次执行耗时——如果反而变慢,说明分档分错了地方。