CopilotKit OpenBot は、AIエージェント1体ごとに専用のブラウザとファイル領域を与え、その全操作を記録するMITライセンスの基盤だ。エージェントに実務を任せるとき最後に引っかかるのは性能ではなく「何をさせたのか後から説明できるか」である。ブラウザを触らせれば社内SaaSにログインし、フォームを送信し、ファイルを書く。動いた証拠はスクリーンショットしか残らず、権限は担当者のアカウントに紐づいたまま——という構成は、試作では通っても運用には乗らない。OpenBotはそこを設計の中心に据え、エージェント1体ごとにChromium入りのコンテナを割り当て、そのコンピュータに対する操作をすべて単一のゲートウェイに通す。2026-08-17公開・424★(2026-08-20時点)という生まれたてのリポジトリだ。

AIエージェント基盤そのものの選び方は AIエージェントフレームワーク比較2026|LangGraph・CrewAI・Dify等9種をStar数・実コードで検証 を参照してほしい。

この記事では公式README・docs/・ソースコードを一次資料として、OpenBotが何をするものか、起動に本当に必要なもの、そして「自分のインフラで動く」という説明がどこまでを指すのかを整理する。設定読み込み関数は実際に手元で実行して測定した。

公式READMEに埋め込まれたデモ。チャンネルでコワーカーに指示すると、そのBot専用のブラウザ画面が横で動く(出典: CopilotKit/openbot README・720pに再エンコード)

30秒でわかるOpenBot

エージェント1体=コンテナ1台。supervisorが各Botに専用のChromium・/workspaceボリューム・ブラウザプロファイルを割り当てる
操作は必ずゲートウェイ経由。対象を解決 → ポリシー判定 → 監査行を書く → 実行、の順で、記録より先に動く経路が存在しない
AG-UI準拠なら何でも載る。LangGraph・Mastra・CrewAI・手書きのエンドポイントが同じ扱いで「コワーカー」になる
MITだがIntelligenceが必須。APIサーバーはCopilotKitのマネージドサービス設定4点が無いと起動しない(実測)
既定ポリシーは全許可。エンジンはfail-closedだが、出荷時は「記録するが止めない」
alpha段階。リポジトリ自身が破壊的変更を予告している

CopilotKit OpenBotとは——AIエージェントに1台ずつ「自分のPC」を与えるAG-UI基盤

OpenBotはCopilotKitが2026-08-17に公開したエージェントプラットフォームで、READMEは自らを「自分のインフラの中で動くエージェントプラットフォーム」と説明する。Docker Composeが全構成要素を立ち上げ、データは自分のPostgreSQLに入り、モデルは自分で選ぶ——箱の中にモデルは同梱されず、管理者が資格情報を供給し、それは保存時に暗号化されログには出ない、という設計だ。

中心にあるのは「コワーカー(coworker)」という単位である。サンプルパッケージには3体が同梱され、いずれもコードではなく設定として定義されている。examples/fintech/agents.yaml を読むと、General Assistant(日常業務)と Knowledge(社内知識への回答)は type: built-in でシステムプロンプトを持つだけの存在、Risk Analyst(リスク・コンプライアンス)は type: remote-ag-ui で外部エンドポイントを指している。同梱のBotが、顧客が自分で書いたBotとまったく同じ登録経路を通る構造になっており、READMEのコメントも「自分のサービスに置き換えても何も変わらない」と書いている。

