Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【ITニュース解説】Building an AI Conversation Practice App: Part 3- From Simple Prompts to Database-Driven Dynamic AI Characters

2025年09月22日に「Dev.to」が公開したITニュース「Building an AI Conversation Practice App: Part 3- From Simple Prompts to Database-Driven Dynamic AI Characters」について初心者にもわかりやすく解説しています。

作成日: 更新日:

ITニュース概要

AI英会話アプリは、初期の固定的なAI応答から、データベースを用いてキャラクターの性格や状況に応じた動的なプロンプトを生成するシステムを構築した。これにより、GPT-4oがより自然で多様な会話を実現し、キャラクターの追加・変更も容易になった。

ITニュース解説

この解説は、AIとの会話練習ができる英語学習アプリをどのように開発しているかを説明するシリーズの第3弾として、特に「AIキャラクターがどのように文脈に合った、より自然で多様な応答を生成するのか」に焦点を当てたものだ。最初のシンプルな仕組みから、データベースを活用したより高度なシステムへと進化させた過程が詳しく述べられている。

まず、このアプリの核となる機能は、ユーザーが話した内容を認識し、それに対してAIが適切に、かつ人間らしい返答をすることである。開発当初、アプリの基本的な動作を確認するための最小限の機能(MVP)では、シナリオごとにAIのセリフや振る舞いをコードに直接書き込む「ハードコード」という方法を採用していた。たとえば、「ティムホートンズ」というシナリオでは「あなたはフレンドリーなティムホートンズの従業員です。親切にカナダの表現を使ってください…」といった指示をプログラム内に直接記述していたのだ。この方法は、開発の初期段階では手軽で非常に効果的だった。

しかし、アプリに登場させるシナリオやキャラクターの種類が増えるにつれて、このハードコード方式では限界が見えてきた。新しいキャラクターを追加したり、既存のキャラクターの個性を微調整したりするたびに、プログラムのコードを書き換える必要があり、作業が煩雑になるだけでなく、バグの原因にもなりかねない。そこで、将来的な拡張性(スケーラビリティ)と、キャラクターごとの多様な個性を柔軟に表現するために、データベースを活用したシステムへと大幅に刷新することになった。

新しいシステムにおけるAIキャラクターの応答生成は、いくつかのステップを経て行われる。最初に、ユーザーが選択した「シナリオのタイトル」を分析し、そのシナリオに最も適した「キャラクターの種類」をAIが自動的に判断する。次に、そのキャラクターの種類に基づいて、データベースから該当するキャラクターの詳しいプロフィール情報を引き出す。これらの情報を使って、キャラクターの個性や話し方、さらにはその場の状況(例えば、店が忙しい時間帯か、それとも比較的ゆっくりしている時間帯か)といった詳細を盛り込んだ「動的なプロンプト」が組み立てられる。そして、最終的にこのプロンプトが最先端のAIモデルである「GPT-4o」に送られ、キャラクター設定にぴったり合った自然な会話応答が生成される仕組みだ。この一連の処理にかかる時間は、ネットワーク状況にもよるが、およそ1秒から2秒程度とされている。

このシステムを支える技術要素は多岐にわたる。データベースには、PostgreSQLをベースとしたクラウドサービス「Supabase」が採用されている。AIに指示を出す「プロンプト」は、単一ではなく複数の層で構成され、動的に内容が構築される。AIモデル自体は「GPT-4o」が使われており、各キャラクター専用のプロンプトが与えられることで、より正確なキャラクター表現が可能となっている。プログラミング言語はJavaScriptが基盤となり、ウェブアプリケーションフレームワークのNext.jsのAPIルート機能が活用されている。また、データの処理中にエラーが発生しないよう、JSON形式のデータを安全に解析する機能や、データベースから情報が取得できなかった場合の代替処理(フォールバック)なども考慮されている。

初期のシンプルなプロンプトは、特定のシナリオタイトルが含まれているか否かで条件分岐する形だった。これは最初の一歩としては非常に効率的だったが、多様なキャラクターや複雑なシナリオに対応するには不十分であり、柔軟性に欠けることが課題だった。

この課題を解決するために導入されたのが、データベース駆動型のソリューションである。まず、「インテリジェントなシナリオマッピング」の仕組みが構築された。これは、与えられたシナリオタイトルから、どのキャラクターを使うべきかを自動的に判断する関数である。たとえば、「Tim Hortonsで注文する」というタイトルからは「tim_hortons」というキャラクターキーが返され、「高級レストラン」というタイトルからは「restaurant_fine」といった具体的なキャラクターが選択される。これにより、開発者が手動でキャラクターを指定する手間が省け、システムが自律的に適切なキャラクターを選べるようになった。

