Files
tmp/agentscope-sandbox.md
V-LiuShuang 28f3727f43 add
2026-07-29 17:25:12 +08:00

9.6 KiB
Raw Blame History

Intro

分析 agentscope、agentscope-java 对于容器沙箱的支持。

支持的沙箱类型

沙箱类型 agentscope agentscope-java
Docker DockerWorkspace DockerFilesystemSpec
Kubernetes K8sWorkspace KubernetesFilesystemSpec
E2B E2BWorkspace E2bFilesystemSpec
Daytona DaytonaWorkspace DaytonaFilesystemSpec
AgentRun AgentRunFilesystemSpec
OpenSandbox OpenSandboxWorkspace
Bubblewrap (依赖操作系统)

架构对比

agentscope

Workspace + Backend + Gateway

WorkspaceManager (服务侧缓存 / TTL / IsolationPolicy)
        │
        ▼
SandboxedWorkspaceBase.initialize()
  ├─ _provision_backend()     ← Docker/E2B/K8s/Daytona/OpenSandbox 各实现
  ├─ _ensure_workspace_layout()  (/workspace、skills、sessions、data、.mcp)
  └─ _setup_mcp_gateway()     ← 容器内 FastAPI MCP Gateway
        │
        ▼
BackendBase (exec_shell / read_file / write_file)
  └─ 内置工具 Bash/Read/Write/Edit/Grep/Glob 透明落到沙箱内

关键设计:

  • 容器内 MCP Gateway:宿主机通过 GatewayClient + backend.exec_shell 驱动网关(一般不依赖宿主机到沙箱的端口映射)。
  • WorkspaceManagerPER_AGENT / PER_SESSION / PER_USER,空闲 TTL 驱逐;云后端可按 metadata/label 跨节点重连。

agentscope-java

Filesystem Spec + SandboxManager

HarnessAgent.Builder.filesystem(DockerFilesystemSpec / …)
        │
        ▼
SandboxFilesystemSpec.toSandboxContext(hostWorkspaceRoot)
  └─ SandboxContext(client, options, snapshotSpec, workspaceSpec, isolationScope)
        │
        ▼
SandboxLifecycleHook
  PreCall  → SandboxManager.acquire → Sandbox.start()  (四分支恢复)
  PostCall → Sandbox.stop() (tar 快照) → persist state → release
        │
        ▼
SandboxBackedFilesystem + ShellExecuteTool
  └─ 文件工具 / execute 全部转发到沙箱

关键设计:

  • 生命周期管理:每次推理前后自动 acquire/start/stop适合多租户与快照恢复。
  • 快照与沙箱解耦:换 Docker/K8s/E2B 不影响 LocalSnapshotSpec / RedisSnapshotSpec / OssSnapshotSpec 的选择。启动时把宿主 AGENTS.mdskills/subagents/knowledge/ 等打 tar 注入沙箱,按内容 SHA-256 增量跳过。

Docker沙箱双端对照表

对比项 agentscope agentscope-java
API 形态 Docker Engine API CLI
保活命令 sleep infinity while :; do sleep 3600; done
镜像策略 all-in-one镜像自动构建并内容哈希缓存 用户指定
默认网络 Docker 默认 用户指定
持久化 Bind-mount可选 Tar 快照为主 + 可选 bind-mount
生命周期 Workspace 长生命周期 按 Agent call 借还
MCP 容器内 Gateway Harness 侧注册;沙箱只做 FS/Shell
资源限制 较弱(构造参数少) memory / cpu / ports / network
水平扩展 不适合 需外置快照/状态存储

关键agentscope 通过 HTTP API 端点和 Docker 引擎交互agentscope-java 通过 cli 与 Docker 引擎交互。明显 agentscope 的设计更靠谱一些,因为通过 HTTP API 端点交互有2个好处

  • agentscope 实例本身可以容器化部署,而 agentscope-java 必需在宿主机用 java -jar 运行,因为它需要在宿主机上执行 docker run 命令。
  • 通过 HTTP API 端点 agentscope 可以控制远程服务器上的 Docker 容器。

agentscope

实现原理

  1. 镜像构建(内容哈希缓存)

    • prepare_build_context() 渲染 Dockerfile打包 gateway 脚本、requirements.txt、glob helper。
    • Tag 形如 agentscope-workspace:<12hex>,对 Dockerfile + COPY 文件做 SHA-256本地已有则跳过 build。
    • 默认基础镜像 python:3.11-slim,镜像内预装 gateway venv + agentscopeDocker 路径不做首次 bootstrap
    • 可选 node_version 从官方 Node slim 镜像拷贝 node/npm(供 npx MCP
  2. 容器启动

    • 通过 aiodocker containers.create_or_replace
    • Cmd: ["sleep", "infinity"],工作目录 /workspace
    • Labelagentscope.workspace=trueagentscope.workspace.id=<id>
    • Gateway 端口仅容器内监听,不做 host port 映射;宿主经 DockerBackend.exec 访问。
  3. 持久化

    • 可选 host_workdir bind-mount → /workspaceis_persistent)。
    • 无 mount 则为 ephemeral 容器文件系统。
    • Linux 上 teardown 时尝试 chown 把 bind-mount 文件所有权还给宿主用户。
  4. I/O 原语(DockerBackend

    • exec_shell:容器 exec API直传 argv无中间 shell需要时包 sh -c)。
    • read_file / write_fileget_archive / put_archivetar
  5. 服务侧

    • DockerWorkspaceManagerbasedir 下为每个 workspace 建宿主目录并 bind-mountTTL sweeper 回收空闲容器。