OpenBotの公式アーキテクチャ図。appからserverへ、serverからBotへAG-UIで送られ、Botのツール呼び出しはゲートウェイに戻り、対象解決・ポリシー判定・監査記録を経てBot専用コンピュータに届く
公式アーキテクチャ図(出典: CopilotKit/openbot assets/architecture-light.svg

「1体に1台」が意味するもの

READMEの表現を借りれば、supervisorが各Botに「コンテナ1つ、自分の /workspace ボリューム1つ、自分のブラウザプロファイル1つ」を与える。これが効いてくるのはログイン状態の分離だ。BotAが業務システムにログインしたセッションはBotAのプロファイルにしか残らず、BotBはそこに触れない。ホストが対応していれば COMPUTER_RUNTIME=runsc でgVisor下に置くこともできる。

また、コンピュータは既定で 127.0.0.1 にバインドされ、コンテナごとのトークンを要求する。READMEの言い方が的確で、「ポート番号を知っているだけでログイン済みのブラウザに到達できるものは何も無い」。

サービス構成は以下のとおり分かれている(docker-compose.yml および README のアーキテクチャ表より)。

サービス ポート 役割
app 3010 React/Vite製のUI
server 3001 Hono製API。認証・ポリシー・監査・プラグイン・コンポーネント・チャンネルを担う
agent-computer 4100 Chromiumと /workspace、ブラウザプロファイル
agent-bot 4200 実証用のAG-UI Bot
agent-langgraph 4201 LangGraph製のAG-UI Bot
supervisor 4500(ホスト)/ 4300(コンテナ) Botごとのコンピュータを作成・管理

UI側の主な画面も役割で分かれており、/channel/:id でコワーカーと会話しながらその画面をライブで見る、/admin/boundaries で操作ポリシーを書く、/admin/audit で許可・拒否・失敗を振り返る、/admin/computers でコンピュータを停止・リセットする、といった導線になっている。

AG-UIに乗ることの意味

Botの正体は「AG-UI を話すエンドポイント」でしかない。AG-UIはエージェントとUIのやり取りを定めたオープンプロトコルで、CopilotKit本体が策定に関わってきたものだ。OpenBotはこのプロトコルの上に統治機構を載せているため、READMEの言葉では「統治はフレームワークではなくプロトコルに乗る」。LangGraphで書いてもMastraで書いても手書きでも、同じ入口から入って同じ監査を受ける。

CopilotKitの本体(Reactアプリに組み込むフロントエンド・スタック)とは目的が違う点は押さえておきたい。既存のReact/Angularアプリの中にAIコパイロットを差し込みたいなら CopilotKit完全ガイド|React/Angularで作るAIエージェント & AG-UI Protocol解説 が対象で、OpenBotは「エージェントに作業環境そのものを与える独立した製品」だ。同じ組織のプロダクトだが、置き換え関係にはない。

インストールと起動条件——実測した7つの必須環境変数

READMEのクイックスタートは4手順に見えるが、APIサーバーが実際にどこで止まるかは設定読み込み関数 loadConfig()server/src/config.ts)が決めている。この関数は環境変数のレコードを受け取る純粋な関数なので、リポジトリをbun installしたうえで空の環境から1変数ずつ足しながら直接呼び、拒否の順序を測定した。

OpenBotのAPIサーバーが起動を拒否する7つの関門を順に示した図。DATABASE_URL、KEY_ENCRYPTION_KEY、MANAGED_AGENT_AG_UI_URL、そしてIntelligence関連4つ
空の環境から1変数ずつ埋めて測定した起動ゲート(commit 93ff1b19・2026-08-20実測)

順序は次のとおりだった。

DATABASE_URL — 未設定なら DATABASE_URL must be configured
KEY_ENCRYPTION_KEY — base64デコードして32バイトでなければ拒否
MANAGED_AGENT_AG_UI_URL — http(s) のURLとして解釈できなければ拒否
INTELLIGENCE_API_URL / INTELLIGENCE_GATEWAY_WS_URL / INTELLIGENCE_API_KEY / COPILOTKIT_LICENSE_TOKENこの4つは1つずつではなく、まとめて1つのエラーとして報告される

4つ目のまとめ方は意図的だ。ソースのコメントは「部分的に設定された状態のほうが、まったく設定されていない状態より危険だ。設定しようとして間違えたということだから」と説明し、以前は部分集合のときだけ失敗していたため未設定のデプロイが素通りしていた、と経緯まで書いている。

7つすべてを埋めると起動し、このとき runtime.mode=intelligence / durableHistory=true が返る。注意したいのは、この最小構成では computer=off になることだ。「1体1台のPC」は AGENT_COMPUTER_URL が設定されて初めて有効になり、未設定なら該当ルート自体がマウントされない。ソースのコメントいわく「設定されていない機能は、動かない状態でマウントされるのではなく、存在しないべきだ」。

実際の手順

まず設定ファイルを用意する。

cp .env.example .env

次にCopilotKit Intelligenceの資格情報を取得する。READMEはCLI経由の3コマンドを案内している。project select が表示する cpk-... の実行時キーを INTELLIGENCE_API_KEY に入れ、license --writeCOPILOTKIT_LICENSE_TOKEN を既存の .env に書き込む。

