diff --git a/msg.md b/msg.md index d800886..7596d96 100644 --- a/msg.md +++ b/msg.md @@ -1 +1,354 @@ -123 \ No newline at end of file +# AgentScope vs AgentScope-Java:Workspace 文件系统与沙箱集成分析 + +> 对比版本:`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 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 透明落到沙箱内 +``` + +关键设计点: + +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-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 全部转发到沙箱 +``` + +关键设计点: + +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 + 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=`。 + - **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 快照后端」抽象。 + +--- + +### 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- + [--memory] [--cpus] [-p] [--network=none|...] [-v bind...] + sh -c "while :; do sleep 3600; done" + ``` + - 默认 **`--network=none`**(未配置 network 时),比 Python 版更偏「默认断网隔离」。 + - 支持 `WorkspaceSpec` 中的 `BindMountEntry` → `-v host:container:ro|rw`。 + - `exec`:`docker exec -w sh -c `。 + +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 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 自己装依赖(靠快照摊销)。 + +--- + +### 3.3 Docker 双端对照表 + +| 对比项 | agentscope v2.0.5 | agentscope-java v2.0.0 | +| --- | --- | --- | +| API 形态 | aiodocker(Engine 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 agentscope(Python)Workspace 沙箱体系 + +**好处** + +- 统一 `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 需业务侧理解。 +- 无 OpenSandbox;MCP 不在沙箱内统一托管(与 Python Gateway 模型不同)。 + +--- + +## 7. 实践建议 + +1. **本地可信开发** + - Python:`LocalWorkspace` / `BubblewrapWorkspace` + - Java:`LocalFilesystemSpec`(默认) + +2. **单机强隔离、可调试** + - 两边都用 **Docker**;Python 适合长期 workspace + MCP;Java 适合按次执行 + 快照实验。 + +3. **多副本生产** + - Python:E2B / 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 源码为准。*