跳到正文
AI 知识地图 0.18 · 2026-07-30
关于与纠错文字目录 / Search
理解原理

代码执行与沙箱:让模型计算,但不把主机交给它

理解生成—执行—观察闭环的能力来源,以及进程、文件、网络、资源、凭据与人工授权组成的隔离边界。

核心命题 代码执行把语言模型的意图转换为可重复的确定性计算,但任何生成代码都应视为不可信输入;可靠系统依赖临时沙箱、最小权限、资源限额、输出验证和高风险审批,而不是依赖模型承诺安全。
读完你应该能:解释代码工具为何提升可靠性;画出执行闭环;列出六类隔离;区分沙箱与虚拟环境;安全处理依赖、文件、网络、秘密和输出。
  1. 将任务拆成最小可执行、可回退、可审计且可重放的步骤。
  2. 按风险配置隔离、权限和限额。
  3. 执行并捕获完整状态。
  4. 失败时只提供必要反馈并限制修正次数。
  5. 用测试、哈希或业务规则验收产物。
  6. 高影响外部动作在沙箱之外重新授权。

1代码工具补的是哪类能力直觉

模型能够流畅地解释一个算法,却可能在计算一个大数时给出错误答案,这并非偶然。语言模型擅长把目标转述成程序,而解释器擅长对明确的规则进行精确、可重复的执行。两者解决的问题不同:前者负责“意图的表述”,后者负责“规则的落地”。把计算、数据转换、绘图和测试这些确定性任务交给代码,本质上是用一次真实执行的结果替换掉“凭语言猜结果”,再用这个可观察的结果去校正下一步的判断。

代码执行因此是一种工具:它让解释器运行候选程序,并返回可观察的证据。它的输入是任务、代码、数据与运行环境;它的输出是运行结果、日志与产物。其工作方式遵循“生成—执行—观察—修正”的循环——先由模型生成候选程序,再由解释器执行,模型观察输出后修正自己的下一步。这个循环的价值在于留下了程序、输入、环境版本与输出,使整个过程可以被独立复核,也可以被确定性重放。

需要严格区分的是,一次执行结果能说明的只是“这个程序在这个环境中这次运行产生了什么”,它不能自动证明程序正确、安全,也不等于获得了发布授权。正确性需要另外的验证,安全性需要另外的隔离,发布授权需要另外的决策。代码执行补的是“确定性计算与可观察反馈”这一类能力,而不是对结论的最终背书。

2最小执行闭环工程

代码从生成到被信任,要依次经过生成、边界检查、隔离执行、观察记录、反馈修正和独立验收这几个状态,每个状态都由不同的主体负责,不能互相替代。

闭环的输入是候选代码、只读数据、运行策略和完成谓词。所谓完成谓词,是一个可以在执行之外独立判定“任务是否真正成功”的条件,而不是“进程是否正常退出”。模型提出代码、输入、预期产物和这个完成谓词之后,宿主先做静态检查:检查工具、依赖、权限与资源策略;一旦不满足策略,宿主应当拒绝执行,而不是让代码自行降级去迁就。随后,只读输入被复制进一个全新的沙箱,在非特权身份下运行,宿主捕获 stdout、stderr、退出码、信号、资源峰值、网络尝试和文件差异。这些观测结果回到 Agent;失败时只暴露必要的诊断信息,并限制修正次数,防止无限重试。

执行结束后是独立验收:宿主不把“进程成功退出”当作任务成功,只导出被允许的产物。整个闭环中,控制平面负责创建环境、注入策略和决定导出,数据平面只运行候选代码。候选进程既不能访问控制平面的令牌,也不能修改自身的限额;否则所谓沙箱就只是被隔离对象自愿遵守的约定,边界形同虚设。

理解这条闭环的要点在于:宿主先设边界,再执行、观察、验收;退出码 0 只表示进程正常结束,不代表任务完成。一旦控制令牌对候选进程可见,或者完成谓词无法在外部独立检查,闭环就失去了真正的边界。

3为什么必须假设代码有害威胁

模型没有恶意,生成出的代码却仍然要按攻击载荷来处理,原因是威胁不由生成者的意图决定,而由代码的能力和它实际可达的资源决定。提示注入、拼错或误装的依赖、从网页复制来的片段,乃至普通的编程错误,都可能导致删文件、读取秘密、扫描内网、进入无限循环或耗尽资源。作者“只是想算个平均值”并不降低这些后果的真实性。

