Agent Skills by ALSEL
Anthropic ClaudeLLM・AI開発⭐ リポ 0品質スコア 50/100

ai-ui-patterns

AIを活用したReactインターフェース構築のデザインパターンを提供します。チャットボット、インテリジェントアシスタント、ストリーミングUI、その他あらゆるAI駆動のユーザー体験をReactで実装する際に活用してください。

description の原文を見る

Teaches design patterns for building AI-powered React interfaces. Use when creating chatbots, intelligent assistants, streaming UIs, or any AI-driven user experience in React.

SKILL.md 本文

AI UI Patterns

Table of Contents

AI を搭載したインターフェース(チャットボットからインテリジェントアシスタントまで)を構築するには、バックエンド AI サービスをリアクティブな UI コンポーネントと慎重に統合する必要があります。このチャプターでは、そのようなインターフェース用の React デザインパターンを探究し、2 つの実装(Vite を使った vanilla React アプリと Next.js アプリ)に焦点を当てます。AI エンジンとして OpenAI の API(Vercel AI SDK 経由)を使用し、スタイリングは TailwindCSS を使用します。主なトピックには、プロンプト管理、ストリーミング応答、入力デバウンス、エラーハンドリング、および Vite と Next.js の間でのパターンの違いが含まれます。また、再利用可能なコンポーネントパターンと、**Vercel の AI UI コンポーネント(AI Elements)**を強調し、洗練されたチャット UI の構築に役立てます。

When to Use

  • LLM からの応答をストリーミングする会話型 AI インターフェースを構築する場合に使用します
  • OpenAI、Anthropic、またはその他の AI プロバイダーを React アプリケーションに統合するのに役立ちます
  • プロンプト管理、ストリーミング、エラーハンドリング、AI 固有の UI のパターンが必要な場合に使用します

Instructions

  • Vercel AI SDK の useChat フックを使用して、会話状態とストリーミング応答を管理します
  • API キーはサーバーに保持します。AI 呼び出しには Next.js API ルートまたは別のバックエンドを使用します
  • ストリーミングを有効にします(stream: true)。チャットインターフェースでリアルタイムの応答性あるアウトプットを実現します
  • オートコンプリート機能の入力をデバウンスします。チャットでは応答ストリーミング中に入力を無効にします
  • 再利用可能なコンポーネント(ChatMessage、InputBox)を構築し、データ取得ロジックから分離します

Details

Note: このアーティクルは例として OpenAI を使用していますが、Vercel AI SDK は GeminiOpenAIAnthropic を含む複数のモデルプロバイダーをサポートしています。SDK の統一インターフェースを通じてプロバイダー間を簡単に切り替えることができます。デモンストレーション目的で 1 つのオプションを選択しているだけです。

Introduction: AI Interfaces in React

LLM(ChatGPT など)の台頭により、AI 駆動ユーザーインターフェース(UI)が人気を集めています。従来の UI とは異なり、AI インターフェースには、会話型の相互作用、動的コンテンツストリーミング、非同期バックエンド呼び出しが含まれることが多いです。これは React 開発者にとって独特な課題とパターンをもたらします。典型的な AI チャットインターフェースは、フロントエンド(ユーザー入力と応答表示用)とバックエンド(AI モデル呼び出し用)で構成されます。セキュリティとパフォーマンスのため、API キーと重い処理をクライアントから離すことが不可欠です。Vercel の AI SDK などのツールにより、プロバイダー(OpenAI、HuggingFace など)への接続と、リアルタイムでの応答ストリーミングが容易になります。Next.js アプリと Vite(React)アプリの両方を設定して、これらの懸念に対処する方法を探究し、両方に適用される最良の実践について説明します。

