Skip to content

Repository files navigation

AgentBox

AgentBox - 基于 Rust + Docker 的 AI Agent 运行沙箱平台。为 Claude Agent SDK 等 AI Agent 提供隔离、安全、可管理的容器化运行环境。

用途

  • 代码审查:为每个 PR 创建独立容器,运行 Claude Agent 进行自动化代码审查
  • 代码生成:隔离执行 AI 生成的代码,防止对主环境造成影响
  • 多租户 Agent 服务:不同业务团队使用各自的 Skill 和配置,互不干扰
  • CI/CD 集成:在流水线中动态创建 Agent 容器执行任务

架构

┌──────────────────────────────────────────────────────────────┐
│ Control Plane (主服务) │
│ REST API ─ Auth ─ Docker Manager ─ Lifecycle ─ SQLite │
│ │ │ │
│ │ ├─ WebSocket 日志流(脱敏) │
│ │ └─ SSE Query 代理(透传) │
└───────────────────────┼───────────────────────────────────────┘
│ Docker Socket
▼
┌──────────────────────────────────────────────────────────────┐
│ Agent Container │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Sidecar (Axum :9000) │ │
│ │ ├─ POST /query → SSE 流式返回 cc_sdk::query 消息 │ │
│ │ ├─ GET /health │ │
│ │ └─ 心跳上报 → control-plane /api/containers/{id}/status │ │
│ └─────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘

核心组件

组件语言职责
Control PlaneRust容器生命周期管理、REST/WebSocket/SSE API、鉴权、CORS、日志脱敏、Docker 实际状态校验、空闲销毁、Sidecar Query 代理
SidecarRust容器内 HTTP server(:9000);封装 cc-sdk::query,SSE 流式返回 Claude 消息;状态/心跳回传
Agent ImageDocker包含 Sidecar 二进制 + Claude Code CLI + Node.js 20 + Python3 的容器镜像
Admin UIReact + Vite前端管理界面;容器 CRUD、实时 WebSocket 日志流、状态监控
TypeScript SDKTypeScript@agentbox/sdk;零依赖 Node.js SDK,AsyncGenerator 流式交互

技术栈

  • Web 框架:Axum 0.8(HTTP / WebSocket / SSE)
  • Claude SDK:cc-sdk 0.8(sidecar 内调用 Claude Code)
  • Docker 客户端:Bollard 0.21
  • 数据库:SQLite (sqlx 0.8)
  • 异步运行时:Tokio 1.x
  • 日志:Tracing
  • 前端:React 19 + Vite + shadcn/ui + Tailwind CSS v4

快速开始

前置要求

  • Rust 1.70+
  • Docker Desktop / OrbStack
  • Node.js 20+(仅开发 admin-ui 时需要)

一键启动(推荐)

git clone <repo-url>cd agentbox
make setup # 编译 Rust + 构建所有 Docker 镜像 + 启动服务

启动后:

  • Control Plane API: http://localhost:8080
  • Admin UI: http://localhost:3000

本地开发

# 安装前端依赖cd admin-ui && npm install &&cd ..
# 启动后端 + 前端开发服务器(热更新)
make dev
  • Control Plane: http://localhost:8080
  • Admin UI (dev): http://localhost:5173

Docker 运行

# 构建所有镜像(含 agent-sandbox)
make build
# 启动全部(control-plane + admin-ui)
docker compose up -d
# 仅启动 control-plane
docker compose up control-plane -d

API 文档

健康检查

GET /health

响应:

{
"status": "ok",
"timestamp": "2026-05-28T10:23:49.544829+00:00"
}

创建容器

POST /api/containersContent-Type: application/json

请求体:

