camelAI、Cloudflare Durable Object でエージェントを完全移行
camelAI は、コストとスケーラビリティの課題を解決するため、従来の仮想マシン環境からCloudflare Durable Objectへエージェント基盤を完全移行し、SQLite と R2 を活用した新しいアーキテクチャを採用した。
AI深層分析を開く2026年7月29日 23:26
AI深層分析
キーポイント
仮想マシンからの完全移行
camelAI は、ユーザーごとの常時稼働する仮想マシンと高速ディスクの維持コストが高すぎるため、Cloudflare Durable Object 上でエージェントを動作させる設計へ変更した。
独自ハネスの実装
Claude Code ハネスが仮想マシンに依存しているため、同社は Mario Zechner 氏のオープンソース「pi」の低層ライブラリを基盤とした独自のハネスを開発した。
機能制限と設計トレードオフ
エージェントは明示的に構築されたメソッドのみを実行可能となり、従来の Bash 実行能力は制限されるが、製品の安定性と管理性が向上している。
Durable Object を活用したアーキテクチャの進化
各チャットスレッドに個別の Durable Object を割り当て、VM の起動待ちを排除して応答遅延を改善した。
脳と手の分離による柔軟なリソース管理
エージェント(脳)とコマンド実行環境(手)を分離し、不要な VM への起動を抑制することでコストとスケーラビリティの課題に対処した。
重要な引用
The tradeoff is that the agent can now only do things we've built an explicit method for, which sounds limiting but has been good for the product.
Scaling it means scaling real machines with real disks, which was going to be prohibitively expensive at the user counts we're aiming for.
Anthropic describes this same split for its managed agents, the brain separated from the hands.
A single agent could operate several VMs at once.
編集コメントを表示
編集コメント
仮想マシンという重厚なインフラから、サーバーレス型 Durable Object への転換は、AI エージェントの実用化におけるコストと管理の壁を打破する重要な一歩である。特に Bash 実行能力を制限してでもスケーラビリティを選んだ判断は、実運用環境でのアーキテクチャ設計において示唆に富む事例と言える。
Source Article
元記事を日本語で読む
本文に関係しない購読案内、埋め込み通知、サイト内プロモーションは除いています。
私たちは最近、camelAI エージェントを仮想マシンから移行する作業を終えました。現在、このエージェントは Cloudflare Durable Object 内で動作し、ファイルシステムは SQLite と R2 に保存され、スクリプトとして Bash の代わりに JavaScript を記述します。
多くのチームは、コーディングエージェントを完全な Linux VM やコンテナサンドボックスで実行しています。私たちもかつてはそのような運用をしていました。
仮想マシンから移行した理由は、すべてのユーザーに常時稼働するマシンと接続されたディスクを提供することが、スケーラビリティの観点からコスト高すぎるためです。課題は、コーディングエージェントが Linux を前提として設計されている点にあります。これらは Bash コマンドを呼び出すように訓練されており、当初のハンス(実行環境)では完全な VM が必要でした。そのため、現在のアーキテクチャに至るまでに3回の再設計を行いました。
トレードオフとして、エージェントは現在、私たちが明示的にメソッドを用意した機能しか実行できません。これは制限があるように聞こえるかもしれませんが、製品の品質向上には寄与しています。
私は camelAI の CTO、Miguel です。私たちのコードベースは最近オープンソース化されたため、この記事で言及している内容はすべて、github.com/qaml-ai/camelAI で確認できます。随時関連ファイルへのリンクを貼っていきます。
ステップゼロ:仮想マシンの時代
私たちは当初、Claude Code ハンスで立ち上げました。これは完全な仮想マシンが必要でした。いくつかの VM プロバイダを試しましたが、いずれも私たちの永続性とパフォーマンス要件を満たすことができず、最終的に 独自のコンテナサービス を構築することにしました。
この記事は現在も公開されていますが、私たちはすでにそのインフラの運用を終了しています。
コンテナサービスは動作しましたが、重すぎました。ユーザーごとに常時稼働する仮想マシン(VM)を用意するのはコストが高く、高速なディスクにすべてのユーザーのファイルを保持するのも同様です。スケーリングするには、実機と実ディスクをスケールさせる必要があり、目指すユーザー数では費用が許容できないレベルでした。
そこで、仮想マシンのオーケストレーションで工夫をするのではなく、そもそも仮想マシンが必要ない設計へと方針を変えました。
ステップ 1:エージェントを VM から切り離す
Claude Code のハッチは VM と不可分だったため、最初のステップとして独自のハッチを開発しました。ベースとしたのは Mario Zechner 氏のオープンソースコーディングエージェント「pi」です。pi はライブラリのスタックで構成されていますが、最上位層では通常の OS を前提としています。一方、下位層にはエージェントループや状態管理といった基本機能が含まれており、実行環境を問いません。
私たちは pi のコード自体を変更していません。下位層のライブラリを取り込み、その上に独自のハッチを構築しました。具体的には、Linux 環境ではなく Cloudflare の Durable Object(永続オブジェクト)内で動作するものです。
Durable Object は、Cloudflare エッジでユーザーが作成した直後に起動する、状態を保持できる小規模なコンピューティングインスタンスです。各チャットスレッドに個別の Durable Object が割り当てられるため、すべての処理を中央集権型の VM ホストを経由させる必要がなくなり、レイテンシの削減につながりました。
この段階では、VM は維持しましたが、エージェントは VM 内部に常駐させるのをやめました。必要なときにリモートから VM を呼び出してコマンドを実行する形に変更しました。
Anthropic も同様に、管理型エージェントにおいて「脳」と「手」を分離した設計を採用しています。このアプローチにはいくつかの利点があります。
- エージェントは VM の起動を待たずに即座にレスポンスを開始できます。
- 処理が完了すれば VM はスリープ状態に戻り、あるいはコマンド実行が必要ないターンでは一度も起動しないようにすることも可能です。
- 1 つの「脳」で複数の「手」を制御できます。つまり、単一のエージェントが同時に複数の VM を操作できるのです。
私たちはこの「手」にあたる部分をプロジェクトと呼んでいます。各プロジェクトにはコマンド実行用の VM と、Cloudflare Artifacts を介してプログラム作成された Git リポジトリが付属しています。これは Worker から即座にプロビジョニングできる、Git 互換のストレージです。
エージェントは実際には VM の外で動作していることを意識しておらず、bash コマンドも利用でき、他のコーディングエージェントと同様に振る舞います。
しかし、この変更で解決したのはレイテンシの問題だけであり、コストやスケーラビリティといった根本的な課題は残ったままです。依然としてユーザーごとに VM が1つ必要だったため、元の設計が抱えていた問題点は解消されませんでした。
ステップ2:VM の完全排除
次のバージョンではプロジェクト構造は維持しつつ、背後にある VM を完全に撤廃しました。各プロジェクトのデータは Durable Object 内部に存在するファイルシステム に保存され、大容量ファイルには R2 がバックアップとして利用されています。
この仕組みを私たちが発明したわけではありません。Cloudflare のエージェントチームが Workers 向けの実験的なファイルシステムおよび実行ランタイムとして Shell を構築しており、私たちはそのコードを大幅に流用しました。
仕組みはシンプルです。Durable Object のストレージは最大 10 GB の SQLite データベースであり、各行にはサイズ制限があります。小規模なファイルは SQLite の行内に直接保存され、約 1.5 MB を超えるファイルは R2 に書き出されます。その際、SQLite の行には単に参照(ポインタ)が保持されるだけです。エージェントにとっては通常のファイルシステムのように見えますが、裏側ではデータベースとオブジェクトストレージが動いているため、永続化されたデータはインフラを常時稼働させる必要のあるものではなく、保存されたデータそのものです。
バージョン管理については依然として Artifacts を経由して行われるため、Git サーバーを自社でホストすることなく、すべてのプロジェクトで Git の履歴を保持できます。
ステップ 3: Bash を排除する
Bash を排除するのは大胆な決断に思えるかもしれません。コード生成エージェントはつねに Bash に頼ろうと訓練されており、それがエージェントを VM で実行させる理由の一つでもあります。しかし、コストの問題だけではありませんでした。Bash とネットワークアクセスを持つエージェントが有用な作業を行うには認証情報が必要ですが、認証付きプロキシ URL への対応を試みた結果、実装がごまかしになりやすく、厳格な運用が困難になることが判明しました。
そこで、私たちはこれを廃止しました。代わりにエージェントは Bash を使うのではなく、JavaScript を記述します。このコードは Code Mode と Cloudflare の 動的 Worker ローダー を通じて実行されます。
各実行は、数ミリ秒で起動し、数メガバイトのメモリしか使用しない新しい V8 イソレート環境で行われます。サンドボックスにはあらかじめユーザーのデータ接続が読み込まれており、プラットフォームが可能なすべての操作に対応する メソッド群 も用意されています。認証情報は決してサンドボックス内に入り込むことはありません。エージェントは接続先のメソッドを呼び出すだけで、実際の認証処理は当社の側で行われます。
実際のエージェントが Bash を何に使っているかを見てみると、これを廃止しても予想以上に大きな損失にはなりません。Bash の用途の多くはファイル操作ですが、これにはネイティブツールを用意しています。読み取り、書き込み、編集に加え、独自の grep と glob 実装 も提供しています。これで 80% のケースをカバーできます。
残りの 20% は特定のタスクに特化したコマンドですが、これらは明示的なメソッドとして実装しました:
Proxy を通じて wrangler をデプロイする仕組みを、完全に制御できる deploy_project メソッドとして再構築しました。これにより、デプロイがいつ発生するかを正確に把握できるようになり、自動的にライブプレビューを開くフックを実装することが可能になりました。以前は、どのスレッドで何かがデプロイされたかを推測するために、プロキシされた wrangler のトラフィックを監視する必要がありました。
ユーザーのアプリ構築と Python ノートブックの実行もそれぞれ独立したメソッドとして実装し、どちらも短期間のコンテナによってバックアップされています。これらのタスクには Linux 環境が真に必要であるため、コンテナを維持しています。ユーザーアプリは Vite、Tailwind、React Router を使ってビルドされ、依存関係の追加には bun install の実行が必要です。
ビルド自体が Worker であることから、Worker 内でビルドを実行することも検討しましたが、このアプローチは十分にサポートされていません。さらに、Worker はメモリ制限が 128 MB で CPU 資源も極めて限られています。そのため、ビルドには時間がかかりすぎ、多くのプロジェクトでメモリ上限を超えてしまう恐れがあります。
そこで採用したのが、Cloudflare Sandbox SDK を通じてコンテナを起動し、プロジェクトをコピーしてジョブを実行し、結果を返した後、すぐにコンテナを終了させるという仕組みです。ノートブックの実行も同様のフローで行われます。必要な Linux 環境は維持しつつ、実際にそれを必要とする数秒間の作業にのみ利用しています。
正直なところ、課題はエージェントが何を必要とするかを事前に予測しなければならない点です。Bash の場合は自分で状況を把握できましたが、現在は機能不足が発生した際に我々が追加する必要があります。実際には、このプレッシャーが製品にとって良い影響を与えています。なぜなら、ユーザーの行動を深く考え、エージェントに場当たり的な対応をさせるのではなく、第一級のパースを提供する道筋を構築することを強いるからです。
予期せぬメリットもありました。Bash は開かれた環境で動作しますが、安価なモデルはそうした環境では苦戦します。一方、明示された限られたメソッドセットを使用すれば、パフォーマンスが顕著に向上します。これは重要です。なぜなら、このアーキテクチャの目的自体が、camelAI を低コストで実行できるようにすることにあるからです。
現状のまとめ
現在のスタックは以下の通りです。エージェントとファイルシステムには Durable Objects を、大容量ファイルには R2 を、Git の履歴管理には Artifacts を使用します。基盤となるハーンスは pi で、実行には Code Mode と動的な Workers を組み合わせています。デプロイは通常の Cloudflare アプリと同様で、外部のコンテナサービスを管理する必要はありません。
Dynamic Workers は稼働時間ではなく、実行回数に対して課金されます。数千回の実行にかかるコストは、以前評価していたサービスにおける数分間のコンテナ利用時間とほぼ同等です。レイテンシが低いのは、すべてユーザーに近いエッジで動作しているためであり、スケーリングの問題も Cloudflare が担当するため、我々の負担にはなりません。
ユーザー側では依然としてフルスタックアプリを構築し、ライブ URL にデプロイできます。エージェントも引き続き、ファイルの読み書きや検索(grep)、デプロイを実行します。ユーザーにとっての変化はありません。
TL;DR
当初は自社構築の VM サービス上で Claude Code ハーネスを動かしていましたが、コストが高くスケーリングも困難でした。まずエージェント自体を Cloudflare Durable Object 内に移し、リモートで VM を制御できるようにしましたが、これでは遅延は改善されたもののコスト問題は解決されませんでした。
その後、Cloudflare の Shell プロジェクトに基づき、Durable Object SQLite と R2 に保存されるファイルシステムへ VM を完全置換しました。Git の履歴管理には Cloudflare Artifacts を活用しています。さらに bash を排除し、Code Mode と動的な Workers によって JavaScript サンドボックスをエージェントに提供。デプロイ、ビルド、ノートブック実行のための明示的なメソッドも用意しました。
その結果、コストは桁違いに低下し、遅延も大幅に短縮されました。運用がシンプルになり、より小さなモデルでも制御可能になったのです。すべてのコードはオープンソースで公開されており、github.com/qaml-ai/camelAI で確認できます。
原文を表示
We recently finished moving the camelAI agent off of virtual machines. The agent now runs inside a Cloudflare Durable Object, its filesystem lives in SQLite and R2, and it writes JavaScript instead of bash. Most teams run coding agents in a full Linux VM or container sandbox, and we used to as well.
We wanted off VMs because giving every user an always-on machine with attached disk was too expensive to scale. The hard part is that coding agents assume Linux. They are trained to reach for bash, and the harness we launched on required a full VM, so getting here took three redesigns. The tradeoff is that the agent can now only do things we've built an explicit method for, which sounds limiting but has been good for the product.
I'm Miguel, CTO of camelAI. Our codebase recently went open source, so everything in this post is code you can read at github.com/qaml-ai/camelAI. I'll link to the relevant files as we go. Here's the progression.
Step zero: the VM era
We launched on the Claude Code harness, which needs a full virtual machine to run. We tried several VM providers, none of them fit our persistence and performance requirements, and we ended up building our own container service. That post is still up, but we no longer run any of that infrastructure.
The container service worked, but it was heavy. An always-on VM for every user is expensive, and so is holding every user's files on fast attached disk. Scaling it means scaling real machines with real disks, which was going to be prohibitively expensive at the user counts we're aiming for. So instead of getting clever about VM orchestration, we started designing around not needing a VM at all.
Step one: take the agent out of the VM
The Claude Code harness is inseparable from its VM, so the first move was building our own harness. We built it on pi, Mario Zechner's open-source coding agent. pi is a stack of libraries. The highest layer assumes a normal operating system, but the lower layers give you the agent primitives, like the agent loop and state management, without caring where they run. We didn't change any pi code. We imported those lower layers and built our own harness on top of them, running inside a Cloudflare Durable Object instead of a Linux environment.
A Durable Object is a small stateful compute instance that spins up on Cloudflare's edge, close to the user who created it. Each chat thread gets its own Durable Object, which brought latency down on its own compared to routing everything through a centralized VM host.
At this stage we kept the VMs, but the agent no longer lived inside one. It called into the VM remotely when it needed to run commands. Anthropic describes this same split for its managed agents, the brain separated from the hands. It gave us some nice properties:
- The agent starts responding before the VM is awake, because it doesn't wait on a machine to boot.
- The VM can go back to sleep while the agent keeps working, or never wake up at all if the turn doesn't need any commands.
- One brain can control multiple hands. A single agent could operate several VMs at once.
We call those hands projects. Each project came with a VM for executing commands and a git repo created programmatically through Cloudflare Artifacts, which is git-compatible storage you can provision on the fly from a Worker. The agent didn't really know it was running outside the VM. It still had bash and worked like any other coding agent.
The problem is that this fixed latency and nothing else. We still had a VM per user, so we still had all of the cost and scaling problems from the original design.
Step two: remove the VM
The next version kept the same project structure but dropped the VM behind it. Each project is now backed by a filesystem that lives inside a Durable Object, with R2 behind it for larger files.
We didn't invent this. Cloudflare's agents team built Shell, an experimental filesystem and execution runtime for Workers, and we reused their code heavily. The mechanics are simple. A Durable Object's storage is a SQLite database with a 10 GB cap, and each row has a maximum size. Small files live directly in SQLite rows. Files over roughly 1.5 MB get written to R2, and the SQLite row just holds a pointer. To the agent it looks like a normal filesystem, but underneath it's a database and object storage, so persistence is stored data rather than infrastructure we have to keep alive.
Version history still runs through Artifacts, so every project keeps a git history without us hosting a git server.
Step three: remove bash
Removing bash felt drastic. Coding agents are trained to reach for bash, and bash is why everyone runs them in VMs in the first place. It was also a problem beyond cost. An agent with bash and network access needs credentials to do anything useful, and our attempts at authenticated proxy URLs were getting hacky and hard to enforce.
So we removed it. Instead of bash, the agent writes JavaScript, executed through Code Mode and Cloudflare's dynamic Worker loaders. Each execution runs in a fresh V8 isolate that boots in milliseconds and uses a few megabytes of memory. The sandbox comes pre-loaded with the user's data connections and with methods for everything the platform can do. Credentials never enter the sandbox. The agent calls a connection's methods, and authentication happens on our side.
When you look at what agents actually use bash for, losing it costs less than you'd expect. Most of it is file operations, which the agent has native tools for. We give it read, write, and edit, plus our own grep and glob implementations. That covers the 80-20. The rest is specific commands for specific jobs, and those became explicit methods:
- wrangler deploy through a proxy became a deploy_project method we fully control. Since we know exactly when a deploy happens, we can hook it and open a live preview automatically. Before, we had to sniff proxied wrangler traffic to guess which thread had deployed something.
- Building the user's app and running Python notebooks became their own methods, both backed by short-lived containers.
We kept containers for those two jobs because they genuinely need Linux. User apps are built with Vite, Tailwind, and React Router, and adding dependencies means running bun install. We considered running builds inside a Worker, since the thing being built is itself a Worker, but that path isn't well supported, and Workers have a 128 MB memory limit and a fraction of a CPU. Builds would be slow and plenty of projects would blow past the memory cap. So instead a build spins up a container through the Cloudflare Sandbox SDK, copies the project in, runs the job, returns the result, and shuts the container down. Notebook runs work the same way. We still use full Linux, but only for the seconds of work that actually need it.
The honest downside is that we have to anticipate what the agent needs. With bash it could figure things out on its own. Now, if a capability is missing, we have to add it. In practice that pressure has been good for the product, because it forces us to think about what users are doing and build a first-class path for it instead of letting the agent improvise.
There was an unexpected benefit too. Bash is open-ended, and cheap models struggle in open-ended environments. With a smaller set of explicit methods they perform noticeably better, which matters because keeping camelAI cheap to run is the point of this architecture.
Where that leaves us
The stack is now Durable Objects for the agent and its filesystem, R2 for large files, Artifacts for git history, pi as the harness, and Code Mode with dynamic Workers for execution. It deploys like any other Cloudflare app, and there are no external container services to manage.
Dynamic Workers are billed per execution, not per second of uptime. Thousands of executions cost about what a few minutes of container time costs on the services we used to evaluate. Latency is low because everything runs on the edge near the user, and scaling is Cloudflare's problem instead of ours.
Users still build and deploy full-stack apps to live URLs, and the agent still reads, writes, greps, and deploys. From the user's side, nothing changed.
TL;DR
We started with the Claude Code harness on a self-built VM service, which was expensive and hard to scale. First we moved the agent itself into a Cloudflare Durable Object and let it control VMs remotely, which fixed latency but not cost. Then we replaced the VMs entirely with a filesystem stored in Durable Object SQLite and R2, based on Cloudflare's Shell project, with git history through Cloudflare Artifacts. Finally we removed bash and gave the agent a JavaScript sandbox via Code Mode and dynamic Workers, with explicit methods for deploys, builds, and notebooks. The result is cheaper by orders of magnitude, lower latency, simpler to operate, and easier for smaller models to drive. All of it is open source at github.com/qaml-ai/camelAI.
AI算出
技術分析ainew評価標準
記事は AI コーディングエージェントの実行環境に関する技術的深掘りであり、VM から Cloudflare Durable Object への移行という具体的な実装事例と設計思想を報じているため新規性と技術分析の価値が高い。ただし、対象が特定のベンダー(Cloudflare)の導入事例であり、日本固有の事情や企業への直接的な影響は薄いため、日本の関連性は低めとなる。
6つの評価軸を見る
- AI関連度
- 75
- 情報源の信頼性
- 50
- 新規性
- 75
- 調べる価値
- 75
- 重複の少なさ
- 100
- 日本での有用性
- 25
関連記事
今日のまとめ
AIデイリーブリーフで今日の重要ニュースをまとめ読み