研究

クラウドエージェント構築から得た学び

Josh Ma読了時間 3分

1年前にクラウドエージェントを初めてリリースしたとき、私たちはそれをローカルエージェントの素直な延長線上にあるものだと考えていました。それ以来、クラウドエージェントの機能は大きく広がってきました。

現在、クラウドエージェントは専用の仮想マシン上で動作し、それぞれ独自の環境、依存関係、ネットワークアクセスを備えています。並行して作業でき、ユーザーの操作なしで実行でき、ノートPC上で動くローカルエージェントよりも長時間のタスクを担えます。

こうした機能によって、環境設定、信頼性、オーケストレーションに関する課題が生まれます。これらは、エージェントがノートPC上で動いている場合には、比較的表れにくいものです。

この記事では、クラウドエージェントを構築する中で得た最も大きな学びと、なぜこの取り組みがますます「ローカルエージェントをサーバーに移植すること」ではなく、「その周囲の実行基盤を構築すること」に近づいているのかを共有します。

開発環境こそがプロダクトです

この1年で私たちが学んだのは、クラウドエージェントの出力品質を左右する最大の要因は、開発者と同じように、完全な開発環境を用意できているかどうかだということです。

ローカルでは、これはあまり意識する必要がありません。ローカルエージェントは、手元のノートPC上にある使い慣れた開発環境をそのまま引き継げるからです。一方クラウドでは、そのすべてをゼロから再構築しなければならず、しかも完璧に再現できていないことに気づくのは驚くほど難しいのです。

クラッシュやエラーメッセージが出るのではなく、多くの場合、唯一の兆候は出力品質のわずかな低下です。最初は気づかないかもしれませんし、気づいてもモデルのせいだと思ってしまうかもしれません。

しかし、何度調べても行き着く原因は同じでした。クラウドエージェントに、作業を実行したり検証したりするために必要な環境が整っていないのです。1年前は、モデルがそもそも環境をそこまで活用できなかったため、この問題の重要度はそれほど高くありませんでした。ですが、モデルが賢くなるにつれて、環境設定こそがその能力を最大限に発揮できるかどうかを左右する決定的な要因になってきました。

クラウドエージェントのアーキテクチャクラウドエージェントのアーキテクチャ

現在、「完全な環境」を実現するには、驚くほど多くのインフラストラクチャを作り直す必要があります。

  • エージェント環境を構築するための、より優れたユーザーツール
  • メッセージ間でエージェントVMを効率よく休止・再開するための手法
  • VMイメージを高速かつ確実にチェックポイント、復元、フォークするためのパイプライン
  • エージェントと人間の双方が環境を解釈し、操作できるようにするための、密接に連携したハーネスとクライアントの統合

さらに、クラウドエージェントがより多くの作業を担うようになるにつれ、PRの作成、依存関係のプル、調査の実施のために、制御されたネットワークアクセスも必要になります。そうして私たちは、シークレットの秘匿化、ネットワークポリシー、認証情報管理まで備えた、いわばエージェント向けのエンタープライズITを構築することになりました。

長時間稼働するエージェントには耐久性のある実行が必要です

クラウドエージェントは、ローカルエージェントとは異なる種類の信頼性の課題を抱えています。ノートPC上のローカルリソースを奪い合うのではなく、クラウドエージェントはそれぞれ分離された独自の VM 上で実行されます。そのため、開発者は多数のエージェントを並行して実行しやすくなり、数分ではなく数時間かかることも多い長時間のタスクを委ねられます。

ただし、VM 上で動かすことで、推論プロバイダの障害、置き換えが必要になる pod、EC2 ノードの停止といった中断の影響を受けやすくなります。

私たちは当初、ワーカーノードがエージェントを引き継ぎ、完了までループを回すワークスティーリングアーキテクチャでクラウドエージェントの構築を始めました。ローカルでうまく機能していたものをサーバーに移した形でしたが、この構成は脆弱でした。初期ベータ版のクラウドエージェントは、信頼性が 9 ひとつ程度にとどまることも珍しくありませんでした。

初期のクラウドエージェントアーキテクチャ初期のクラウドエージェントアーキテクチャ

クラウドエージェントの成熟が進むにつれて、Temporal がすでに解決している耐久性のある実行の基本機能 (たとえば、リトライの仕組み、マシン間での作業のスケジューリング、ノード障害をまたいだ耐久性) を、自分たちでかなり作り直そうとしていることに気づき、代わりに Temporal へ移行しました。

Temporal 上の現在のクラウドエージェントアーキテクチャTemporal 上の現在のクラウドエージェントアーキテクチャ

現在の Temporal 上のエージェントループは、推論の信頼性の一時的な低下や pod の休止・再開、さらには数日から数週間にわたる実行にも耐えられます。この移行だけで信頼性は 9 を 2 つ超える水準に達し、現在では Temporal が 1 日あたり 5,000 万件を超えるアクションを、700 万件を超える一意のワークフローにわたって処理しています。社内では、PR の 40% 超がクラウドエージェントによるもので、その割合は今も増え続けています。

クラウドエージェントから Cursor モノレポにマージされた PR の割合の推移クラウドエージェントから Cursor モノレポにマージされた PR の割合の推移