因此威胁模型应当从“最坏可达效果”出发,而不是从“作者是否好心”出发。需要逐一确认:代码能读哪些路径、能连接哪些地址、以谁的身份运行、能创建多少子进程,以及它的输出是否会触发下游解析器。即便主任务只是计算平均值,只要运行时继承了云凭据和内网访问权限,它就同时拥有了与任务无关的巨大攻击面。最小权限原则要求的是先删除不需要的能力,而不是在提示里礼貌地请求代码“不要使用”。

eval 并不是 exec 的安全替代:两者都可能执行不可信表达式,安全边界必须建立在独立的执行环境之上,而不是靠挑选某个解释函数来获得。

这个威胁模型的输入,是代码可调用的能力、可达的文件与网络、运行身份和下游解析器;输出是最坏可达影响,以及应当删除的权限。它解决的是“作者没恶意是否就安全”这类误判。它产出的结论用于配置防护,而不是预测某次攻击一定发生;未知漏洞和配置错误仍可能穿透已知边界,所以防护结论是持续收紧的起点,而非一劳永逸的保证。

4沙箱要隔离哪些资源安全

只开一个新进程远远不够,因为威胁来自多个正交的维度,任何一个维度失守都足以造成损害。沙箱需要在五类资源上同时设立边界,并记录每类资源对应的控制证据。

文件方面,使用临时工作区、只读输入,禁止访问主机路径与设备,并记录挂载清单和最终的文件差异。网络方面,默认断网,或仅允许目标与协议的白名单,阻断内网元数据,同时记录 DNS 查询与连接尝试。资源方面,为 CPU、内存、磁盘、进程数和墙钟时间设上限,并记录峰值、终止原因与超限项。身份方面,使用非特权用户、不携带宿主凭据、限制系统调用,并记录有效 uid、capability 与策略版本。生命周期方面,每个任务重建环境,用后即销毁并清理产物,记录环境 id 与创建、销毁时间。

这些控制必须同时存在:只限制 CPU 并不能阻止秘密外传,只断网并不能阻止覆盖宿主文件,只用临时目录也不能防止 fork bomb。输出通道同样属于边界的一部分——stdout、图片、压缩包和电子表格都要限制大小、类型和解析方式,否则攻击只是从执行器被转移到了查看器。

使用这张隔离表时,输入是任务真正需要的资源以及可承受的损失,输出是五类隔离策略及对应的审计记录。宿主对文件、网络、资源、身份和生命周期分别设限,再做联合检查。日志显示未越界,只能解释本次已经观察到的行为;它不能证明共享内核或查看器不存在未知漏洞。

边界控制需要记录的证据
文件临时工作区、只读输入、禁止主机路径与设备挂载清单和最终文件差异
网络默认断网或目标/协议白名单、阻断内网元数据DNS 与连接尝试
资源CPU、内存、磁盘、进程数和墙钟上限峰值、终止原因和超限项
身份非特权用户、无宿主凭据、最小系统调用有效 uid、capability 与策略版本
生命周期每任务重建,用后销毁并清理产物环境 id、创建/销毁时间

5虚拟环境不等于安全沙箱消歧

Python 的 venv 或依赖容器并不会自动隔离主机。venv 主要隔离的是包版本,它不限制文件访问、网络和系统调用;容器虽然提供命名空间与资源控制,但错误的挂载、特权模式,或者共享内核中的漏洞,仍然可以破坏隔离。面对高风险场景,需要叠加更强的组合:非特权容器、只读根文件系统、系统调用过滤、微型虚拟机,以及外部网络策略。

“可复现”与“隔离”也不是同一件事。锁文件、固定运行时和确定性随机种子帮助重放结果,却不限制权限;微型虚拟机强化了边界,却仍可能因为未锁定依赖而得到不同的结果。可靠的执行必须同时回答两个独立的问题:这个程序能否逃逸或破坏环境,以及同一个输入能否被再次算出同样的结果。

做选择时,输入是复现要求、攻击风险,以及需要向宿主开放的能力;输出是依赖环境、容器或微型虚拟机的组合。venv 解决的是包版本冲突,沙箱解决的是越权和损失半径,两者的工作目标不同。容器本身不是安全结论,特权模式、危险挂载或过宽的出网权限都会让隔离失效。

6依赖与结果也不可信供应链

即使代码本身看起来安全,风险仍可能从依赖和产物这两条路径进入。依赖方面,安装包可能被拼写劫持——用一个名字相近但内容不同的包冒充目标包——也可能在安装时执行任意脚本。产物方面,生成的文件可能包含宏、公式注入或巨量数据。应对方式是使用允许列表、锁定版本和内部镜像来约束依赖,同时扫描产物并限制其类型与大小;只有经过验证的结果才被复制出沙箱。

