tool-ui について
Tool UIは、プロジェクトにツール向けUIコンポーネントを追加するためのスキルです。コンポーネントの導入からassistant-ui Toolkitへの接続まで、フロントエンドとバックエンドの実装方法を案内します。
主な機能
- 0125種類のUIコンポーネントカタログ
- 02AI支援またはshadcnによる導入
- 03assistant-ui Toolkitの設定
- 04フロントエンドとバックエンドのツール構成
活用シーン
- 01ツールのワークフローに進捗や計画の表示を追加
- 02引用、コード、データ可視化の提示
- 03ユーザーの選択や承認の収集
- 04アシスタント画面でのメディア表示
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ assistant-ui/ tool-ui --skill tool-uiインストール後、Claude Code で/tool-uiを入力して読み込まれたか確認します。
詳細
ツール UI
このスキルを使うと、リクエストからツール UI の統合までをすばやく進められます。
プロジェクトに既存のチャット UI/ランタイムがない場合は、assistant-ui を優先してください。アプリにすでに動作するランタイムがある場合、assistant-ui は任意です。
ステップ 1:互換性と Doctor
ユーザーのプロジェクトにある components.json を読み、次を確認します。
components.jsonが存在すること。
ステップ 2:コンポーネントをインストール
プロジェクトルートから実行するインストールコマンド
推奨(AI 支援による統合):
npx tool-agent "integrate the <component> component"
以下のカタログにあるコンポーネント固有のプロンプトを使用します(例:integrate the plan component for step-by-step task workflows with status tracking)。
代替手段(レジストリから直接インストール):
npx shadcn@latest add @tool-ui/<component-id>
複数のコンポーネント:
npx tool-agent "integrate the plan, progress-tracker, and approval-card components for planning flows"
または、shadcn 経由:
npx shadcn@latest add @tool-ui/plan @tool-ui/progress-tracker @tool-ui/approval-card
コンポーネントカタログ全体
ツールエージェント向けプロンプトと shadcn のインストールコマンドを含む、Tool UI の全 25 コンポーネント:
進捗
| コンポーネント | 説明 | ツールエージェント向けプロンプト | shadcn |
|---|---|---|---|
plan | ステータスを追跡しながら進める、ステップごとのタスクワークフロー | integrate the plan component for step-by-step task workflows with status tracking | npx shadcn@latest add @tool-ui/plan |
progress-tracker | 複数ステップの操作に対するリアルタイムのステータスフィードバック | integrate the progress tracker component for real-time status feedback on multi-step operations | npx shadcn@latest add @tool-ui/progress-tracker |
入力
| コンポーネント | 説明 | ツールエージェント向けプロンプト | shadcn |
|---|---|---|---|
option-list | ユーザーが複数の選択肢から選べるようにします | integrate the option list component to let users select from multiple choices | npx shadcn@latest add @tool-ui/option-list |
parameter-slider | 数値パラメーターを調整するためのコントロール | integrate the parameter slider component for numeric parameter adjustment controls | npx shadcn@latest add @tool-ui/parameter-slider |
preferences-panel | ユーザー設定用のコンパクトなパネル | integrate the preferences panel component for compact user settings | npx shadcn@latest add @tool-ui/preferences-panel |
question-flow | 分岐のある、複数ステップのガイド付き質問 | integrate the question flow component for multi-step guided questions with branching | npx shadcn@latest add @tool-ui/question-flow |
表示
| コンポーネント | 説明 | tool-agent プロンプト | shadcn |
|---|---|---|---|
citation | 出典を明記して参照元を表示します | integrate the citation component to display source references with attribution | npx shadcn@latest add @tool-ui/citation |
item-carousel | コレクションを閲覧するための横スクロールカルーセル | integrate the item carousel component for horizontal browsing of collections | npx shadcn@latest add @tool-ui/item-carousel |
link-preview | Open Graph データを使ったリッチなリンクプレビュー | integrate the link preview component for rich link previews with Open Graph data | npx shadcn@latest add @tool-ui/link-preview |
stats-display | 主要な指標と KPI をビジュアルグリッドで表示します | integrate the stats display component for key metrics and KPIs in a visual grid | npx shadcn@latest add @tool-ui/stats-display |
terminal | コマンドラインの出力とログを表示します | integrate the terminal component to show command-line output and logs | npx shadcn@latest add @tool-ui/terminal |
weather-widget | 予報や気象状況を表示する天気ウィジェット | integrate the weather widget component for weather display with forecasts and conditions | npx shadcn@latest add @tool-ui/weather-widget |
アーティファクト
| コンポーネント | 説明 | tool-agent プロンプト | shadcn |
|---|---|---|---|
chart | インタラクティブなチャートでデータを可視化します(recharts が必要です) | integrate the chart component to visualize data with interactive charts | npx shadcn@latest add @tool-ui/chart |
code-block | 構文ハイライト付きのコードスニペットを表示します | integrate the code block component for syntax-highlighted code snippets | npx shadcn@latest add @tool-ui/code-block |
code-diff | 構文ハイライト付きの差分でコードの変更を比較します(@pierre/diffs が必要です) | integrate the code diff component to compare code changes with syntax-highlighted diffs | npx shadcn@latest add @tool-ui/code-diff |
data-table | 構造化データを並べ替え可能なテーブルで表示します | integrate the data table component to present structured data in sortable tables | npx shadcn@latest add @tool-ui/data-table |
message-draft | 送信前にメッセージを確認して承認します | integrate the message draft component to review and approve messages before sending | npx shadcn@latest add @tool-ui/message-draft |
instagram-post | Instagram の投稿プレビューを表示します | integrate the instagram post component to render Instagram post previews | npx shadcn@latest add @tool-ui/instagram-post |
linkedin-post | LinkedIn の投稿プレビューを表示します | integrate the linkedin post component to render LinkedIn post previews | npx shadcn@latest add @tool-ui/linkedin-post |
x-post | X の投稿プレビューを表示します | integrate the x post component to render X/Twitter post previews | npx shadcn@latest add @tool-ui/x-post |
確認
| コンポーネント | 説明 | tool-agent プロンプト | shadcn |
|---|---|---|---|
approval-card | エージェントのアクションを二択で確認します | integrate the approval card component for binary confirmation of agent actions | npx shadcn@latest add @tool-ui/approval-card |
order-summary | 明細付きの価格で購入内容を表示します | integrate the order summary component to display purchases with itemized pricing | npx shadcn@latest add @tool-ui/order-summary |
メディア
| コンポーネント | 説明 | tool-agent プロンプト | shadcn |
|---|---|---|---|
audio | アートワークとメタデータを含む音声再生 | integrate the audio component for audio playback with artwork and metadata | npx shadcn@latest add @tool-ui/audio |
image | メタデータとクレジットを含む画像の表示 | integrate the image component to display images with metadata and attribution | npx shadcn@latest add @tool-ui/image |
image-gallery | フルスクリーンのライトボックスビューアーを備えたメイソングリッド | integrate the image gallery component with masonry grid and lightbox viewer | npx shadcn@latest add @tool-ui/image-gallery |
video | コントロールとポスター画像を備えた動画再生 | integrate the video component for video playback with controls and poster | npx shadcn@latest add @tool-ui/video |
表示(地図)
| コンポーネント | 説明 | tool-agent プロンプト | shadcn |
|---|---|---|---|
geo-map | 地理情報が付与されたエンティティと車両の位置を表示 | integrate the geo map component to display geolocated entities and fleet positions | npx shadcn@latest add @tool-ui/geo-map |
ユースケース別のインストール例
tool-agent(推奨):
npx tool-agent "integrate the plan, progress-tracker, and approval-card components for planning flows"
npx tool-agent "integrate citation, link-preview, code-block, and code-diff for research output"
npx tool-agent "integrate data-table, chart, and stats-display for data visualization"
npx tool-agent "integrate image, image-gallery, video, and audio for media display"
shadcn(直接):
npx shadcn@latest add @tool-ui/plan @tool-ui/progress-tracker @tool-ui/approval-card
npx shadcn@latest add @tool-ui/citation @tool-ui/link-preview @tool-ui/code-block @tool-ui/code-diff
npx shadcn@latest add @tool-ui/data-table @tool-ui/chart @tool-ui/stats-display
# npm i recharts # peer for chart
npx shadcn@latest add @tool-ui/image @tool-ui/image-gallery @tool-ui/video @tool-ui/audio
コードベースでの Toolkit のセットアップ
コンポーネントをインストールしたら、Toolkit を介して assistant-ui に接続します。このセクションでは、プロバイダー、ランタイム、Toolkit ファイル、ID の処理を含むセットアップ全体について説明します。
1. プロバイダーとランタイム
ランタイム、トランスポート、ツールを提供するアシスタント用ラッパーを作成します。
"use client";
import { lastAssistantMessageIsCompleteWithToolCalls } from "ai";
import { AssistantRuntimeProvider, Tools, useAui } from "@assistant-ui/react";
import {
AssistantChatTransport,
useChatRuntime,
} from "@assistant-ui/react-ai-sdk";
import { Thread } from "@/components/assistant-ui/thread";
import { toolkit } from "@/components/toolkit";
export const Assistant = () => {
const runtime = useChatRuntime({
transport: new AssistantChatTransport({ api: "/api/chat" }),
sendAutomaticallyWhen: lastAssistantMessageIsCompleteWithToolCalls,
});
const aui = useAui({ tools: Tools({ toolkit }) });
return (
<AssistantRuntimeProvider runtime={runtime} aui={aui}>
<div className="h-dvh">
<Thread />
</div>
</AssistantRuntimeProvider>
);
};
主なポイント:
useChatRuntime+AssistantChatTransport:チャット API に接続します。Tools({ toolkit }):ツールの定義とレンダラーをモデルに渡します。sendAutomaticallyWhen: lastAssistantMessageIsCompleteWithToolCalls:ツール呼び出し後に自動で処理を続行します(任意ですが、ツールを多用するフローでよく使われます)。
2. Toolkit ファイルの構成
Toolkit オブジェクトをエクスポートする単一の toolkit.ts(または toolkit.tsx)を作成します。各キーはツール名で、各値には type、description、parameters、render が含まれます。
ツールの説明 — すべてのツールに必ず description を記述してください。表示される内容ではなく、そのツールを_いつ_呼び出すか、どのような役割を果たすかを説明します。Tool UI コンポーネントはペイロード(選択肢、プラン、チャートなど)をすでにユーザーに表示するため、その内容を繰り返す説明は冗長です。内容をそのまま繰り返す説明(例:「ラベルと説明付きの選択肢一覧を表示します」)よりも、モデル向けの指示(例:「ユーザーが実行できるプランを提示します」「ユーザーが選択肢を選べるようにします」)を優先してください。
-フロントエンドツールとバックエンドツール
| - | フロントエンド | バックエンド | |
|---|---|---|---|
| - | 実装 | ブラウザーで実行され、ユーザー操作によって addResult 経由でコミットされます | ツールの実装はサーバー上にあり、モデルが結果を返します |
| - | execute | 必須 — クライアント側でツールの UI フローを実行します | 不要 |
| - | parameters | 必須(モデル引数のスキーマ) | 使用しません。バックエンドの LLM が aisdk 経由で処理される場合は、代わりに inputSchema を使用します |
| - | render | 必須(引数、ステータス、結果、addResult の UI) | 必須(result の UI) |
バックエンドツール(モデルが結果を返し、ユーザー入力は不要):
import { type Toolkit } from "@assistant-ui/react";
import { Plan } from "@/components/tool-ui/plan";
import { safeParseSerializablePlan } from "@/components/tool-ui/plan/schema";
export const toolkit: Toolkit = {
showPlan: {
type: "backend",
render: ({ result }) => {
const parsed = safeParseSerializablePlan(result);
if (!parsed) return null;
return <Plan {...parsed} />;
},
},
};
フロントエンドツール(モデルが引数を送り、ユーザー操作によって addResult 経由でコミットされます):
import { type Toolkit } from "@assistant-ui/react";
import { OptionList } from "@/components/tool-ui/option-list";
import {
SerializableOptionListSchema,
safeParseSerializableOptionList,
} from "@/components/tool-ui/option-list/schema";
const optionListTool: Toolkit[string] = {
description: "Render selectable options with confirm and clear actions.",
parameters: SerializableOptionListSchema,
render: ({ args, toolCallId, result, addResult }) => {
const parsed = safeParseSerializableOptionList({
...args,
id: args?.id ?? `option-list-${toolCallId}`,
});
if (!parsed) return null;
if (result) {
return <OptionList {...parsed} choice={result} />;
}
return (
<OptionList
{...parsed}
onAction={async (actionId, selection) => {
if (actionId === "confirm" || actionId === "cancel") {
await addResult?.(selection);
}
}}
/>
);
},
};
export const toolkit: Toolkit = {
option_list: optionListTool,
approval_card: {
/* ... */
},
};
3. API ルート(AI SDK)
チャット API が AI SDK(streamText)を使用する場合、ai の tool() を使ってバックエンドツールを定義します。
inputSchemaを使用します- バックエンドツールはサーバー上で
executeを使用します。結果はストリーミングされ、ツールキットのrender関数によってレンダリングされます
import { streamText, tool, convertToModelMessages } from "ai";
import { openai } from "@ai-sdk/openai";
import { z } from "zod";
// With frontend tools: ...frontendTools(clientTools) — clientTools come from the request body via AssistantChatTransport
const result = streamText({
model: openai("gpt-4o"),
messages: await convertToModelMessages(messages),
tools: {
get_weather: tool({
description:
"Get the current weather and forecast for a location. Returns data to display in a weather widget.",
inputSchema: z.object({
location: z.string().describe("City name, e.g. 'San Francisco'"),
units: z
.enum(["celsius", "fahrenheit"])
.default("fahrenheit")
.describe("Temperature unit"),
}),
execute: async ({ location, units }) => {
// Fetch weather data, return shape matching your widget schema
return { location, units /* ... */ };
},
}),
},
});
4. アクション中心型と複合コンポーネント
| パターン | コンポーネント | 用途 |
|---|---|---|
| アクション中心型 | OptionList、ParameterSlider、PreferencesPanel、ApprovalCard | onAction または onConfirm/onCancel を直接接続し、ToolUI ラッパーは使用しません。レシート状態には choice={result} を渡します。 |
| 複合型 | OrderSummary、DataTable など | ToolUI + ToolUI.Surface + ToolUI.Actions でラップし、DecisionActions または LocalActions を使用します。 |
アクション中心型の例(OptionList):
return (
<OptionList
{...parsed}
onAction={async (actionId, selection) => {
if (actionId === "confirm" || actionId === "cancel") {
await addResult?.(selection);
}
}}
/>
);
複合型の例(DecisionActions を使った OrderSummary):
return (
<ToolUI id={parsed.id}>
<ToolUI.Surface>
<OrderSummary {...parsed} />
</ToolUI.Surface>
<ToolUI.Actions>
<ToolUI.DecisionActions
actions={[
{ id: "cancel", label: "Cancel", variant: "outline" },
{ id: "confirm", label: "Purchase" },
]}
onAction={(action) =>
createDecisionResult({ decisionId: parsed.id, action })
}
onCommit={(decision) => addResult?.(decision)}
/>
</ToolUI.Actions>
</ToolUI>
);
ApprovalCard はアクションを内包します。onConfirm/onCancel を直接接続します。
return (
<ApprovalCard
{...parsed}
choice={
result === "approved" || result === "denied" ? result : parsed.choice
}
onConfirm={async () => addResult?.("approved")}
onCancel={async () => addResult?.("denied")}
/>
);
アクションモデル
Tool UI では 2 つのアクションサーフェスを使用し、表示コンポーネントの外側に複合型の兄弟要素としてレンダリングします。
ToolUI.LocalActions:影響を伴わない副作用(エクスポート、コピー、リンクを開く)。ハンドラーからaddResult(...)を呼び出してはいけません。ToolUI.DecisionActions:createDecisionResult(...)経由でDecisionResultエンベロープを生成する、影響を伴う選択肢です。コミットコールバックからaddResult(...)を呼び出します。
アクションを含む表示コンポーネントの複合型ラッパーパターン:
<ToolUI id={surfaceId}>
<ToolUI.Surface>
<DataTable {...props} />
</ToolUI.Surface>
<ToolUI.Actions>
<ToolUI.LocalActions
actions={[{ id: "export-csv", label: "Export CSV" }]}
onAction={(actionId) => {
/* side effects only */
}}
/>
</ToolUI.Actions>
</ToolUI>
3 つのコンポーネントはアクション中心型の例外で、兄弟サーフェスではなく、アクション用の埋め込み props を保持します。3 つすべてで統一されたインターフェースを共有します。
actions:コンポーネントによってレンダリングされるアクションボタンです。onAction(actionId, state):アクションの実行後に実行され、アクション後の状態を受け取ります。onBeforeAction(actionId, state):アクションの実行前に評価されるガードです。
| コンポーネント | ハンドラーに渡される状態の型 |
|---|---|
OptionList | OptionListSelection |
ParameterSlider | SliderValue[] |
PreferencesPanel | PreferencesValue |
複合型パターンを使用するコンポーネント:CodeBlock、CodeDiff、Terminal、ProgressTracker。
コンテキストは createContext + use()(React 19)で共有されます。サブコンポーネントを Root の外部で使用すると、エラーがスローされます。
レシートと選択の規約
結果を伴うコンポーネントでは、choice プロパティを使用して、確定済み/完了済みの状態を表示します。
| コンポーネント | choice の型 | 値/形式 |
|---|---|---|
ApprovalCard | "approved" | "denied" | 文字列リテラル |
OptionList | string | string[] | 選択されたオプション ID(一つまたは複数) |
OrderSummary | OrderDecision | { action: "confirm", orderId?, confirmedAt? } |
ProgressTracker | ToolUIReceipt | { outcome, summary, identifiers?, at }(共通の型) |
choice が指定されている場合、コンポーネントはレシートモードで表示されます。読み取り専用で、アクションはありません。
運用ルール
- リクエストを解決するために必要な、最小限のコンポーネントをインストールしてください。
- すべてのツールに
descriptionが必要です。モデル向けに、呼び出すタイミングと役割を記述し、コンポーネントが表示する内容を繰り返さないようにしてください。
注意: フロントエンドのツールには実行関数が必要です。 バックエンドのツールは、サーバー側にツールの実装があります。 バックエンドのツールにはどちらも必要ありません。 生成されたファイルは無視してください。 セットアップ後:
- 変更後に初めて実行したときに問題なく使えるよう、必要なパッケージ依存関係がインストールされていることを確認してください。
- 実装した機能を正常に実行するために設定すべき環境変数が未設定の場合は、ユーザーに通知してください。多くの場合、API チャットエンドポイントで必要となる変数が該当します。