カバーされる主要パターン:

  • AI プロンプトデータの構造化と会話状態の管理
  • AI 応答を UI にストリーミングし、リアルタイムフィードバックを実現
  • ユーザー入力をデバウンスして、API スパムを回避
  • AI UI でのエラーハンドリングとフォールバック
  • メッセージ、入力など、その他の再利用可能な UI コンポーネント(TailwindCSS を使用)
  • アーキテクチャの違い:Next.js ルートハンドラー対 Vite とノードバックエンド

終了時には、Next.js を好むか Vite ツールチェーンを好むかに関わらず、React で応答性が高く堅牢な AI 駆動 UI を構築する準備が整います。

Project Setup and Tools

コードに進む前に、必要なパッケージと構成があることを確認してください:

  • React & Vite: Vite + React プロジェクトを初期化します(例:npm create vite@latest my-ai-app -- --template react)。Next.js の場合、npx create-next-app または Next 13 App Router テンプレートを使用できます。どちらでも動作します。進むにつれて違いを強調します。

  • TailwindCSS: プロジェクトで Tailwind を設定し、素早くスタイリングを行います。

  • OpenAI API & Vercel AI SDK: OpenAI のライブラリまたは Vercel AI SDK をインストールします。Vercel の AI SDKnpm i ai)を使用します。これは、有用な React フック(useChatuseCompletion)とサーバーユーティリティを提供します。この SDK はフレームワーク非依存であり、Next.js、vanilla React、Svelte など様々で動作します。ストリーミングと状態管理を簡潔にし、無料でオープンソースです。

  • API Keys: OpenAI ダッシュボードから OpenAI API キーを取得し、安全に保存します。Next.js では、.env.local に入力します(例:OPENAI_API_KEY=sk-...)。絶対にコミットしないでください。Vite アプリでは、クライアントコードにキーを公開しないでください。代わりに、バックエンドプロキシまたはサーバー上の環境変数を使用します。

Setting Up AI Endpoints (Next.js vs. Vite)

Next.js Implementation: Next.js により、ルートハンドラーをサーバーレス関数として作成できます。React フロントエンドが AI 応答を呼び出す API ルートを定義できます:

// app/api/chat/route.ts (Next.js)
import { Configuration, OpenAIApi } from 'openai-edge';
import { OpenAIStream, StreamingTextResponse } from 'ai';

export const runtime = 'edge';

const config = new Configuration({ apiKey: process.env.OPENAI_API_KEY });
const openai = new OpenAIApi(config);

export async function POST(req: Request) {
  const { messages } = await req.json();
  const response = await openai.createChatCompletion({
    model: 'gpt-3.5-turbo',
    stream: true,
    messages: messages.map((m: any) => ({ role: m.role, content: m.content }))
  });
  const stream = OpenAIStream(response);
  return new StreamingTextResponse(stream);
}

このハンドラーでは、メッセージの配列(チャット履歴)を含む JSON ボディを受け取ります。stream: true を使用して OpenAI のチャット完了を呼び出し、ストリーミング応答を取得します。その後、AI SDK によって提供される StreamingTextResponse でレスポンスをラップし、それをチャンクで クライアントに戻します。Next.js API ルートは API キーをサーバーに保持し、データを効率的にストリーミングします。

Vite (React) Implementation: Vite アプリには組み込みサーバーがないため、OpenAI 呼び出し用に独自のバックエンドを作成する必要があります。これは単純な Node/Express サーバーの場合があります:

// backend/server.js (Node/Express for Vite app)
import express from 'express';
import { Configuration, OpenAIApi } from 'openai';

const app = express();
app.use(express.json());

const config = new Configuration({ apiKey: process.env.OPENAI_API_KEY });
const openai = new OpenAIApi(config);

app.post('/api/chat', async (req, res) => {
  try {
    const { messages = [] } = req.body;
    const systemMsg = { role: 'system', content: 'You are a helpful assistant.' };
    const inputMessages = [systemMsg, ...messages];
    const response = await openai.createChatCompletion({
      model: 'gpt-3.5-turbo',
      stream: false,
      messages: inputMessages
    });
    const content = response.data.choices[0].message?.content;
    res.json({ content });
  } catch (err) {
    console.error(err);
    res.status(500).json({ error: 'Internal Server Error' });
  }
});