供应链检查的输入是依赖名称、版本、来源和待导出文件,输出是允许或拒绝的决定以及扫描证据。它通过锁定版本、使用可信镜像、类型与大小检查来阻断依赖和产物夹带的风险。

需要清醒的是,通过扫描只说明已知规则没有命中,并不能保证绝对安全;未知的恶意包、宏和解析器漏洞仍然存在,因此最小权限和安全查看仍然必须保留。锁定版本与可信镜像降低了依赖被替换的概率,而类型与大小限制降低了产物在查看器中引爆风险的概率,两者叠加才构成对供应链这条隐蔽路径的有效约束。

7预算必须能算,而不是写“适量”推导

单轮限时 30 秒、最多重试 3 次,用户却仍可能等待两分钟,原因在于端到端等待时间不是单轮上限,而是整个修正循环的上界。最坏墙钟时间可以用公式表示为:

T最坏 ≤ (1 + N重试) × T单轮 + T排队与启动

公式输入三个量:N重试 是首次失败后最多再执行的次数,T单轮 是一轮允许占用的最长墙钟时间,T排队与启动 是等待资源与创建沙箱的额外预算;输出 T最坏 是用户端到端等待上界。这里的“最大重试数”不含首次执行。若单轮 30 秒、允许失败后再试 3 次、排队与启动共预留 12 秒,则最坏端到端预算是 (1+3)×30+12 = 132 秒,而不是 30 秒。

输出同样要能算。若最多允许 20 个文件、单文件 5MB,仅文件导出理论上就可达 20×5 = 100MB;因此还需另设一个总产物上限,避免用许多小文件绕过单文件限制。

预算需要沿多个轴分别设硬上限,并规定超限动作。计算上设 2 CPU、512MB、30 秒,超限即终止整组进程并记录超限项;并发上设 64 个进程或线程,拒绝继续创建以防 fork bomb;存储上设临时盘 1GB、导出总量 40MB,超限停止写入且不导出半成品;反馈上设 stdout+stderr 共 2MB,超限截断并保留哈希与尾部诊断;尝试上设首次加 3 次修正,超限停止自动循环,交由外部策略决定。

预算应当是双层的:沙箱内限额约束单次执行,控制器的端到端预算约束整个修正循环;缺了任何一层都可能造成资源失控。这个上界依赖配置假设,是约束性的上限,不是实际耗时的预测,也不覆盖外部人工审批的时间。

预算轴示例硬上限超限动作
计算2 CPU、512MB、30 秒终止整组进程并记录超限项
并发64 个进程/线程拒绝继续创建,防 fork bomb
存储临时盘 1GB、导出总量 40MB停止写入;不导出半成品
反馈stdout+stderr 2MB截断并保留哈希与尾部诊断
尝试首次 + 3 次修正停止自动循环,交给外部策略决定
T最坏(1+N重试)·T单轮+T排队与启动

8从意图到可信结果综合

让执行反馈提升能力而不是扩大损失半径,靠的是一条把意图逐步收紧成可信结果的链路。第一步是把任务拆成最小可执行、可回退、可审计且可重放的步骤;第二步按风险等级配置隔离、权限和限额;第三步执行并捕获完整状态;第四步在失败时只提供必要反馈并限制修正次数;第五步用测试、哈希或业务规则验收产物;第六步,高影响的外部动作要在沙箱之外重新授权。

这条综合链路的输入是任务意图、风险等级、候选代码和完成谓词,输出是通过验收的有限产物,或者带证据的停止结果。每一步都在缩小动作的范围,同时让下一步变得可验证:拆解限定了单步的破坏面,配置限定了运行的能力,捕获限定了可追查的状态,反馈限定了重试的规模,验收限定了可导出的产物,而重新授权则把真正危险的动作挡在沙箱的信任边界之外。

通过沙箱验收只表示产物满足了已声明的规则,不等于允许把它发布、转账或写入生产。发布、转账和写生产都是高影响的外部动作,必须重新授权。执行反馈提升的是模型逐步校正意图的能力,而损失半径由每一步的边界和最后的重新授权共同约束。

9一次缓存修复怎样在沙箱中被证明运行示例

模型提出一个复合缓存键的修复方案后,不能直接把补丁写进生产仓库并宣布完成,因为“提出方案”和“方案已被证明可行”之间隔着一整条验证链路。补丁要先经过宿主策略门,进入临时沙箱执行,产物通过验证之后,才由宿主决定是否导出。安全边界由宿主在执行前配置、执行后复核;沙箱内的进程不能自行扩大网络、文件或凭据权限。