npx --yes copilotkit@latest login
npx --yes copilotkit@latest project select
npx --yes copilotkit@latest license --write

.env.example に入っている KEY_ENCRYPTION_KEY は公開値なので、手元で試すだけなら触らなくてよいが、デプロイ前に必ず作り直す。ソースのコメントがこの危険性を正確に言い当てている——「それは有効な鍵であり、そこが問題そのものだ。長さも符号化も正しいので、どの検査にも引っかからない。変更しなかったデプロイは、公開リポジトリに印刷された鍵で資格情報の金庫を暗号化しており、変更したデプロイと見分けがつかない」。

openssl rand -base64 32

あとは依存を入れて起動する。scripts/start.sh はDockerサービスを立ち上げ、マイグレーションを適用し、APIサーバー(3001)とアプリ(3010)を起動したうえで、各サービスがヘルスチェックに応答することを確認してから次の手順を表示する。

bun install
bash scripts/start.sh

必要なのはDocker、Bun 1.3以降、CopilotKit Intelligenceのプロジェクトとライセンス、そしてモデルキー(同梱の実証用BotはOpenAI、LangGraph製BotはOpenAI/Anthropic/Googleに対応)だ。OPENAI_BASE_URL などを設定すれば、同じAPI形式を話すゲートウェイや自前ホストのモデルに向けることもできる。

「自分のインフラで動く」の境界線——CopilotKit Intelligenceが必須な理由

ここがOpenBotを評価するうえで最も誤解しやすい部分なので、資料の記述をそのまま突き合わせる。

server/src/config.ts の冒頭コメントは端的だ。「実行時に何ができるかの答えは1つしかない。durableなスレッドとメモリのためにCopilotKit Intelligenceが必要だからだ」。型定義もこれを反映していて、RuntimeCapabilitiesmode"intelligence" という単一メンバーのユニオンになっている。degraded modeやローカルモードが将来の分岐として用意されているのではなく、型の上に第2の選択肢が存在しない。.env.example の注記も「degraded modeは無い(There is no degraded mode)」と明言する。

では会話はどこに保存されるのか。server/src/channels/thread-identity.ts の設計コメントが答えを持っている。冒頭の一文は 「Threads live in an Intelligence project」(スレッドはIntelligenceプロジェクトの中に存在する)だ。同ファイルは、1つのIntelligenceプロジェクトを複数のデプロイが共有しうること、プラットフォーム側にはデプロイが自分の名前を書き込めるフィールドが無くユーザーとエージェントでしかスレッドを一覧できないこと、だからスレッドIDそのものにデプロイ名のダイジェスト6バイトを埋め込んで識別している、と説明している。RFC 9562のバージョン8を使う理由まで書かれた丁寧なコードだ。

「MIT・自ホスト」と「Intelligence必須」は両立している

OpenBot本体——アプリ、APIサーバー、Bot用コンテナ、PostgreSQL、モデルキー——は確かに自分のマシンで動き、コードはMITで読める。一方でAPIサーバーはIntelligenceの4点が揃うまで起動せず、会話スレッドとメモリはIntelligenceプロジェクト側に置かれる。そしてIntelligence自体を自社インフラに置くことについて、.env.example はこう書いている——「Intelligenceを自分で動かさないでください。この2つはマネージドサービスを指しており、変更しないでください。自分のインフラでIntelligenceを動かすのはEnterprise Intelligence Platformの機能で、Helmチャートで導入され、セルフサーブではありません」。

ここで重要なのは、これは料金の壁とは限らないという点だ。同じ .env.example はCLIが「無償のライセンスを発行する」と書いている。したがって正確な理解は「支払わないと動かない」ではなく、アカウント登録と、会話データの置き場所の境界である。公式サイトが「Docker Composeはデモ、Helmが本番への道」と位置づけているのも同じ構図だ。自社データを外部に出せない要件があるなら、OSS版のクイックスタートではなくEnterprise側の話になる、と読むのが妥当だろう。