app.listen(6000, () => console.log('API server listening on http://localhost:6000'));

開発中、Vite 開発サーバーを設定して、/api 呼び出しをこのバックエンドにプロキシできます(例:vite.config.jsserver.proxy['/api'] = 'http://localhost:6000' を設定)。重要なのは、React アプリが相対 /api/chat エンドポイントを呼び出し、プロキシ/ホスティングがそれをサーバーコードにルーティングすることです。これにより OpenAI キーが隠されます。

Node でのストリーミング有効化: 上記の Express の例は、完了後に完全な応答を返します(簡潔さのため stream: false)。Node でストリーミングするには、OpenAI の HTTP ストリームを使用できます:stream: true を設定し、応答をデータストリームとして処理します。これには、response.data ストリームを読み取り、res.write() を使用してクライアントにチャンクをフラッシュすることが含まれます。完全な応答を使用する(ストリーミングなし)場合、UI パターンは依然としてほぼ同じですが、ストリーミングは UX を大幅に改善します。

Prompt Handling and Conversation State

あらゆる AI インターフェースの中核は、プロンプト管理です。ユーザー入力(および コンテキスト)を AI モデル用のプロンプトまたはメッセージシーケンスに組み立てます。チャットシナリオでは、メッセージのリストを保持します。各メッセージには役割とコンテンツがあります。OpenAI のチャット API は、{ role: 'user' | 'assistant' | 'system', content: string } 形式のメッセージを想定しています。通常、システムメッセージ(アシスタントの動作やコンテキストを設定するため)から始まり、会話が進むにつれてユーザーとアシスタントのメッセージが交互に続きます。

React での状態管理: コンポーネント状態で会話を保存できます。Vercel SDK の React フックを使用します:

import { useChat } from 'ai/react';

function ChatInterface() {
  const { messages, input, handleInputChange, handleSubmit } = useChat();
  // ...
}

useChat フックは多くのことを処理します。messages 状態(メッセージオブジェクトの配列)、input 状態(現在のテキスト入力用)を管理し、handleInputChangehandleSubmit ヘルパーを提供します。デフォルトでは、useChat() は送信時に /api/chat に POST します。

手動状態処理: useChat を使用していない場合、useState またはコンテキストで状態を管理できます。フォーム送信で API を呼び出し、メッセージ配列にユーザークエリとアシスタントの応答を追加して更新します。

システムプロンプトとコンテキスト: 一般的なパターンは、アシスタントの役割や知識ベースを説明するシステムメッセージの初期化です。例えば、ドキュメントヘルパーを構築している場合、システムコンテンツは「ドキュメントアシスタントです。ドキュメントの例を使用して回答してください。」かもしれません。

単一ターンと複数ターン: インターフェースが単一の質問応答(会話メモリなし)の場合、Vercel SDK の useCompletion フックを代わりに使用できます。チャットボットと複数ターンダイアログの場合、useChat がゴーツーパターンです。メッセージ履歴を保持し、各リクエストで送信するため。

Streaming AI Responses to the UI

現代的な AI UI の特徴は、出力ストリーミングです。AI がトークンを生成するにつれて、ユーザーはリアルタイムで応答が表示されるのを見ます。これは、モデルで生成された回答は長くなったり遅くなったりする可能性があるため、より良い UX のために重要です。沈黙で多くの秒を待つ代わりに、ストリーミングで部分的な結果をすぐに表示できます。

ストリーミングがどのように機能するか: OpenAI API で stream: true を有効にすると、応答は 1 つの JSON ブロブではなく、チャンク(データイベント)のシーケンスとして送信されます。Vercel AI SDK がこれらのチャンクの使用を簡潔にしています。サーバー上で、レスポンスをテキストストリーム(StreamingTextResponse)に変換しました。クライアント側では、useChat フックはこのストリームを読み取り、新しいテキストが到着するにつれてメッセージ状態を段階的に更新することを処理します。

SDK なしで React でストリーミングを手動で実装する場合、次のようなことをするでしょう:

const res = await fetch('/api/chat', { method: 'POST', body: JSON.stringify({ messages }) });
const reader = res.body.getReader();
const decoder = new TextDecoder();
let partial = "";
while(true) {
  const { value, done } = await reader.read();
  if (done) break;
  partial += decoder.decode(value);
  setAssistantMessage(partial);
}

自動スクロール: ストリーミング時の UX の詳細の 1 つは、最新メッセージが表示されていることを確認することです。これを処理するパターンは、メッセージ配列の長さを監視する useEffect でメッセージコンテナを自動スクロールしることです。

部分的なレンダリングと完成: ストリーミング中の視覚的インジケーターを表示します。例えば、点滅するカーソルまたは「AI が入力しています…」メッセージ。ストリームが完了したら、メッセージ表示を確定します。

Input Handling and Debouncing

チャット相互作用では、通常、ユーザーがフォームを送信するときにクエリを送信します。しかし、一部の AI アプリケーションでは、継続的に入力に反応したいことがあります。例えば、オートコンプリート提案AI による リアルタイム検証。そのような場合、デバウンスが重要です。

なぜデバウンス? キーストロークのたびに OpenAI API を呼び出すのは非常に非効率で、コストがかかります。デバウンスは、ユーザーが短期間入力を停止するまで API 呼び出しを遅延させます。

const [draft, setDraft] = useState("");

useEffect(() => {
  if (!draft) return;
  const timeout = setTimeout(() => {
    getSuggestion(draft);
  }, 500);
  return () => clearTimeout(timeout);
}, [draft]);

明示的な「送信」アクションを含むシンプルなチャットボットでは、デバウンスは通常不要です。ユーザーが Enter キーを押すと送信します。ただし、AI の応答が進行中に入力を無効にするまたは複数送信を防止することは依然として有用です。

Error Handling and Resilience

AI アプリケーションでは堅牢なエラーハンドリングが重要です:

  • API 呼び出し周辺の Try/Catch: サーバー上で、OpenAI 呼び出しを try/catch でラップします。何かが失敗した場合、適切なエラー応答を返します。

  • クライアント側のエラー状態: 応答がエラーを示す場合を処理します。

try {
  await sendMessage({ text: input });
} catch (error) {
  console.error("Failed to send message:", error);
}
  • ユーザーフィードバック: 何か問題が発生したときは、常にユーザーに知らせてください。エラーをチャットにインラインで表示します。例えば、「申し訳ございません。問題が発生しました。もう一度お試しください。」という特別な「システム」メッセージとしてです。

  • 再試行メカニズム: ユーザーが「もう一度試す」ボタンで再試行できることを検討してください。

  • 検証エラー: API を呼び出す前にクライアントで検証します。空の入力で送信を無効にするか、一定の長さを超える入力を切り詰めます。

Building the UI: Components and Styling Patterns

チャットメッセージコンポーネント: 単一のメッセージバブルをレンダリングする ChatMessage コンポーネントを作成します。役割に基づいて、異なるスタイルを適用します:

function ChatMessage({ role, content }) {
  const isUser = role === 'user';
  return (
    <div className={`flex ${isUser ? 'justify-end' : 'justify-start'} mb-2`}>
      <div className={`max-w-xl px-4 py-2 rounded-lg ${
        isUser ? 'bg-blue-500 text-white' : 'bg-gray-200 text-gray-900'
      }`}>
        {content}
      </div>
    </div>
  );
}

入力コンポーネント:

