エージェントの進化:VMを活用したモバイルAIエージェントの仕組み(Claude Code, Instinct)
The VMs Powering Mobile Agents (Instinct, Claude Code) (rohanadwankar.github.io)
要約
AIエージェントがローカルコンピュータからクラウド上のVMへと移行し、スマートフォンなど様々なデバイスから利用可能になる進化について解説しています。Claude CodeはFirecracker microVM上で独自のRust製initプロセスを実行し、セキュアな環境でユーザーセッションを管理しています。一方、InstinctはE2Bというサービスが提供する使い捨てのUbuntu VMを利用し、エージェントの「記憶」をMarkdown形式のGitリポジトリとしてS3に永続化するユニークなアプローチを採用しています。両者ともVM技術を活用しつつ、異なるアーキテクチャと永続化戦略でユーザー体験を向上させています。
全文翻訳
エージェントが動作する箱
エージェント(Claude Code, Instinct, Pokeなど)がローカルコンピュータから離れて、スマートフォンで利用できるようになるというのは、製品の素晴らしい進化の一つです。最終的には、エージェント企業がそれらを動作させるためのVMを提供してくれるため、顧客にとって非常に有益です。ここでは、ws-termを調査した結果に基づき、主要なプラットフォームがどのように機能するかについてのメモを記します。
スマートフォン上のClaude Code
Claude Codeの箱は、独自のカーネルを持ち、Rustで書かれたinitに直接ブートされるKVMゲストである、FirecrackerマイクロVMです。
$ cat /proc/cmdline
... rdinit=/process_api ... --listen-vsock-port 2024
$ uname -r
6.18.5-fc-v20 # -fc- = Firecracker; カスタムビルドされたゲストカーネル
$ ps -o comm -p 1
process_api # PID 1 は systemd ではなく、Rust/Tokio バイナリです
process_apiはPID 1であり、VM内で動作するホストの制御エージェントです。ディスクをマウントし、vsockポート2024でリッスンするため、ホストは外部からセッションを制御できます。これがプラットフォームの決定的な特徴です:オペレーターがテナントスペース内に存在し、それを隔離するために多くのエンジニアリングが行われています(PID 1はダンプ不可能、CAP_SYS_PTRACEがあっても/proc/1/memは拒否され、シェルにはCAP_SYS_RESOURCEがありません)。
ディスクは、あなたのもの(書き込み可能、永続的)と彼らのもの(読み取り専用、共有)にきれいに分割されています。
$ lsblk -o NAME,SIZE,RO,MOUNTPOINT
vda 256G 0 / # あなたのもの: 書き込み可能、リクレーム後も保持
vdc 341M 1 /opt/claude-code # 彼らのもの: 324 MB の `claude` ハーネス (Bun)
vdd 45.6M 1 /opt/env-runner # 彼らのもの: タスクランチャー
vde/vdf ... 1 /mnt/skills/... # 彼らのもの: スキル
ハーネスは、ツールの呼び出しを実行するもので、読み取り専用ディスク上の324 MBのコンパイル済みBunバイナリです。モデルは別の場所にあり、推論はHTTPS/2経由のServer-Sent Events(WebSocketではない)として/v1/messagesに送信されます。これは、443のみでMITM(CN = Egress Gateway ... (production))されたエグレスゲートウェイを経由し、/etc/hostsにapi.anthropic.comがピン留めされています。インバウンド通信は一切ありません(RFC-5737テストアドレスである192.0.2.2)。認証は、ホストが発行したOAuthトークンで、ディスク上にルートのみでキャッシュされ、ブートごとにローテーションされます。
ライフサイクルはホスト駆動型で、内部から測定されます:初期化まで約430 ms、ハーネスプロセスまで約6.4秒です。スピンアップはインバウンドメッセージによってトリガーされ(ホストがvsock経由でVMをウェイクアップし、--session-mode resumeを実行)、スピンダウンはホストが決定するアイドルリクレームです。リクレームされると、プロセスは終了しますが、vdaはそのままデタッチされ、次のコールドブート時に再アタッチされるため、コンピューティングリソースが破壊されたにもかかわらず、会話は連続しているように感じられます。
user([あなたのキーストローク]) -->|http post| ingress[セッションイングレッション]
ingress --> pa
hostctl([ホスト制御プレーン]) -->|vsock port 2024| pa
subgraph vm[FirecrackerマイクロVM]
pa[process_api, pid 1, Rust] --> harness[claude, 324 MB Bunハーネス]
vda[("vda (rw), あなたのもの, 永続化")] --- harness
ro[("vdc/vdd/vde/vdf (ro), 彼らのもの")] --- harness
end
harness -->|推論をSSEで送信| gw[エグレスゲートウェイ, 443, mitm, api.anthropic.com]
Instinct
Instinctは最近ローンチされた新しいスタートアップで、メモリサイドで非常に優れた機能を提供しており、単なるチャットボットではなく、真のアシスタントであるという感覚を与えます。
$ hostname
e2b.local
$ cat /.e2b
n038afjvewg7jnc9pwdz
e2b.localは、Instinctが独自のVMフリートを運用していないことを意味します。代わりに、E2Bサンドボックス(「サンドボックス・アズ・ア・サービス」)をレンタルしています。これは、エージェントに与えてコンピュータとして機能させる使い捨てのUbuntuボックスです。
Ubuntu 22.04.5, 2 vCPU, 1.9 GB RAM, 29 GB ディスク, 稼働時間 ~30分, ユーザーサンドボックス (uid 1001)
そして、内部を見てみましょう...
$ systemd-detect-virt → kvm
$ cat /proc/cmdline
pci=off virtio_mmio.device=4K@... i8042.noaux i8042.nokbd reboot=k panic=1
clocksource=kvm-clock root=/dev/vda ip=169.254.0.21::...:eth0:off:tap0
$ cat /sys/class/dmi/id/product_name → (空) # SMBIOSは全くありません
$ ps -o comm -p 1 → systemd # init=/sbin/init、カスタムPID 1ではありません
再びFirecrackerです!
pci=off + virtio-over-MMIO + 空のDMI + tap0ネットワーキングはFirecrackerの署名です:PCIバスなし、SMBIOSなし、最小限のデバイス。したがって、両方のアプリケーションは同じマイクロVM上にありますが、違いはフリートを実行しているのが誰か、そしてその中に何がブートされるかです。Claude Codeは最小限のカスタムinit(PID 1としてのprocess_api)をブートするのに対し、E2Bはsystemdと完全なXFCEデスクトップを備えたフルUbuntuをブートします。
$ systemd-analyze
Startup finished in 265ms (kernel) + 992ms (userspace) = 1.258s
graphical.target reached after 977ms
グラフィカルデスクトップまで完全にコールドブートするのに約1.26秒かかります。ゲスト内のオペレーターもここにも存在しますが、それは単にE2Bのenvdが通常のsystemdサービスとして実行されているだけで、密封されたPID 1ではありません。E2Bサンドボックスは設定可能でもあります(vCPU、RAM、ディスク、アイドルタイムアウト、およびボックスをコールドブートする代わりにメモリ スナップショットから一時停止および再開できるかどうかを選択できます)。Instinctは、控えめな2 vCPU / 1.9 GBのデスクトップテンプレートを実行します。
では、箱が使い捨ての場合、エージェントのメモリはどこに保存されるのでしょうか? /memoryというディレクトリにあり、これがプラットフォームの決定的なアイデアです。
$ cat /memory/README.md
Persistent memory for [[rohan-adwankar]]
$ ls /memory
entities/ comms/ timeline/ workstreams/ knowledge/
$ git -C /memory log --format='%an <%ae>' -1
Instinct Agent <agent@instinct.com>
エージェントのメモリは、[[wiki-links]]を持つMarkdownファイルのGitリポジトリであり、grepでナビゲートされます。timeline/は時間とともに粗くなります(生 → 時間ごと → 日ごと → 週ごと、人間の記憶のように)。エージェントは文字通りGitの作者です。メモリAPIを呼び出すのではなく、Markdownを書き込み、自分自身としてコミットします。
永続的なレイヤーはそのリポジトリであり、S3にプッシュされ、ユーザーIDごとにキー付けされ、ファイルとしてではなく単一のGitバンドルとして保存されます。これは素晴らしい小さな落とし穴です。
$ git -C /memory remote -v
origin s3://instinct-prod-agent-memory/filesystem-memory/user-01M1VW7...
$ aws s3 ls s3://.../user-01M1VW7.../ --recursive
HEAD
refs/heads/main/<sha>.bundle # 全てのボルトがパックされています; 同期後の`ls`は空に見えます
認証は、長期的なキーではなく、短命のSTS認証情報です。そのため、漏洩したサンドボックスはトークンが失効すると自己修復します。
$ cat /etc/instinct-aws-creds
export AWS_ACCESS_KEY_ID='ASIA…' # ASIAプレフィックス + セッショントークン = 一時的なSTS
... # (値は編集済み、ライブシークレット)
# role: instinct-sandbox-observations-role
subgraph box[E2Bサンドボックス (レンタル、使い捨て)]
agent[Instinct Agent (agent@instinct.com)] -->|書き込みとコミット| mem[/memory, MarkdownボルトGitリポジトリ]
creds[/etc/instinct-aws-creds, 短命STS]
end
mem -->|git push| store
creds -->|git pushを承認| store
subgraph store[S3 (永続的、ユーザーごと)]
vault[("instinct-prod-agent-memory, ボルト")]
obs[("instinct-prod-observations, 生のファイアホース")]
end
永続的なもの = S3内のGitリポジトリ。マシンは使い捨てです。
これをGitリポジトリで行うのは非常に良いです。デフォルトの構造は次のようになっているようです。
~/instinct-vault/.. │ 24 ボルト
.git │ 23
comms │ 22 rohan-adwankarのための永続的なメモリ。Markdown + wiki-links、grepでナビゲート。ここから始めて、次にジャンプ
chat │ 21
rohan-adwankar--inst│ 20 Rohanが誰で、何に取り組んでいて、entities/, workstreams/, および knowledでライブに接続されているもの
entities │ 19
people │ 18 レイアウト
rohan-adwankar.md │ 17
projects │ 15 README.md
ws-term.md │ 14 timeline/ 時間順の記録、上に粗くなる: raw/ → hourly/ → daily/ → weekly/ → monthly/
knowledge │ 13 entities/ people/ projects/ — Rohanの世界の名詞、それぞれ1つのファイル
decisions │ 12 comms/ chat/ email/ meetings/ — スレッドごとに1つのファイル、名前は <誰>--<トピック>--<日付>.md
x-account-signup-dec│ 11 workstreams/ active/ completed/ someday/ — 作業単位; ステータス: フロントマターはサブディレクトリと一致
preferences │ 10 knowledge/ facts/ procedures/ preferences/ decisions/
instinct │ 8
autonomy.md │ 7 knowledge/preferences/instinct/ には、Rohanがアシスタント自体にどのように振る舞ってほしいか(自律性、ドラフティングなど)が保持されています。
iteration-style.md│ 6
timeline │ 5 規約
daily │ 4
2026-09-06.md │ 3 ● すべてのファイルには、id、type、およびエイリアスを持つフロントマターがあります。[[id]]はid.mdまたはid/_index.mdに解決されます。
workstreams │ 2 ● エンティティと知識ファイルはインプレースで更新され、現在の状態として読み取られ、ログとしては決して読み取られません。履歴は...
active │ 1 ● 1ページを超えるファイルは、元のidを持つ_index.mdを持つディレクトリに昇格されます。
dragon-game-asset.md│ 25 - タイムラインとコミュニケーションはイベントと会話を保持し、エンティティは永続的なプロパティのみを保持します。
startup-idea-search.│~
README.md │~
~ │~
~ │~
:!tmux capture-pane -pS - | pbcopy
VM内のClaude Codeのハーネスはオープンソースで通常と同じですが、Instinctはどうでしょうか?
$ ps -eo args | grep -E 'agent-exec|tools'
agent-exec-server --port 8080 # Go、送信されたbash/コードを実行します
tools __internal_daemon --socket /tmp/.tools/bridge.sock
--base-url https://api.instinct.com/-/api/graphql/tool-execute # Rust
$ strings /usr/local/bin/tools /usr/local/bin/agent-exec-server \
| grep -iE 'anthropic|openai|/v1/messages|x-api-key|claude|gpt|model'
# → なし。モデルはリストされていません
したがって、箱上で推論呼び出しが行われている様子はありません。Claude Codeはオペレーターをゲスト内に封じ込めますが、Instinctは脳をゲスト内に置きません。サンドボックスは純粋な実行サーフェスです。agent-exec-serverはバックエンドから渡されたbashを実行し、すべてのツール呼び出し(Gmail、クラウドブラウザ、支払いなど)は、サーバーサイドで実行されるGraphQLリクエストとしてapi.instinct.comに送信されます。--base-urlはコンパイル時ではなく、実行時引数です。
実際のツールサーフェスについては、MCPの代わりに、InstinctはすべてのツールにCLIを使用しているようです。
sandbox@e2b:~/ws-term-v1$ tools --help | wc
90 1466 10891
sandbox@e2b:~/ws-term-v1$ tools --help
Tools CLI
You are a task agent. Your parent (the main agent) spawned you for a focused job. When the job is done, report back to your parent and hold. Your parent owns task-agent cleanup.
Your direct-execute traits:
- work - integrations, files, web page fetching
....
Run `tools --help` for the current surface.
USAGE
tools <command-path> [options]
tools help [<path>...]
....
Built-ins (no help read needed): help, async wait, async list.
EXECUTABLE (you can call these directly)
agent_message namespace (1 action) Send messages to other agents.
browser_guidance namespace (3 actions) Search per-config website guidance and this user's past outcomes before browser navigation, and record how a config performed after an attempt. Missing guidance is normal and means unknown, not supported or blocked.
cloud_browser namespace (27 actions) Drive a cloud-hosted Chrome lease with the user's saved logins. Use for agent-driven web tasks (order food, book rides, compare prices, fetch receipts) that need real authenticated capability on real sites. A task agent acquires its own `lease_id` with `tools cloud_browser_scheduler acquire` and drives it here.
....
DELEGATED (only callable by the other role)
account namespace (2 actions) Read the user's Instinct account profile.
feedback namespace (3 actions) Submit product feedback and respond to team follow-ups.
generate_referral_link action Ask the main agent to get the member's reusable referral link and current lifetime allowance.
revoke_referral_link action Ask the main agent to revoke the member's reusable referral link.
speak action Generate a WAV speech file from a transcript, optional director's notes, and a voice.
UNAVAILABLE (does not apply to this role)
steer_voice_agent action Send an answer or context into the user's active live voice session.
ツールサーフェスは、このボックスがコーディングサンドボックスではまったくないことを示しています。tools --helpは〜50のネームスペース(Gmail、Notion、Slack、Stripe支払い、認証情報ボルト)をリストしていますが、設計を明らかにするのはクラウドブラウザです。
$ tools --help | grep -iE 'cloud_browser|vault'
cloud_browser (27) Drive a cloud-hosted Chrome lease with the user's saved logins.
cloud_browser_scheduler (4) acquire, list, release, extend leases
vault (7) Manage, fill, and import the user's stored credentials
Instinctが「あなたに代わって」食品を注文したり、航空券を予約したりするとき、このサンドボックス上でブラウザを開くことはありません。代わりに、クラウドブラウザの別のプールからブラウザをリースし、各ブラウザにはあなたの保存されたプロファイル(Cookieとログイン情報)が含まれており、それを同じapi.instinct.comブリッジ経由で駆動します。
tools cloud_browser_scheduler acquire # → lease_id、ブラウザ「設定」(プロファイル)上で
tools cloud_browser <action> # そのChromeをクリック/入力/読み取り/スクリーンショット
リースがどのように動作するかについてのモデル全体を読むことができます。各プロファイルには1つの書き込みリース(新しいログイン情報を保存できる唯一のセッション)があり、最大5つまで同時に実行できます。リースを解放すると、「まずCookieを保存するため、次のリースがそれらをロードします」。その永続性がポイントです。あなたのブラウザIDは、S3ボルトとオブザベーションインデックスの隣にサーバーサイドに配置された3番目の永続的なものであり、使い捨てボックスが1つのタスクのためにそれを借りて返却できるように保持されています。2つの詳細により、シークレットがボックスに触れることなくサインインできます。
- ナビゲート前に偵察。
tools browser_guidance searchは、キュレーションされたサイトごとのメモと、あなた自身の過去の各プロファイルの結果(config-a: success、config-b: blocked)を返します。これはリスクの事前情報であり、決定ではありません。 - シークレットはボルトを経由し、チャットは経由しません。
tools vault fillは、保存された認証情報を直接ページに入力します。ボルトにない場合、tools vault requestはあなたが入力するリンク(app.instinct.com/vault/fill?t=…)を発行します。ワンタイムコードは、接続されているGmailまたはOutlookから自身で読み取ります。
ta[タスクエージェント、オフボックス] -->|リースを取得| sched[cloud_browser_scheduler]
sched --> cb
ta -->|クリック、入力、読み取り| cb[あなたの保存されたプロファイルを持つクラウドブラウザ]
vault[("ボルト、あなたのシークレット、サーバーサイド")] -->|入力| cb
cb -->|"あなたとしてログイン"| sites([Amazon, Uber, 航空会社など])
box[使い捨てE2Bボックス] -->|"ツール呼び出しを発行、Cookieは保持しない"| cb
要約
| Claude Code | Instinct | |
|---|---|---|
| 隔離プリミティブ | FirecrackerマイクロVM (KVM) | FirecrackerマイクロVM (KVM) |
| フリートを実行するのは誰か | Anthropic、自社 | E2B、レンタル、サードパーティ |
| VM内のゲスト | 最小限のカスタムinit (process_api) | フルUbuntu + systemd + XFCEデスクトップ |
| コールドブート (測定値) | 約430 msの初期化、ハーネスまで約6.4秒 | グラフィカルデスクトップまで約1.26秒 |
| 永続的なもの | マシン (vdaブロックボリューム) | S3上のGitリポジトリ |
| メモリモデル | ディスク上の会話状態 | Markdownボルト、Gitバージョン管理、エージェント作成 |
| 認証情報 | ホスト発行OAuth、ディスク上、ローテーション | 短命STS、ロールスコープ |
| バックエンドストア | ローカルvirtio-block | S3、ユーザーIDごとにキー付け |
| ハーネスの場所 | ボックス上 (324 MB Bunバイナリ) | ボックス外; ボックスは2つの実行シムを保持 |
| モデルへの到達方法 | エグレスゲートウェイ経由で/v1/messagesへSSE送信 | ボックスからは決して行われない; GraphQLをapi.instinct.comへ、サーバーサイドで |
覗いてみてとても楽しかったです。新しい製品が登場したら、メモを記録し続けます!