先に結論
を一通り読んで、一番強く感じたのはこれです。
AG-UI、つまり Agent User Interaction Protocol は、単なる「AIチャットUIの作り方」ではありません。
また、「AIが画面を生成するための仕様」そのものでもありません。
もっと本質的には、
AI Agent とユーザー向けアプリケーションの間で、状態・メッセージ・ツール実行・人間の介入をリアルタイムにやり取りするためのイベントベースプロトコル
です。
公式ドキュメントでも、AG-UI は AI agents と user-facing applications を接続する open / lightweight / event-based protocol であり、agentic backend と frontend application の間の双方向接続を標準化するものだと説明されています。(AG-UI)
短く言うと、
MCP が Agent と Tool/Data をつなぎ、A2A が Agent と Agent をつなぐなら、AG-UI は Agent と User Interface をつなぐ
ということです。
AG-UIとは何か
AG-UI は、AI Agent の実行結果をフロントエンドに流すためのプロトコルです。
ただのテキストストリーミングではありません。
AG-UI が扱うのは、たとえば次のようなものです。
- Agent の実行開始・終了
- テキストのストリーミング
- ツール呼び出し
- ツール引数のストリーミング
- ツール実行結果
- フロントエンドとの共有状態
- 人間の承認待ち
- reasoning 表示や暗号化された reasoning continuity
- activity / progress 表示
- generative UI との接続
- セッションの復元、分岐、time travel
つまり、AG-UI は「チャット欄に文字を出す」ためだけのものではありません。
Agent が何をしているのか。
どの状態にいるのか。
どのツールを呼ぼうとしているのか。
ユーザーの承認が必要なのか。
UI 側がどう反応すべきなのか。
これらをイベントとして扱うための仕組みです。
公式ドキュメントでは、AG-UI は agent state、UI intents、user interactions が model / agent runtime と frontend application の間を流れる方法を標準化すると説明されています。(AG-UI)
なぜAG-UIが必要なのか
従来のWebアプリは、だいたいこうでした。
Client → Request
Server → Response
Client → Render
シンプルです。
でも、Agentic application ではこれが崩れます。
Agent はすぐに答えないことがあります。
途中経過を出します。
ツールを呼びます。
状態を更新します。
人間に確認を求めます。
場合によっては sub-agent に委任します。
ユーザーが途中で介入します。
公式ドキュメントでも、agentic applications は従来の request/response モデルを壊すと説明されています。理由として、agent は long-running で intermediate work を stream し、nondeterministic に UI を制御し、structured / unstructured I/O を混ぜ、sub-agent などの user-interactive composition を必要とすると整理されています。(AG-UI)
ここがかなり大事です。
Agent を本気でアプリに組み込むと、問題は「モデルから文字を受け取ること」ではなくなります。
問題は、
Agent の進行中の状態を、ユーザーが理解・介入・修正できるUIとしてどう表現するか
になります。
そのためのプロトコルが AG-UI です。
Skills / MCP / Plugin / A2A / AG-UI の関係
これまでの流れと合わせると、役割はこう整理できます。
| 技術 | 本質 | 何をつなぐか |
|---|---|---|
| Agent Skills | 作業手順 | Agent ↔ 手順・判断基準 |
| MCP | 外部接続 | Agent ↔ Tools / Data |
| Codex Plugin | 配布 | Skills / Apps / MCP を配布可能にする |
| A2A | Agent間通信 | Agent ↔ Agent |
| AG-UI | ユーザー体験 | Agent ↔ User-facing App |
AG-UI 公式サイトでも、MCP、A2A、AG-UI は相互補完的な3つの agentic protocols として整理されています。MCP は Agent と tools/context、A2A は Agent と Agent、AG-UI は Agent と users through user-facing applications をつなぐものと説明されています。(AG-UI)
もう少し実務っぽく言うと、こうです。
Agent Skills:
この仕事はこう進める
MCP:
この外部ツール・データにはこう接続する
Codex Plugin:
それらを配布可能な形にまとめる
A2A:
他のAgentに仕事を委任する
AG-UI:
Agentの進行状況・状態・承認・結果をユーザーUIに出す
この5つは競合しません。
むしろ、組み合わせるものです。
たとえば、契約レビューAgentならこうなります。
契約レビューAgent
- Skills: 契約レビューの観点
- MCP: 契約DB、社内規程、過去案件に接続
- Plugin: チーム向けに配布
- A2A: 法務Agentや営業Agentに確認を依頼
- AG-UI: レビュー進捗、差分、承認、修正案をUIに表示
AG-UI は最後の「ユーザーにどう見せるか」を担当します。
ここが抜けると、Agent は裏側では賢く動いていても、ユーザーから見るとただの黒箱になります。
AG-UIはGenerative UI仕様そのものではない
ここは誤解しやすいです。
AG-UI という名前を見ると、「AIがUIを生成する仕様かな」と思います。
でも違います。
公式ドキュメントでは、A2UI、MCP-UI、Open-JSON-UI は generative UI specification であり、agent が dynamic UI components を返せるようにするものだと説明されています。一方で、AG-UI は generative UI specification ではなく、agent と application の間の bidirectional runtime connection を提供する User Interaction protocol だと説明されています。(AG-UI)
つまり、
Generative UI spec:
AgentがどんなUI部品を返すか
AG-UI:
Agentとアプリがどう双方向にやり取りするか
です。
AG-UI は generative UI をサポートできます。
でも、AG-UI 自体は「UI部品のJSON仕様」ではありません。
もっと下の実行レイヤーです。
AG-UIの基本構造
AG-UI のアーキテクチャは、かなり素直です。
User-facing Application
↓
AG-UI Client
↓
Agent / Agent Backend
公式ドキュメントでは、AG-UI は client-server architecture に従い、Application、AG-UI Client、Agents、Secure Proxy などの構成要素で整理されています。Application は chat や AI-enabled application、AG-UI Client は HttpAgent などの通信クライアント、Agents は backend AI agents です。(AG-UI)
中心にあるのはイベントです。
Agent は実行中にイベントを emit します。
Client はそのイベントを受け取ります。
Frontend はイベントを見て UI を更新します。
type RunAgent = () => Observable<BaseEvent>
公式ドキュメントでも、AG-UI の primary abstraction は run(input: RunAgentInput) -> Observable<BaseEvent> のように、agent を実行して event stream を受け取る形で説明されています。(AG-UI)
この設計がかなり良いです。
なぜなら、Agent の実行は「1回の返答」ではなく「イベント列」だからです。
イベントがAG-UIの中心
AG-UI では、すべての通信が typed events に基づいています。
公式ドキュメントでは、Events は agents と frontends の間の fundamental units of communication であり、real-time structured interaction を可能にすると説明されています。(AG-UI)
主なイベントカテゴリはこうです。
| カテゴリ | 役割 |
|---|---|
| Lifecycle Events | Agent run の開始・終了・エラー |
| Text Message Events | テキストのストリーミング |
| Tool Call Events | ツール呼び出しと引数ストリーミング |
| State Management Events | Agent と UI の状態同期 |
| Activity Events | 進行中の作業や進捗表示 |
| Reasoning Events | reasoning の可視化・継続 |
| Special Events | RAW / CUSTOM などの拡張 |
たとえば、普通のテキスト出力でも、単なる文字列ではなくこういう流れになります。
RUN_STARTED
TEXT_MESSAGE_START
TEXT_MESSAGE_CONTENT
TEXT_MESSAGE_CONTENT
TEXT_MESSAGE_END
RUN_FINISHED
ツール呼び出しならこうです。
TOOL_CALL_START
TOOL_CALL_ARGS
TOOL_CALL_ARGS
TOOL_CALL_END
TOOL_CALL_RESULT
公式ドキュメントでも、text message は Start → Content → End、tool call は Start → Args → End の streaming pattern として説明されています。(AG-UI)
ここが本質です。
AG-UI は「結果」を受け取るのではなく、Agent の実行プロセスをイベントとして受け取ります。
だから UI 側は、
- ローディングを出す
- ステップを表示する
- ツール呼び出しを見せる
- 承認ボタンを出す
- 状態をリアルタイム更新する
- エラーから復旧する
といったことができます。
State ManagementはAG-UIの強いところ
AG-UI の中でかなり重要なのが State Management です。
Agentic UI では、会話ログだけでは足りません。
たとえば、旅行計画アプリなら、
{
"destination": "Tokyo",
"dates": ["2026-07-10", "2026-07-15"],
"budget": 200000,
"selectedHotel": null,
"approvalStatus": "pending"
}
のような状態があります。
これは frontend も見たいし、agent も見たい。
AG-UI では、state は structured data object として扱われ、agent と frontend の両方からアクセスでき、interaction の進行に合わせてリアルタイム更新されます。公式ドキュメントでは、shared state architecture によって、agent は application の現在状態を見て判断し、frontend は agent の内部状態変化に反応でき、双方が state を変更できると説明されています。(AG-UI)
状態同期には2種類あります。
STATE_SNAPSHOT:
完全な状態を渡す
STATE_DELTA:
JSON Patchで差分だけ渡す
STATE_DELTA は JSON Patch、つまり RFC 6902 の形式を使います。公式ドキュメントでも、snapshot は全体状態、delta は JSON Patch による incremental updates と説明されています。(AG-UI)
これはかなり実務的です。
毎回 state 全体を送ると重い。
でも差分だけなら軽い。
接続が切れたら snapshot で復旧できる。
Agent と UI が協調するには、この共有 state がかなり重要になります。
Toolsは「フロントエンド側の能力」をAgentに渡す
AG-UI の Tools も面白いです。
MCP の tools は、Agent が外部ツールやデータにアクセスするためのものです。
一方で AG-UI の tools は、特に frontend-defined tools が重要です。
公式ドキュメントでは、AG-UI は backend-defined tools と client-defined tools を区別し、client-defined tools は RunAgentInput.tools で agent に渡されると説明されています。これにより、UI actions、approvals、user-mediated workflows のような application-specific frontend behavior を agent が呼び出せます。(AG-UI)
たとえば、フロントエンドがこういう tool を渡します。
const confirmAction = {
name: "confirmAction",
description: "Ask the user to confirm a specific action before proceeding",
parameters: {
type: "object",
properties: {
action: { type: "string" },
importance: {
type: "string",
enum: ["low", "medium", "high", "critical"]
}
},
required: ["action"]
}
}
Agent はこれを呼び出します。
Frontend は確認ダイアログを出します。
ユーザーが承認または拒否します。
その結果を Agent に返します。
公式ドキュメントでも、frontend-defined tools の利点として、frontend が利用可能な能力を決められること、ユーザー権限や application state に応じて tools を増減できること、agent は reasoning に集中し frontend が tool implementation を扱えること、sensitive operations を application 側で制御できることが説明されています。(AG-UI)
これはかなり大事です。
Agent に全部の権限を渡すのではなく、UI 側が「今このユーザーに許可できる操作」だけを tool として渡す。
これが Human-in-the-loop な Agent UI の基本になります。
Interruptsは「人間の介入」をプロトコル化する
Agent が実務で使われると、必ずこういう場面が出ます。
- このメールを本当に送ってよいか
- このデータを削除してよいか
- この見積もりで進めてよいか
- この契約条項を修正してよいか
- 追加情報がないと続行できない
こういう時、Agent は勝手に進むべきではありません。
AG-UI では、これを Interrupts として扱います。
公式ドキュメントでは、Interrupts は human-in-the-loop pauses and resumes の仕組みであり、Agent が sensitive action の前に承認を求めたり、structured input を要求したり、policy decision を待つために pause できると説明されています。(AG-UI)
AG-UI の interrupt は、普通の一時停止ではありません。
Run が RUN_FINISHED で終わるときに、
{
"outcome": {
"type": "interrupt",
"interrupts": [...]
}
}
のように「interrupt outcome」として終了します。
その後、client は同じ thread で resume を含む新しい run を開始します。
公式ドキュメントでは、RunFinished の outcome は success または interrupt を持ち、interrupt の場合は client が次の RunAgentInput に resume array を含めて再開すると説明されています。(AG-UI)
ここがかなりよくできています。
Agent の実行を無理に同じ run に閉じ込めない。
人間の入力を受けたら、新しい run として再開する。
でも threadId と interruptId でつなぐ。
この設計なら、監査ログも取りやすいです。
Capabilitiesは「このAgentは何ができるか」をUIが知る仕組み
UI 側が Agent に接続するとき、何に対応しているか分からないと困ります。
この Agent は streaming できるのか。
tools を呼べるのか。
state delta を出せるのか。
reasoning を出せるのか。
multimodal input を受けられるのか。
human-in-the-loop に対応しているのか。
AG-UI では、これを capability discovery で扱います。
公式ドキュメントでは、agents は runtime に getCapabilities() を通じて自分が何をサポートしているか宣言でき、client はそれを見て UI や挙動を適応できると説明されています。(AG-UI)
たとえば、こういう判断ができます。
const capabilities = await agent.getCapabilities?.()
if (capabilities?.reasoning?.supported) {
showReasoningPanel()
}
if (capabilities?.humanInTheLoop?.approvals) {
enableApprovalWorkflow()
}
if (capabilities?.multimodal?.input?.image) {
showImageUploadButton()
}
公式ドキュメントでも、capabilities は identity、transport、tools、output、state、multi-agent、reasoning、multimodal、execution、human-in-the-loop などのカテゴリに整理されています。(AG-UI)
これも実務ではかなり重要です。
Agent ごとにできることが違うなら、UI も変わるべきです。
対応していない機能を表示して、実行時に失敗するより、最初から capabilities を見て UI を出し分ける方が自然です。
Reasoningは「そのまま見せる」ではなく「見せ方と継続性を設計する」
AG-UI には Reasoning のサポートもあります。
ただし、これは「chain-of-thought を全部ユーザーに見せよう」という話ではありません。
公式ドキュメントでは、AG-UI の reasoning support は、reasoning visibility、state continuity、privacy compliance の3つの課題に対応するものだと説明されています。具体的には、raw chain-of-thought を露出せずに reasoning signals を見せること、encrypted reasoning items で会話ターンをまたいだ状態継続を可能にすること、zero data retention などの enterprise privacy requirements を支えることが挙げられています。(AG-UI)
つまり、AG-UI 的には reasoning も UI の一部です。
ただし、見せ方を選べます。
Full visibility:
reasoningをそのまま表示する
Summary only:
要約だけ表示し、詳細はencryptedValueで保持する
Hidden:
reasoningは表示せず、encryptedValueだけで継続性を保つ
公式ドキュメントでも、visibility control として full visibility、summary only、hidden の考え方が説明されています。(AG-UI)
これはかなり現実的です。
ユーザーには「今なにをしているか」は見せたい。
でも raw chain-of-thought をそのまま出すべきではない。
一方で、モデル側には reasoning continuity が必要になる。
この間を埋めるのが AG-UI の Reasoning support です。
Serializationは「Agent UIを復元・分岐できる」ようにする
Agent UI は長く続くことがあります。
ページをリロードする。
接続が切れる。
途中から再開する。
別案を試す。
前の run から分岐する。
こういうことをするには、event stream を保存できる必要があります。
AG-UI では Serialization がその役割を持ちます。
公式ドキュメントでは、AG-UI の serialization は agent–UI session を駆動する event stream を persist / restore する標準的方法であり、chat history や UI state の復元、running agent への再接続、過去 run からの branching / time travel、history compaction を可能にすると説明されています。(AG-UI)
ここで面白いのは、parentRunId です。
parentRunId を使うと、同じ thread の中で git-like な lineage を作れます。
run1:
東京旅行を計画して
run2:
run1から分岐して、大阪旅行に変更して
run3:
run1から分岐して、予算を半分にして
公式ドキュメントでも、parentRunId によって git-like append-only log を作り、branching / time travel を可能にすると説明されています。(AG-UI)
これは、Agent UI にとってかなり重要です。
なぜなら、Agent との作業は「1本の会話」ではなく、複数の試行錯誤になるからです。
MiddlewareはAG-UIを既存システムに合わせるための層
AG-UI を採用するとき、既存の Agent framework を全部作り直す必要はありません。
Middleware を使えば、既存の event stream を変換・フィルタ・拡張できます。
公式ドキュメントでは、AG-UI の middleware は agent を流れる event streams を transform、filter、augment する仕組みであり、logging、authentication、rate limiting、event filtering のような cross-cutting concerns を core agent logic を変えずに追加できると説明されています。(AG-UI)
たとえば、
- ログを追加する
- 特定の tool call をフィルタする
- metadata を追加する
- error handling を差し込む
- rate limit をかける
- debug mode のときだけ詳細イベントを出す
こういうことが middleware でできます。
公式ドキュメントでは、middleware は chain として動き、agent execution と event consumer の間でイベントを順番に処理すると説明されています。(AG-UI)
これは、実務導入でかなり効きます。
最初から完璧な AG-UI native agent を作らなくてもよい。
既存 framework の出力を middleware で AG-UI 互換にできる。
この柔軟さは大事です。
実装は2パターンある
AG-UI integration を作る方法は、大きく2つあります。
Server Implementation:
AgentやserverがAG-UI eventsを直接emitする
Middleware Implementation:
既存protocolや既存アプリをAG-UI eventsに変換する
公式の Quickstart でも、AG-UI integration は agent を AG-UI protocol で話せるようにするものであり、custom API を client ごとに作る代わりに、AG-UI を一度実装すれば compatible application と接続できると説明されています。また、実装方法として server implementation と middleware implementation の2つが整理されています。(AG-UI)
自分なら、こう判断します。
| 状況 | 選ぶもの |
|---|---|
| 新しくAgent backendを作る | Server Implementation |
| AG-UI eventsを細かく制御したい | Server Implementation |
| 既存Agent frameworkがある | Middleware Implementation |
| 既存APIをAG-UI対応させたい | Middleware Implementation |
| 直接イベントを出せない外部システムをつなぎたい | Middleware Implementation |
公式の server guide でも、server implementation は新しい agent を scratch から作る場合や、agent capabilities 専用サービスを作りたい場合に向いていると説明されています。(AG-UI)
まず触るなら何から始めるか
AG-UI を触るなら、いきなり大規模な Agent UI を作らなくていいと思います。
まずは、最小の event stream を出すところから始めるのがよいです。
RUN_STARTED
TEXT_MESSAGE_CHUNK
TEXT_MESSAGE_CHUNK
RUN_FINISHED
公式 Quickstart でも、AG-UI compatible server は request を受け取り、OpenAI の GPT-4o に接続し、AG-UI events として response を stream し、tool calls と state management を扱う例が示されています。(AG-UI)
アプリ側は、scaffold から始められます。
公式ドキュメントでは、AG-UI は npx create-ag-ui-app@latest による application scaffold を提供していると説明されています。(AG-UI)
個人的には、順番はこうです。
- 最小の chat streaming を作る
- text events を UI に表示する
- tool call events を表示する
- frontend-defined tool を1つ作る
- approval interrupt を入れる
- state snapshot / delta を入れる
- capabilities を実装する
- serialization で restore / branching を試す
この順番なら、AG-UI の本質がかなり分かりやすいです。
AG-UIで失敗しやすいところ
1. ただのチャットストリーミングとして扱う
AG-UI を TEXT_MESSAGE_CONTENT だけで使うと、かなりもったいないです。
それなら普通の SSE チャットでもできます。
AG-UI の価値は、
- state
- tools
- interrupts
- activity
- reasoning
- capabilities
- serialization
まで含めて、Agent UI をイベントとして設計できるところにあります。
2. frontend-defined tools を何でも渡す
frontend-defined tools は便利ですが、渡しすぎると危険です。
ユーザー権限。
現在の画面。
業務コンテキスト。
承認が必要な操作。
これらに応じて、渡す tool を変えるべきです。
AG-UI では client-defined tools によって frontend が利用可能な能力を制御できるため、ここを設計しないと安全性が崩れます。(AG-UI)
3. shared state に機密情報を入れる
State は便利ですが、何でも入れてよいわけではありません。
公式ドキュメントの best practices でも、shared state に sensitive information を保存しないよう注意されています。(AG-UI)
UI と Agent の両方が見る state なので、入れる情報は慎重に選ぶべきです。
4. interrupt を UI の都合だけで実装する
Interrupt は単なる modal 表示ではありません。
interruptId、threadId、resume、responseSchema、expiresAt、audit trail まで含めて設計する必要があります。
公式ドキュメントでも、resume は同じ threadId で行うこと、すべての open interrupts を address すること、payload validation や idempotency を考慮することなどの contract rules が示されています。(AG-UI)
5. capabilities を実装しない
最初は固定 UI でも動きます。
でも、Agent が増えると capabilities がないとつらくなります。
この Agent は画像入力に対応しているのか。
この Agent は approval を出せるのか。
この Agent は reasoning を表示できるのか。
これを hardcode し始めると、すぐ壊れます。
Capabilities を使って UI を適応させる方がよいです。
まとめ
AG-UI は、AI Agent とユーザー向けアプリケーションをつなぐためのイベントベースプロトコルです。
ただし、本質は「AIチャットUIを作ること」ではありません。
本当に大事なのは、
- Agent の実行をイベント列として扱う
- text、tool、state、activity、reasoning を分けて流す
- frontend-defined tools で UI 側の能力を Agent に渡す
- shared state で Agent と UI を同期する
- interrupts で human-in-the-loop をプロトコル化する
- capabilities で UI を Agent ごとに適応させる
- serialization で復元・分岐・time travel を可能にする
- generative UI specs と競合せず、それらを運ぶ runtime connection になる
という点です。
Agent Skills は、AI に仕事のやり方を渡します。
MCP は、AI と外部 tools/data をつなぎます。
Codex Plugin は、それらを配布可能にします。
A2A は、Agent 同士をつなぎます。
AG-UI は、Agent とユーザー体験をつなぎます。
これから AI Agent を実務アプリに組み込むなら、モデルの回答品質だけでは足りません。
重要になるのは、
Agent が今何をしていて、ユーザーがどこで介入できて、UI がどう状態を共有するか
を設計する力です。
AG-UI は、そのためのかなり重要なレイヤーになると思います。