なお公式サイトの製品ページには「ドキュメント・ベクトル・権限・会話はあなたのPostgresに入る。設定していない場所には何も送られない」という説明もあり、リポジトリのコードの記述と額面上は食い違って見える。製品ページのFAQには「CopilotKit Intelligenceは必要か?」という項目が用意されているが、回答本文はJavaScriptで描画される作りで、本記事の執筆時点では取得できなかった。したがってこの食い違いの公式な解消は確認できていない——Enterprise構成(Helm)とOSS版クイックスタートで前提が違うと読むのが自然だが、それは筆者の推測であり一次資料の裏付けは無い。確かなのはリポジトリ側の事実だけで、runtimeCapabilities() は4値が欠けると例外を投げ、mode に第2の選択肢は存在せず、スレッドはIntelligenceプロジェクトに属する。データの置き場所が要件になるなら、この点はCopilotKitに直接確認するのが確実だ。

ゲートウェイの仕組み——決めて、記録して、それから動く

OpenBotが「ツールを使えるエージェント」と「ツールに近づけてよいエージェント」を分ける、と主張する根拠がこのゲートウェイだ。server/src/computer/gateway.ts(898行)の冒頭コメントは「記録は行動と並行して書かれるレポートではない。記録されなかった行動は起きていない。なぜなら、先に行を書かずに動く経路が存在しないからだ」と述べる。

sequenceDiagram participant U as 利用者 participant S as server participant B as Bot(AG-UI) participant G as ゲートウェイ participant D as PostgreSQL participant C as Bot専用コンピュータ U->>S: チャンネルで指示 S->>B: ターンをAG-UIで送る B->>G: ツール呼び出し G->>G: サーバー保持のスナップショットから対象を解決 G->>G: 反復回数を数える G->>G: ポリシー評価(denyが先、壊れたルールは拒否) G->>D: 監査行を書く(実行より前) alt 許可 G->>C: ブラウザ/ファイル操作を実行 C-->>G: 結果 G->>D: 失敗した場合は失敗行を追記 else 拒否 G-->>B: 理由となったルール名を添えて拒否 end G-->>S: 結果 S-->>U: コンポーネントで応答

順序で効いているのは3点ある。

対象の解決が先。ゲートウェイは、呼び出し側が「これをクリックする」と主張したラベルではなく、サーバー自身が取得したスナップショットから要素を解決する。コメントは「ステップ1は省略しやすく、省略すると致命的だ」「攻撃者が供給したラベルで判定するポリシーは飾りだ」と書く。「Submitと書かれたものはクリックさせない」というルールが、名前を変えただけで回避できてしまっては意味がない、という理屈である。未知の参照でも例外を投げずに判定へ進む——識別できない要素への操作にもポリシー判定を受けさせるためだ。

監査行は成功の後ではなく実行の前。許可されたが後で失敗した操作も監査系列の一部として残る。コメントいわく「成功しか含まないログは、起きたことを説明できない」。失敗した場合は、ポリシー判定の行とは別に失敗の行が追記される。ここも丁寧で、失敗する前に副作用が生じている可能性があるため、判定の結果と実行の結果を分けて記録している。

反復はポリシーより先に数える。同一の呼び出しが何回連続したかは判定前にカウントされ、ポリシー側は repeat.count >= 10 のようなルールで参照できる。ソースはこの指標の限界も自分から列挙している——時間窓ベースなので遅いBotは引っかからない、カウントは処理したプロセスが保持するのでAPIを2台に増やすと分裂する、MCP経由の呼び出しは数えない、そして「同じ対象への操作は入力内容が違っても同じ呼び出しとみなす」ため検索ボックスへの10回の入力も10回の反復になる。だからこそ、まず dry-run で試すことを勧めている。

読み取りはゲートウェイを素通りする

snapshot() には「読み取り専用なので素通りする。何も変わっておらず、判定すべきことが無い」というコメントが付いている。つまりゲートウェイが統治しているのは行動であって観測ではない。Botがページを読む・スクリーンショットを撮ること自体はポリシー判定と監査の対象外だと理解しておくべきだ。「見せてよい情報か」は別のレイヤー(知識コネクタの権限やコンピュータのネットワーク到達性)で制御することになる。

人が操作を代わる「Take the wheel」も監査される。Botがログイン画面や2要素認証に突き当たると助けを求め、computer.help_requested / computer.control_taken / computer.control_released が記録される。人が運転している間、Botの操作はキューに積まれるのではなく拒否される。ただしこの引き継ぎ自体はポリシー判定の対象外で、記録されるのは「誰が、いつ、なぜ」の期間である。ポリシーはBotを縛るものであり、人が介入する経路まで塞いだら逃げ道が無くなる、という設計判断だ。

既定のポリシーは「全許可」——fail-closedエンジンとの二層構造

