camelAI 把 Agent 从虚拟机里改造成跑在 Cloudflare 边缘节点上
- 大部分团队跑 AI Agent 都用完整的 Linux 虚拟机,camelAI 一开始也是。算完账他们把这台机器整个拆了。
- 分三步拆:先搬走 Agent,再把文件搬进数据库,最后连命令行都删掉。用户那边什么都没变。
- 最激进的是删命令行这一步。不过代码里那个「删掉」,留了一个口子。
每个用户一台常驻机器还得挂一块高速磁盘,按他们规划的用户量算不过来
这是 camelAI 的 CTO Miguel Salinas 写的一篇架构重构复盘。他们把原本跑在独立虚拟机里的 AI Agent,完全重构成跑在 Cloudflare Durable Object 上的轻量架构,成本和延迟都大幅下降。改造分三次做完,代码 7 月 24 日全部开源,每一处机制都能对着仓库核。
不认识 camelAI?点开看一眼
camelAI 是一个 AI 编程助手,三个人的团队做的:Illiana Reed 管产品,Miguel Salinas 管技术,Isabella 管运营。
你在对话框里说要做什么,它写代码、装依赖、把项目跑起来,最后部署到一个能打开的网址;它还能接你的数据库和几十种外部服务,跑 Python notebook、做仪表盘。
官网的自我介绍是「一个住在自己电脑里的 AI 软件工程师」。那台「电脑」就是每个用户分到的一台 Linux 虚拟机,也正是这篇要拆掉的东西。
大部分团队跑 AI Agent 都用完整的 Linux 虚拟机或容器沙箱,camelAI 一开始也是。
问题出在成本结构上:给每个用户配一台常驻机器,还要挂上高速磁盘存文件。用户数一涨,扩容就是在扩真实的机器和真实的磁盘。按他们规划的用户量算,这条路走不通。
难点在于,AI Agent 天然假设自己跑在 Linux 上,被训练成一遇到问题就去调 bash。而他们最初用的是 Claude Code 那套 harness,它本身就必须要有完整虚拟机才能跑。harness 指的是包在模型外面那层程序,负责跑对话循环、管工具、管状态。
所以他们没去琢磨虚拟机怎么调度更省,而是按「根本不需要虚拟机」重新设计了一遍。
四个多月前,camelAI 的 CEO Illiana Reed 还发过一篇博客,第一句是「camelAI 的每个用户都有一台持久的电脑,一个真正的 Linux 环境」,并称这是产品的核心承诺。那篇讲他们试了 Modal、Cloudflare Containers、Fly.io 的 Sprites 都不合适,最后花一周自己搭了一套容器服务。这次 Miguel 写:那篇还挂着,但那套基础设施我们一台都不跑了。
那台虚拟机里装着三样东西:Agent 本体、项目文件、命令行。三次重构就是把它们一件件搬走,每搬走一件,就得回答它原来干的活现在归谁。
第一步搬走 Agent 本体:响应变快了,但机器还占着
Claude Code 的 harness 和虚拟机分不开,所以第一件事是自己写一个。
底座用的是 pi,Mario Zechner 的开源 Agent 工具包,MIT 许可,GitHub 上 8.1 万 star。pi 是一摞库,不是一个程序。最上面那层是命令行工具,假设脚下有操作系统;下面几层只给 Agent 的原材料,对话循环、状态管理,不关心自己跑在哪。camelAI 一行 pi 的代码都没改,只拿了下面两层。
camelAI 的 package.json 里只有 @earendil-works/pi-agent-core 和 @earendil-works/pi-ai(都是 0.80.6 版),没有 pi-coding-agent,就是那个假设有操作系统的命令行层。
新的 harness 跑在一个 Durable Object 里。这是 Cloudflare 的一种小型计算实例,自带一块专属存储,会在离用户最近的机房里醒来。camelAI 给每个聊天会话分一个。
普通的云服务像去银行取号,每次叫到你的可能是不同的柜员,你得把情况重讲一遍。Durable Object 更像一个带私人抽屉的固定接待员:你每次回来找的都是同一个人,抽屉里还放着你上次留下的东西。
这一步虚拟机还在,只是 Agent 不住里面了。要跑命令就远程调过去。Anthropic 讲自家的托管 Agent 也是这么分的:脑子和手分开。
好处有三条。Agent 不用等机器开机就能回话;Agent 干活的时候机器可以先睡,这一轮不需要跑命令它就一直不醒;一个脑子能指挥好几只手,同时操作多台机器。
这些「手」在产品里叫项目。每个项目配一台虚拟机,外加一个 git 仓库,用 Cloudflare Artifacts 直接从代码里建出来,不用自己架 git 服务器。这个阶段 Agent 照样有命令行,它基本不知道自己已经跑在虚拟机外面。
第二步扔掉硬盘:文件改存进数据库,存储和常驻机器的钱一起省了
下一版把虚拟机拿掉了,项目结构不动。文件系统改成住在 Durable Object 里,大文件放 R2,也就是 Cloudflare 的对象存储。
这套是现成的。Cloudflare 的 Agents 团队做了个包叫 @cloudflare/shell,自我描述是「实验性的 Worker 沙箱执行与文件系统运行时」,camelAI 大量复用了它的代码。
Durable Object 的存储本来就是一个 SQLite 数据库,单个实例上限 10 GB,每一行有大小限制。所以小文件直接存成一行;超过大约 1.5 MB 的写进 R2,那行只留一个指针。Agent 看到的还是普通文件系统,底下是一张表加一个仓库。
- 阈值在
workspace-filesystem-do.ts里是写死的常量:DEFAULT_INLINE_THRESHOLD = 1_500_000,也就是 150 万字节。 - Cloudflare 官方文档:SQLite 版 Durable Object 每个实例存储上限 10 GB(付费版),单行上限 2 MB。1.5 MB 这条线卡在 2 MB 硬上限下面留了余量,不是随手定的。
虚拟机时代,「文件还在」是因为你一直在花钱养着一台机器和一块盘。现在「文件还在」是因为数据存下来了。数据躺着不要钱,机器躺着要钱,这一步真正砍掉的成本就在这里。
版本历史继续走 Artifacts,每个项目照样有完整的 git 记录。
第三步删掉命令行:Agent 改成写 JavaScript 调固定方法
删命令行是三步里最激进的一步,camelAI 自己也这么说。
命令行的问题不只是钱。Agent 既能敲命令又能上网,要干成事就得往它手里塞凭据,数据库密码、API 密钥这些。他们试过用带鉴权的代理网址把凭据挡在外面,越写越糙,越来越难保证。
所以直接删掉。Agent 改成写 JavaScript,代码交给 Cloudflare 的 Code Mode 执行,不再一次调一个工具,而是写一段代码把要做的事串起来跑完。每次执行开一个全新的 V8 isolate。
V8 isolate 不是一台新电脑。它更像在已经开着的浏览器里新开一个标签页:几毫秒就出来,只占几 MB 内存,用完直接关掉,下次再开一个干净的。而起一个容器,按 Cloudflare 官方的说法要几百毫秒、占几百 MB。
凭据被挡在沙箱外面
沙箱里预装好了这个用户的数据连接,以及平台能干的所有事对应的方法。凭据从不进沙箱:Agent 调某个连接的方法,鉴权在平台那一侧完成,密钥自始至终不出现在 Agent 能碰到的地方。
删掉命令行,能力损失多少
Agent 拿命令行干的事,绝大部分是文件操作:列目录、读文件、改文件、搜内容。这些有原生工具顶上,覆盖了八成。剩下两成是特定的活跑特定的命令,一条条变成了明确的方法。
左边那行「想干啥都行」,正是被换掉的东西。现在 Agent 能干什么,得团队事先写进右边那 64 个里。
- 公开说法是「read、write、edit,外加我们自己实现的 grep 和 glob」,代码里实际是 7 个:
read/write/edit/ls/grep/find/delete。多出来的是ls和delete,glob 在代码里叫find。 - 装方法的那个文件
code-mode-tools.ts有 4632 行,注册了 64 个方法。既有deploy_project、run_notebook这种平台动作,也有WebSearch、TodoWrite这种 harness 自带的通用工具。 - 沙箱里还有一个
tools.search()。Agent 按关键词搜工具,再用tools.describe()看参数,不用一上来把 64 份说明书全塞进上下文。 - 系统提示词里有一条硬规定:不许用 create-worker、wrangler 或包管理器的命令来做脚手架、构建和部署。明着堵住模型的老习惯。
最能说明问题的例子是部署。以前 Agent 通过代理跑 wrangler deploy,平台只能去嗅探代理流量,猜是哪个会话部署了东西。现在它是一个完全由平台控制的 deploy_project 方法,部署发生在哪一秒是确切知道的,可以挂个钩子,部署完自动把预览打开。
改造成果:成本降了几个数量级,响应变快,凭据不再进沙箱,代码全开源
三步走完,账面上换来四样东西。
成本:从按在线时长收费,改成按执行次数收费
虚拟机和容器只要醒着,内存和磁盘就一直在计费,哪怕没人碰它。isolate 是有人调才开、跑完就没,不跑的时候它不存在,也就没有账单。扩容也不再是扩真实的机器和真实的磁盘。
他们给的对比是:几千次执行的花费,大约等于自己评估过的那些容器服务上几分钟的时间。能核的是 Cloudflare 那一侧的官方数字,来自 2026 年 3 月 24 日的动态 Workers 发布博客:
但全文没有一笔前后对比的账。文末的总结写着「便宜了几个数量级」,从头到尾没有出现过「以前每月多少、现在每月多少」这样的数字。这是 camelAI 单方面的说法,读者核不了。
延迟:Agent 就在离用户最近的机房里
Agent 跑在 Cloudflare 的边缘节点上,请求不用绕到一台中心虚拟机。它也不用等虚拟机开机,用户说完话它就能开始回。
安全和便宜模型:凭据进不去,工具边界也变清楚了
凭据从不进沙箱,鉴权在平台那一侧完成,Agent 手里始终没有钥匙。
命令行是开放的,什么都能敲,便宜模型在这种环境里容易乱试、绕远、卡住。换成一小组边界清楚的方法之后,便宜模型明显好用了。这一条直接落在成本上:让产品跑起来便宜正是这整套架构的目的,模型这一头的账同样要省。
这条也没有公开数字。仓库里有 52 个跑真实模型的测试文件,还有一批文件名带 camel-free- 的(看着是给免费档的便宜模型准备的),但没有任何公开的跑分结果。
代码全部开源
camelAI 的仓库 7 月 24 日以 MIT 许可开源,地址是 github.com/qaml-ai/camelAI。上面写的每一处机制都能翻到对应的文件读,本文标「核对过」的内容就是这么查出来的。
拆完之后 Linux 只剩三处:构建应用、跑数据分析、查数据库
构建用户的应用得留容器,这活真的需要 Linux。用户的应用用 Vite、Tailwind、React Router 搭,加个依赖就要跑 bun install。
他们想过在 Worker 里做构建,毕竟构建出来的东西本身就是个 Worker。但 Cloudflare 这条路支持得不好,而且 Worker 只有 128 MB 内存和几分之一个 CPU,构建会很慢,很多项目直接爆内存。(这个 128 MB 本站查过官方文档,免费版付费版都一样。)
做法是:要构建就起一个容器,把项目拷进去,跑完,拿回结果,关掉。跑 notebook 一样。Linux 还在用,只用真正需要的那几秒。
公开说法是两个容器,生产环境配置文件里实际有三类。第三类专门跑 SQL 查询和数据导出,博客里没提到;代码注释写明这个容器里不跑用户代码。
| 容器 | 干什么 | 规格 | 最多几个 | 空闲多久睡 |
|---|---|---|---|---|
| 构建沙箱 | 跑 bun install 和前端构建 | 2 vCPU · 8 GiB | 100 | 2 分钟 |
| 分析沙箱 | 跑 notebook、shell、DuckDB | 2 vCPU · 8 GiB | 100 | 5 分钟 |
| 查询沙箱 | 跑 SQL 查询和导出(未公开提及) | 0.5 vCPU · 4 GiB | 25 | 2 分钟 |
数据来自仓库的生产配置文件与 container-sizing.ts。
休眠时间为什么压到 2 到 5 分钟,代码注释里给了答案:内存和磁盘按「预置的量」计费,只要容器醒着就一直在扣;只有 CPU 按实际用量算。一个开着但什么都没干的容器,照样在烧钱。这条规则也正好解释了他们为什么要拆掉常驻虚拟机,同一个道理,只是量级不同。
「删掉 bash」这句话,代码里留了个口子
仓库里还有一个叫 analysis_exec 的方法,能在分析容器里跑 shell 命令。工具说明里明写它是「run_notebook 覆盖不到的数据活的逃生口」。
所以严格说,命令行没有从这个系统里消失,它只是从 Agent 的日常工作区里消失了,变成一个必须走特定容器、有明确用途的窄口子。这和「Agent 手里随时有个 bash」是两回事,但也不等于字面上的「删掉」。
代价是 Agent 不能再自己找路,缺什么都得团队先替它想到
camelAI 自己把这条列了出来,写得很实在:有命令行的时候,Agent 遇到没见过的情况能自己琢磨出办法;现在缺哪个能力,就得他们去补一个。
诚实的坏处是,我们必须预判 Agent 需要什么。有了 bash 它可以自己摸索。现在如果某个能力缺席,我们就得把它加上。
Miguel Salinas,camelAI CTO
但他们认为这个压力对产品有好处:它逼着团队去想用户到底在干什么,然后给那件事修一条正经的路,而不是任由 Agent 现场即兴发挥。
还有一条代价没被提到
他们自己实现的那个 grep,本站读了代码:它把目录下每个文件读出来,在 JavaScript 里一行一行扫过去。最多扫两万个文件,默认返回 100 条匹配,超过 500 个字符的行会被截断。
ripgrep 那种为搜索专门优化过的工具是编译好的程序,直接在磁盘上并行扫,两者不是一个量级。小项目上看不出差别,仓库大了之后会怎么样,公开材料里没有交代。
Agent 需要的并不是一台电脑,这是他们拆完才看清的事
整个行业默认的做法,是给 Agent 复刻一套人类程序员的工作环境:一台机器、一个文件系统、一个命令行,因为人类程序员就是这么干活的。
camelAI 把这套环境一件件拆掉之后发现,Agent 真正需要的是准确的能力接口。文件操作要有,那就给七个工具;部署要有,那就给一个方法。至于底下是不是一台真的电脑,它并不需要知道。
他们的路径本身就是方法:先把 Agent 从环境里摘出来,再把状态从机器搬进数据,最后把开放式的能力收成有边界的接口。每一步都能单独验证有没有效,也都能单独回退,比一次性推翻重来的风险小得多。
从用户那边看,什么都没变。照样让 Agent 构建应用、部署到一个能打开的网址,Agent 照样读文件、写文件、搜内容、发布。四个多月前那句「每个用户都有一台持久的电脑」,承诺没变,只是那台「电脑」现在是一张数据库表加一个用完就丢的沙箱。
想现在照着搭一套,有一处过不去
Cloudflare Artifacts 还在封闭测试。官方文档(最后更新于 2026 年 5 月 5 日)上写着要填表申请访问权限。这套架构里管版本历史的那一环,现在拿不到公开入口。
另一处不算门槛,但值得先知道:@cloudflare/shell 自我描述就是「实验性」的。这个包 2026 年 3 月 13 日首发,到 7 月 23 日已经出了 19 个版本,最新是 0.4.3,而 camelAI 锁死在 0.3.7。四个多月发 19 个版本,说明这块地基还在剧烈变动。
能直接拿走的是代码本身。camelAI 的仓库 7 月 24 日以 MIT 许可开源,上面每个机制都能翻到对应的文件读。
workers/main/src/chat-thread-do.ts 是跑在 Durable Object 里的 Agent 主循环(第一步);workspace-filesystem-do.ts 是那套数据库文件系统,1.5 MB 的阈值就在开头(第二步);code-mode-tools.ts 是替代命令行的 64 个方法(第三步);pi-container-tools.ts 是 7 个文件工具,那个逐行扫的 grep 也在里面。camelAI 把编程 Agent 脚下那台 Linux 电脑整个拆掉了,三步走完,代码全开源
camelAI 的 CTO 公开了完整的架构账本:Agent 搬走、硬盘换成数据库、命令行删掉,一页带图讲完。
↓ 一页读完 · 有一张会动的图
camelAI 是一个 AI 编程助手:你在对话框里说要做什么,它写代码、装依赖、把项目部署到一个能打开的网址。它的卖点原本是「每个用户都有一台持久的 Linux 电脑」,Linux 虚拟机就是在云上隔出来的一台小电脑,有自己的硬盘和命令行,开着就一直在计费。
问题出在成本结构:给每人配一台常驻机器再挂一块高速磁盘,用户数一涨,扩容就是在扩真实的机器和真实的磁盘。
示意图,原文没给具体时长。两条时间的差额就是虚拟机方案要付的钱。所以他们没去优化调度,而是按「根本不需要虚拟机」重来一遍。
那台虚拟机里装着三样东西:Agent 本体、项目文件、命令行。三次重构就是把它们一件件搬走,每搬走一件,就得回答它原来干的活现在归谁。
第一步只解决了延迟,机器还占着;第二步把常驻机器和磁盘的钱一起省掉,但 Agent 干活烧的算力还在按分钟计;第三步才动到算力。每步都能单独验证、单独回退。
虚拟机拿掉之后,文件系统住进了 Durable Object,Cloudflare 的一种小型计算实例,自带一块专属存储,会在离用户最近的机房里醒来,每个聊天会话分一个。它的存储本来就是一个 SQLite 数据库。
开着才有文件
没人用也在扣钱
data.csv → 超 1.5 MB,行里只留指针
本体进 R2 对象存储
这一步的题眼:虚拟机时代「文件还在」,是因为你一直花钱养着一台机器;现在「文件还在」,是因为数据存下来了。数据躺着不要钱,机器躺着要钱。
删命令行不只为省钱。Agent 既能敲命令又能上网,要干成事就得往它手里塞数据库密码、API 密钥这些凭据。camelAI 试过用带鉴权的代理网址挡住,越写越糙。
于是直接删掉:Agent 改成写 JavaScript,每次执行开一个全新的 V8 isolate,同一个进程里隔出来的一小块独立运行环境,几毫秒开出来、只占几 MB,跑完就丢,更像在已经开着的浏览器里新开一个标签页。凭据从不进沙箱,鉴权在平台那一侧完成。
本站读代码发现两处和公开说法有出入:文件工具实际是 7 个(公开说法只提了 5 个),装方法的那个文件注册了 64 个。
容器只要醒着,内存和磁盘就一直计费,哪怕没人碰;isolate 是有人调才开、跑完就没。camelAI 给的对比是:几千次执行的花费,约等于他们评估过的容器服务上几分钟的时间。
还有两处口子:仓库里留着一个能在分析容器里跑 shell 的方法,注释写明是「逃生口」,所以命令行没从系统里消失,只是从 Agent 的日常工作区里消失了。他们自己实现的 grep 是在 JavaScript 里逐行扫文件(最多两万个),和专门优化过的搜索工具不是一个量级,仓库变大后的代价原文没交代。想照着搭还有一处过不去:管版本历史的 Cloudflare Artifacts 仍在封闭测试,要填表申请。
零星几段,
钱一直在走。
要跑命令
才叫醒它。
那条分界线
机器躺着要钱。
- × 随便敲一条
没人想过的命令 - × 碰任何一把钥匙
加 7 个文件工具,
顶掉整个 bash
构建应用、跑分析、
查数据库。