function InputBox({ value, onChange, onSubmit, disabled }) {
  return (
    <form onSubmit={onSubmit} className="flex gap-2">
      <input
        type="text"
        value={value}
        onChange={onChange}
        disabled={disabled}
        className="flex-1 border rounded px-3 py-2"
        placeholder="Type your message..."
      />
      <button type="submit" disabled={disabled} className="bg-blue-500 text-white px-4 py-2 rounded">
        Send
      </button>
    </form>
  );
}

構成:

function ChatInterface() {
  const { messages, input, handleInputChange, handleSubmit, isLoading } = useChat();
  
  return (
    <div className="flex flex-col h-screen max-w-2xl mx-auto p-4">
      <div className="flex-1 overflow-y-auto">
        {messages.map((msg, i) => (
          <ChatMessage key={i} role={msg.role} content={msg.content} />
        ))}
      </div>
      <InputBox 
        value={input} 
        onChange={handleInputChange} 
        onSubmit={handleSubmit}
        disabled={isLoading}
      />
    </div>
  );
}

この関心の分離により、UI パーツのテストと交換が容易になります。ロジック(useChat)は表示コンポーネントから分離されています。

Vercel AI Elements (Pre-Built Chat UI Components)

Vercel の AI Elements ライブラリは、AI チャットインターフェース用に特別に設計された一連のすぐに使える React コンポーネントを提供します:

  • Conversation: メッセージのリストを自動スクロール機能でレンダリングするコンテナ。
  • Prompt: チャットプロンプト用に最適化された入力コンポーネント。
  • TypingIndicator: AI が「考えている」またはストリーミング応答を表示している場合を表示します。
  • ErrorBoundary/ErrorMessage: エラーを適切に処理して表示します。
import { Conversation, Prompt, TypingIndicator } from '@vercel/ai-elements';

function ChatApp() {
  const { messages, input, handleInputChange, handleSubmit, isLoading } = useChat();
  
  return (
    <div className="h-screen flex flex-col">
      <Conversation messages={messages} />
      {isLoading && <TypingIndicator />}
      <Prompt 
        value={input} 
        onChange={handleInputChange} 
        onSubmit={handleSubmit}
      />
    </div>
  );
}

Putting It All Together

  1. バックエンド API ルート: Next.js ルートハンドラーを使用している場合でも、別の Express サーバーを使用している場合でも、メッセージを受け取り、AI モデルを呼び出し、応答をストリーミングして戻すエンドポイントを作成します。

  2. 状態管理: Vercel AI SDK の useChat フック(または useState で独自に作成)を使用して、会話状態を管理します。

  3. ストリーミング: サーバーとクライアント両方でストリーミングを有効にして、応答性の高い UX を実現します。

  4. デバウンスとレート制限: オートコンプリートなどの機能の場合、API 呼び出しをデバウンスします。チャットの場合、応答ストリーミング中に入力を無効にします。

  5. エラーハンドリング: API 呼び出しを try/catch でラップし、エラーについてユーザーフィードバックを提供し、再試行メカニズムを検討します。

  6. 再利用可能なコンポーネント: プレゼンテーションコンポーネント(ChatMessageInputBox)を構築し、データ取得ロジックから分離します。本番環境対応コンポーネントには AI Elements の使用を検討してください。

  7. スタイリング: TailwindCSS(またはお好みのスタイリングソリューション)を使用して、クリーンで応答性の高いチャットインターフェースを作成します。

Architectural Comparison: Next.js vs. Vite