次に、このシステムを支える重要な要素がデータベースの設計である。キャラクターに関する情報は、以下の4つのテーブルに分けて管理されている。

  1. character_profiles:各キャラクターの基本的な情報を格納するテーブルだ。キャラクターID、シナリオキー(どのシナリオで使われるかを示すID)、キャラクター名、そしてAIに与える「ベースプロンプトテンプレート」(基本的な指示文)、「修正スタイル」(ユーザーの英語間違いをどのように訂正するか)などが含まれる。
  2. personality_traits:各キャラクターの個性に関する詳細を格納するテーブルだ。例えば、そのキャラクターがどれくらいフォーマルか、エネルギッシュか、おしゃべりか、サービス提供のスピードはどうか、といった具体的な特性がここに定義される。
  3. canadian_expressions:キャラクターが使用するカナダ特有の表現を格納するテーブルだ。挨拶、会話のつなぎの言葉、確認のフレーズなどがカテゴリ別にJSON形式で保存され、キャラクターがより自然なカナダ英語を話すための参考となる。
  4. response_patterns:特定の時間帯(忙しい時、ゆっくりしている時)や状況に応じたキャラクターの応答パターンを定義するテーブルだ。平均的な文章の長さ、質問を含めるかどうか、といった情報が含まれる。

これらのテーブルは互いに関連し合っている。一つのキャラクタープロフィールには、複数の性格特性やカナダの表現が紐付けられ、さらに時間帯に応じた複数の応答パターンが存在する。

実際にキャラクタープロンプトを生成する際には、generateCharacterPromptというサービス関数が中心的な役割を果たす。この関数は、まず指定されたシナリオキーに基づいてcharacter_profilesテーブルからキャラクターの基本情報を取得する。次に、そのキャラクターIDを使ってpersonality_traitscanadian_expressionsresponse_patternsの各テーブルから、該当するすべての情報を取得する。取得したデータは、扱いやすいようにマップ(連想配列)形式に変換され、たとえば性格特性であれば「フォーマルさ:カジュアル」「エネルギー:高」といった形で整理される。また、応答パターンは、ランダムに選ばれた「時間帯コンテキスト」(例:「忙しい時間帯」)に基づいて取得され、その時間帯に合わせた応答の指示に利用される。

これらの全ての情報が揃った後、buildSystemPromptという別の関数が呼び出される。この関数は、キャラクターのベースプロンプトテンプレートに加えて、現在の時間帯コンテキスト(忙しいかゆっくりか)、性格特性の具体的な内容、カナダ表現の例、そして応答に関する詳細なガイドライン(応答の長さ、修正スタイル、禁止事項など)を動的に組み合わせて、最終的なシステムプロンプトを構築する。この動的に生成されるプロンプトには、「忙しい時間帯なので、迅速かつ簡潔に答える」「フォーマルさ:カジュアル、エネルギー:高い」といった具体的な指示から、「『Hey there!』『How's it going?』のようなカナダの挨拶を使う」「英語の間違いを修正する際は『gentle clarification(穏やかな説明)』スタイルを用いる」といった細かな指示まで含まれる。さらに、具体的な修正例(例: 「I want big coffee」と言われたら「Oh, you mean a large coffee?」と返す)もプロンプト内に含めることで、AIの応答の質と一貫性を高めている。

具体的な例として、ユーザーが「Tim Hortonsで注文する」というシナリオを選んだ場合を考えてみよう。システムはまず「tim_hortons」というキャラクターキーを特定し、データベースから「Tim Hortons Employee」のキャラクター情報、性格特性、カナダの表現、そしてたまたま選ばれた「忙しい時間帯」の応答パターンなどを取得する。これらの情報が全て組み合わされて、最終的なシステムプロンプトが生成される。このプロンプトには、「あなたはフレンドリーなティムホートンズの従業員であり、現在は忙しい時間帯なので、迅速かつ簡潔に返答する。カジュアルで高いエネルギーを持つ…」といった具体的な指示が含まれる。このプロンプトに基づいてGPT-4oが応答を生成すると、「Hey there! What can I get started for you today?(やあ!今日は何にしましょうか?)」といった、忙しい時間帯に合わせた簡潔でカジュアルな挨拶が返ってくる。もし、同じシナリオでも「ゆっくりした時間帯」に設定されていたら、「Morning! How's your day going so far? What can I get you today - maybe a nice double-double to start?(おはようございます!今日はいかがお過ごしですか?今日は何になさいますか?まずはダブルダブルなんてどうでしょう?)」といった、より会話的で詳細な応答になるだろう。このように、同じキャラクターでも状況に応じて応答スタイルが大きく変わることがわかる。

このデータベース駆動型のシステム最大の利点は、すべてのキャラクター情報がデータベースに格納されているため、新しいキャラクターの追加や既存キャラクターの個性の変更が、コードを一切変更することなく、非常に簡単に行える点である。各キャラクターが独自の雰囲気と状況に応じた異なる反応を示せるようになり、もしデータ取得で何らかの問題が発生しても、会話が中断することなく続けられる堅牢性も備えている。

次回の記事では、今回生成されたテキスト応答が、ブラウザベースの無料テキスト音声変換機能を使って、どのように音声に変換され、完全な音声会話ループが実現されるのかについて解説される予定である。

関連コンテンツ

関連IT用語

関連ITニュース