このブログ投稿では、NoSQL Go SDKおよびLangChainGoを使用してAzure Cosmos DBを使用したチャット履歴の実装方法について説明します。Go SDKが初めての方は、ブログで紹介されているサンプルチャットボットアプリケーションは、読み取り、アップサートなどの基本的な操作をカバーする実践的な導入として役立ちます。また、Azure Cosmos DBのLinuxベースのエミュレーター(執筆時点ではプレビュー)を使用して、Go向けのTestcontainersを使用した統合テストをデモンストレーションします。
Go 開発者は、LLMパワードアプリケーションを構築する際に、LangChainGoを使用できます。これは、ベクトルストア、埋め込み、ドキュメントのロード、複数の操作を組み合わせるチェーン(チャット履歴を含む)、その他のコンポーネント向けのプラグイン可能なAPIを提供します。
さあ、本題に入る前に、基礎を理解しましょう。
チャット履歴とは何か、そして現代のAIアプリケーションにとってなぜ重要なのかについて理解するために一歩後退してみましょう。
会話型AIアプリケーションの一般的な要件は、会話の一環としてやり取りされたメッセージを保存および取得できるようにすることです。これはよく「チャット履歴」と呼ばれます。ChatGPTなどのアプリケーションを使用したことがある場合(ちなみに、Azure Cosmos DBも使用しています)、このコンセプトに馴染みがあるかもしれません。
ユーザーがログインすると、チャットを開始し、会話の一環としてやり取りされたメッセージが保存されます。再度ログインすると、以前の会話を見ることができ、前回終了したところから続けることができます。
チャット履歴はアプリケーションエンドユーザーにとって重要ですが、LLMを忘れてはいけません!LLMがどれだけ賢く見えるかはともかく、組み込みメモリがないため過去のやり取りを思い出すことはできません(少なくとも現時点では)。チャット履歴を使用することで、以前の会話が追加のコンテキストとして提供され、LLMがより関連性の高い高品質な応答を生成できるようになります。これにより、会話の自然な流れが向上し、ユーザーエクスペリエンスが大幅に向上します。
簡単な例で説明します:APIを介してLLMに尋ねる、「Azure Cosmos DBについて教えてください」とすると、LLMは長い段落で応答します。次に、「これを箇条書きにして読みやすくしてください」という別のAPI呼び出しを行うと、以前のやり取りからのコンテキストがないため、LLMは混乱する可能性があります。
しかし、2番目のAPI呼び出しのコンテキストとして以前のメッセージを含めると、LLMは正確な応答を提供する可能性が高くなります(LLMの出力は本質的に非決定論的であるため、保証されるわけではありません)。
チャットボットの実行方法
前述のように、サンプルアプリケーションは、langchaingo
、Azure Cosmos DB チャット履歴の実装、およびGo SDKを探索するための便利な方法です。
実装の詳細を探る前に、アプリケーションを実際に動作させてみるのは良い考えです。GitHub リポジトリのREADME セクションを参照してください。ここには、チャットボットとの会話を開始、実行、および開始する方法に関する手順が記載されています。
アプリケーション概要
このチャットアプリケーションは、シンプルなドメインモデルに従います:ユーザーは複数の会話を開始でき、各会話には複数のメッセージが含まれることができます。Goで構築されたこのアプリケーションには、バックエンドとフロントエンドの両方のコンポーネントが含まれています。
バックエンド
複数のサブパートがあります:
- Azure Cosmos DB チャット履歴の実装。
- チャットの開始、メッセージの送受信、および会話履歴の取得などのコア操作は、REST API経由で公開されています。
- REST APIは、ユーザーメッセージを処理するために
langchaingo
チェーンを活用しています。このチェーンは、過去の会話がLLMに送信されるように、チャット履歴を自動的に組み込みます。langchaingo
は、手動での実装を必要とせずに、LLMの呼び出し、チャット履歴の追加など、すべてのオーケストレーションを処理します。
フロントエンド
これはJavaScript、HTML、およびCSSを使用して構築されています。Goウェブサーバーの一部としてパッケージ化されており(embedパッケージを使用)、ユーザーのインタラクションに応じてバックエンドREST APIを呼び出します。
Azure Cosmos DBを使用したチャット履歴の実装
LangChainGoは、チャット履歴(またはメモリ)コンポーネントを含むプラガブルなフレームワークです。Azure Cosmos DBを統合するには、チャット履歴を管理するためのメソッドを提供するschema.ChatMessageHistory
インターフェースを実装する必要があります:
AddMessage
は、会話にメッセージを追加する(または新しい会話を開始する)ためのものです。Messages
は、会話のすべてのメッセージを取得するためのものです。Clear
は、会話のすべてのメッセージを削除するためのものです。
直接にCosmosDBChatMessageHistory
のインスタンスを作成してこれらのメソッドを使用することができますが、推奨される方法はそれをlangchaingo
アプリケーションに統合することです。以下はAzure Cosmos DBチャット履歴をLLMChain
と共に使用する例です:
// チャット履歴インスタンスを作成
cosmosChatHistory, err := cosmosdb.NewCosmosDBChatMessageHistory(cosmosClient, databaseName, containerName, req.SessionID, req.UserID)
if err != nil {
log.Printf("Error creating chat history: %v", err)
sendErrorResponse(w, "Failed to create chat session", http.StatusInternalServerError)
return
}
// チャット履歴を持つメモリを作成
chatMemory := memory.NewConversationBuffer(
memory.WithMemoryKey("chat_history"),
memory.WithChatHistory(cosmosChatHistory),
)
// LLM チェーンを作成
chain := chains.LLMChain{
Prompt: promptsTemplate,
LLM: llm,
Memory: chatMemory,
OutputParser: outputparser.NewSimple(),
OutputKey: "text",
}
Azure Cosmos DBの観点から、この例での実装は多くの可能なオプションのうちの1つに過ぎません。ここで示されている方法は、ユーザーIDをパーティションキーとし、会話ID(場合によってはセッションIDとも呼ばれる)をユニークキー(Azure Cosmos DBアイテムのid
)とするものです。
これにより、アプリケーションは次のことができます:
- 会話のすべてのメッセージを取得します。これは、ユニークID(会話ID)とパーティションキー(ユーザーID)を使用したポイントリードです。
- 会話に新しいメッセージを追加します。これは、upsert操作を使用して(createの代わりに)、書き込みの前にreadが必要ないようにします。
- 特定の会話を削除します。これは、delete操作を使用して会話(およびそのすべてのメッセージ)を削除します。
langchaingo
インターフェースはそれを公開していませんが、これをアプリケーションの一部として統合する際には、ユーザーのすべての会話を取得するために別のクエリを発行することもできます。これは、単一のパーティションにスコープされているため、効率的です。
Azure Cosmos DBエミュレーターとTestcontainersでテストを簡素化する
サンプルアプリケーションには、Azure Cosmos DBのチャット履歴とメインアプリケーションの両方の基本的なテストケースが含まれています。 testcontainers-goを使用して、Azure Cosmos DB LinuxベースのエミュレーターのDockerコンテナを統合する点を強調する価値があります。
これは、データベースがローカルで利用可能であり、テストがはるかに高速に実行されるため(コスト削減も忘れてはいけません!)、統合テストに最適です。さらに、Dockerコンテナのライフサイクルを手動で管理する必要はありません。これは、テストスイートの一部として処理されるため、testcontainers-go API
によって、テストが実行される前にコンテナを起動し、完了したら終了させるのが便利です。
詳細については、サンプルアプリケーションのテストケースを参照してください。以下は、testcontainers-go
の使用方法のスニペットです:
func setupCosmosEmulator(ctx context.Context) (testcontainers.Container, error) {
req := testcontainers.ContainerRequest{
Image: emulatorImage,
ExposedPorts: []string{emulatorPort + ":8081", "1234:1234"},
WaitingFor: wait.ForListeningPort(nat.Port(emulatorPort)),
}
container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
ContainerRequest: req,
Started: true,
})
if err != nil {
return nil, fmt.Errorf("failed to start container: %w", err)
}
// エミュレーターが完全に初期化されるまで少し時間を与える
time.Sleep(5 * time.Second)
return container, nil
}
CIパイプラインでAzure Cosmos DBエミュレーターを使用する場合は、ブログ記事をチェックしてください。
結びつける
チャット履歴を保存できることは、会話型AIアプリの重要な部分です。これらは、RAG(検索拡張生成)などの既存の技術に素晴らしい付加機能として機能することができます。チャットボットアプリを試して、ご意見をお聞かせください!
サンプルアプリケーションでの実装は比較的単純ですが、チャット履歴データのモデリング方法は要件によります。提示されたシナリオの1つは、この優れたブログ投稿にあります。Microsoft CopilotがAzure Cosmos DBを使用して数百万のユーザーにスケーリングする方法についての詳細が説明されています。
要件には、次のようなものが含まれる場合があります:
- リアクション(メッセージに加えて)などのメタデータを保存すること
- 上位N件の最近のメッセージを表示すること
- チャット履歴データの保持期間を考慮すること(TTLを使用)
- チャット履歴データに基づいたユーザーインタラクションに関する追加の分析を組み込むことなど
実装方法に関係なく、常にデータモデリングのベストプラクティスを取り入れるようにしてください。ガイドラインについては、こちらを参照してください。here
あなたはすでにGoアプリケーションにAzure Cosmos DBを使用していますか、それとも利用を計画していますか?ぜひお知らせください!質問やフィードバックをお待ちしています。
Source:
https://dzone.com/articles/chat-history-ai-applications-azure-cosmos-db-go-sdk