次の方法で共有


Azure SignalR と OpenAI Completion API を使用して AI 搭載のグループ チャットを構築する

AI をアプリケーションに統合することは、ユーザーの創造性、生産性、健康目標の達成を支援しようとする開発者にとって、急速に必須の要件となりつつあります。 インテリジェントなチャットボット、パーソナライズされたおすすめ機能、文脈に応じた応答など、AI 搭載の機能は、最新のアプリに大きな付加価値を与えます。 ChatGPT が私たちの想像力を掻き立てて以降登場した AI 搭載アプリは、主に 1 人のユーザーと 1 人の AI アシスタントの間で使用されるものでした。 しかし、開発者が AI をより使いこなせるようになるにつれ、AI を搭載したアプリをチーム全体で活用できないかと模索され始めています。 彼らが考えているのは、「AI は、チームで共同作業を行うユーザーにどのような付加価値を与えることができるのだろうか」という点です。

このチュートリアルでは、リアルタイムのグループ チャット アプリケーションを構築する手順について説明します。 このチャットには、共同作業をしている人間のユーザー紛れて、AI アシスタントが追加されます。この AI アシスタントはチャット履歴にアクセスできるだけでなく、冒頭に @gpt が付いている任意のユーザーのメッセージに対して、支援を提供することができます。 完成したアプリは次のようになります。

AI 搭載のグループ チャットのユーザー インターフェイスのスクリーンショット。

ここでは、OpenAI を使用して文脈に応じたインテリジェントな応答を生成し、SignalR を使用してグループ内のユーザーに応答を配信します。 完全なコードは、こちらのリポジトリにあります

依存関係

このプロジェクトには、Azure OpenAI または OpenAI のいずれかを使用できます。 appsetting.jsonendpointkey を更新してください。 OpenAIExtensions は、アプリの起動時に構成を読み取り、認証していずれかのサービスを使用する必要があります。

このアプリケーションを構築するには、次のものが必要です。

  • ASP.NET Core: Web アプリケーションを作成し、SignalR ハブをホストするため
  • SignalR: クライアントとサーバー間のリアルタイム通信に使用
  • Azure SignalR: SignalR 接続を大規模に管理するため
  • OpenAI クライアント: OpenAI の API と対話し、AI 応答を生成するためため

実装

このセクションでは、SignalR と OpenAI を統合して AI 搭載のグループ チャット エクスペリエンスを実現するコードの主要部分について説明します。

データ フロー

AI 搭載のグループ チャットのシーケンス図。

SignalR Hub の統合

GroupChatHub クラスは、ユーザー接続、メッセージ ブロードキャスト、AI 対話を管理します。 ユーザーが冒頭に @gpt を付けてメッセージを送信すると、ハブによってメッセージが OpenAI に転送され、応答が生成されます。 AI の応答は、リアルタイムでグループにストリーミングされます。

var chatClient = _openAI.GetChatClient(_options.Model);
await foreach (var completion in chatClient.CompleteChatStreamingAsync(messagesIncludeHistory))
{   
    // ...
    // Buffering and sending the AI's response in chunks
    await Clients.Group(groupName).SendAsync("newMessageWithId", "ChatGPT", id, totalCompletion.ToString());
    // ...
}

履歴を使用して文脈を保持する

OpenAI の Chat Completions API に対するすべての要求はステートレスです。OpenAI 側に、過去の対話は保存されません。 チャット アプリケーションでは、ユーザーまたはアシスタントの発言内容は、文脈に適した応答を生成するために重要です。 これを実現するには、Completions API に対するすべての要求にチャット履歴を含めます。

各グループのチャット履歴は、GroupHistoryStore クラスで管理します。 これにはユーザーと AI アシスタントの両方によって投稿されたメッセージが格納され、対話を通して会話の文脈が保持されます。 この文脈は、一貫した AI 応答を生成するために不可欠です。

// Store message generated by AI-assistant in memory
public void UpdateGroupHistoryForAssistant(string groupName, string message)
{
    var chatMessages = _store.GetOrAdd(groupName, _ => InitiateChatMessages());
    chatMessages.Add(new AssistantChatMessage(message));
}
// Store message generated by users in memory
_history.GetOrAddGroupHistory(groupName, userName, message);

AI 応答をストリーミングする

CompleteChatStreamingAsync() メソッドは、OpenAI からの応答を段階的にストリーミングします。これにより、部分的な応答が生成されるごとに、アプリケーションからクライアントに応答を送信できます。

このコードでは、StringBuilder を使用して AI の応答を蓄積します。 バッファリングされたコンテンツの長さをチェックし、特定のしきい値 (20 文字など) を超えたときにクライアントに送信します。 このアプローチにより、ユーザーに AI の応答が生成される過程を見せ、人間が実際に入力しているような効果を演出することができます。

totalCompletion.Append(content);
if (totalCompletion.Length - lastSentTokenLength > 20)
{
    await Clients.Group(groupName).SendAsync("newMessageWithId", "ChatGPT", id, totalCompletion.ToString());
    lastSentTokenLength = totalCompletion.Length;
}

さらに深堀する

このプロジェクトは、次のようなさらなる強化のための素晴らしい可能性を開きます。

  • 高度な AI 機能: 感情分析、翻訳、要約といった、他の OpenAI 機能を活用します。
  • 複数の AI エージェントを組み込む: 同じチャット内に、異なる役割または専門知識領域を持つ複数の AI エージェントを導入することができます。 たとえば、1 つのエージェントがテキスト生成に重点を置き、もう 1 つは画像生成や音声生成の機能を提供するなどです。 この対話により、異なる AI エージェントがユーザーと相互にシームレスに対話する、より豊富で動的なユーザー エクスペリエンスを実現できます。
  • サーバー インスタンス間でチャット履歴を共有する: データベース レイヤーを実装してセッション間でチャット履歴を保持し、切断後でも会話を再開できるようにします。 SQL または NO SQL ベースのソリューション以外に、Redis などのキャッシュ サービスの利用を検討することもできるでしょう。 チャット履歴や AI 応答などの頻繁にアクセスされるデータをメモリに格納することで、パフォーマンスを大幅に向上させることができます。 これにより、待機時間が短縮され、データベース操作の負荷が軽減されるため、特にトラフィックの多いシナリオでは応答時間を短縮できます。