Slide 1

Slide 1 text

実践AI チャットボットUI 実装入門 syumai フロントエンドカンファレンス東京 2025 (2025/9/21)

Slide 2

Slide 2 text

自己紹介 syumai ECMAScript 仕様輪読会 / Asakusa.go 主催 株式会社ベースマキナで管理画面のSaaS を開発中 Go でGraphQL サーバー (gqlgen) や TypeScript でフロン トエンドを書いています Software Design 2023 年12 月号から2025 年2 月号まで Cloudflare Workers の連載をしました Twitter ( 現𝕏): @__syumai Website: https://syum.ai

Slide 3

Slide 3 text

本日話すこと AI チャットボットのインタラクション方法 AI チャットボットのUI に関する主要な話題のふりかえり 主要ライブラリ・プロトコルの解説 AG-UI (CopilotKit) MCP UI 具体的な実装方法

Slide 4

Slide 4 text

AI チャットボットのインタラクション方法

Slide 5

Slide 5 text

AI チャットボットの基本的なインタラクション方法 テキストベース ユーザー: テキストを入力 AI: テキストを返す

Slide 6

Slide 6 text

Mastra x Vercel AI SDK v5 のサンプル https://github.com/mastra-ai/mastra/tree/main/examples/ai-sdk-v5

Slide 7

Slide 7 text

AI チャットボットの基本的なインタラクション方法 テキストベース ユーザー: テキストを入力 AI: テキストを返す → これは常に理想的なインタラクション方法と言えるか?

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

テキスト以外のインタラクション方法が適切な例 ルート案内 地図が表示された方が嬉しい ショッピング 商品の写真が表示されたり、色を選択したりできた方が嬉しい

Slide 10

Slide 10 text

一時期あった言説

Slide 11

Slide 11 text

「どこのWeb サービスもMCP サーバーを提供するようになったら、 全部チャットで済むようになって、フロントエンドの開発は要らなくなる んじゃないか?」

Slide 12

Slide 12 text

西尾さんのツイート ( 勝手に引用) MCP に、従来のUI の役割は完全には置き換えられない

Slide 13

Slide 13 text

フロントエンドカンファレンス北海道 2025 の yusukebe さんの発表でも同様の話がありました https://speakerdeck.com/yusukebe/aishi-dai-nouihadokohexing-ku

Slide 14

Slide 14 text

時と場合に応じて、適切なUI があるはず そもそも、文字入力のコストは低くないので、全ての利用者に常に使うよう求めるべ きではない

Slide 15

Slide 15 text

Gemini の事例

Slide 16

Slide 16 text

カレンダーの予定UI が表示され、クリックすると詳細に飛べる

Slide 17

Slide 17 text

No content

Slide 18

Slide 18 text

地図が表示され、ルートを視覚的に確認できる

Slide 19

Slide 19 text

目指すべきインタラクション方法 ユーザー: テキストか、専用のUI から入力 AI: テキストか、専用のUI を返す (Gemini の例で確認できたのはこちら)

Slide 20

Slide 20 text

AI チャットボットのUI に関する主要な話題のふりかえり

Slide 21

Slide 21 text

2024/5/15-16 Evan Bacon さんのReact Conf 2024 での発表 2025/4/10 Kent C. Dodds さんの「New Content Type for "UI" 」Proposal 2025/5/3 Kent C. Dodds さんの記事「The future of AI interaction: Beyond just text 」 2025/5/12 AG-UI リリースのアナウンス 2025/5/17 MCP UI リリースのアナウンス (MCP 公式ではない)

Slide 22

Slide 22 text

2024/5/15-16 Evan Bacon さんのReact Conf 2024 での発表 Expo Router のRSC 対応についての発表の一環で、AI チャットボットがUI を返すデモを行った https://www.youtube.com/watch?v=djhEgxQf3Kw&t=677s

Slide 23

Slide 23 text

2025/4/10 Kent C. Dodds さんの「New Content Type for "UI" 」Proposal MCP に生のHTML でUI を返す機能追加の提案を行った https://github.com/modelcontextprotocol/modelcontextprotocol/discussions/1146

Slide 24

Slide 24 text

2025/5/3 Kent C. Dodds さんの記事「The future of AI interaction: Beyond just text 」 Evan Bacon さんの発表をベースに、AI チャットボットでUI を使う提案を行う記事 https://www.epicai.pro/the-future-of-ai-interaction-beyond-just-text-w22ps

Slide 25