{
"description": "Review code PR #42",
"skill_ids": ["uuid-of-uploaded-skill"],
"skill_repos": ["https://github.com/company/skills.git"],
"skill_branch": "main",
"cpu_limit": "2",
"memory_limit": "4Gi",
"idle_timeout": 300,
"max_lifetime": 3600,
"env": {
"ANTHROPIC_API_KEY": "your-key"
}
}
字段类型必填说明
descriptionstringAgent 执行的任务描述
skill_idsstring[]已上传的 Skill ID 列表(复制到容器 /workspace/skills/
skill_reposstring[]Skill 仓库地址列表(可选)
skill_branchstringSkill 仓库分支,默认 main
cpu_limitstringCPU 限制,默认 2 (核)
memory_limitstring内存限制,默认 4Gi
idle_timeoutinteger空闲超时(秒),默认 300
max_lifetimeinteger最大生命周期(秒),默认 3600
envobject额外环境变量

响应 (201 Created):

{
"id": "9c52cbc6-20a4-48a9-a7fb-cc8e8d64319b",
"status": "Running",
"created_at": "2026-05-28T10:23:51.155912+00:00",
"docker_id": "agent-9c52cbc6-20a4-48a9-a7fb-cc8e8d64319b"
}

注意: 创建接口会等待容器内 Sidecar /health 端点就绪后才返回(指数退避重试,最多约 20 秒),确保返回后即可直接发送 Query 请求。

查询容器状态

GET /api/containers/{id}

响应 (200 OK):

{
"id": "9c52cbc6-20a4-48a9-a7fb-cc8e8d64319b",
"description": "Review code PR #42",
"status": "Running",
"docker_id": "agent-9c52cbc6-20a4-48a9-a7fb-cc8e8d64319b",
"skill_repos": "[\"https://github.com/company/skills.git\"]",
"cpu_limit": "2",
"memory_limit": "4Gi",
"idle_timeout": 300,
"max_lifetime": 3600,
"created_at": "2026-05-28T10:23:51.155912+00:00",
"last_activity": "2026-05-28T10:23:53.459101+00:00"
}

删除容器

DELETE /api/containers/{id}

响应 (204 No Content)

容器日志流 (WebSocket)

GET /api/containers/{id}/logs

WebSocket 端点,实时推送容器 stdout/stderr。已对启动时收集到的密钥值(ANTHROPIC_API_KEYAPI_KEYOPENAI_API_KEYGITHUB_TOKENGH_TOKEN)做 ***REDACTED*** 替换。

wscat -H "Authorization: Bearer $API_KEY" \
-c ws://localhost:8080/api/containers/<id>/logs

Sidecar Query 代理 (SSE)

POST /api/containers/{id}/query

通过 Control Plane 代理向容器内 Sidecar 发送 prompt,SSE 流式返回 Claude 消息(chunk-by-chunk 透传,不缓冲)。统一外部入口,经过鉴权层。

请求体:

{
"prompt": "Review this code for bugs",
"options": {
"model": "claude-sonnet-4-6",
"max_turns": 5,
"allowed_tools": ["Read", "Edit"]
}
}
字段类型必填说明
promptstring发送给 Claude 的提示词
optionsobject查询选项(透传给 sidecar)
options.modelstring模型名
options.max_turnsinteger最大对话轮次
options.allowed_toolsstring[]工具白名单
options.system_promptstring系统提示词
options.max_thinking_tokensintegerthinking token 上限
options.max_budget_usdfloat单次预算上限

响应: Content-Type: text/event-stream,事件名包括 systemassistantuserresultstream_eventrate_limiterror。详细说明见下方 Sidecar API 章节。

curl 示例:

curl -N -X POST http://localhost:8080/api/containers/<id>/query \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $API_KEY" \
-d '{"prompt":"Review this code for bugs"}'

Skill 管理

POST /api/skills # 上传 Skill(multipart: file=ZIP, name=可选, description=可选)GET /api/skills # 列表(支持 ?search= 和分页)GET /api/skills/{id} # 详情PUT /api/skills/{id} # 更新 name/descriptionDELETE /api/skills/{id} # 删除

上传时自动从 ZIP 内 skill.md 的 YAML frontmatter 提取 namedescription(文件名不区分大小写)。Skill 存储在 SKILLS_DIR(默认 /data/skills),创建容器时通过 skill_ids 指定要复制的 Skill。

状态回传 (Sidecar → Control Plane)

POST /api/containers/{id}/statusContent-Type: application/json

请求体:

{
"status": "running",
"progress": 0.5,
"current_step": "analyzing code",
"logs": ["Reading src/main.rs", "Checking imports"],
"timestamp": "2026-05-28T10:24:00Z"
}

Sidecar API(容器内 :9000

由 control-plane 透传或在同一 Docker 网络下直连 agent-{id}:9000

健康检查

GET /health → 200 "ok"

Query (SSE)

POST /queryContent-Type: application/jsonAccept: text/event-stream

请求体:

{
"prompt": "重构这段代码",
"options": {
"model": "claude-opus-4-7",
"system_prompt": "你是 Rust 专家",
"max_turns": 5,
"allowed_tools": ["Read", "Edit"]
}
}

options 字段(任意可选;未识别字段会被忽略):

字段类型说明
modelstring主模型
fallback_modelstring兜底模型
system_promptstring系统提示词
append_system_promptstring追加到默认系统提示词后
max_turnsi32最大对话轮次
max_output_tokensu32输出 token 上限
max_thinking_tokensi32thinking token 上限
allowed_toolsstring[]允许的工具白名单
disallowed_toolsstring[]禁用工具黑名单
cwdstring工作目录
session_idstring复用 session ID
resumestring从指定 session 续跑
continue_conversationbool继续上一次会话
include_partial_messagesbool是否推送增量消息
max_budget_usdf64单次预算上限

需要更多字段在 sidecar/src/query.rs::build_options 加一行 builder 调用即可。

响应: Content-Type: text/event-stream,每条 cc_sdk::Message 一个事件,类型即 event 名:

event: assistant
data: {"type":"assistant","message":{...}}
event: stream_event
data: {"type":"stream_event","uuid":"...","event":{...}}
event: result
data: {"type":"result","duration_ms":1234,"total_cost_usd":0.0012,...}
Event说明
assistant / user / system普通对话消息
stream_event流式增量(启用 include_partial_messages 时)
rate_limit速率受限通知
result终止事件,附 duration / cost / usage
error流中错误,随后流自然结束

Keep-alive 间隔 15s。客户端按 SSE 标准断线重连即可。

curl 示例:

curl -N -X POST http://agent-<id>:9000/query \
-H 'Content-Type: application/json' \
-d '{"prompt":"hello"}'

容器状态

状态说明
Creating正在创建
Running运行中
Idle空闲
Stopping正在停止
Stopped已停止
Failed失败

配置

环境变量 (Control Plane)

变量默认值说明
DATABASE_URLsqlite:agent_sandbox.db?mode=rwcSQLite 数据库路径
SERVER_ADDR0.0.0.0:8080监听地址
AGENT_IMAGEagent-sandbox:latestAgent 容器镜像
API_KEY(unset)设置后所有非 /health 路由要求 Authorization: Bearer <key>;未设置则不鉴权(开发模式)
ALLOWED_ORIGINSlocalhost onlyCORS 允许来源;逗号分隔;* 表示通配(会打 warning)
ANTHROPIC_API_KEY(unset)注入到所有 agent 容器;同时被收集用于日志流脱敏
SKILLS_DIR/data/skillsSkill 文件存储目录
RUST_LOGinfo日志级别

环境变量 (Sidecar 容器)

变量默认值说明
CONTAINER_ID(必填)容器 ID(由 Control Plane 注入)
CONTROL_PLANE_URLhttp://localhost:8080心跳上报地址
SIDECAR_ADDR0.0.0.0:9000sidecar HTTP server 监听地址
SKILL_REPOS(可选)启动时克隆到 /workspace/skills/ 的 Git 仓库(逗号分隔)
ANTHROPIC_API_KEY(可选)由 cc-sdk 内部使用

Skill 加载

Skill 文件从 Git 仓库自动克隆到容器内 /workspace/skills/ 目录。

仓库结构:

skills-repo/
├── code-review/
│ └── SKILL.md
├── test-generator/
│ └── SKILL.md
└── custom-tool/
└── SKILL.md

SKILL.md 示例:

---name: code-reviewdescription: 自动化代码审查工具---# Code Review Skill
你是一个代码审查专家,负责审查 Pull Request。
## 审查要点- 代码风格一致性
- 潜在 bug 和安全问题
- 性能优化建议

开发指南

项目结构

agentbox/
├── Cargo.toml # Workspace 配置
├── Dockerfile # Control Plane 镜像
├── docker-compose.yml # Docker 编排
├── control-plane/ # 主服务
│ ├── Cargo.toml
│ └── src/
│ ├── main.rs # 入口 + 路由 + CORS 构造
│ ├── config.rs # 配置加载(含 ALLOWED_ORIGINS)
│ ├── auth.rs # Bearer token 中间件
│ ├── redact.rs # 日志流密钥脱敏
│ ├── error.rs # 错误类型
│ ├── models/
│ │ ├── container.rs # 容器数据模型(含 skill_ids)
│ │ └── skill.rs # Skill 数据模型
│ ├── docker/
│ │ ├── manager.rs # Docker 操作(Bollard)
│ │ └── lifecycle.rs # 生命周期巡检(含 Docker 实际状态校验)
│ ├── db/sqlite.rs # 数据库操作
│ └── api/
│ ├── containers.rs # 容器 CRUD + 状态回调
│ ├── skills.rs # Skill CRUD(ZIP 上传 + skill.md 元数据提取)
│ ├── query.rs # POST /query SSE 代理透传
│ ├── ws.rs # WebSocket 日志流(含 redact)
│ └── health.rs # 健康检查
├── sidecar/ # 容器内服务
│ ├── Cargo.toml # 含 cc-sdk = "0.8"
│ └── src/
│ ├── main.rs # axum server :9000
│ ├── query.rs # POST /query SSE handler(cc_sdk::query 封装)
│ ├── reporter.rs # 状态/心跳上报
│ └── health.rs # 后台心跳循环
├── agent-image/ # Agent 镜像
│ ├── Dockerfile # sidecar + Claude CLI
│ └── entrypoint.sh # 克隆 skills 后 exec sidecar
├── admin-ui/ # 前端管理界面 (React + Vite + shadcn/ui)
│ ├── Dockerfile # Nginx 静态部署
│ └── src/
│ ├── pages/ # 容器列表、详情、创建
│ ├── components/ # UI 组件(含 LogViewer WebSocket 日志)
│ └── hooks/ # API hooks、WebSocket 日志 hook、Query SSE hook
├── cc-sdk-local/ # cc-sdk 0.8.1 本地补丁 (添加 --include-partial-messages)
│ └── src/query.rs # 补丁: 传递 include_partial_messages 到 CLI
└── sdk/ # TypeScript SDK (@agentbox/sdk)
├── package.json
└── src/
├── agentbox.ts # AgentBox 类 (create/query/delete)
├── types.ts # 类型定义 + 类型守卫
├── sse.ts # SSE 流解析器
├── errors.ts # 错误类
└── index.ts # barrel export

运行测试

# 单元测试
cargo test# 指定包测试
cargo test -p control-plane
cargo test -p sidecar
# 前端开发cd admin-ui && npm run dev

构建镜像

# 编译 release
cargo build --release
# 构建 Agent 镜像
docker build -t agent-sandbox:latest -f agent-image/Dockerfile .

扩展方向

  • WebSocket 实时日志流(含密钥脱敏)
  • API 认证鉴权(API Key Bearer token)
  • 收紧 CORS 默认值(localhost only,可配 ALLOWED_ORIGINS
  • Sidecar 接入 Claude SDK(cc-sdk 0.8,SSE 流式 query)
  • Admin UI 管理界面(容器 CRUD + 实时日志流)
  • 容器列表/分页查询、历史日志(非实时)查询
  • Control-plane 透传 sidecar 的 /query SSE(统一外部入口 + 鉴权 + 流量控制)
  • Skill 管理(ZIP 上传、自动元数据提取、容器内技能复制)
  • TypeScript SDK (@agentbox/sdk,零依赖,AsyncGenerator 流式交互)
  • 创建容器时 sidecar 就绪检查(指数退避健康检查重试)
  • SSE 端到端流式透传(sidecar stream::unfold + control-plane bytes_stream,流结束即关闭连接)
  • Token 级流式输出(cc-sdk 本地补丁 + include_partial_messages + stream_event 处理)
  • 容器池/预热机制
  • Kubernetes 部署支持
  • Prometheus 监控指标
  • 容器快照与恢复
  • 多节点调度

TypeScript SDK (@agentbox/sdk)

零运行时依赖的 TypeScript SDK,用于从 Node.js (>= 18) 应用调用 AgentBox 平台。仿照 cc-sdk 接口风格,使用 AsyncGenerator 流式交互。

安装

cd sdk && npm install && npm run build

使用示例

import{AgentBox,isTextDelta}from'@agentbox/sdk'constagent=awaitAgentBox.create({agentServer: 'http://localhost:8080',token: 'your-api-key',description: 'You are a helpful coding assistant.',env: {ANTHROPIC_AUTH_TOKEN: 'your-token',ANTHROPIC_BASE_URL: 'https://api.anthropic.com',ANTHROPIC_MODEL: 'claude-sonnet-4-6',},})forawait(constmsgofagent.query('What is 2+2?',{max_turns: 1,include_partial_messages: true,// token-by-token streaming})){if(msg.type==='stream_event'&&msg.event.type==='content_block_delta'){if(isTextDelta(msg.event.delta))process.stdout.write(msg.event.delta.text)}}awaitagent.delete()

API

方法说明
AgentBox.create(config)创建容器,返回 AgentBox 实例
agent.query(prompt, options?)流式查询,返回 AsyncGenerator<Message>
agent.delete()删除容器(幂等)

配置 (AgentBoxConfig)

字段类型必填说明
agentServerstringControl Plane URL
tokenstringControl Plane API key
descriptionstringAgent 任务描述
envobject注入到容器的 LLM 环境变量
skill_idsstring[]已上传的 Skill ID
skill_reposstring[]Skill Git 仓库地址
cpu_limitstringCPU 限制
memory_limitstring内存限制
idle_timeoutnumber空闲超时(秒)
max_lifetimenumber最大生命周期(秒)

env 字段中的所有环境变量会注入到容器内,供 Claude CLI 使用。常见变量:ANTHROPIC_AUTH_TOKENANTHROPIC_BASE_URLANTHROPIC_MODEL 等。

Demo

cp .env.example .env # 填入实际配置
npx tsx demo.ts

Admin UI

React + Vite + TypeScript 管理后台,位于 admin-ui/ 目录。

功能

  • API Key 登录认证
  • Dashboard 统计面板(容器状态分布 + 最近容器)
  • 容器列表(搜索、状态筛选、排序、分页、删除)
  • 创建容器表单(任务、Skill 选择、Skill Repos、资源限制、环境变量)
  • 容器详情 + WebSocket 实时日志流
  • Sidecar Query 交互查询(prompt 输入 + 高级选项 + SSE 实时返回)
  • Skill 管理(ZIP 上传、拖拽上传、自动从 skill.md 提取元数据、编辑、删除)
  • 中英双语(自动检测 + 手动切换)
  • 暗色/亮色主题切换

本地开发

cd admin-ui
npm install
npm run dev # → http://localhost:5173

Vite dev server 自动代理 /api/healthlocalhost:8080(需同时运行 Control Plane)。

生产部署

docker compose up -d admin-ui # → http://localhost:3000

Nginx 反向代理 SPA + API + WebSocket。

License

MIT

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages