【React × Gemini API】AIキャラクターチャットを作りました

技術

こんにちは。
今回は、ReactとNext.jsを使って「AIキャラクターチャットアプリ」を作ったので、その制作過程を紹介します。


🎯 作ろうと思ったきっかけ

AIチャットのアプリはたくさんありますが、
どれも「汎用的なAIとの会話」が中心でした。

そこで私は思いました。

自分だけのキャラクターと会話できるアプリがあれば面白いのでは?

たとえば、幼なじみ風・先生風・同級生風のキャラクターを作り、
その性格や口調、関係性を設定して会話できるようにしたら…。
―― そうしてこの「AIキャラクターチャット」が生まれました。


🧩 アプリの概要

このアプリは、ユーザーが設定したキャラクターと
リアルタイムで自然な会話ができるReactアプリです。


💡 主な機能

  • 🎨 キャラクター設定(名前・性格・口調・関係性・背景)
  • 🧍 あなたの名前を保存して呼びかけ対応
  • 💬 LINE風のチャットUI
  • ⚙️ Gemini APIを使ったAI応答生成
  • 💾 localStorageで設定の永続化
  • 🪶 Zustandを使った軽量状態管理

⚙️ 使用技術

  • ⚛️ React 18:コンポーネント構築とUIレンダリング
  • 🌐 Next.js 14 (App Router):ページ構成とAPIルートの管理
  • 🧩 TypeScript:型安全なReact開発を実現
  • 🎨 Tailwind CSS:柔軟でスピーディなスタイリング
  • 🔄 Zustand:React Hooksベースの軽量状態管理
  • 🤖 Gemini API:キャラクターの会話を生成するAIエンジン
  • 💾 localStorage:キャラ設定やユーザー名を永続保存

🧠 React構成のポイント

アプリはすべてReact Hooksで構築しました。
グローバル状態管理には Zustand を採用し、Reduxより軽量な構成にしています。

const { messages, addMessage, character } = useChatStore();
const [input, setInput] = useState("");

return (
  <div className="chat-container">
    {messages.map((m, i) => (
      <div key={i} className={m.role === "user" ? "user" : "assistant"}>
        <span>{m.content}</span>
      </div>
    ))}
    <input
      value={input}
      onChange={(e) => setInput(e.target.value)}
      onKeyDown={(e) => e.key === "Enter" && addMessage({ role: "user", content: input })}
    />
  </div>
);

useEffect と useRef でスクロール制御、
localStorage でキャラ設定を保持することで、
リロードしても前回の会話が再現されます。


🧍 キャラクター設定の仕組み

キャラ設定画面では、以下をユーザーが自由に入力できます:

  • 名前
  • 性格
  • 口調
  • 関係性
  • 背景設定
  • あなたの名前

さらにテンプレートボタンで、

  • 🎀 幼なじみツンデレ
  • 📘 優しい先生
  • 🌟 明るい同級生

をワンクリックで生成できます。

設定した内容は localStorage に保存され、
リロードしてもすぐにチャットを再開可能です。


💬 AIとの会話生成(Gemini API)

AIの応答は、Googleの Gemini 2.0 Flash を使っています。

const endpoint =
  "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent";

const res = await fetch(`${endpoint}?key=${apiKey}`, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    contents: [{ parts: [{ text: prompt }] }],
    generationConfig: { temperature: 0.8, maxOutputTokens: 800 },
  }),
});

プロンプトには、
ユーザー設定のキャラクター情報と会話履歴をすべて含めて送信。
そのため、キャラごとに性格・口調が変わる自然な会話が生まれます。


🎨 UIデザインへのこだわり

Tailwind CSSで全体を設計しました。
LINE風の吹き出し、アイコン、入力バーなど、
実際のチャットアプリに近い使いやすさを目指しました。

  • 吹き出しの形は rounded-br-none / rounded-bl-none で左右差を表現
  • 送信ボタンは hover:bg-green-600 で軽いアニメーション
  • 配色は「緑×白×グレー」でフレンドリーな印象に統一

🔧 工夫した点・苦労した点

💬 Enterキー誤送信の対策

日本語入力中(変換中)にEnterを押しても送信されないよう
onCompositionStart / onCompositionEnd を実装。

💾 localStorageの安全な読み込み

SSR環境でも動作するように、typeof window !== “undefined” をチェック。

⚙️ APIエラーハンドリング

ネットワークエラー時は「AIが沈黙している」などのメッセージを返してUXを維持。


📸 最終完成イメージ


📦 GitHubで公開中

👉 GitHubリポジトリを見る


✨ 今後の展望

  • キャラクター画像の自動生成(AIアバター)
  • 会話履歴の永続化
  • PWA化でスマホ対応
  • 複数キャラ対応

🎓 まとめ

React × Next.js × Gemini API で、
**「自分だけのキャラと会話できるアプリ」**を作ることができました。

技術的な学びだけでなく、
UI/UX・プロンプト設計・状態管理など、
総合的な開発スキルが身についた作品です。


💬 最後に

この作品は、
「AIを使ったプロダクトを自分の手で作りたい」という思いから始まりました。

同じようにReactやAIに興味がある方の参考になれば嬉しいです。
質問などあればコメントでもぜひどうぞ!

コメント

タイトルとURLをコピーしました