Slide 25 text

2025/5/12 AG-UI リリースのアナウンス AI エージェントがUI を含んだインタラクションを行うためのプロトコルとライブラリ https://x.com/CopilotKit/status/1921940427944702001

Slide 26

Slide 26 text

2025/5/17 MCP UI リリースのアナウンス (MCP 公式ではない) AI エージェントがMCP 経由でUI を含んだインタラクションを行うためのプロトコルとライブラリ https://x.com/idosal1/status/1923477857881190718

Slide 27

Slide 27 text

2025 年5 月時点で、以下の2 つが出揃った AG-UI MCP UI

Slide 28

Slide 28 text

AG-UI とは

Slide 29

Slide 29 text

AG-UI AI エージェントがUI を含んだインタラクションを行うためのプロトコルとライブラリ AI チャットボット実装のためのフレームワーク、CopilotKit のチームによって開発さ れた CopilotKit との結び付きが強い。AG-UI のリポジトリ内にもCopilotKit への言及が 数多く存在 CopilotKit でデファクトスタンダードを取りに行くための動きと思われる

Slide 30

Slide 30 text

CopilotKit によって、Mastra を含む多くのフレームワークをサポート https://github.com/ag-ui-protocol/ag-ui

Slide 31

Slide 31 text

AG-UI (CopilotKit) のデモ

Slide 32

Slide 32 text

AG-UI (CopilotKit) の機能を一通り試せるPlayground https://dojo.ag-ui.com/

Slide 33

Slide 33 text

AG-UI の特徴

Slide 34

Slide 34 text

AG-UI はエージェントとユーザー間のプロトコル (A2A やMCP と競合しない) https://github.com/ag-ui-protocol/ag-ui

Slide 35

Slide 35 text

AG-UI のプロトコルが行うこと ユーザーからの以下のような要求を、全てAG-UI のプロトコルで行うことが想定されてい る エージェントとのテキストメッセージのやり取り ツールの呼び出し エージェントとの状態の同期 部分的に導入できるものではない

Slide 36

Slide 36 text

エージェントとの状態の同期 CopilotKit のShared State という機能を実現するための機構 スキーマ定義付きの、ただのオブジェクトが共有されるイメージ ツール呼び出しのようなワンショットで終わるものではなく、エージェントが徐々に 情報を集めて画面に書き込んでいくような、時間のかかる処理に使える

Slide 37

Slide 37 text

https://docs.copilotkit.ai/shared-state

Slide 38

Slide 38 text

AG-UI のプロトコルが行わないこと エージェントからのUI そのものの返却 MCP UI ( 後述) のように、ツールの呼び出し結果自体が生のHTML にはなったり しない あくまで、ユーザー(ブラウザ)とエージェントの間では、メッセージのやり取 りと、状態の同期をするだけ UI の表示方法は完全にフロントエンドに委ねられている →AI チャットボットのフロントエンドが、対応するエージェント向けの 専用の実装を持つ必要がある

Slide 39

Slide 39 text

MCP UI とは

Slide 40

Slide 40 text

MCP UI AI エージェントがMCP 経由でUI を含んだインタラクションを行うためのプロトコル とライブラリ プロトコルとしては、完全にMCP の上に乗っている 独自色の少ない、ただの拡張仕様 Kent C. Dodds さんのProposal のアイデアを元に、Ido Salomon さん (@idosal) が実装 https://mcpui.dev/

Slide 41

Slide 41 text

Shopify もMCP UI に注目しているらしい https://shopify.engineering/mcp-ui-breaking-the-text-wall

Slide 42

Slide 42 text

MCP UI のデモ

Slide 43

Slide 43 text

MCP UI の機能を試せるPlayground ( 手元でAPI Key を設定して動かす必要あり) https://github.com/idosal/scira-mcp-ui-chat

Slide 44

Slide 44 text

https://mcpstorefront.com のMCP UI Server に繋いだ例

Slide 45

Slide 45 text

MCP UI の特徴

Slide 46

Slide 46 text

UI はただのMCP のResource UI は、独自の ui:// scheme のURL で始まるMCP のResource として表現され、 Tool の呼び出し結果として返される 例: ui://my-custom-form/instance-01 Resource の mimeType に応じて、 レンダリング方法が変わる mimeType: 'text/html' → HTML の中身をそのままiframe に表示 mimeType: 'text/uri-list' → URL の示す先をiframe に表示 MCP のResource は、元々Tool の結果として返せるので、仕様に反する部分がなくシ ンプル MCP のHost が、 ui:// Resource のレンダリング方法を知ってさえいればいい

