cloudflare/claude-managed-agents
GitHub: cloudflare/claude-managed-agents
Cloudflare 官方的 Claude Managed Agents 自托管控制平面,用于在 Cloudflare 上编排、沙箱化运行并扩展 AI Agent。
Stars: 247 | Forks: 41
# 在 Cloudflare 上运行 Claude Managed Agents
在 Cloudflare 上运行 Claude Managed Agents (CMA)。
本仓库提供了一个可自定义的控制平面,允许您:
- 在完整容器和轻量级 isolate 上运行 CMA 沙箱
- 自定义您的 agent 使用的容器大小和镜像
- 获得对 agent 沙箱更好的可观测性
- 应用自定义的出站控制以实现[零信任凭证注入](https://blog.cloudflare.com/sandbox-auth/),并通过 [Workers VPC](https://developers.cloudflare.com/workers-vpc/) 连接到私有服务
- 使用 [Cloudflare 开发者平台](https://workers.cloudflare.com/products#all),通过 [Browser Run](https://developers.cloudflare.com/browser-run)、[Email](https://developers.cloudflare.com/email-service/) 以及任何其他自定义工具来扩展您的 Agent
您的需求。
请按照[入门指南](#onboarding-guide)开始操作。我们支持两种
部署方式:一键部署到 Cloudflare
按钮(基于 git,在 Workers Builds 中运行)以及从您的笔记本电脑执行的基于终端的
`npm run deploy` 流程。
## 概述
本仓库部署了一个基于 Workers 的控制平面,用于在 Cloudflare 上运行 Claude Managed Agents。
当 agent 会话开始或结束时,Claude Managed Agents 会向您的 Worker 发送 webhook。控制平面会为每个会话启动一个沙箱,在会话休眠期间同步状态,并在会话结束时关闭沙箱。
沙箱可以是 [Cloudflare Containers](https://developers.cloudflare.com/containers/),也可以是使用 [AgentsSDK](https://developers.cloudflare.com/agents/) 的 [Isolate](https://developers.cloudflare.com/dynamic-workers/) 沙箱。这允许您要么获得 Linux VM 的完整功能,要么获得一个轻量级的 isolate,它可以在没有微 VM (microVM) 的资源开销和成本的情况下实现大规模扩展。
您可以配置策略来限制 agent 访问特定域名,在不让 agent 访问机密的情况下将凭证注入到传出请求中,或者编写任意代理代码来修改、重新路由或记录出站流量。
此外,您可以将 [Workers VPC](https://developers.cloudflare.com/workers-vpc/) 和 [Mesh](https://developers.cloudflare.com/workers-vpc/examples/connect-to-cloudflare-mesh/) 资源连接到您的沙箱。这允许您轻松访问任何云端或本地部署的私有资源,而无需将它们暴露给公共互联网。
最后,可以轻松扩展此代码库,以便向您的 agent 沙箱添加自定义工具。工具会被两种后端自动拾取,并在拥有 Worker 绑定的直接访问权限的情况下运行,从而可以利用整个 Cloudflare 开发者平台。
该仓库提供了以下内置工具:
- 发送电子邮件
- 访问私有服务
- 浏览器自动化
- 图像生成
所有这些都可以通过部署到您 Cloudflare 账户的 UI 和 API 进行访问。
借助这个代码仓库,您应该能够快速建立并运行一个基于 Cloudflare 的自托管环境。然后您可以将其 fork,根据您的需求进行自定义并重新部署。此仓库旨在作为一个起点。
## 入门指南
顺序很重要 —— 请按从上到下的步骤操作。
### 选择部署方式
有两种部署方式。请选择一种,并在整个入门过程中坚持使用:
- **基于 Git**。点击 [Deploy to Cloudflare](#step-1-initial-deploy) 按钮。
Cloudflare 会将此仓库 fork 到您的 GitHub 账户中,部署您的控制平面,然后未来向此 GitHub 仓库推送的更新将自动进行部署。
- **基于终端**。在您的笔记本电脑上运行 `npm run deploy`。需要
Docker(用于构建容器镜像)和 `wrangler login`
会话。
**两种途径在第 1 步和第 3 步有所不同** —— 下文为每种途径提供了
单独的小节。无论您如何部署,第 2 步以及第 4 步到第 9 步都是完全相同的。
### 第 1 步. 初始部署
#### 基于 Git
Deploy to Cloudflare 按钮会将此仓库 fork 到您的 GitHub 账户中,
自动配置 D1 数据库、KV 命名空间、R2 存储桶和 Durable Objects,
提示您输入所需的机密(见第 2 步),并
通过 Workers Builds 部署 Worker。
部署完成后,您将获得一个 `https://.workers.dev`
URL,您将在第 2 步中需要它。
[](https://deploy.workers.cloudflare.com/?url=https://github.com/cloudflare/claude-managed-agents)
在完成剩余步骤之前,Worker 将无法运行。
#### 基于终端
```
npm run deploy
```
`npm run deploy` 会构建您的基础沙箱容器镜像(需要
Docker),部署 Worker,并通过
`postdeploy` 钩子应用 D1 迁移。提交的 `wrangler.jsonc` 故意将
KV `id` 字段和 D1 `database_id` 留空 —— `scripts/ensure-kv.mjs`
和 `scripts/ensure-d1.mjs` 会在 `prebuild` 时运行,并将真实的 ID 修补进去(会采用按名称已存在的任何命名空间/数据库,
否则就创建全新的)。R2 存储桶按名称绑定(无需查找 ID),并由 wrangler 自动创建。
如果您登录的 Cloudflare 账户有权访问多个
账户,请在运行前设置 `CLOUDFLARE_ACCOUNT_ID`,以便确保
脚本知道要与哪个账户通信:
```
export CLOUDFLARE_ACCOUNT_ID=
npm run deploy
```
在完成剩余步骤之前,Worker 将无法运行,但是
部署过程会为您提供 Webhook 所需的
`https://.workers.dev` URL。
### 第 2 步. 创建 Anthropic 环境和 webhook
在
[Claude Platform Console](https://platform.claude.com/workspaces/default/environments)
中创建一个“自托管”环境,
并保存环境密钥。然后,在
[Webhooks 设置](https://platform.claude.com/settings/workspaces/default/webhooks)中,
将 webhook URL 设置为 `https://.workers.dev/webhooks`
并保存生成的 Webhook Secret。
您将需要以下值:
- `ENVIRONMENT_ID` —— 您的新自托管环境的 ID
- `ANTHROPIC_ENVIRONMENT_KEY` —— 控制平面用于验证来自指定 Claude agent 环境的调用所使用的
环境密钥
- `ANTHROPIC_API_KEY` —— Worker 用来调用 Anthropic 的密钥
- `WEBHOOK_SECRET` —— 标准 Webhooks 签名密钥。Anthropic
将事件发布到您的 Worker;我们在对它们执行任何操作之前会
验证签名。
### 第 3 步. 设置机密
#### 基于 Git
Deploy to Cloudflare 表单在您部署时已提示输入核心机密,因此
`ENVIRONMENT_ID`、`ANTHROPIC_ENVIRONMENT_KEY` 和
`ANTHROPIC_API_KEY` 已经在您的 Worker 上。如果没有,
请使用 `npx wrangler secret put` 添加它们。
有两个后续操作:
1. **重新添加 `WEBHOOK_SECRET`。** 在您部署时 Webhook 尚未存在(您是在第 2 步中创建的),所以无论您在表单中
提供了什么占位符都是错误的。现在推送真实值:
npx wrangler secret put WEBHOOK_SECRET
2. **将机密值复制到 `.dev.vars` 以进行本地开发。**
Workers Builds 不会将您的表单输入同步回仓库,因此
否则 `wrangler dev` 将无法看到它们。
cp .dev.vars.example .dev.vars
# 编辑 .dev.vars 并粘贴你在表单中提供的值,
# 以及来自第 2 步的真实 WEBHOOK_SECRET。
#### 基于终端
设置本地开发:
```
cp .dev.vars.example .dev.vars
# 使用你的真实值进行编辑
```
在生产环境中,`.dev.vars` 中的每个条目都需要匹配的
`wrangler secret put NAME`。四个核心机密是:
```
npx wrangler secret put ENVIRONMENT_ID
npx wrangler secret put ANTHROPIC_ENVIRONMENT_KEY
npx wrangler secret put ANTHROPIC_API_KEY
npx wrangler secret put WEBHOOK_SECRET
```
### 第 4 步. 应用 D1 迁移
`postdeploy` 钩子会在每次 `npm run deploy`(包括 Deploy to
Cloudflare 按钮的部署)之后自动运行 `wrangler d1 migrations apply DB --remote`,
因此在生产环境方面无需执行任何操作。对于本地开发:
```
npm run db:migrate # local
```
### 第 5 步. 配置 R2 快照凭证
R2 存储桶本身已在第 1 步中自动创建。生产环境中使用的 presigned-URL
路径仍然需要一个访问密钥。如果您在 Deploy to Cloudflare 表单期间提供了
`R2_ACCESS_KEY_ID` / `R2_SECRET_ACCESS_KEY` / `BACKUP_BUCKET_NAME` /
`CLOUDFLARE_ACCOUNT_ID`,您可以
直接跳过 —— 它们已经设置好了。
除非您专门使用 Isolate 沙箱
或运行无状态的 agent 会话,否则这是必需的。Isolate 会话通过
Durable Object SQLite 存储进行持久化,不需要 R2 —— 如果您确定
永远不会运行 MicroVM agent,则可以跳过此步骤(并从
`wrangler.jsonc` 中删除 `r2_buckets` 块)。
任何运行 MicroVM 后端的人都应将此视为核心
入门步骤。
[生成一个 R2 访问密钥](https://dash.cloudflare.com?to=/:account/r2/api-tokens/create?type=user)
,拥有对 `claude-managed-agents-snapshots` 存储桶的读写权限
(Cloudflare dashboard → R2 → Manage R2 API Tokens → Create token),
复制 Access Key ID 和 Secret Access Key,然后推送
以下机密:
```
npx wrangler secret put R2_ACCESS_KEY_ID
npx wrangler secret put R2_SECRET_ACCESS_KEY
npx wrangler secret put BACKUP_BUCKET_NAME # same as bucket_name in wrangler.jsonc (IE: claude-managed-agents-snapshots)
npx wrangler secret put CLOUDFLARE_ACCOUNT_ID # found in your dashboard URL
```
有关更多信息,请参阅[快照和状态持久化](./docs/snapshots-and-state-persistence.md)。
### 第 6 步.(可选)开启额外功能
Browser Rendering、Workers AI 和发送电子邮件功能都是开箱即用地配置好的 —— 如果您不需要,请在 `wrangler.jsonc` 中禁用它们。VPC 绑定
是选择加入的。
| 功能 | 默认 | 绑定 | 要添加的机密 | 设置步骤 |
|---|---|---|---|---|
| Browser Rendering 工具 | 开启 | `wrangler.jsonc` 中的 `browser` | `CLOUDFLARE_API_TOKEN`(用于 REST 工具) | 无 |
| Workers AI 图像生成 | 开启 | `wrangler.jsonc` 中的 `ai` | 无 | 无 |
| 发送电子邮件 + 收件箱 | 开启 | `wrangler.jsonc` 中的 `send_email`;设置 `EMAIL_DOMAIN` + `EMAIL_FROM`(Deploy to Cloudflare 会提示输入这些内容,或者在本地使用 `wrangler.jsonc` 中的 `vars`) | 无 | [Email 文档](./docs/agent-email.md) |
| VPC 私有服务 | 关闭 | 在 `wrangler.jsonc` 中添加 `vpc_services` 块 | 无 | [Workers VPC 文档](./docs/connecting-to-private-services.md) |
### 第 7 步. 访问仪表板
`https://.workers.dev/`。创建一个 agent(表单允许
您选择 MicroVM 或 Isolate 后端),启动一个会话,查看
日志。
### 第 8 步. 保护仪表板
**您的控制平面默认是不安全的!**
一旦您完成了设置,您将需要通过设置 Cloudflare Access 来保护仪表板。
有关更多信息,请参阅 [Cloudflare Access 文档](./docs/securing-access.md)。
### 第 9 步. 自定义控制平面(可选)
Fork 此仓库并对其进行修改以适合您的需求或添加自定义
工具。
## 深入探索
一旦控制平面启动并运行了第一个端到端的会话,
您可以进一步探索:
- [连接到私有服务](./docs/connecting-to-private-services.md)
通过 Workers VPC 绑定在其他云端或本地(甚至在您的笔记本电脑上)进行连接。
- [注入凭证并锁定 agent 会话](./docs/applying-egress-policies.md)
使用出站策略。设置允许/拒绝列表、标头注入、自定义 Worker 代理
以及 VPC 路由。
- [在 Isolate 和基于 VM 的沙箱之间进行选择](./docs/isolate-vs-vm-sandboxes.md)
以获得最佳的 agent 执行环境。
- [设置 Agent 电子邮件](./docs/agent-email.md),为您的新
agent 提供电子邮件地址和发送功能。
- [使用 Browser Run](./docs/browser-rendering-tools.md) 以获得
强大且可观察的 agent 浏览器交互。
- [添加自定义工具](./docs/adding-custom-tools.md) 新工具在一个
文件 [`src/tools/custom-tools.ts`](./src/tools/custom-tools.ts) 中声明。
- [自定义您的沙箱](./docs/customizing-sandboxes.md),通过更改 MicroVM 后端的
`Dockerfile` 和 `instance_type` 设置。
- [了解状态持久化](./docs/snapshots-and-state-persistence.md)
涵盖这两种沙箱类型。
- [探索架构](./docs/architecture.md) 以了解请求生命周期,
从 webhook 入口到分发到任一沙箱后端,并
盘点控制平面使用的每个 Worker 绑定。
- 对新的 CMA 控制平面进行[安全访问](./docs/securing-access.md)。
## 配置参考
所需的机密和变量:
| 名称 | 描述 |
|---|---|
| `ENVIRONMENT_ID` | 要轮询工作的环境 |
| `ANTHROPIC_ENVIRONMENT_KEY` | Anthropic 环境密钥 (sk-ant-oat01-...)。控制平面用于轮询、确认、心跳、强制停止以及会话事件流的单一凭证。在 0.96 SDK / ant 18 CLI 中从 `ANTHROPIC_ENV_KEY` 重命名而来。 |
| `ANTHROPIC_API_KEY` | Anthropic API 密钥 (`sk-ant-...`) |
| `WEBHOOK_SECRET` | 用于验证 webhook 签名的 HMAC 密钥 |
| `CLOUDFLARE_ACCOUNT_ID` | R2 快照(预签名 URL 模式);也由 Browser Rendering REST 工具使用 |
| `R2_ACCESS_KEY_ID` / `R2_SECRET_ACCESS_KEY` | R2 快照(预签名 URL 模式) |
| `BACKUP_BUCKET_NAME` | R2 快照(预签名 URL 模式) |
运行 MicroVM 沙箱的生产环境部署需要与快照相关的值。
`wrangler dev` 可以通过直接回退到 BACKUP_BUCKET 绑定在没有它们的情况下运行,
但 R2 存储桶本身必须存在(在初始部署中完成)。专门使用 Isolate
沙箱的部署可以完全删除快照机密和 `r2_buckets` 块。
可选的机密:
| 名称 | 用于 |
|---|---|
| `CLOUDFLARE_API_TOKEN` | Browser Rendering REST 工具 |
| `ANTHROPIC_BASE_URL` | 覆盖(默认为 `https://api.anthropic.com`) |
可选的变量:
| 名称 | 用于 |
|---|---|
| `EMAIL_DOMAIN` | 每个会话收件箱地址的后缀 |
| `EMAIL_FROM` | `cf_email_send` 的默认发件人 |
| `EMAIL_FORWARD` | 杂散(非会话)电子邮件的后备收件箱 |
可选的绑定(在 `wrangler.jsonc` 中声明):
| 绑定 | 用于 |
|---|---|
| `BROWSER` | Isolate CDP 浏览器工具 |
| `AI` | `cf_image_generate` |
| `BACKUP_BUCKET` | 沙箱快照 |
| `SEND_EMAIL` | `cf_email_send` |
| `vpc_services[]` | 私有 VPC 服务路由 + `cf_call_service` |
## 测试
```
npm test
```
Vitest 涵盖了出站代理、存储层和 API 表面。VPC 和
Mesh 测试存根已包含但已被注释掉 —— 请参阅 `tests/egress.test.ts` 底部的 `describe.skip(...)`
块以了解计划的形态。
## 常见陷阱
一些会困扰人们的边缘情况,其中大多数与
`wrangler.jsonc` 中空的 `id` / `database_id` 占位符有关:
- **直接运行 `npx wrangler deploy` 会失败。** 提交的
`wrangler.jsonc` 设计上具有空的 KV `id` 和 `database_id` 字段;
如果不先运行修补脚本,wrangler 会拒绝加载它。
使用 `npm run …` 包装器(它会触发 `prebuild`),或者在克隆后运行一次 `npm run prebuild` 以在您的工作树中填充 ID。
`npm run cf-typegen` 也有同样的注意事项 —— 如果它抱怨缺少 ID,请先运行
`prebuild`。
- **不要提交修补后的 ID。** 在本地部署后,脚本会将真实的命名空间/数据库 ID 写入您的工作副本
`wrangler.jsonc` 中。
这些值是特定于账户的。如果您要向规范仓库贡献 PR,请将它们排除在提交之外(使用 `git checkout wrangler.jsonc` 或有选择地暂存)。如果您在个人 fork 上工作,提交它们是没问题的 —— 您的 Workers Builds 重建会对它们执行快速空操作。
- **切换 Cloudflare 账户。** 当本地已经填充了 ID 时,prebuild 快速路径会跳过 API 检查。如果您切换了要部署到的
`CLOUDFLARE_ACCOUNT_ID`,请先运行
`git checkout wrangler.jsonc` 以便将 ID 重置为空,并且脚本会针对新账户重新填充它们。否则,wrangler 将尝试将旧账户的 ID 用于新账户,并因
权限错误而失败。
- **多账户本地开发。** 如果您的 Cloudflare 登录有权访问多个账户,则 prebuild 脚本在非交互模式下无法选择一个。在运行 `npm run deploy` 或 `npm run dev` 之前设置 `CLOUDFLARE_ACCOUNT_ID`(脚本的错误消息列出了候选项)。
- **通过 Deploy to Cloudflare 表单重命名 worker。** 这是安全的
做 —— Cloudflare 的设置页面允许您选择 Worker 名称,以避免与现有的名称发生冲突。KV 命名空间和 D1 数据库
使用新名称作为前缀,因为 ensure 脚本在构建时从 `wrangler.jsonc` 中读取 `name`。
只要记住在第 2 步中配置 Anthropic webhook 时使用重写后的 URL(`https://..workers.dev`)即可。
- **Deploy to Cloudflare 表单:您必须重命名两个 KV 命名空间中的至少一个。** 此仓库声明了两个 KV 命名空间
(`SECRETS` 和 `EGRESS_POLICIES`),并且表单的“Configure resources”步骤用 worker 名称预填充了两个名称输入框,没有绑定后缀 —— 所以第一次创建成功,第二次失败并显示 `Cannot provision a KV Namespace with the title
"" because it already exists`。在点击部署之前,
编辑这两个输入框使其不同,例如 `-secrets` 和 `-egress-policies`。
然后 `ensure-kv.mjs` 将在随后的每次构建中模糊匹配这些名称回到正确的绑定。
## 许可证
[MIT](./LICENSE)
标签:AI智能体, DLL 劫持, MITM代理, 大语言模型, 沙箱管理, 程序员工具, 自动化攻击, 零信任网络, 高对比度