READMEには「CEL policy, fail closed」と書かれている。これは正しいのだが、エンジンの仕様と出荷時の既定値を分けて読む必要がある。ここを混同すると、導入直後の挙動を実際より安全に見積もることになる。

ポリシーエンジンの仕様と出荷時の既定値を対比した図。エンジンはfail-closedだが既定値はallow trueで全許可
エンジンの性質と既定値は別の決定。どちらもリポジトリの記述どおりで、矛盾ではない

エンジン側(server/src/computer/policy.ts)は確かに厳格だ。CEL式で書かれ、denyallow より先に評価され、ポリシーが無ければ何も許可せず、壊れたルールは開くのではなく拒否する。AGENT_COMPUTER_POLICY が不正なJSONなら起動そのものを止める——「ルールを書いて打ち間違えた運用者が、いま禁止しようとしたものを黙って許可し続けるデプロイを得てしまう」ことを防ぐためだ。ルールが参照できる属性は tool.name / intent / bot.id / actor.id / page.url / page.host / element.* / key / file.* / mcp.* と幅広い。

一方、出荷時の既定値(server/src/computer/policy-store.tsDEFAULT_ACTION_POLICY)はこうなっている。

{ "mode": "enforce", "deny": [], "allow": ["true"] }

allow: ["true"] は「常に真」であり、すべてを許可する。これも意図的で、コメントは「ページを見られるだけで何も触れないBotは製品ではないし、人が最初にすることは何かを入力させることだ」と説明し、「特別な未設定状態」ではなく明示的なallowとして書き下したと述べている。結果として、箱から出した状態のOpenBotは「すべてを記録するが、何も止めない」。統治を効かせるには管理者が最初の1本を書く必要がある。

mode には enforce のほかに dry-run があり、判定と記録だけ行って全部通す。運用者が実トラフィックに対してルールを書き、誰の仕事も止めないまま監査ログで影響を確認できる。コメントの言い方が良い——「誰も有効化する勇気を持てない統治機能は、統治機能ではない」。

実測:書けるルールと、書くと全部止まるルール

ここで実際にルールを書こうとすると、資料からは読み取れない制約に当たる。evaluateActionPolicy() に判定文脈を与えて、わざと偽になる式を投げ(偽なら「許可」が返るはず)、どの演算子が本当に動くかを切り分けた。式が動かず例外になった場合はfail-closedで「拒否」に倒れるので、偽のはずの式に対して拒否が返れば未対応と判定できる。

演算子・関数 結果
== / != / >= ✅ 動く
&& / \|\| ✅ 動く
in(リスト包含) ✅ 動く
size() / has() ✅ 動く
matches()(正規表現) Unknown method: matches
contains() ❌ 例外
startsWith() / endsWith() ❌ 例外

つまり同梱の cel-js には文字列メソッドが実装されていない。これが効いてくるのは、READMEがCELを採用した理由として挙げている例そのものが文字列マッチだからだ——「自社ドメイン外でSubmitと書かれたものは絶対にクリックさせない」。この文をそのまま正規表現で書くと式が例外になり、fail-closedによってすべての操作が拒否される。ポリシーの設計としては正しい挙動だが、運用者から見れば「ルールを1本足したらBotが一切動かなくなった」という形で現れる。

もう1つの罠:element は省略可能なフィールド

PolicyContextelement は optional で、ページ遷移やキー入力のように要素を伴わない操作では存在しない。存在しないフィールドを参照するとCELは例外を投げ、denyルールの例外は拒否に倒れる。実測すると差は明確だった。

deny: ["element.name == \"Submit\" && page.host != \"example.co.jp\""] の場合——外部サイトのSubmitは拒否(意図どおり)、外部サイトの検索欄は許可(意図どおり)、自社サイトのSubmitは許可(意図どおり)。ところがelementを伴わない browser.navigate まで拒否される。この状態で dry-run から enforce に切り替えると、Botはページ遷移すらできなくなる。

has() で保護すると4ケースすべてが意図どおりになる。

したがって、自社ドメイン外での送信操作を止めたい場合の実際に動くルールはこうなる。正規表現ではなく完全一致で書き、has() で要素の有無を先に確認する(まずは dry-run で様子を見るのが推奨されている)。

export AGENT_COMPUTER_POLICY='{
  "mode": "dry-run",
  "deny": ["has(element.name) && element.name == \"Submit\" && page.host != \"example.co.jp\""],
  "allow": ["true"]
}'

ボタンのラベルが「Submit」「送信」「確定」と揺れるなら in を使って has(element.name) && element.name in ["Submit", "送信", "確定"] && page.host != "example.co.jp" と列挙する。文字列の部分一致に頼れない以上、守りたいラベルを事前に洗い出して列挙するのが現時点での書き方になる。alpha段階なので、この制約はCELエンジンの差し替えで将来変わりうる点も含みおきたい。

MCPは「読み取りと確認できたものだけが読み取り」

外部ツール連携も同じ思想で扱われる。Atlassian・Box・Slack・Salesforce・ServiceNow向けの精査済みカタログが同梱され、管理者がURLで追加したサーバーには独自の検査が入る。分類ロジック(classifyTool)は明快で、サーバー自身がツールを広告しており、かつ書き込みリストに載っていない場合だけが「読み取り」、それ以外はすべて書き込み扱いになる。カタログに無いサーバーのツールは全部書き込みだ。コメントは「読み取りを書き込みに分類するほうが、書き込みを読み取りに分類するよりましだ」と理由を述べている。

カスタムMCPサーバーのURL検査も鈍器のように単純で、そのぶん堅い。HTTPSのみ(資格情報がbearerトークンなので平文は論外)、IPアドレスリテラル・localhost・内部サフィックスは拒否。コメントは「『MCPサーバーを追加』は、そうしなければサーバーが到達できる先——クラウドのメタデータエンドポイント、同一ネットワークのデータベース、localhostにバインドされた管理画面——を狙うリクエストフォージェリの部品になる」と、SSRFの危険を明示している。なおこれは文字列としてのホスト検査であり、DNS解決時やリクエスト単位のネットワーク制御は別のデプロイ管理項目だと自ら断っている。

このあたりの「資格情報をエージェントにどこまで預けるか」という論点は、OpenSandbox解説|AIエージェント用サンドボックスに資格情報の金庫を持たせる設計 とも重なる。OpenBotは資格情報を /admin/credentials 経由で保存し、APIからは返さず、監査イベントからも伏せる。秘密が要求された事実と長さは記録するが、中身は記録しない。

類似ツール・同名プロジェクトとの比較

まず検索の障害物を片付けておきたい。GitHubで「openbot」を名前に含むリポジトリは複数あり、★数が最も多いのは本記事の対象ではない。

GitHubの同名プロジェクトを★数で比較した棒グラフ。ob-f/OpenBotが3382で最多、CopilotKit/openbotは424
GitHub Search API(q=openbot in:name, sort=stars)で2026-08-20に取得

ob-f/OpenBot(3,382★)— スマートフォンを頭脳にする約50ドルの低価格ロボット。2020年開始で、本記事の対象とは完全に無関係
CopilotKit/openbot(424★)— 本記事の対象
meetopenbot/openbot(317★)— “OS for Agents” を掲げる別のAIエージェント製品。分野が近いぶん取り違えやすい
openbotx/openbotx(88★)— AIエージェント統合プラットフォーム

つまり「openbot」単体は指名キーワードとして機能しない。組織名を添えて検索するのが確実だ。

次に、エージェントに実行環境を与える他のOSSとの立ち位置を整理する。

  CopilotKit/openbot AgentENV OpenSandbox 一般的なブラウザ操作エージェント
主目的 業務コワーカーの運用と統治 大量環境の高速な複製 資格情報を預けた実行環境 タスクの自動化
分離単位 Botごとのコンテナ(gVisor可) Firecracker microVM サンドボックス プロセス/プロファイル
監査の位置づけ 実行前に必須で記録 学習基盤のため対象外 資格情報の取り扱い中心 実装依存
ポリシー言語 CEL(deny優先・fail-closed。文字列メソッドは未対応)
エージェントの持ち込み AG-UIエンドポイントなら何でも E2B互換API 固定
人間の介入 Take the wheel(記録付き) 実装依存
ライセンス MIT MIT Apache-2.0 実装依存
外部サービス依存 Intelligence必須(実測) 本記事では未検証 本記事では未検証 実装依存

大量の環境を安く並列に維持したいなら AgentENV解説|Firecracker microVMをforkして並列実行するE2B互換のエージェント基盤 の方向で、これは学習・評価のスループットを解く道具だ。OpenBotが解こうとしているのは別の問題——少数のエージェントに継続的な役割を与え、その行動を後から説明できるようにすることである。「1体を隔離する」ではなく「1体に職務と記録を与える」と言い換えてもよい。

読者の3つの問いに答えるなら、こうなる。何ができるか——AG-UI準拠のエージェントに専用のブラウザとファイル領域を与え、チャンネルで会話しながら画面を見て、必要なら操作を代われる。何を解決するか——エージェントの行動の証跡が残らない問題と、権限が個人アカウントに癒着する問題。何を代替できるか——自前で組んだ「エージェント+ヘッドレスブラウザ+場当たり的なログ」の構成を、統治込みの基盤に置き換えられる。ただし後述のとおり、現時点では代替を急ぐ段階ではない。

CopilotKit OpenBot導入前のチェックリスト——alpha段階でできること・できないこと

リポジトリは自らalphaと宣言している。「OpenBotは初期段階です。粗い部分とバグを想定してください。そして状況が動くことを想定してください」——READMEのこの断り書きは、統治機能を評価する文脈では重く受け取るべきだ。以下は2026-08-20時点・commit 93ff1b19 での確認事項である。

クイックスタートは認証なしが前提OPENBOT_DEV_NO_AUTH=true は全リクエストを単一の管理者として通す。ソースには独立した2つの鍵が実装されており、実測でも確認した——(1) この変数が true でなければ何も起こらない、(2) NODE_ENV=production との併用は起動時に例外を投げる。コメントいわく「認証があると信じているのに無いデプロイが、3つの状態のうち最悪だ」
.env.example の暗号鍵は公開値NODE_ENV=production では起動が拒否されるが、それ以外の環境では警告のみで通る。実測で両方の挙動を確認した
Google認証は全部か無しか。クライアントIDとシークレットの片方だけを設定すると起動時に落ちる。「最初のログイン試行時ではなく起動時に失敗させる」ための設計
「1体1台」は既定で有効ではないAGENT_COMPUTER_URL 未設定なら共有コンピュータ1台、COMPUTER_SUPERVISOR_URL を設定して初めてBotごとに割り当てられる
既定ポリシーは全許可。最初の禁止ルールを書くまで、統治は「記録」だけを意味する
CELで文字列の部分一致が書けない(実測)。matches / contains / startsWith / endsWith は例外になり、fail-closedで全操作が拒否される。完全一致と in での列挙、has() による省略可能フィールドの保護が必須
読み取りは監査されない。スナップショット取得はゲートウェイを素通りする
反復カウントは単一プロセス前提。APIを複数レプリカで動かすとカウントが分裂し、反復に関するルールが期待どおり発火しない
Intelligenceへの依存。会話とメモリの置き場所が要件に合うかを最初に確認する

評価するなら、まずローカルで /bot を開き、READMEが例示する「news.ycombinator.comを開いてトップ記事を教えて」を実行し、/admin/audit に何が残るかを見るのが早い。次に /admin/boundaries で拒否ルールを1本足し、同じ操作を再実行して拒否の記録と理由(違反したルール名)が出ることを確かめる。この2往復で、この製品が何を売りにしているかはだいたい掴める。

逆に、いま本番投入を検討するのは早い。alphaであること、統治の既定値が全許可であること、そして本番構成が事実上Enterprise側(Helm)に寄っていることを踏まえると、現時点では設計思想を学び、自社要件と突き合わせる対象として見るのが妥当だろう。「監査行を書いてから動く」「攻撃者が供給したラベルで判定しない」「分類できないMCPツールは書き込み扱い」といった判断は、自前でエージェント基盤を組む場合にもそのまま持ち帰れる考え方だ。

参照ソース

CopilotKit/openbot — GitHubリポジトリ(README・server/src/config.tsserver/src/computer/gateway.tsserver/src/computer/policy.tsserver/src/computer/policy-store.tsserver/src/channels/thread-identity.tsserver/src/auth/dev-actor.tsserver/src/plugins/catalogue.ts.env.exampleexamples/fintech/agents.yaml。commit 93ff1b19 を2026-08-20に取得)
OpenBot 製品ページ — copilotkit.ai/openbot
AG-UI Protocol — ag-ui-protocol/ag-ui
CopilotKit Intelligence セルフホスティングに関する記載.env.example が参照するURL)