Slide 47

Slide 47 text

UI はiframe にレンダリングされる UI は、iframe 内にレンダリングされるため、直接AI チャットボット (MCP Host) のア プリケーションのWindow object に触れられないので安全 通信はpostMessage で行う iframe 内にレンダリングされるコンポーネントと、MCP UI のホストとの postMessage ベースの通信プロトコルが定義されている ツール呼び出し以外に、プロンプトを入力したり、URL を渡してリンクを開くよ うHost に依頼したりもできる

Slide 48

Slide 48 text

UI 側からのツール呼び出しの例 window.parent.postMessage( { type: "tool", payload: { toolName: "get-weather", params: { city: "Tokyo", }, }, }, "*" ); https://mcpui.dev/guide/embeddable-ui#tool

Slide 49

Slide 49 text

対応しているMCP Host が既に複数存在。Postman などから、素の状態でMCP UI を使える https://mcpui.dev/guide/supported-hosts

Slide 50

Slide 50 text

AG-UI とMCP UI の比較

Slide 51

Slide 51 text

AG-UI とMCP UI の比較 汎用性 基本的にMCP UI の方が上。 MCP UI のResource をレンダリングできるクライアントならどこでも使える AG-UI は、専用のフロントエンド実装が必要 MCP 非依存という観点ではAG-UI の方が上。 エージェントの使用するツールが、MCP のTool として実装されるとは限らな い

Slide 52

Slide 52 text

AG-UI とMCP UI の比較 表現力 AG-UI の方が、表現力は高い。 エージェントとの状態共有など、高度な機能も備えている MCP UI は、汎用性に振っている分、出来ることが少ない

Slide 53

Slide 53 text

AG-UI とMCP UI の比較 ベンダー依存度 AG-UI の方が、ベンダー依存度が高く見える。 AG-UI のプロトコル自体がCopilotKit 発で、他に主要な実装が特に無さそう プロトコルの複雑性もこちらの方が高いので、この状況は続きそう 一方、MCP UI は、Postman など対応するクライアント実装が数多く存在し ている

Slide 54

Slide 54 text

具体的な実装方法

Slide 55

Slide 55 text

AG-UI (CopilotKit) の実装

Slide 56

Slide 56 text

AG-UI (CopilotKit) の実装 Mastra のサンプルを取り上げます https://github.com/CopilotKit/with-mastra

Slide 57

Slide 57 text

AG-UI (CopilotKit) の実装 やること 「天気情報取得ツール」のUI のレンダリング

Slide 58

Slide 58 text

「天気情報取得ツール」のUI のレンダリング エージェント側 結果のスキーマを定義 export type WeatherToolResult = z.infer; const WeatherToolResultSchema = z.object({ temperature: z.number(), feelsLike: z.number(), humidity: z.number(), windSpeed: z.number(), windGust: z.number(), conditions: z.string(), location: z.string(), }); https://github.com/CopilotKit/with-mastra/blob/main/src/mastra/tools/index.ts

Slide 59

Slide 59 text