观察证据和它能证明的内容需要逐项区分。退出码为 0,只能证明测试进程正常结束,不能证明测试覆盖完整、业务目标正确。测试通过 4/4,只能证明已声明的隔离与命中行为通过,不能证明隐藏的并发问题或跨版本问题不存在。资源峰值 310MB / 6.2s,只能证明本次低于 512MB / 30s 的限额,不能证明任意输入规模都安全。文件差异显示 2 个允许文件,只能证明本次未观察到越界写入,不能证明代码没有其他安全缺陷。

资源限额并不是“防坏人”专用:一个错误递归就可能耗尽内存。在这个例子里,允许的 3 次修正意味着最多执行 4 轮,单任务执行部分的上限是 4×30 = 120 秒;再加上排队与启动才是完整预算。

失败的边界在于:沙箱降低的是损失半径,它不会把恶意代码变成安全代码。共享内核漏洞、错误挂载、过宽的出网权限和宿主代理接口都可能穿透边界。高风险系统需要采用分层隔离、及时打补丁和外部策略检查,而不是依赖单一沙箱给出绝对保证。

候选补丁复合缓存键+ 回归测试宿主策略门只读输入副本断网 · 无凭据2 CPU / 512MB / 30s临时沙箱应用补丁 → 运行测试捕获 exit/stdout/stderr记录文件 diff / 资源峰值超限立即终止并销毁独立验收隔离 2/2命中 2/2无越界文件失败证据仅回给修正循环;通过产物也只导出补丁,不携带沙箱秘密与临时文件
图 1 安全边界由宿主在执行前配置、执行后复核;沙箱内进程不能自行扩大网络、文件或凭据权限。
观察能证明什么不能证明什么
退出码0测试进程正常结束测试覆盖完整、业务目标正确
测试4/4已声明隔离与命中行为通过隐藏并发、跨版本问题不存在
资源峰值310MB / 6.2s本次低于 512MB / 30s任意输入规模都安全
文件差异2 个允许文件本次未观察到越界写入代码没有其他安全缺陷

10怎样证明策略真的生效评测

“配置里写了断网”本身不是证据;要证明策略真的生效,应当让测试主动尝试越界,并从沙箱之外观察结果。对抗测试逐项验证隔离是否真正起作用,每一类测试都对应一个期望的观察结果,以及失败时优先排查的位置。

读取宿主秘密诱饵时,期望路径不可见,审计日志中没有内容泄漏;若失败,优先查挂载、环境变量和代理凭据注入。访问公网与云元数据地址时,期望连接被宿主网络策略拒绝并留下痕迹;若失败,优先查 DNS、IPv6、代理和旁路接口。fork bomb 或无限循环时,期望进程数或墙钟超限,整组进程被清理;若失败,优先查 cgroup/job object 和子进程回收。写满磁盘或巨量 stdout 时,期望配额触发且宿主服务仍然可用;若失败,优先查临时盘、日志与导出总量上限。符号链接或压缩包路径穿越时,期望导出器拒绝沙箱之外的目标;若失败,优先查路径规范化和解包器。正确程序与业务反例组合时,期望安全测试通过,但错误产物被业务谓词拦截;若失败,优先查验收覆盖而非隔离层。

这意味着存在两张必须分开看的成绩单:安全性评测问“越界是否被阻断”,任务评测问“结果是否正确”。某一张满分不能替代另一张。对抗测试只能增加对已测策略的证据,它不能证明不存在未知逃逸;安全测试通过也不等于任务做对,反之亦然。两张成绩单分别回答两个不同的问题,必须同时成立,策略才算真正生效。

对抗测试期望观察若失败,优先查哪里
读取宿主秘密诱饵路径不可见,审计日志无内容泄漏挂载、环境变量、代理凭据注入
访问公网与云元数据地址连接被宿主网络策略拒绝并留痕DNS、IPv6、代理和旁路接口
fork bomb / 无限循环进程数或墙钟超限,整组进程被清理cgroup/job object、子进程回收
写满磁盘 / 巨量 stdout配额触发且宿主服务仍可用临时盘、日志与导出总量上限
符号链接或压缩包路径穿越导出器拒绝沙箱外目标路径规范化和解包器
正确程序与业务反例安全测试通过,但错误产物被业务谓词拦截验收覆盖而非隔离层
资料来源与改编说明
访问日期:2026-07-23