building-ai-chat について
building-ai-chat は、対話型 AI インターフェースを開発する人向けの設計・実装ガイドです。ストリーミング応答、コンテキスト、マルチモーダル入力、エラー処理に加え、ツール利用の表示やアクセシビリティも扱います。
主な機能
- 01ストリーミングと Markdown 表示のパターン
- 02コンテキストとトークン使用量の管理
- 03画像、ファイル、音声入力のパターン
- 04AI のエラーと拒否応答への対応
- 05ツール利用の表示とユーザーフィードバック
- 06アクセシビリティとパフォーマンスの指針
活用シーン
- 01チャットボットや AI アシスタントの画面構築
- 02ストリーミング Markdown 応答の実装
- 03画像、ファイル、音声入力への対応
- 04ツール利用と応答へのフィードバックの表示
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ ancoleman/ ai-design-components --skill building-ai-chatインストール後、Claude Code で/building-ai-chatを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
outputs.yamlassets/error-messages.jsonmessage-templates.jsonsystem-prompts.jsonthemes.jsonexamples/basic-chat.tsxcode-assistant.tsxmultimodal-chat.tsxstreaming-chat.tsxtool-calling-chat.tsxreferences/accessibility-chat.mdaccessibility.mdcontext-management.mderror-handling.mdfeedback-loops.mdlibrary-guide.mdmessage-components.mdmulti-modal.mdmultimodal-input.mdperformance-optimization.mdstreaming-patterns.mdstreaming-ux.mdtool-usage.mdscripts/calculate_tokens.pyformat_messages.jsparse_stream.js詳細
AI チャットインターフェースコンポーネント
目的
2024〜2025年のAI統合ブームにおいて、AIと人間の対話型インターフェースに関する新たな標準を定義します。Claude とともに構築することで得られたメタ知識を活用し、ストリーミング UX、コンテキスト管理、マルチモーダルなやり取りに関する決定版パターンを確立します。業界で確立されたパターンが不足しているため、このリファレンス実装は、他の実装が参考にする指針となります。
使用する場面
以下の場合に、このスキルを有効にします。
- ChatGPT スタイルの対話型インターフェースを構築する
- AI アシスタント、コパイロット、チャットボットを作成する
- Markdown を使ったテキスト応答のストリーミングを実装する
- 会話のコンテキストとトークン上限を管理する
- マルチモーダル入力(テキスト、画像、ファイル、音声)を処理する
- AI 固有のエラー(ハルシネーション、拒否、上限)に対処する
- フィードバック機能(評価、再生成、編集)を追加する
- 会話の分岐やスレッド化を実装する
- ツール/関数呼び出しを可視化する
クイックスタート
50行未満で作成する、最小限のAIチャットインターフェース:
import { useChat } from 'ai/react';
export function MinimalAIChat() {
const { messages, input, handleInputChange, handleSubmit, isLoading, stop } = useChat();
return (
<div className="chat-container">
<div className="messages">
{messages.map(m => (
<div key={m.id} className={`message ${m.role}`}>
<div className="content">{m.content}</div>
</div>
))}
{isLoading && <div className="thinking">AI is thinking...</div>}
</div>
<form onSubmit={handleSubmit} className="input-form">
<input
value={input}
onChange={handleInputChange}
placeholder="Ask anything..."
disabled={isLoading}
/>
{isLoading ? (
<button type="button" onClick={stop}>Stop</button>
) : (
<button type="submit">Send</button>
)}
</form>
</div>
);
}
ストリーミング Markdown を使った完全な実装については、examples/basic-chat.tsx を参照してください。
コアコンポーネント
メッセージ表示
ストリーミングに対応したユーザー、AI、システムのメッセージバブルを作成します。
// User message
<div className="message user">
<div className="content">{message.content}</div>
<time className="timestamp">{formatTime(message.timestamp)}</time>
</div>
// AI message with streaming
<div className="message ai">
<Streamdown className="content">{message.content}</Streamdown>
{message.isStreaming && <span className="cursor">▊</span>}
</div>
// System message
<div className="message system">
<Icon type="info" />
<span>{message.content}</span>
</div>
Markdown のレンダリング、コードブロック、書式設定の詳細については、references/message-components.md を参照してください。
入力コンポーネント
添付ファイルや音声に対応した、使いやすい入力機能を作成します。
<div className="input-container">
<button onClick={attachFile} aria-label="Attach file">
<PaperclipIcon />
</button>
<textarea
value={input}
onChange={handleChange}
onKeyDown={handleKeyDown}
placeholder="Type a message..."
rows={1}
style={{ height: textareaHeight }}
/>
<button onClick={toggleVoice} aria-label="Voice input">
<MicIcon />
</button>
<button type="submit" disabled={!input.trim() || isLoading}>
<SendIcon />
</button>
</div>
応答コントロール
AI の応答に欠かせないコントロール:
<div className="response-controls">
{isStreaming && (
<button onClick={stop} className="stop-btn">
Stop generating
</button>
)}
{!isStreaming && (
<>
<button onClick={regenerate} aria-label="Regenerate response">
<RefreshIcon /> Regenerate
</button>
<button onClick={continueGeneration} aria-label="Continue">
Continue
</button>
<button onClick={editMessage} aria-label="Edit message">
<EditIcon /> Edit
</button>
</>
)}
</div>
フィードバック機能
AI の応答を改善するために、ユーザーからフィードバックを収集します。
<div className="feedback-controls">
<button
onClick={() => sendFeedback('positive')}
aria-label="Good response"
className={feedback === 'positive' ? 'selected' : ''}
>
<ThumbsUpIcon />
</button>
<button
onClick={() => sendFeedback('negative')}
aria-label="Bad response"
className={feedback === 'negative' ? 'selected' : ''}
>
<ThumbsDownIcon />
</button>
<button onClick={copyToClipboard} aria-label="Copy">
<CopyIcon />
</button>
<button onClick={share} aria-label="Share">
<ShareIcon />
</button>
</div>
ストリーミングとリアルタイム UX
AI の応答を段階的にレンダリングするには、特別な処理が必要です。
// Use Streamdown for AI streaming (handles incomplete markdown)
import { Streamdown } from '@vercel/streamdown';
// Auto-scroll management
useEffect(() => {
if (shouldAutoScroll()) {
messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
}
}, [messages]);
// Smart auto-scroll heuristic
function shouldAutoScroll() {
const threshold = 100; // px from bottom
const isNearBottom =
container.scrollHeight - container.scrollTop - container.clientHeight < threshold;
const userNotReading = !hasUserScrolledUp && !isTextSelected;
return isNearBottom && userNotReading;
}
ストリーミングの完全なパターン、自動スクロールの動作、生成の停止については、references/streaming-ux.md を参照してください。
コンテキスト管理
トークン上限をユーザーに明確に伝えます。
// User-friendly token display
function TokenIndicator({ used, total }) {
const percentage = (used / total) * 100;
const remaining = total - used;
return (
<div className="token-indicator">
<div className="progress-bar">
<div className="progress-fill" style={{ width: `${percentage}%` }} />
</div>
<span className="token-text">
{percentage > 80
? `⚠️ About ${Math.floor(remaining / 250)} messages left`
: `${Math.floor(remaining / 250)} pages of conversation remaining`}
</span>
</div>
);
}
要約の戦略、会話の分岐、整理方法については、references/context-management.md を参照してください。
マルチモーダル対応
画像、ファイル、音声入力を処理します。
// Image upload with preview
function ImageUpload({ onUpload }) {
return (
<div
className="upload-zone"
onDrop={handleDrop}
onDragOver={preventDefault}
>
<input
type="file"
accept="image/*"
onChange={handleFileSelect}
multiple
hidden
ref={fileInputRef}
/>
{previews.map(preview => (
<img key={preview.id} src={preview.url} alt="Upload preview" />
))}
</div>
);
}
音声や画面共有を含む、マルチモーダル対応の完全なパターンについては、references/multi-modal.md を参照してください。
エラー処理
AI 固有のエラーを適切に処理します。
// Refusal handling
if (response.type === 'refusal') {
return (
<div className="error refusal">
<Icon type="info" />
<p>I cannot help with that request.</p>
<details>
<summary>Why?</summary>
<p>{response.reason}</p>
</details>
<p>Try asking: {response.suggestion}</p>
</div>
);
}
// Rate limit communication
if (error.code === 'RATE_LIMIT') {
return (
<div className="error rate-limit">
<p>Please wait {error.retryAfter} seconds</p>
<CountdownTimer seconds={error.retryAfter} onComplete={retry} />
</div>
);
}
エラーパターンの詳細については、references/error-handling.md を参照してください。
ツール使用状況の可視化
AI がツールや関数を使用していることを表示します。
function ToolUsage({ tool }) {
return (
<div className="tool-usage">
<div className="tool-header">
<Icon type={tool.type} />
<span>{tool.name}</span>
{tool.status === 'running' && <Spinner />}
</div>
{tool.status === 'complete' && (
<details>
<summary>View details</summary>
<pre>{JSON.stringify(tool.result, null, 2)}</pre>
</details>
)}
</div>
);
}
関数呼び出し、コード実行、ウェブ検索のパターンについては、references/tool-usage.md を参照してください。
実装ガイド
推奨スタック
主要ライブラリ(2025年11月に検証済み):
# Core AI chat functionality
npm install ai @ai-sdk/react @ai-sdk/openai
# Streaming markdown rendering
npm install @vercel/streamdown
# Syntax highlighting
npm install react-syntax-highlighter
# Security for LLM outputs
npm install dompurify
パフォーマンスの最適化
スムーズなストリーミングには不可欠です。
// Memoize message rendering
const MemoizedMessage = memo(Message, (prev, next) =>
prev.content === next.content && prev.isStreaming === next.isStreaming
);
// Debounce streaming updates
const debouncedUpdate = useMemo(
() => debounce(updateMessage, 50),
[]
);
// Virtual scrolling for long conversations
import { VariableSizeList } from 'react-window';
パフォーマンスパターンの詳細については、references/streaming-ux.md を参照してください。
セキュリティに関する考慮事項
AI の出力は必ずサニタイズしてください。
import DOMPurify from 'dompurify';
function SafeAIContent({ content }) {
const sanitized = DOMPurify.sanitize(content, {
ALLOWED_TAGS: ['p', 'br', 'strong', 'em', 'code', 'pre', 'blockquote', 'ul', 'ol', 'li'],
ALLOWED_ATTR: ['class']
});
return <Streamdown>{sanitized}</Streamdown>;
}
アクセシビリティ
誰もがAIチャットを使えるようにします。
// ARIA live regions for screen readers
<div role="log" aria-live="polite" aria-relevant="additions">
{messages.map(msg => (
<article key={msg.id} role="article" aria-label={`${msg.role} message`}>
{msg.content}
</article>
))}
</div>
// Loading announcements
<div role="status" aria-live="polite" className="sr-only">
{isLoading ? 'AI is responding' : ''}
</div>
アクセシビリティ対応の完全なパターンについては、references/accessibility.md を参照してください。
同梱リソース
スクリプト(トークンを消費しない実行)
scripts/parse_stream.jsを実行して、ストリーミング中の未完成な Markdown を解析しますscripts/calculate_tokens.pyを実行して、トークン使用量とコンテキスト上限を推定しますscripts/format_messages.jsを実行して、エクスポート用にメッセージ履歴を整形します
リファレンス(段階的な情報開示)
references/streaming-patterns.md- ストリーミング UX の完全なパターンreferences/context-management.md- トークン上限と会話の戦略references/multimodal-input.md- 画像、ファイル、音声の処理references/feedback-loops.md- ユーザーフィードバックと RLHF のパターンreferences/error-handling.md- AI 固有のエラーシナリオreferences/tool-usage.md- 関数呼び出しとツール使用状況の可視化references/accessibility-chat.md- スクリーンリーダーとキーボードのサポートreferences/library-guide.md- ライブラリの詳細なドキュメントreferences/performance-optimization.md- ストリーミングのパフォーマンスパターン
例
examples/basic-chat.tsx- ChatGPT 風の最小限のインターフェースexamples/streaming-chat.tsx- メモ化を活用した高度なストリーミングexamples/multimodal-chat.tsx- 画像とファイルのアップロードexamples/code-assistant.tsx- IDE 風のコードコパイロットexamples/tool-calling-chat.tsx- 関数呼び出しの可視化
アセット
assets/system-prompts.json- さまざまなユースケース向けに厳選したプロンプトassets/message-templates.json- すぐに使えるメッセージコンポーネントassets/error-messages.json- ユーザーにわかりやすいエラーメッセージassets/themes.json- ライト、ダーク、高コントラストのテーマ
デザイントークンとの統合
すべてのビジュアルスタイルにデザイントークンシステムを使用しています。
/* Message bubbles use design tokens */
.message.user {
background: var(--message-user-bg, var(--color-primary));
color: var(--message-user-text, var(--color-white));
padding: var(--message-padding, var(--spacing-md));
border-radius: var(--message-border-radius, var(--radius-lg));
}
.message.ai {
background: var(--message-ai-bg, var(--color-gray-100));
color: var(--message-ai-text, var(--color-text-primary));
}
テーマ設定システムの詳細については、skills/design-tokens/ をご覧ください。
主な革新
このスキルでは、業界初の次のソリューションを提供します。
- メモ化ストリーミングレンダリング - パフォーマンスを10~50倍向上
- インテリジェントな自動スクロール - ユーザーのアクティビティに応じたスクロール
- トークンの比喩表現 - ユーザーにわかりやすいコンテキストの説明
- 未完成のMarkdownへの対応 - 部分的なレンダリングを適切に処理
- RLHFパターン - 効果的なフィードバック収集
- 会話の分岐 - 非線形の会話ツリー
- マルチモーダル統合 - ファイル、画像、音声をシームレスに処理
- アクセシビリティ優先 - スクリーンリーダーを標準でサポート
戦略的重要性
これが最も重要なスキルである理由は次のとおりです。
- 絶好のタイミング - AIを導入するアプリが急増する時期(2024~2025年)
- 標準が存在しない - パターンを定義するチャンス
- メタ的な優位性 - Claude と共に構築することで、UXを深く理解
- 固有の課題 - ストリーミング、コンテキスト、ハルシネーションはいずれも新しい課題
- リファレンス実装 - 他の人が従う標準になる可能性
このスキルを習得して、AIインターフェースの革新をリードしましょう。