agentscope-ai / agentscope-ai/agentscope-java

[Bug]: AgentRun MCP initialize 创建新沙箱实例,不复用 CreateSandbox 创建的带 OSS/NAS 挂载的实例

Đang mở
#2,070 1 bình luận 0 reaction 0 người được giao Xem trên GitHub
area/ext/integration bug
Ngôn ngữ chính
Java
Star
5.6k
Fork
1.3k
Merge trung bình
4 ngày 12 giờ
Pull request đã merge (30 ngày)
77

Mô tả

## 版本

- agentscope-java: `2.0.0-RC5`(本地源码 2.0.0-SNAPSHOT,含 #1907/#1908 本地修复后同样复现)
- 沙箱后端: AgentRun(阿里云函数计算 FC 3.0 Sandbox API `2025-09-10`)

## 问题描述

AgentRun 沙箱后端通过 `CreateSandbox` API 创建带 `ossMountConfig` 的沙箱实例后,Java 客户端用 MCP URL(`AgentRunMcpChannel`)连接时,平台会**创建一个新的沙箱实例**(无 OSS 挂载),而不是复用 `CreateSandbox` 创建的那个。导致所有通过 MCP 执行的文件操作(`write_file`、`execute`、`read_file`)都在没有 OSS 挂载的容器里执行,文件不会落到 OSS。

### 核心矛盾

| 步骤 | 创建的实例 | OSS 挂载 |
|------|-----------|---------|
| `CreateSandbox` API(带 `ossMountConfig`) | 容器 A(`containerId=c-xxx`) | ✅ `/mnt/workspace` 是 ossfs FUSE 挂载 |
| MCP `initialize`(任何 URL 形式) | 容器 B(`containerId=c-yyy`,不同) | ❌ `/mnt/workspace` 不存在 |

两个实例共享同一个 `sandboxId`,但物理容器不同。`ossMountConfig` 只在 `CreateSandbox` 时生效,MCP `initialize` 创建的新容器不带挂载。

## 复现步骤

### 1. 创建带 OSS 挂载的沙箱

```bash
curl -s -X POST "https://{accountId}.agentrun-data.{region}.aliyuncs.com/sandboxes" \
-H "X-API-Key: Bearer {apiKey}" \
-H "X-Acs-Parent-Id: {accountId}" \
-H "Content-Type: application/json" \
-d '{
"sandboxId": "TESTSANDBOX1234567890123456",
"templateName": "{templateName}",
"sandboxIdleTimeoutSeconds": 3600,
"ossMountConfig": {
"mountPoints": [{
"bucketName": "my-bucket",
"bucketPath": "/data/files",
"endpoint": "http://oss-cn-hangzhou-internal.aliyuncs.com",
"mountDir": "/mnt/workspace",
"readOnly": false
}]
}
}'
```

API 返回 `status: READY`,`ossMountConfig` 在响应中确认存在。通过 AgentRun 控制台进入此沙箱,`/mnt/workspace` 是 ossfs FUSE 挂载,手动 `echo > /mnt/workspace/test.txt` 能在 OSS 桶里看到文件。

### 2. 通过 MCP 连接(模板级 URL)

```bash
MCP_URL="https://{accountId}.agentrun-data.{region}.aliyuncs.com/templates/{templateName}/mcp"
# MCP initialize → 返回 Mcp-Session-Id
# MCP tools/call process_exec_cmd: ls /mnt/workspace/
# → "No such file or directory"
```

### 3. 通过 MCP 连接(沙箱级 URL)

尝试了沙箱级 URL `/templates/{templateName}/sandboxes/{sandboxId}/mcp`,HTTP 200 + 返回 `Mcp-Session-Id`,但执行命令仍然连到了**没有 OSS 挂载的容器**:

```bash
SANDBOX_MCP_URL="https://{accountId}.agentrun-data.{region}.aliyuncs.com/templates/{templateName}/sandboxes/{sandboxId}/mcp"
# MCP initialize → 200 OK, Mcp-Session-Id 返回
# MCP tools/call process_exec_cmd: ls /mnt/workspace/
# → "No such file or directory"(仍然连到了错误容器)
```

### 4. 验证

对比 `containerId`:
- `GetSandbox` API 返回的 `metadata.fcSessionDetails.containerId` = `c-A`(有 OSS)
- MCP `initialize` 后执行命令所在容器的 `containerId` = `c-B`(无 OSS,不同)

控制台显示两个沙箱实例:
- 大写 ID(`sandboxId`)的沙箱:有 OSS 挂载 ✅
- UUID 格式的沙箱:无 OSS 挂载 ❌(MCP `initialize` 创建的)

## 影响

- **OSS/NAS 挂载功能完全不可用**:所有文件操作通过 MCP 执行,但 MCP 连到的容器没有挂载
- `write_file` 返回 "SUCCESS" 但文件不在 OSS(写到容器本地盘,idle timeout 后丢失)
- `workspaceOnNas=true` 的优化路径(跳过 tar 持久化)反而导致数据丢失——以为文件在 OSS 上,实际不在
- 此问题被 #1907(data 信封未解包)和 #1908(MCP 嵌套响应解析)两个 bug 遮盖,修复后才暴露

## 相关代码

- `AgentRunMcpChannel.resolveUrl()`(`AgentRunMcpChannel.java:191-208`):只用 `mcpServerUrl`(模板级 URL)+ `mcpEndpoint`(`/mcp`),不包含 `sandboxId`
- `AgentRunSandboxClient.create()`(`AgentRunSandboxClient.java:64-97`):调用 `CreateSandbox` 后不保存 `fcSessionId`,后续 MCP 连接无法关联
- `AgentRunSandbox.ensureSandbox()`(`AgentRunSandbox.java:211-231`):`createSandbox` 和 `mcp.connect()` 是两个独立步骤

## 尝试过的路由方式

以下 header 均无法让 MCP `initialize` 复用 CreateSandbox 的容器实例:
- `X-Sandbox-Id: {sandboxId}`
- `X-Session-Id: {fcSessionId}`
- `X-Agentrun-Session-Id: {fcSessionId}`
- `X-Fc-Session-Id: {fcSessionId}`

沙箱级 URL `/templates/{template}/sandboxes/{sandboxId}/mcp` 返回 200 但 MCP 仍创建新容器。

## 期望行为

`CreateSandbox` 创建的沙箱实例(带 OSS/NAS 挂载)应能被 MCP `initialize` 复用,或者 AgentRun 平台应提供一种方式将 MCP session 关联到指定的 `sandboxId`/`fcSessionId`。

## 环境

- AgentRun 模板: `sandbox-aio-o6XEzX`(AllInOne 类型)
- 区域: `cn-hangzhou`
- OSS: 标准存储,同地域,内网 endpoint
- RAM 角色: 已配置 `executionRoleArn`,OSS 权限已授予

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.