.agents/design/core/ai/sandbox/index.md
状态:当前实现
最后核对:2026-08-12
用户级实例、生命周期、Legacy 迁移以及本分支后续变更的最终契约统一见 用户级 Sandbox 最终方案。本文只维护当前代码入口和运行行为索引。
OpenSandbox Kubernetes PVC 的问题定论、生命周期设计和验证记录统一见 OpenSandbox Kubernetes PVC 生命周期问题与设计。
Agent Sandbox 为 Agent 提供隔离的 Linux 运行环境、文件系统和工具调用能力,同时维护物理实例、业务归属、Provider 生命周期、归档恢复和 Skill 部署。
Sandbox 不负责 Agent 的模型循环、Workflow 调度或 Skill 版本创建。Agent Loop 只持有已经准备好的 SandboxClient,具体实例管理留在 Sandbox 模块。
目录:packages/service/core/ai/sandbox
interface
对 Workflow、API、Skill Edit 暴露稳定入口
|
application
runtime / toolCall / file / resource / archive 编排
|
infrastructure
instance repository / provider adapter / runtime profile / volume
|
provider: opensandbox | sealosdevbox
约束:
interface/* 引用,不直接依赖 infrastructure。SandboxClient 只用于运行态,可能创建或恢复实例。业务归属统一使用:
sourceType:当前支持 App 和 Skill Edit。sourceId:App id 或 Skill id。userId:实例逻辑身份的一部分。App 使用有效用户 ID;Skill Edit 固定使用
ChatSourceTypeEnum.skillEdit。chatId:只用于 App Sandbox 内的 session 目录,不参与实例或 Provider 资源 ID。sandboxId:Provider 侧的物理资源标识,不替代业务归属。当前寻址规则:
| 场景 | sandboxId | 归属 |
|---|---|---|
| App chat | app-<hash(sourceId-effectiveUserId)> | sourceType=app,userId=effectiveUserId |
| Skill Edit | skilledit-<hash(sourceId-skillEdit)> | sourceType=skillEdit,userId=skillEdit |
| Chat Agent Helper | 不支持 Sandbox | 调用时直接报错 |
agent_sandbox_instances_v2 使用 (provider, sandboxId) 唯一索引,并使用
(sourceType, sourceId, userId) 唯一约束逻辑身份。v2 不保留旧 ID 生成规则的兼容分支。
旧 appId、type 和 metadata.skillId 字段只用于 Legacy 数据识别与用户级 Sandbox 迁移。新运行态写入和业务查询只使用 sourceType/sourceId,不能新增旧字段兼容分支。
当前 Provider:
opensandboxsealosdevboxinfrastructure/provider/runtimeProfile 负责把 Provider 映射为默认镜像、工作目录、HOME、环境变量和创建参数。业务层不能根据 Provider 名称自行拼这些值。
当使用 Sandbox 时必须配置 AGENT_SANDBOX_PROVIDER;未知或缺失 Provider 显式报错。
公共 stop() 执行 Provider 自身的停止策略:OpenSandbox 删除远端计算实例但保留 FastGPT 管理的
volume、Mongo 记录和 S3 归档,Sealos Devbox 则暂停远端实例。业务级删除始终继续清理全部受管资源。
getSandboxClient 的流程是:
SandboxClient,写入或刷新 running 实例记录。上层在调用 prepareAgentSandboxRuntime 前完成普通 App 可用性判断或 Skill Edit 强可用性断言;
runtime preparation 不再接受绕过权限检查的布尔参数。随后根据标准 chat source 计算 sandboxId。
同一 sandbox 的初始化通过 Redis lease 串行化:
agent-sandbox:init:<sandboxId>
锁覆盖文件部署、entrypoint 和 Skill 扫描,避免并发请求交错修改同一工作区。租约会自动续期,获取失败转换为标准 initializing 错误。
Sandbox 初始化使用 prepareSandbox(context, ...steps) 顺序组合步骤。可复用步骤包括:
user_files。SKILL.md。具体场景只组合需要的 step,不在通用 prepare 层读取业务数据库。
App Agent 和 ToolCall 在实际使用 Sandbox 前调用 ensureAppSandboxRuntimeReady。Provider 或镜像变化时,
同一次 Workflow 先通过标准 archive/provider migration 收敛配置,再继续恢复 runtime;前端只消费
upgrading -> lazyInit 粗粒度状态。Skill Edit 保留显式确认和轮询升级。
execution_complete 或 error 终态立即结束内部流;无终态 EOF、
iterator 异常和调用方取消进入对应错误边界,不再等待 Provider 延迟关闭响应体。ISandbox 文件 API;只在解压、递归扫描等需要 shell
语义时执行命令,并通过 workingDirectory 传入已知工作目录。SandboxClient 独占 provider adapter,每次请求检查 Provider readiness;同一 client 内的并发
检查复用 Promise。当前不使用跨请求 ready cache,避免连接被关闭后仍复用过期状态。values: Record<string, string | string[]>,让 hash、etag 和版本列表共享读写、
校验、去重与空值清理逻辑。entrypoint.sh。versionId 记录,只执行一次。当前系统工具集合:
sandbox_shellsandbox_read_filesandbox_write_filesandbox_edit_filesandbox_grepsandbox_findsandbox_lssandbox_get_file_url工具定义和名称位于 packages/global/core/ai/sandbox,执行实现在 application/toolCall。runSandboxTools 统一完成 JSON 参数解析、Zod 校验、工具选择和标准结果转换。
文件/命令输出遵循共享裁剪规则;read file 使用 offset/limit,内容搜索和路径搜索分别使用 grep/find,已经不存在旧 sandbox_search 兼容入口。
普通 Agent runtime 可以把选中的已发布 Skill 版本注入 Sandbox:
SKILL.md,把名称、描述和路径写入 Agent reminder。Skill Edit 复用编辑器 Sandbox 中的当前工作区,不把编辑中的内容当成已发布版本重新下载。
内置 Skill 同步到 Sandbox HOME 下的 .fastgpt/skills/<name>,不进入用户 workspace、编辑器树、导出包或发布包。同步状态按文件内容 etag 记录,内容未变化时跳过覆盖。
sessions/<chatId> 目录。普通 App Chat 在系统关闭、App 未开启或团队套餐不可用时,不注入 Sandbox prompt、tools 和依赖
Sandbox 的 Skill,也不准备 runtime;其他对话能力继续运行。关闭原因通过
systemDisabled/appDisabled/teamPlanUnavailable 表达。
Skill Edit 和 Skill 调试保持强依赖。文件 API 在服务端重新校验可用性,checkExist 只查询本地
记录并返回可选关闭原因,不创建或恢复实例。
HTML 预览和 sandbox_get_file_url 使用 Redis preview session 签发短期只读 URL。公开请求经
agent-sandbox-proxy 回查 FastGPT,再由 Sandbox 内 fastgpt-ide-agent:1319 在 Workspace 范围内
流式返回文件;预览不再上传临时文件到 S3,也不改变 Workspace 冷归档流程。
Sandbox 文件、ticket、preview、keepalive 等 API 位于 projects/app/src/pages/api/core/ai/sandbox。API 边界负责:
parseApiInput 校验请求。sourceType/sourceId。内部 runtime 接口假定调用方已经完成普通 App 可用性判断或 Skill Edit 强可用性断言,不再重复 查询团队套餐。
| 能力 | 路径 |
|---|---|
| Runtime 接口 | packages/service/core/ai/sandbox/interface/runtime.ts |
| Tool 接口 | packages/service/core/ai/sandbox/interface/toolCall |
| Resource 接口 | packages/service/core/ai/sandbox/interface/resource |
| Preview 接口 | packages/service/core/ai/sandbox/interface/preview |
| Migration 接口 | packages/service/core/ai/sandbox/interface/migration |
| Runtime client | packages/service/core/ai/sandbox/application/runtime/client.ts |
| 初始化 pipeline | packages/service/core/ai/sandbox/application/runtime/prepare.ts |
| Skill runtime | packages/service/core/ai/sandbox/application/runtime/skill |
| 资源服务 | packages/service/core/ai/sandbox/application/resource.ts |
| 归档服务 | packages/service/core/ai/sandbox/application/archive.ts |
| Legacy migration | packages/service/core/ai/sandbox/application/legacyMigration |
| 实例仓储 | packages/service/core/ai/sandbox/infrastructure/instance |
| Provider profile | packages/service/core/ai/sandbox/infrastructure/provider/runtimeProfile |
Sandbox 改动应按影响范围覆盖: