Files
tmp/msg.md
V-LiuShuang 70c80e4048 add
2026-07-29 16:14:17 +08:00

355 lines
17 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AgentScope vs AgentScope-JavaWorkspace 文件系统与沙箱集成分析
> 对比版本:`agentscope` **v2.0.5** · `agentscope-java` **v2.0.0**
> 重点Docker 沙箱;兼顾 Kubernetes / E2B / Daytona / OpenSandbox / AgentRun
---
## 1. 结论摘要
两套框架都把「Agent 读写文件 / 执行命令」从本机磁盘解耦到可替换的隔离后端,但抽象重心不同:
| 维度 | agentscope (Python) | agentscope-java |
| --- | --- | --- |
| 核心抽象 | **Workspace**(长期运行的工作区 + 进程内 MCP Gateway | **Filesystem Spec**(声明式配置)→ 每次 `call` 借出/归还沙箱 |
| 生命周期粒度 | Workspace 级:`initialize` → 长期复用 → `close` | Call 级:`PreCall acquire/start``PostCall stop(快照)/release` |
| Docker 接入方式 | **aiodocker**Docker Engine HTTP API | **`docker` CLI**`ProcessBuilder`,无 docker-java 依赖) |
| 持久化主路径 | Bind mount / 云沙箱 pause / K8s PVC | **Workspace tar 快照**Local/Redis/OSS/…)+ 可选 bind mount |
| 分布式能力 | 依赖云沙箱 metadata 重连或 K8s 集群资源 | 依赖 `SandboxStateStore` + 分布式快照后端 |
| 独有后端 | OpenSandbox、Bubblewrap | AgentRun阿里云 |
**选型直觉:** 需要「常驻工作区 + MCP 网关 + Python Agent 服务」→ agentscope需要「HarnessAgent 按次隔离、快照跨副本恢复、Java 生态」→ agentscope-java。
---
## 2. 总体架构对比
### 2.1 agentscopeWorkspace + 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 透明落到沙箱内
```
关键设计点:
1. **模板方法**:子类只实现 `_provision_backend` / `_teardown_backend` / `_bootstrap_commands`
2. **容器内 MCP Gateway**:宿主机通过 `GatewayClient` + `backend.exec_shell` 驱动网关(一般不依赖宿主机到沙箱的端口映射)。
3. **WorkspaceManager**`PER_AGENT` / `PER_SESSION` / `PER_USER`,空闲 TTL 驱逐;云后端可按 metadata/label 跨节点重连。
### 2.2 agentscope-javaFilesystem 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 全部转发到沙箱
```
关键设计点:
1. **声明式 Spec**`DockerFilesystemSpec` 等只描述「如何创建」,不是运行时文件系统本身。
2. **Call 边界生命周期**:每次推理前后自动 acquire/start/stop适合多租户按次计费与快照恢复。
3. **快照与执行后端正交**:换 Docker/K8s/E2B 不影响 `LocalSnapshotSpec` / `RedisSnapshotSpec` / `OssSnapshotSpec` 的选择。
4. **Workspace Projection**:启动时把宿主 `AGENTS.md``skills/``subagents/``knowledge/` 等打 tar 注入沙箱,按内容 SHA-256 增量跳过。
---
## 3. Docker 集成深挖(重点)
### 3.1 agentscope · `DockerWorkspace`
**源码入口:** `src/agentscope/workspace/_docker/_docker_workspace.py`
**配套:** `_docker_backend.py``_make_dockerfile.py`
#### 实现原理
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`
- 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-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 快照后端」抽象。
---
### 3.2 agentscope-java · `DockerFilesystemSpec` / `DockerSandbox`
**源码入口:**
- Spec`.../sandbox/impl/docker/DockerFilesystemSpec.java`
- 运行时:`DockerSandbox.java``DockerSandboxClient.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. **Call 级编排**
- `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 可增量注入。
- `IsolationScope`SESSION/USER/AGENT/GLOBAL覆盖多租户 SaaS 常见模型。
- `executionGuard` 可对 AGENT/GLOBAL 做串行化,缓解快照互踩。
#### 弊端
- 每次 call 的 start/stop/snapshot 有固定开销(尤其大工作区 tar
- CLI 进程模型:高并发时大量 `docker exec` 子进程与线程池开销。
- 无内置 MCP GatewayMCP 走 Harness 侧 `tools.json` 注册,与沙箱内进程模型不同。
- 默认断网 + 裸镜像,冷启动后常需 agent 自己装依赖(靠快照摊销)。
---
### 3.3 Docker 双端对照表
| 对比项 | agentscope v2.0.5 | agentscope-java v2.0.0 |
| --- | --- | --- |
| API 形态 | aiodockerEngine API | docker CLI |
| 保活命令 | `sleep infinity` | `while :; do sleep 3600; done` |
| 镜像策略 | 自动构建并内容哈希缓存 | 用户指定现成镜像 |
| 默认网络 | Docker 默认(通常有网) | **`none`** |
| 持久化 | Bind-mount可选 | Tar 快照为主 + 可选 bind-mount |
| 生命周期 | Workspace 长生命周期 | 按 Agent `call` 借还 |
| MCP | 容器内 Gateway | Harness 侧注册;沙箱只做 FS/Shell |
| 资源限制 | 较弱(构造参数少) | memory / cpu / ports / network |
| 水平扩展 | 不适合 | 需外置快照/状态存储 |
---
## 4. 其它沙箱类型
### 4.1 支持矩阵
| 沙箱类型 | agentscope v2.0.5 | agentscope-java v2.0.0 | 共同点 |
| --- | --- | --- | --- |
| Docker | ✅ `DockerWorkspace` | ✅ `DockerFilesystemSpec`harness 内置) | 本地隔离、需 Docker |
| Kubernetes | ✅ `K8sWorkspace`Pod + PVC | ✅ `KubernetesFilesystemSpec`extension | 集群级资源、适合生产 K8s |
| E2B | ✅ `E2BWorkspace` | ✅ `E2bFilesystemSpec` | 云沙箱 SDK、metadata/API 重连 |
| Daytona | ✅ `DaytonaWorkspace` | ✅ `DaytonaFilesystemSpec` | 云沙箱、标签/API 重挂接 |
| AgentRun | ❌ 暂未支持 | ✅ `AgentRunFilesystemSpec`(阿里云) | — |
| OpenSandbox | ✅ `OpenSandboxWorkspace` | ❌ 暂未支持 | — |
| Bubblewrap | ✅(另有 Local | ❌(有 LocalFilesystemSpec | Linux 轻量沙箱 / 本机模式 |
### 4.2 agentscope 各后端要点
| 后端 | 供给方式 | 持久化 | Teardown | Bootstrap |
| --- | --- | --- | --- | --- |
| **Docker** | aiodocker 建容器 | Bind-mount 或 ephemeral | kill + delete 容器 | 镜像已含 gateway |
| **K8s** | Pod + PVC`as-ws-{id}` | PVC 跨 Pod 存活 | 删 Pod默认可保留 PVC | 首次 apt + uv + gateway |
| **E2B** | `AsyncSandbox.create/connect` | pause 保留磁盘 | `pause()` | 首次 bootstrap |
| **Daytona** | SDK create / label 查找 | `stop(force=False)` | stop + close client | 首次 bootstrap路径由 SDK 推导) |
| **OpenSandbox** | `Sandbox.create` / resume / connect | `pause()` | pause + close | 首次 bootstrap |
云后端共性:用 `agentscope.workspace.id`(或等价 metadata/label索引Manager 缓存 miss 时可跨服务副本重连——这是文档推荐的**分布式部署**路径。
### 4.3 agentscope-java 各后端要点
| 后端 | 模块位置 | 交互方式 | 持久化侧重 |
| --- | --- | --- | --- |
| **Docker** | harness 核心 | CLI | Tar 快照 + 可选 bind |
| **Kubernetes** | extension | fabric8 / Pod 侧 exec+tar文档侧亦描述 agent-sandbox WarmPool 演进) | 快照 Spec集群侧还可结合 PVC/模板 |
| **E2B** | extension | E2B HTTP + envd支持 TAR / NATIVE_SNAPSHOT 等持久化模式 | 平台快照或 tar |
| **Daytona** | extension | Control Plane HTTP API | 快照 Spec不应用 host bind-mount有则 WARN |
| **AgentRun** | extension | 阿里云 AgentRun API可配 NAS/OSS mount、MCP URL | 云侧空闲超时 + 快照 Spec |
公共能力均来自 `SandboxFilesystemSpec``isolationScope`、`snapshotSpec`、`executionGuard`、`workspaceProjection*`。
### 4.4 OpenSandbox 补充(仅 Python
[OpenSandbox](https://open-sandbox.ai/getting-started) 是通用沙箱平台Docker/K8s 运行时 + 多语言 SDK。agentscope 通过官方 `opensandbox` SDK
- 按 metadata 过滤 RUNNING/PAUSED 沙箱并 resume/connect
- close 时 **pause** 保文件系统;
- 与 E2B 类似走 `_bootstrap_commands` 安装 gateway。
Java 侧 v2.0.0 **未集成**,若要在 Java 使用需自研 `SandboxClient` 或等待官方 extension。
---
## 5. 隔离模型对比
| | agentscope `IsolationPolicy` | agentscope-java `IsolationScope` |
| --- | --- | --- |
| 会话级 | `PER_SESSION` | `SESSION`(沙箱默认) |
| 用户级 | `PER_USER`(跨 agent 慎用) | `USER`(跨 session 共享记忆/快照) |
| Agent 级 | `PER_AGENT`(默认,按 user+agent | `AGENT`(按 agent 名共享) |
| 全局 | 无对等枚举 | `GLOBAL` |
| 绑定时机 | Session 创建时写入 `workspace_id` | 每次 call 用 RuntimeContext 算 isolation key |
Java 另强调:**沙箱模式下的 scope 是「顺序复用 + 快照」,不是同一容器实时共享**;并发需 `executionGuard`。
---
## 6. 好处与弊端总览
### 6.1 agentscopePythonWorkspace 沙箱体系
**好处**
- 统一 `SandboxedWorkspaceBase`,后端可插拔,服务侧一行切换 Manager。
- MCP Gateway 与文件工具同处沙箱,安全边界清晰。
- Docker 镜像预烘焙,稳态性能好;云后端天然支持多副本重连。
- OpenSandbox / Bubblewrap 覆盖「自托管云」与「轻量 Linux 沙箱」。
**弊端**
- Docker/Local 单节点限制明显。
- 非 Docker 后端首次 bootstrap 重(网络、时间、镜像权限)。
- 缺少 Java 那种可插拔「快照存储后端」产品化抽象。
- 无 AgentRun。
### 6.2 agentscope-java Harness 沙箱体系
**好处**
- Filesystem 三模式Local / Remote KV / Sandbox切换不改 Agent 业务代码。
- Call 级生命周期 + 多快照后端,适合多租户与水平扩展。
- Docker 资源/网络控制细;扩展点(自定义 `SandboxClient`)文档化完整。
- AgentRun 对接阿里云projection 解决静态资产分发。
**弊端**
- Docker CLI 与大 tar 快照带来延迟与运维开销。
- 默认 `network=none`、裸镜像,开发体验需额外配置。
- 并发 last-write-wins 需业务侧理解。
- 无 OpenSandboxMCP 不在沙箱内统一托管(与 Python Gateway 模型不同)。
---
## 7. 实践建议
1. **本地可信开发**
- Python`LocalWorkspace` / `BubblewrapWorkspace`
- Java`LocalFilesystemSpec`(默认)
2. **单机强隔离、可调试**
- 两边都用 **Docker**Python 适合长期 workspace + MCPJava 适合按次执行 + 快照实验。
3. **多副本生产**
- PythonE2B / Daytona / OpenSandbox / K8s Manager
- Java任意 `SandboxFilesystemSpec` + **分布式** `snapshotSpec` + `AgentStateStore`(否则 build 会强制提醒单点风险)
4. **中国云 / AgentRun**
- 仅 Java `AgentRunFilesystemSpec`。
5. **自托管沙箱平台**
- 仅 Python `OpenSandboxWorkspace`;需先部署 OpenSandbox Server。
---
## 8. 参考链接
| 资源 | URL |
| --- | --- |
| agentscope DockerWorkspace | https://github.com/agentscope-ai/agentscope/blob/v2.0.5/src/agentscope/workspace/_docker/_docker_workspace.py |
| agentscope Workspace Manager 文档 | https://docs.agentscope.io/versions/2.0.5/zh/deploy/workspace-manager |
| agentscope-java DockerFilesystemSpec | https://github.com/agentscope-ai/agentscope-java/blob/v2.0.0/agentscope-harness/src/main/java/io/agentscope/harness/agent/sandbox/impl/docker/DockerFilesystemSpec.java |
| agentscope-java Filesystem 文档 | https://java.agentscope.io/v2/zh/docs/harness/filesystem.html |
| OpenSandbox 入门 | https://open-sandbox.ai/getting-started |
| OpenSandbox GitHub | https://github.com/opensandbox-group/OpenSandbox |
---
*报告基于上述版本标签源码与官方文档整理;若文档站点已超前于 tag以对应 Git tag 源码为准。*