news 2026/8/15 10:08:29

【AgentScope 2.0】07-沙箱(Sandbox)详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【AgentScope 2.0】07-沙箱(Sandbox)详解

版本基准:本文档基于 AgentScope 2.0 GA(v2.0.0)编写。具体版本号以 Release Notes 为准。

一句话概括

沙箱就是把 AI Agent 关在一个隔离的安全笼子里干活——它可以在笼子里随便折腾(装软件、跑命令、写文件),但不会影响到你的主机系统,而且笼子里的东西还能被"打包带走"下次继续用。

你能学到什么

  • 为什么需要沙箱?Agent 直接在主机上跑不行吗?
  • 5 种沙箱后端怎么选:Docker、Kubernetes、Daytona、E2B、AgentRun
  • 4 种隔离级别(IsolationScope)的区别和使用场景
  • 快照机制:5 种存储后端,沙箱如何"记住"上次的状态
  • 分布式部署:多副本场景下沙箱状态如何共享
  • 并发控制:两个请求同时抢同一个沙箱怎么办
  • 自管理沙箱实例:3 种"我自己管"的场景
  • 工作区投影:宿主机文件如何同步到沙箱
  • SandboxContext 编程 API

前置知识

通用前置详见 README.md。本篇额外需要:

  • 01-overview:理解 Middleware 机制和 HarnessAgent 整体架构
  • 05-filesystem:理解 FilesystemSpec 声明式配置(本文在沙箱模式下深入展开)
  • 容器化基础(可选):基本了解 Docker 是什么,理解"镜像"、"容器"等基本概念即可

核心概念

沙箱解决什么 —— 就像给鹦鹉准备独立工作间