使用限制

限制 说明
依赖 Docker daemon 需本机/远端可达的 Docker Engine + aiodocker
基础镜像须含 python3 Gateway 与工具链假设 Python 可用
单节点 官方文档明确Docker/Local/Bubblewrap 不适配水平扩容;跨节点请用 E2B/Daytona/OpenSandbox/K8s
首次镜像构建成本 缓存未命中时 build 较慢;构建失败需解读 docker stream 日志
无细粒度 CPU/内存 API 构造参数侧重镜像与环境变量,资源限额不如 Java Spec 直接
Linux bind-mount 权限 容器内 root 写文件可能留下错误 uid框架仅在 teardown 做 chown 尽力修复

好处

  • 镜像内预置 gateway冷启动无需 apt/uv/pip bootstrap(对比 E2B/K8s/OpenSandbox
  • 内容哈希镜像缓存Dockerfile 不变则秒级复用。
  • Workspace 长期存活MCP / skills / sessions 与服务模型一致。
  • Bind-mount 可把工作区落在宿主磁盘,便于调试与备份。
  • WorkspaceManager 隔离策略PER_AGENT 等)无缝衔接。

弊端

  • 强依赖本机 Docker水平扩展与多副本亲和困难。
  • 常驻 sleep infinity 容器占用资源,依赖 TTL 清扫。
  • Gateway 健康检查失败时排查需看容器内日志路径。
  • 与 Java 版相比,缺少一等公民的「跨 call tar 快照后端」抽象。

agentscope-java

实现原理

  1. 配置层Spec
    Fluent APIimageworkspaceRoot(默认 /workspace)、memorySizeBytescpuCountexposedPortsnetworkenvironmentadditionalRunArgssnapshotSpecworkspaceSpec

  2. 创建与客户端

    • DockerSandboxClient.create(...) 生成 DockerSandboxStatesessionId、镜像、资源参数、快照句柄
    • 不引入 docker-java:一律 docker run / exec / inspect / stop / rm CLI。
    • 要求宿主 PATH 上有 docker,且 daemon 可达。
  3. 容器命令

    docker run -d --name agentscope-sandbox-<sessionId>
      [--memory] [--cpus] [-p] [--network=none|...] [-v bind...]
      <image> sh -c "while :; do sleep 3600; done"
    
    • 默认 --network=none(未配置 network 时),比 Python 版更偏「默认断网隔离」。
    • 支持 WorkspaceSpec 中的 BindMountEntry-v host:container:ro|rw
    • execdocker exec -w <workspaceRoot> <id> sh -c <command>
  4. 工作区 tar 快照

    • Persistdocker exec tar -cf - -C /workspace .(并对 bind-mount 路径 --exclude)。
    • Hydratedocker exec -i tar -xf - -C /workspace
    • AbstractBaseSandbox 四分支恢复:容器是否仍保留目录 × 是否有可恢复快照。
  5. 编排

    • start():确保容器 running → 四分支初始化 → workspace projection。
    • stop():写快照,容器可继续跑
    • shutdown():自管容器则 docker stop + docker rm --force

使用限制

限制 说明
依赖 Docker CLI 无嵌入式 Engine APIWindows/远程 Docker 场景需确保 CLI 行为一致
默认无网络 network 未设时为 none;需要拉包/访问外网必须显式配置
镜像需自备 不像 Python 那样自动构建含 gateway 的专用镜像;由用户指定(如 ubuntu:24.04
输出截断 stdout/stderr 单流约 512KB 上限
并发语义 同一 IsolationScope 并发 call 可起多个容器stop 时 last-write-wins 覆盖快照
多副本 本地 Docker + 本地快照会成单点;生产需 Redis/OSS 快照 + 分布式 AgentStateStore
AgentRun/K8s 等扩展 Docker 在 harness 核心;其它后端在 extension 模块,需单独依赖

好处

  • 零额外 Java Docker 库依赖,部署简单。
  • 资源限额CPU/内存)、端口、网络、额外 run args 一等配置。
  • 快照体系成熟,可跨 call / 跨副本恢复 node_modules 等重状态。
  • Workspace projection 把静态资产与运行态分离,宿主改 skills 可增量注入。
  • IsolationScopeSESSION/USER/AGENT/GLOBAL覆盖多租户 SaaS 常见模型。
  • executionGuard 可对 AGENT/GLOBAL 做串行化,缓解快照互踩。

弊端

  • 每次 call 的 start/stop/snapshot 有固定开销(尤其大工作区 tar
  • CLI 进程模型:高并发时大量 docker exec 子进程与线程池开销。
  • 无内置 MCP GatewayMCP 走 Harness 侧 tools.json 注册,与沙箱内进程模型不同。
  • 默认断网 + 裸镜像,冷启动后常需 agent 自己装依赖(靠快照摊销)。