add
This commit is contained in:
@@ -34,10 +34,7 @@ BackendBase (exec_shell / read_file / write_file)
|
||||
└─ 内置工具 Bash/Read/Write/Edit/Grep/Glob 透明落到沙箱内
|
||||
```
|
||||
|
||||
关键设计:
|
||||
|
||||
- **容器内 MCP Gateway**:宿主机通过 `GatewayClient` + `backend.exec_shell` 驱动网关(一般不依赖宿主机到沙箱的端口映射)。
|
||||
- **WorkspaceManager**:`PER_AGENT` / `PER_SESSION` / `PER_USER`,空闲 TTL 驱逐;云后端可按 metadata/label 跨节点重连。
|
||||
关键设计:通过 MCP 网关收敛文件系统相关 tool 的访问,采用空闲 TTL 驱逐的方案释放沙箱资源。
|
||||
|
||||
### agentscope-java
|
||||
|
||||
@@ -52,18 +49,15 @@ SandboxFilesystemSpec.toSandboxContext(hostWorkspaceRoot)
|
||||
│
|
||||
▼
|
||||
SandboxLifecycleHook
|
||||
PreCall → SandboxManager.acquire → Sandbox.start() (四分支恢复)
|
||||
PreCall → SandboxManager.acquire → Sandbox.start()
|
||||
PostCall → Sandbox.stop() (tar 快照) → persist state → release
|
||||
│
|
||||
▼
|
||||
SandboxBackedFilesystem + ShellExecuteTool
|
||||
└─ 文件工具 / execute 全部转发到沙箱
|
||||
└─ 文件工具 / execute
|
||||
```
|
||||
|
||||
关键设计:
|
||||
|
||||
- **生命周期管理**:每次推理前后自动 acquire/start/stop,适合多租户与快照恢复。
|
||||
- **快照与沙箱解耦**:换 Docker/K8s/E2B 不影响 `LocalSnapshotSpec` / `RedisSnapshotSpec` / `OssSnapshotSpec` 的选择。启动时把宿主 `AGENTS.md`、`skills/`、`subagents/`、`knowledge/` 等打 tar 注入沙箱,按内容 SHA-256 增量跳过。
|
||||
关键设计:在ReAct生命周期内,通过 hook 机制(2.0版本叫中间件)start、stop 沙箱。
|
||||
|
||||
## Docker沙箱双端对照表
|
||||
|
||||
@@ -79,121 +73,21 @@ SandboxBackedFilesystem + ShellExecuteTool
|
||||
| 资源限制 | 较弱(构造参数少) | 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:
|
||||
- 通过 HTTP API 与 Docker 引擎交互,除了与本机 Docker 引擎交互之外,还可以访问远程服务器上的 Docker 引擎。
|
||||
- 自动构建镜像,且可以随着依赖库的增删不断迭代 Dockerfile。
|
||||
- agentscope-java:
|
||||
- 每次 call 的时候都会在 start/stop/snapshot 生成 tar 包快照。
|
||||
- 隔离级别更贴近多租户场景(SESSION/USER/AGENT/GLOBAL)覆盖多租户常见模型。
|
||||
|
||||
### 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 + agentscope(Docker 路径**不做**首次 bootstrap)。
|
||||
- 可选 `node_version` 从官方 Node slim 镜像拷贝 `node`/`npm`(供 npx MCP)。
|
||||
|
||||
2. **容器启动**
|
||||
- 通过 **aiodocker** `containers.create_or_replace`。
|
||||
- `Cmd: ["sleep", "infinity"]`,工作目录 `/workspace`。
|
||||
- Label:`agentscope.workspace=true`、`agentscope.workspace.id=<id>`。
|
||||
- **Gateway 端口仅容器内监听,不做 host port 映射**;宿主经 `DockerBackend.exec` 访问。
|
||||
|
||||
3. **持久化**
|
||||
- 可选 `host_workdir` bind-mount → `/workspace`(`is_persistent`)。
|
||||
- 无 mount 则为 ephemeral 容器文件系统。
|
||||
- Linux 上 teardown 时尝试 `chown` 把 bind-mount 文件所有权还给宿主用户。
|
||||
|
||||
4. **I/O 原语(`DockerBackend`)**
|
||||
- `exec_shell`:容器 `exec` API,直传 argv(无中间 shell,需要时包 `sh -c`)。
|
||||
- `read_file` / `write_file`:`get_archive` / `put_archive`(tar)。
|
||||
|
||||
5. **服务侧**
|
||||
- `DockerWorkspaceManager`:`basedir` 下为每个 workspace 建宿主目录并 bind-mount;TTL 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 API:`image`、`workspaceRoot`(默认 `/workspace`)、`memorySizeBytes`、`cpuCount`、`exposedPorts`、`network`、`environment`、`additionalRunArgs`、`snapshotSpec`、`workspaceSpec`。
|
||||
|
||||
2. **创建与客户端**
|
||||
- `DockerSandboxClient.create(...)` 生成 `DockerSandboxState`(sessionId、镜像、资源参数、快照句柄)。
|
||||
- **不引入 docker-java**:一律 `docker run` / `exec` / `inspect` / `stop` / `rm` CLI。
|
||||
- 要求宿主 `PATH` 上有 `docker`,且 daemon 可达。
|
||||
|
||||
3. **容器命令**
|
||||
```text
|
||||
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`。
|
||||
- `exec`:`docker exec -w <workspaceRoot> <id> sh -c <command>`。
|
||||
|
||||
4. **工作区 tar 快照**
|
||||
- Persist:`docker exec tar -cf - -C /workspace .`(并对 bind-mount 路径 `--exclude`)。
|
||||
- Hydrate:`docker exec -i tar -xf - -C /workspace`。
|
||||
- `AbstractBaseSandbox` **四分支恢复**:容器是否仍保留目录 × 是否有可恢复快照。
|
||||
|
||||
5. **编排**
|
||||
- `start()`:确保容器 running → 四分支初始化 → workspace projection。
|
||||
- `stop()`:写快照,**容器可继续跑**。
|
||||
- `shutdown()`:自管容器则 `docker stop` + `docker rm --force`。
|
||||
|
||||
#### 使用限制
|
||||
|
||||
| 限制 | 说明 |
|
||||
| --- | --- |
|
||||
| 依赖 Docker CLI | 无嵌入式 Engine API;Windows/远程 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 可增量注入。
|
||||
- `IsolationScope`(SESSION/USER/AGENT/GLOBAL)覆盖多租户 SaaS 常见模型。
|
||||
- `executionGuard` 可对 AGENT/GLOBAL 做串行化,缓解快照互踩。
|
||||
|
||||
#### 弊端
|
||||
|
||||
- 每次 call 的 start/stop/snapshot 有固定开销(尤其大工作区 tar)。
|
||||
- CLI 进程模型:高并发时大量 `docker exec` 子进程与线程池开销。
|
||||
- 无内置 MCP Gateway;MCP 走 Harness 侧 `tools.json` 注册,与沙箱内进程模型不同。
|
||||
- 默认断网 + 裸镜像,冷启动后常需 agent 自己装依赖(靠快照摊销)。
|
||||
- agentscope:
|
||||
- 文件沙箱的生命周期过长,强依赖 TTL 清扫。
|
||||
- 工作区没有快照或副本能力,可以自行开发。
|
||||
- agentscope-java:
|
||||
- 随着工作区目录越来越大,会导致快照越来越慢(tar命令)可以自定义这个逻辑规避。
|
||||
- 没有 agentscope 那样不断迭代镜像的能力,需要人工干预(私以为自动迭代沙箱镜像是个伪需求)
|
||||
- 若隔离级别会 session 级别,每个 session 都会被拉起一个容器(要控制一台服务器的会话总数量)
|
||||
Reference in New Issue
Block a user