要素Next.jsVite + Node Backend
API Routes組み込み(pages/api/ または app/api/別の Express/Node サーバーが必要
ストリーミングEdge Runtime でのネイティブサポートres.write() での手動実装
デプロイVercel(最適化)またはセルフホストフロントエンド(スタティック)とバックエンドを別々にデプロイ
複雑さ低(オールインワン)高(2 つのコードベース)
柔軟性フレームワーク規約完全な制御

ほとんどの AI チャットアプリケーションでは、Next.js は統合 API ルートとストリーミングサポートにより、より シンプルな開発者エクスペリエンスを提供します。ただし、既存の Vite/React アプリがある場合、またはより多くの制御を望む場合、ここで説明するパターンは別のバックエンドでもよく機能します。

Source

References

ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ

詳細情報

作者
patternsdev
リポジトリ
patternsdev/skills
ライセンス
MIT
最終更新
不明

Source: https://github.com/patternsdev/skills / ライセンス: MIT

関連スキル

OpenAILLM・AI開発⭐ リポ 6,054

agent-browser

AI エージェント向けのブラウザ自動化 CLI です。ウェブサイトとの対話が必要な場合に使用します。ページ遷移、フォーム入力、ボタンクリック、スクリーンショット取得、データ抽出、ウェブアプリのテスト、ブラウザ操作の自動化など、あらゆるブラウザタスクに対応できます。「ウェブサイトを開く」「フォームに記入する」「ボタンをクリックする」「スクリーンショットを取得する」「ページからデータを抽出する」「このウェブアプリをテストする」「サイトにログインする」「ブラウザ操作を自動化する」といった要求や、プログラマティックなウェブ操作が必要なタスクで起動します。

by JimmyLv
汎用LLM・AI開発⭐ リポ 1,982

anyskill

AnySkill — あなたのプライベート・スキルクラウド。GitHubを基盤としたリポジトリからエージェントスキルを管理、同期、動的にロードできます。自然言語でクラウドスキルを検索し、オンデマンドでプロンプトを自動ロード、カスタムスキルのアップロードと共有、スキルバンドルの一括インストールが可能です。OpenClaw、Antigravity、Claude Code、Cursorに対応しています。

by LeoYeAI
汎用LLM・AI開発⭐ リポ 1,982

engram

AIエージェント向けの永続的なメモリシステムです。バグ修正、意思決定、発見、設定変更の後はmem_saveを使用してください。ユーザーが「覚えている」「記憶している」と言及した場合、または以前のセッションと重複する作業を開始する際はmem_searchを使用します。セッション終了前にmem_session_summaryを使用して、コンテキストを保持してください。

by LeoYeAI
汎用LLM・AI開発⭐ リポ 21,584

skyvern

AI駆動のブラウザ自動化により、任意のウェブサイトを自動化できます。フォーム入力、データ抽出、ファイルダウンロード、ログイン、複数ステップのワークフロー実行など、ユーザーがウェブサイトと連携する必要があるときに使用します。Skyvernは、LLMとコンピュータビジョンを活用して、未知のサイトも自動操作可能です。Python SDK、TypeScript SDK、REST API、MCPサーバー、またはCLIを通じて統合できます。

by Skyvern-AI
汎用LLM・AI開発⭐ リポ 1,149

pinchbench

PinchBenchベンチマークを実行して、OpenClawエージェントの実世界タスクにおけるパフォーマンスを評価できます。モデルの機能テスト、モデル間の比較、ベンチマーク結果のリーダーボード提出、またはOpenClawのセットアップがカレンダー、メール、リサーチ、コーディング、複数ステップのワークフローにどの程度対応しているかを確認する際に使用します。

by pinchbench
汎用LLM・AI開発⭐ リポ 4,693

openui

OpenUIとOpenUI Langを使用してジェネレーティブUIアプリを構築できます。これらはLLM生成インターフェースのためのトークン効率的なオープン標準です。OpenUI、@openuidev、ジェネレーティブUI、LLMからのストリーミングUI、AI向けコンポーネントライブラリ、またはjson-render/A2UIの置き換えについて述べる際に使用します。スキャフォルディング、defineComponent、システムプロンプト、Renderer、およびOpenUI Lang出力のデバッグに対応しています。

by thesysdev
本サイトは GitHub 上で公開されているオープンソースの SKILL.md ファイルをクロール・インデックス化したものです。 各スキルの著作権は原作者に帰属します。掲載に問題がある場合は info@alsel.co.jp または /takedown フォームよりご連絡ください。
原作者: patternsdev · patternsdev/skills · ライセンス: MIT