時間をかけて、私たちは Temporal のワークフローをより適切に設計する方法を学んできました。version のアップグレードを容易にするため、「永続的な」エージェントワークフローから、単一のタスクを完了したら終了する複数の短いワークフローへ移行しました。また、非同期のツール呼び出しやサブエージェント、推論プロバイダの障害によって前提が変わる中で、timeout と retries をより適切に扱えるよう、アクティビティも分割しました。

クラウドエージェントワークフロー全体における 1 日あたりの Temporal action 数クラウドエージェントワークフロー全体における 1 日あたりの Temporal action 数

会話状態からエージェントとマシンを切り離す

クラウドエージェントは、もはや1台のマシン上で1つのループを回すだけの存在ではありません。エージェントが1台のマシン上で動くこともあれば、複数のマシンにまたがって非同期のサブエージェントを生成することもありますし、ローカルで開始してから作業をクラウドに委ねることもあります。サブエージェントは親より長く生き続けたり、まったく異なる種類のpod上で動作したりすることさえあります。

エージェント、マシン、会話状態が分離されたクラウドエージェントループエージェント、マシン、会話状態が分離されたクラウドエージェントループ

これを実現するために、私たちはエージェントループ、マシンの状態、会話状態を、それぞれ独立したコンポーネントとして切り離しておくことが重要だと考えました。エージェントループはVM自体ではなくTemporal上で動作するため、podのライフサイクルを独立して管理でき、読み取り専用VMや事前にウォームアップされたVMといった最適化も含めて、異なる種類のpodにまたがってエージェントを実行できます。

会話まわりでは、ストレージ層とストリーミング層を中核となるエージェントのワークフローから分離しました。会話の更新をWebクライアントやデスクトップクライアントにストリーミング配信するための、効率的な追記専用ストレージ機構も構築しました。この層はリトライも考慮しているため、エージェントループのあるステップが部分的な出力をストリーミングしたあとに失敗して再試行された場合でも、クライアント側でそれを検知し、ストリームを巻き戻して、古いデータではなく新しいデータを表示できます。

どうすればうまく任せられるか

クラウドエージェントの会話フロークラウドエージェントの会話フロー

クラウドエージェントのハーネスを構築するということは、どこまでを決定論的な挙動にするか、どこからをエージェントに任せるかを絶えず見直し続けることです。

初期の頃は、私たちはエージェントをあまり信頼していなかったため、ハーネスが各タスクのたびにその作業を再確認し、commit と push を強制していました。モデルが賢くなるにつれて、私たちはロジックをハーネスから、エージェントが制御するツール側へと移し始めました。1年前は、マルチリポジトリ構成にはハードコードされたハーネスの挙動が必要でした。今では、エージェントにリポジトリのレイアウトを渡し、ブランチや PR のためのツールを用意すれば、作業の進め方はエージェント自身に判断させられます。

同じことは CI Autofix でも起きました。以前のクラウドエージェントのハーネスには、ジョブの失敗ログを取得して VM に書き込むためのロジックが含まれていました。今では、エージェントに GitHub CLI へのアクセスを与え、大きな出力は検索可能なファイルに自動的に書き出すだけです。エージェントへの通知もずっとシンプルになり、この流れは今後も続くと考えています。

ハーネス自体がなくなるわけではなく、変わっているのはその中身です。今のよい例がコンピュータ操作です。私たちのクラウドエージェントのハーネスには、コンピュータ操作専用のサブエージェント型があり、独自のモデルルーティング、カスタムプロンプト、画面録画を備えています。VNC と Chrome は環境に属しており、その環境は親エージェントとサブエージェントの間で共有されます。これにより、親エージェントはたとえば Playwright スクリプトを実行して、それらを直接利用できます。私たちがこの足場を使っているのは、モデルがまだ単独でコンピュータ操作を扱える段階にはないからですが、それをいつ呼び出すかはエージェントが制御します。

クラウドエージェントでは、ハーネス内で必要になるプロンプトの種類もローカルエージェントとは異なります。私たちは、より自律的に動くよう促しています。止まってしまうことのコストがはるかに大きいからです。ローカルでは、エージェントが止まって許可待ちになっていることがわかりますが、クラウドでは、こちらが確認しに戻るまで何時間もそのまま待ち続けることがあります。

自己修復するエージェント環境

今後を見据え、私たちは、エージェントを手取り足取り支援するか、完全に任せるかという二者択一を超えることに注力しています。よりよいアプローチは、エージェントが自分を取り巻くシステムを理解するためのツールを持てるようにすることです。

私たちは、クラウドエージェントが、シークレットの不足やネットワークアクセスの遮断、あるいはそのほか環境上の要因によって作業を進められない状況を報告でき、さらに自己修復的に対処できるようにしたいと考えています。最近のリサーチブログでは、これを実現するための一つのアプローチとして、私たちが「autoinstall」と呼ぶものについて紹介しました。

クラウドエージェントは、この数か月だけでも大きく進化しており、その変化のスピードは今後さらに加速していくと考えています。Cursorのクラウドエージェントを使えば、チームはその基盤となるインフラストラクチャを構築・維持することなく、この広範な機能領域のメリットを活用できます。

カテゴリー: 研究

著者: Josh Ma