想象你养了一只聪明的鹦鹉(Agent),它能帮你干活:查资料、写代码、整理文件。但是:

  • 问题 1:信任问题—— 鹦鹉可能会打翻花瓶、咬坏沙发、把厨房搞乱(Agent 执行了rm -rf
  • 问题 2:连续性问题—— 鹦鹉今天干了一半的活,明天怎么让它从原地继续?(下次调用怎么恢复环境)
  • 问题 3:多副本问题—— 你开了三家分店,每家都有鹦鹉在干活,怎么让它们共享同一份进度?

沙箱就是给鹦鹉准备的一个独立"工作间"

┌─────────────────────────────────────────────────────────────┐ │ 你的家(宿主机) │ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ 沙箱(安全工作间) │ │ │ │ │ │ │ │ ┌─────────┐ ┌─────────┐ ┌─────────────────┐ │ │ │ │ │ 工作台 │ │ 工具箱 │ │ 储物柜 │ │ │ │ │ │ (文件) │ │ (命令) │ │ (已安装的依赖) │ │ │ │ │ └─────────┘ └─────────┘ └─────────────────┘ │ │ │ │ │ │ │ │ Agent 在这里干活,随便折腾,不影响外面 │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ 你的保险柜、私人文件、生产环境 —— 完全安全! │ └─────────────────────────────────────────────────────────────┘

沙箱给出的三个承诺:

问题沙箱的解决方案生活类比
执行边界文件和命令都在沙箱内部执行,碰不到宿主机鹦鹉只能在工作间里活动
跨调用恢复每次对话结束把工作间"打包",下次打开继续用拍照记录工作间的状态
多副本可用任意副本都能从共享存储恢复出同一份工作区三家分店共享同一份进度档案

5 种沙箱后端 —— 就像不同级别的安保服务

生活类比:你需要租一个仓库来存放货物。市面上有 5 种仓库可选,从"自家地下室"到"五星级安保仓库",价格和安全级别各不同。但不管选哪种,你操作货物的方式是一样的——都是"放进仓库、从仓库取出"。

┌──────────────────────────────────────────────────────────────────┐ │ 统一的沙箱接口 │ │ │ │ 不管后端是哪种,Agent 代码、工具集、AGENTS.md 都不用变 │ └───────────────────────────────┬──────────────────────────────────┘ │ ┌─────────────────────┼─────────────────────┐ │ │ │ ▼ ▼ ▼ ┌─────────────┐ ┌──────────────┐ ┌──────────────┐ │ 自建仓库 │ │ 托管仓库 │ │ 云仓库 │ │ │ │ │ │ │ │ • Docker │ │ • Daytona │ │ • E2B │ │ • K8s │ │ │ │ • AgentRun │ │ │ │ │ │ (阿里云FC) │ └─────────────┘ └──────────────┘ └──────────────┘
后端适合场景生活类比
Docker本地开发、单机部署、信任 shell自己家地下室,自己管钥匙
Kubernetes自建 K8s 集群、节点级 bind mount自建仓库大楼,有电梯和货梯
Daytona通用托管沙箱 HTTP API托管仓库,打电话就能用
E2B通用托管沙箱 + 平台原生快照高级托管仓库,自带备份服务
AgentRun阿里云函数计算 FC 3.0,中国大陆低延迟,NAS 动态挂载国内云仓库,同城配送速度最快

核心要点:所有后端实现同一组接口,你的 Agent 代码完全不用改——换后端只需要改一行配置。


IsolationScope —— 就像酒店房间的分配策略

沙箱怎么分配?是每个人独享,还是共享?这由IsolationScope(隔离范围)决定。

生活类比:酒店有不同的房型策略——有人每次入住都开新房间,有人长期包一间,还有人整个酒店只有一间大通铺。

隔离级别谁共享同一沙箱生活类比适用场景
USER(默认)同一 userId 的多个 session 共享(未传 userId 时回退为SESSIONVIP 客户专属房间跨会话共享工作区,分布式部署
SESSION每个 sessionId 独立每次入住开新房间多用户 SaaS,对话完全隔离
AGENT这个 agent 的所有用户/会话共享公司包下一间房公用公共知识库型 Agent
GLOBAL一个 store 内全局共享整个酒店一个大通铺极少使用,谨慎配置
// 配置隔离级别——只需一行.filesystem(newDockerFilesystemSpec().image("ubuntu:24.04").isolationScope(IsolationScope.USER))

并发安全提示SESSION天然并发安全(每个会话自己一份);USER/AGENT/GLOBAL在多副本部署时建议配合并发锁(见后面的"并发控制"章节)。


快照机制 —— 就像游戏存档

生活类比:你在玩游戏,每次退出前可以存档。下次进入时,系统要判断从哪里继续:游戏机还开着就直接继续(最快),游戏机关了但存档还在就读档继续,存档也没了就从头开始。

沙箱的快照机制就是这样工作的。每次call()结束时,沙箱把工作区状态打包成快照存起来;下次call()开始时按情况恢复:

沙箱 start() 被调用 │ ▼ ┌──────────────────────┐ │ workspaceRootReady? │ └──────────┬───────────┘ ╱ ╲ true false │ │ ▼ ▼ ┌───────────────┐ ┌───────────────┐ │ 容器内目录还在?│ │ 快照可用? │ └───────┬───────┘ └───────┬───────┘ ╱ ╲ ╱ ╲ 是 否 是 否 │ │ │ │ ▼ ▼ ▼ ▼ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ │BranchA│ │BranchB│ │BranchC│ │BranchD│ │ 热启动 │ │读快照 │ │读快照 │ │ 冷启动 │ │ 最快 │ │+临时文件│ │+全量 │ │ 全量 │ └───────┘ └───────┘ └───────┘ └───────┘

四个分支的含义:

分支条件行为生活类比
A容器还在 + 工作目录完好只刷新临时文件(最快)游戏机开着,直接继续玩
B容器还在 + 工作目录丢失从快照恢复 + 刷新临时文件游戏机开着,但存档丢了,读档
C容器没了 + 快照可用创建新容器 + 从快照恢复游戏机关了,读档重新开始
D容器没了 + 快照不可用创建新容器 + 全量初始化(最慢)新游戏,从头开始

快照存到哪里?取决于你配的snapshotSpec

Spec存储位置适用场景生活类比
NoopSnapshotSpec(默认)不持久化临时任务,不需要恢复一次性用品,用完即弃
LocalSnapshotSpec宿主本地文件单机长期运行家里的储物间
OssSnapshotSpecOSS/S3 兼容存储多副本分布式云端大仓库
RedisSnapshotSpecRedis低延迟、小工作区快递柜,存取快但空间小
JdbcSnapshotSpecJDBC 数据库(MySQL 等)沉淀进关系型库、可审计企业档案柜

OssSnapshotSpec/RedisSnapshotSpec/JdbcSnapshotSpec都继承自通用的RemoteSnapshotSpec,你也可以基于它实现自己的远端快照后端。


分布式沙箱 —— 就像连锁分店共享会员系统

生活类比:你开了一家连锁健身房。会员 Alice 今天在 A 店锻炼,明天出差去了 B 店。她希望两个店都能看到她的锻炼记录,B 店能接着 A 店的进度继续。

这就是分布式沙箱解决的问题:多个 Pod(分店)部署同一个 Agent,要让任意 Pod 都能接住同一用户的对话。

┌──────────────────────┐ │ 共享存储层 │ │ │ │ ┌────────────────┐ │ │ │ Redis AgentStateStore │ ← AgentState(含会话状态) │ └────────────────┘ │ │ ┌────────────────┐ │ │ │ OSS 快照存储 │ │ ← 沙箱快照 │ └────────────────┘ │ └──────────┬───────────┘ │ ┌───────────────┼───────────────┐ │ │ │ ▼ ▼ ▼ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ Pod A │ │ Pod B │ │ Pod C │ │ (分店 A) │ │ (分店 B) │ │ (分店 C) │ └────────────┘ └────────────┘ └────────────┘ │ │ │ └───────────────┴───────────────┘ │ Alice 的请求 不管落在哪个 Pod 都能恢复同一份沙箱

要实现分布式沙箱,需要三样东西:

  1. 分布式 AgentStateStore(例如基于 Redis 的实现)
  2. 远端快照存储(OSS / Redis 等非 Noop 的SandboxSnapshotSpec
  3. 合适的 IsolationScopeUSER/AGENT/GLOBAL

HarnessAgent 提供了.distributedStore(...)方法,一次性把这"分布式三件套"打包声明:传入一个DistributedStore(聚合了AgentStateStore+ 文件存储baseStore+SandboxSnapshotSpec+SandboxExecutionGuard),框架在构建期自动把它们分别装配到对应位置。

// Redis:一条龙配齐分布式存储(AgentStateStore + 文件存储 + 沙箱快照 + 执行锁)JedisPooledjedis=newJedisPooled("redis-host",6379);DistributedStorestore=RedisDistributedStore.fromJedis(jedis,"agentscope:");HarnessAgentagent=HarnessAgent.builder().name("assistant").model(model).distributedStore(store)// ← 一行配齐分布式三件套.filesystem(newDockerFilesystemSpec().image("ubuntu:24.04").isolationScope(IsolationScope.USER))// USER 级别共享.build();

说明:DistributedStore是分布式场景的统一入口。如果你显式配过.stateStore(...)SandboxFilesystemSpec.snapshotSpec(...)等局部项,会覆盖distributedStore提供的对应组件(优先级:显式 builder 方法 > distributedStore > 工作区默认值)。这样既能在分布式场景一行搞定,也能在需要时局部微调。


并发控制 —— 就像会议室预约系统

生活类比:公司有一间公共会议室(共享沙箱)。Alice 在里面开会时,Bob 不能冲进去。Bob 需要等 Alice 开完(释放锁)才能进去。会议室门口有个预约牌,写着"当前使用者"和"预计结束时间"。

USER/AGENT/GLOBAL模式下,两个 Pod 同时处理同一个用户的请求,可能会把状态写到同一个 slot,最后"后写入覆盖前写入"。加一把分布式锁就能解决:

用户 A 想用 → 检查会议室是否空闲 → 空闲?获得使用权 → 用完释放 ↓ 不空闲 等待...(轮询 retryInterval)

不同隔离级别的并发安全性:

隔离级别并发安全性说明
SESSION天然安全每个会话独立沙箱,互不干扰
USER需要保护同一用户的多个会话可能冲突
AGENT需要保护所有用户共享一个沙箱
GLOBAL需要保护全局共享,最容易冲突

HarnessAgent 内置了一个基于 Redis 的分布式锁实现RedisSandboxExecutionGuard。锁的 key 会按 scope 自动分桶(USER→ 按 userId,AGENT→ 按 agent 名)。你也可以实现SandboxExecutionGuard接口,接入其他锁后端(数据库、Zookeeper、etcd 等)。


自管理沙箱实例 —— 就像自租房 vs 酒店托管

生活类比:默认情况下,沙箱就像住酒店——前台(框架)帮你开门、关门、打扫。但有时候你想自己租一间房子,自己拿钥匙、自己决定什么时候退租。

默认沙箱的整个生命周期由框架托管。但 HarnessAgent 提供了三种"我自己管"的场景:

场景 1:我已经启动好一个容器,想让 Agent 用它

// 你自己创建并启动沙箱SandboxmySandbox=dockerClient.create(workspaceSpec,snapshotSpec,options);mySandbox.start();// 注入到调用中SandboxContextcallCtx=SandboxContext.builder().client(dockerClient).externalSandbox(mySandbox)// 框架在 call 结束时只 stop(),不 shutdown().build();agent.call(msgs,RuntimeContext.builder().sessionId("my-session").put(SandboxContext.class,callCtx)// 通过 RuntimeContext 注入 SandboxContext.build()).block();// 你自己决定什么时候销毁mySandbox.shutdown();

场景 2:我有一个具体的快照串,想恢复到那个时刻

// 从保存的状态恢复SandboxStatesavedState=dockerClient.deserializeState(savedStateJson);SandboxContextcallCtx=SandboxContext.builder().client(dockerClient).externalSandboxState(savedState)// 框架按这个 state 恢复.build();// 生命周期仍由框架管

场景 3:多个 Agent 共享同一个沙箱

把同一个externalSandbox透传给多个 Agent 的call(),最后由你自己shutdown()


工作区投影 —— 就像给工作间配标准工具

生活类比:你给鹦鹉准备了一个工作间,但每次都希望里面有一些基础工具:手册、常用工具、参考资料。这些工具可能会更新(你买了新工具),但你不希望鹦鹉的工作间是空的。

宿主机侧workspace/下的关键文件在每次沙箱启动时同步进去。按内容哈希增量同步——不变就跳过传输。

宿主机工作区 沙箱工作区 ┌─────────────────┐ ┌─────────────────┐ │ workspace/ │ │ /workspace/ │ │ ├── AGENTS.md │ 投影同步 │ ├── AGENTS.md │ │ ├── skills/ │ ──────────▶ │ ├── skills/ │ │ ├── subagents/ │ 每次启动 │ ├── subagents/ │ │ └── knowledge/ │ │ └── knowledge/ │ └─────────────────┘ └─────────────────┘ (宿主机) (沙箱内)
目录/文件用途
AGENTS.mdAgent 的身份定义和指令
skills/所有 Skill 的目录(包含 SKILL.md 和脚本)
subagents/子 Agent 的定义文件
knowledge/领域知识文件

三个关键特性:

  • 单向同步:宿主机 → 沙箱。沙箱内修改不会反向同步回宿主机
  • 增量更新:按 SHA-256 哈希比较,不变则跳过
  • 每次启动执行:保证沙箱内的文件是最新的

GA 变更(marketplace skills 预阶段):如果配置了 marketplace 技能仓库(GitSkillRepository等),HarnessSkillMiddleware会在工作区投影之前先把 Layer-1/Layer-2 marketplace skills 的资源预阶段(stage)到工作区,然后再做宿主机 → 沙箱的投影同步。这保证 marketplace 技能的脚本/资源也能正确进入沙箱,而不是只投影 workspace 本地目录(源码 commit37bb6e7e)。

如果你改了skills/里的脚本,下次call()沙箱里就是新版。想取沙箱里的产物,让 Agent 自己read_file读出来。


关键代码解读

1. 最小 Docker 沙箱示例

// 创建一个使用 Docker 沙箱的 AgentHarnessAgentagent=HarnessAgent.builder().name("code-agent")// Agent 名称.model(model)// 模型配置.filesystem(newDockerFilesystemSpec().image("ubuntu:24.04"))// 指定 Docker 镜像.build();// 调用——每个 sessionId 对应一个独立沙箱agent.call(msg,RuntimeContext.builder().sessionId("user-1-conv-1")// 不同 sessionId → 不同沙箱.build()).block();

sessionId不同 → 沙箱不同;相同sessionId→ 自动复用同一沙箱(或从快照恢复)。

2. USER 级别 + OSS 快照 + 分布式部署

// 配置 OSS 快照存储OssSnapshotSpecsnapshotSpec=newOssSnapshotSpec(ossClient,// OSS 客户端"my-bucket",// Bucket 名称"agentscope/"// 存储路径前缀);// 创建 Agent,支持分布式部署HarnessAgentagent=HarnessAgent.builder().name("assistant").model(model).distributedStore(// ← 分布式存储:配齐 stateStore + 快照 + 锁RedisDistributedStore.fromJedis(jedis,"agentscope:")).filesystem(newDockerFilesystemSpec().image("ubuntu:24.04").isolationScope(IsolationScope.USER)// USER 级别共享.snapshotSpec(snapshotSpec))// 显式指定 OSS 快照(覆盖 distributedStore 提供的).build();// 两次调用,不同 session,但同一个 userId → 共享沙箱agent.call(msgs,RuntimeContext.builder().userId("alice")// ← 相同 userId.sessionId("session-1").build());agent.call(msgs,RuntimeContext.builder().userId("alice")// ← 恢复到同一个沙箱.sessionId("session-2").build());

3. 并发控制——Redis 分布式锁

// 配置 Redis 分布式锁UnifiedJedisjedis=newJedisPooled("redis-host",6379);SandboxExecutionGuardguard=RedisSandboxExecutionGuard.builder(jedis).leaseTtl(Duration.ofMinutes(30))// 比最坏情况 call 时长稍长.retryInterval(Duration.ofMillis(500))// 轮询间隔.build();// 把锁配到沙箱上HarnessAgentagent=HarnessAgent.builder().name("assistant").model(model).filesystem(newDockerFilesystemSpec().image("ubuntu:24.04").isolationScope(IsolationScope.USER)// USER 级别需要加锁.snapshotSpec(redisSnapshotSpec).executionGuard(guard))// ← 分布式锁.build();

4. 自管理沙箱——自己控制生命周期

// 你自己创建沙箱SandboxmySandbox=dockerClient.create(workspaceSpec,snapshotSpec,options);mySandbox.start();// 构建调用上下文SandboxContextcallCtx=SandboxContext.builder().client(dockerClient).externalSandbox(mySandbox)// 告诉框架:这个沙箱我自己管.build();// 调用 Agent——框架只做 stop(),不做 shutdown()agent.call(msgs,RuntimeContext.builder().sessionId("my-session").put(SandboxContext.class,callCtx)// 通过 RuntimeContext 注入 SandboxContext.build()).block();// 你自己决定什么时候销毁mySandbox.shutdown();

整体流程图

┌─────────────────────────────────────────────────────────────────────────────┐ │ 沙箱模式完整流程 │ └─────────────────────────────────────────────────────────────────────────────┘ ┌──────────────────┐ │ agent.call() │ └────────┬─────────┘ │ ▼ ┌───────────────────────────────────┐ │ SandboxLifecycleMiddleware │ │ (PreCall) │ └─────────────────┬─────────────────┘ │ ▼ ┌───────────────────────────────────┐ │ SandboxManager.acquire() │ │ │ │ Priority 1: externalSandbox? │──▶ 用户管理的沙箱 │ Priority 2: externalState? │──▶ 从指定状态恢复 │ Priority 3: stateStore 有状态? │──▶ 按隔离范围恢复 │ Priority 4: 创建新沙箱 │──▶ 冷启动 └─────────────────┬─────────────────┘ │ ▼ ┌───────────────────────────────────┐ │ Sandbox.start() │ │ │ │ ┌─────────────────────────┐ │ │ │ 4-分支恢复逻辑 │ │ │ │ │ │ │ │ A: 热启动(容器+目录都在)│ │ │ │ B: 读快照(容器在,目录丢)│ │ │ │ C: 读快照(容器没了) │ │ │ │ D: 冷启动(全量初始化) │ │ │ └─────────────────────────┘ │ │ │ │ 应用 WorkspaceProjectionEntry │ │ (同步 AGENTS.md, skills/ 等) │ └─────────────────┬─────────────────┘ │ ▼ ┌───────────────────────────────────┐ │ Agent 执行 │ │ │ │ ┌─────────────────────────────┐ │ │ │ ShellExecuteTool │ │ │ │ → 在沙箱内执行命令 │ │ │ │ │ │ │ │ FilesystemTool │ │ │ │ → 在沙箱内读写文件 │ │ │ └─────────────────────────────┘ │ └─────────────────┬─────────────────┘ │ ▼ ┌───────────────────────────────────┐ │ SandboxLifecycleMiddleware │ │ (PostCall/Error) │ └─────────────────┬─────────────────┘ │ ▼ ┌───────────────────────────────────┐ │ Sandbox.stop() │ │ │ │ 1. 打包工作区为 tar │ │ 2. 上传到快照后端(OSS/Redis) │ │ 3. 设置 workspaceRootReady=true │ └─────────────────┬─────────────────┘ │ ▼ ┌───────────────────────────────────┐ │ 持久化 SandboxState │ │ (存到 SessionSandboxStateStore)│ └─────────────────┬─────────────────┘ │ ▼ ┌───────────────────────────────────┐ │ SandboxManager.release() │ │ │ │ 自管理:调用 shutdown() 销毁容器 │ │ 用户管理:不销毁,容器继续运行 │ └─────────────────┬─────────────────┘ │ ▼ ┌──────────────────┐ │ call() 返回 │ └──────────────────┘

模块关系与学习顺序

  • 文件系统SandboxFilesystemSpec把文件读写和 Shell 执行路由到隔离环境
  • 工作区:工作区内容会投影到沙箱,为 Agent 提供统一的目录和规则
  • 上下文:沙箱句柄通过RuntimeContext在一次调用中传递,快照用于跨调用恢复
  • 计划模式:规划阶段限制写操作,沙箱负责执行阶段的环境隔离,两者解决不同层面的安全问题

学习要点

必须记住

  1. 沙箱 = 隔离 + 可恢复 + 可分布:三个承诺对应三个核心能力——执行边界、跨调用恢复、多副本部署
  2. 5 种后端,代码不用改:Docker、Kubernetes、Daytona、E2B、AgentRun 都实现同一组接口,换后端只改配置
  3. 5 种快照后端NoopSnapshotSpec(不存)、LocalSnapshotSpec(本地)、OssSnapshotSpec(OSS/S3)、RedisSnapshotSpec(Redis)、JdbcSnapshotSpec(数据库)
  4. 分布式三件套:分布式 AgentStateStore + 远端快照 + 合适的 IsolationScope;用.distributedStore(...)一行配齐
  5. SESSION 天然安全,其他级别要加锁USER/AGENT/GLOBAL在多副本下必须配SandboxExecutionGuard

容易混淆

  1. IsolationScope vs SnapshotSpec

    • IsolationScope:决定"谁和谁共享同一个沙箱"(隔离粒度)
    • SnapshotSpec:决定"快照存到哪里"(存储位置)
    • 两个是独立的维度,可以任意组合
  2. 自管理 vs 用户管理

    • 自管理(Self-managed):默认行为,框架全权负责沙箱的创建、启动、停止、销毁
    • 用户管理(User-managed):通过SandboxContext.externalSandbox()注入,框架只stop()shutdown()
  3. 工作区投影 vs 快照

    • 工作区投影:宿主机 → 沙箱的单向同步(AGENTS.mdskills/等),每次启动执行
    • 快照:沙箱工作区的完整打包保存(包括pip install的依赖、生成的文件等),call()结束时执行

实践建议

  1. 开发阶段用 Docker + SESSION:最简配置,本地就能跑,不需要分布式组件
  2. 上线前切换到 OSS 快照 + USER 隔离:生产环境必须持久化快照,避免冷启动
  3. 分布式场景一定配锁USER/AGENT/GLOBAL级别 + 多副本 = 必须加RedisSandboxExecutionGuard
  4. 分布式场景用.distributedStore(...)一次配齐:传入DistributedStore(如RedisDistributedStore.fromJedis(jedis, prefix)),框架自动把 AgentStateStore、文件存储、沙箱快照、执行锁都装配好,避免漏配某一环导致跨副本状态不一致

常见问题

Q:什么时候该用沙箱,什么时候用本地文件系统?

维度沙箱模式本地文件系统
执行位置隔离容器内宿主机
Shell 命令在沙箱内执行在宿主机执行
适用场景不可信输入、需要隔离、多副本可信环境、轻量级、单机
复杂度较高(需要容器基础设施)较低

Q:5 种沙箱后端怎么选?

你的场景是什么? ├── 本地开发,有 Docker → Docker ├── 自建 K8s 集群 → Kubernetes ├── 需要托管沙箱,不关心基础设施 → Daytona / E2B ├── 阿里云用户,中国大陆业务 → AgentRun(低延迟 + NAS) └── 需要自定义隔离环境 → 实现自己的沙箱后端

Q:NAS-first 模式为什么比 tar 快照快?

传统 tar 快照: 沙箱工作区 → 打包 tar → 上传 OSS → 下次下载 → 解压到沙箱 (大工作区可能需要几分钟) NAS-first: 沙箱工作区 → 直接在 NAS 上 → 下次启动直接可用 (秒级恢复,因为文件一直都在 NAS 上)

Q:如何调试沙箱问题?

  1. 查看SandboxLifecycleMiddleware日志,确认走了 4-分支中的哪一个
  2. 检查SessionSandboxStateStore中的状态是否正确持久化
  3. 检查快照是否成功上传到 OSS/Redis
  4. AgentRun 可通过GetSandboxAPI 查看沙箱状态

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/15 9:59:59

NCM文件解密完整指南:用ncmdump快速解锁网易云音乐格式

NCM文件解密完整指南:用ncmdump快速解锁网易云音乐格式 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 开通了会员、下载了整张专辑,结果文件后缀清一色是 .ncm,除了网易云音乐App谁也打不开——这…

作者头像 李华
网站建设 2026/8/15 9:57:55

Allegro 17.4 BRD文件导入Altium Designer全流程实战指南

1. 项目概述:跨越设计工具的鸿沟作为一名在电子设计行业摸爬滚打了十几年的老工程师,我几乎每天都在和各种EDA工具打交道。Cadence Allegro和Altium Designer(AD)无疑是这个领域的两大巨头,各自拥有庞大的用户群体和独…

作者头像 李华
网站建设 2026/8/15 9:57:35

图片转换ICO(图标)—批量转换

语言:WPF C# 批量图标转换 本项目基于 WPF .NET Framework/.NET Windows 开发一款桌面端批量图标转换工具,核心实现多张 PNG/JPG 图片一键批量生成多尺寸内嵌一体的标准 ICO 图标文件,适配 Windows 程序、软件快捷方式、网站图标、EXE 程序…

作者头像 李华