「天気情報取得ツール」のUI のレンダリング エージェント側 先ほどのスキーマをoutputSchema に設定して、tool を宣言 export const weatherTool = createTool({ id: 'get-weather', description: 'Get current weather for a location', inputSchema: z.object({ location: z.string().describe('City name'), }), outputSchema: WeatherToolResultSchema, execute: async ({ context }) => { // ツールの内容は省略 return await getWeather(context.location); }, }); https://github.com/CopilotKit/with-mastra/blob/main/src/mastra/tools/index.ts

Slide 60

Slide 60 text

「天気情報取得ツール」のUI のレンダリング エージェント側 tool をエージェントに設定して公開 ( 普通のMastra のtool となんら変わらない) export const weatherAgent = new Agent({ name: "Weather Agent", tools: { weatherTool }, model: openai("gpt-4o"), instructions: "You are a helpful assistant.", // ... }); https://github.com/CopilotKit/with-mastra/blob/main/src/mastra/agents/index.ts

Slide 61

Slide 61 text

「天気情報取得ツール」のUI のレンダリング クライアント側 React で、天気情報の表示コンポーネントを実装 function WeatherCard({ result, location, status }: { // toolのoutputSchemaの型がそのまま使える! result: WeatherToolResult, location?: string, status: "inProgress" | "executing" | "complete" }) { // ... https://github.com/CopilotKit/with-mastra/blob/main/src/app/page.tsx

Slide 62

Slide 62 text

「天気情報取得ツール」のUI のレンダリング クライアント側 weatherTool の呼び出しに合わせて WeatherCard コンポーネントをレンダリングするこ とを useCopilotAction hook 呼び出しで指定 import { useCopilotAction } from "@copilotkit/react-core"; // Pageのコンポーネント内 useCopilotAction({ name: "weatherTool", description: "Get the weather for a given location.", available: "frontend", parameters: [{ name: "location", type: "string", required: true }], // WeatherCardのコンポーネントを返す render: ({ args, result, status }) => }); https://github.com/CopilotKit/with-mastra/blob/main/src/app/page.tsx

Slide 63

Slide 63 text

「天気情報取得ツール」のUI のレンダリング クライアント側 チャット内容は CopilotSidebar コンポーネントに表示される import { CopilotSidebar } from "@copilotkit/react-ui"; export default function CopilotKitPage() { return ( ); } https://github.com/CopilotKit/with-mastra/blob/main/src/app/page.tsx

Slide 64

Slide 64 text

weatherTool の応答として WeatherCard が表示された

Slide 65

Slide 65 text

MCP UI の実装

Slide 66

Slide 66 text

MCP UI の実装 やること カラーピッカーで選んだ色のグリンピースのシュウマイを生成 MCP Server 側の実装だけ取り上げます (Cloudflare のAgents SDK を使用)

Slide 67

Slide 67 text

MCP UI の実装 Tool の実装 (generateSyumai) 最後に呼ぶ、 generateSyumai tool を用意しておきます this.server.tool("generateSyumai", "Generate a syumai avatar image with the specified color code.", { colorCode: z.string().length(6) }, async ({ colorCode }) => ({ content: [{ type: "text", text: `{ "imageUrl": "https://syum.ai/image?code=${colorCode}"}` }] }));

Slide 68

Slide 68 text

MCP UI の実装 コンポーネントの実装 カラーピッカーのHTML を実装 (Claude に書いてもらいました)

色を選択してください

選択された色:

Slide 69

Slide 69 text

MCP UI の実装 コンポーネントの実装 onClick でMCP Host にpostMessage して、 generateSyumai を呼ぶようにする document.querySelectorAll('.color-button').forEach(button => { button.addEventListener('click', () => { // ... const message = { type: 'tool', payload: { toolName: 'generateSyumai', params: { colorCode: colorData.hex, } } }; window.parent.postMessage(message, '*');

Slide 70

Slide 70 text

MCP UI の実装 Tool の実装 (showSyumaiColorPicker) Tool から、コンポーネントのResource を返すようにする // 生のHTMLを文字列でexportしている import { colorpicker } from "./colorpicker"; import { createUIResource } from "@mcp-ui/server"; this.server.tool( "showSyumaiColorPicker", {}, () => { // `createUIResource` でMCP UIのリソースを生成 const resourceBlock = createUIResource({ uri: "ui://server-generated/syumaiColorPicker", content: { type: "rawHtml", htmlString: colorpicker }, encoding: "text", }) return { content: [resourceBlock] } },

Slide 71

Slide 71 text

MCP UI の実装 カラーピッカーで選んだ色のグリンピースのシュウマイを生成するMCP サーバーは、これ だけで実装完了!

Slide 72

Slide 72 text

設定したHTML が表示される

Slide 73

Slide 73 text

ボタンクリックで、Tool が呼ばれる

Slide 74

Slide 74 text

まとめ AI チャットボットでは、テキストではなく、専用のUI をレンダリングする方が適切な ことがある AG-UI (CopilotKit) / MCP UI は、それぞれ大きく出来ることが異なる AG-UI アプリケーション全体を制御したいならこちら MCP UI ツール呼び出しの結果の表示だけ制御したいならこちら MCP Host の対応も増えていて、より広く使える可能性がある

Slide 75

Slide 75 text

ご清聴ありがとうございました!

Slide 76

Slide 76 text

補足

Slide 77

Slide 77 text

AI チャットボット向けフレームワークは他にもある Assistant UI https://www.assistant-ui.com/ これも有望っぽいです

Slide 78

Slide 78 text

最近見付けて面白かったもの nanobot https://www.nanobot.ai/ MCP サーバーをYAML ファイル一本でエージェントに変換 MCP UI も対応しています