生成型 AI の急速に進化する領域では、GPT のような大規模な言語モデル (LLM) によって自然言語処理が変換されました。 しかし、AI の新たなトレンドは、AI アプリケーションを強化する上で極めて重要な役割を果たすベクトル ストアの使用です。
このチュートリアルでは、Azure DocumentDB、LangChain、OpenAI を使用して、優れた AI パフォーマンスのための取得拡張生成 (RAG) を実装する方法と、LLM とその制限について説明する方法について説明します。 RAG の急速に採用されたパラダイムについて説明し、LangChain フレームワークと Azure OpenAI モデルについて簡単に説明します。 最後に、これらの概念を実際のアプリケーションに統合します。 閲覧者は最後まで、これらの概念の理解を深めることができます。
LLM とその制限事項について
LLM は、広範なテキスト データセットでトレーニングされた高度なディープ ニューラル ネットワーク モデルであり、人間のようなテキストを理解して生成できるようにします。 自然言語処理において画期的である一方、LLM には次のような固有の制限があります。
- 幻覚: LLM では、"幻覚" として知られる、事実と異なる情報や、根拠のない情報が生成されます。
- 古いデータ: LLM は、最新の情報を含まない可能性がある静的データセットに対してトレーニングされ、現在の関連性が制限されます。
- ユーザーのローカル データへのアクセスなし: LLM は個人またはローカライズされたデータに直接アクセスできないため、パーソナライズされた応答を提供する機能が制限されます。
- トークンの制限: LLM には相互作用ごとの最大トークン制限があり、一度に処理できるテキストの量が制限されます。 たとえば、OpenAI の gpt-3.5-turbo のトークン制限は 4,096 です。
検索拡張生成を使用する
RAG は、LLM の制限を克服するように設計されたアーキテクチャです。 RAG は、入力クエリに基づいて関連するドキュメントを検索するためにベクトル検索を使用し、より正確な応答を生成するために LLM にこれらのドキュメントをコンテキストとして提供します。 RAG は、事前トレーニング済みのパターンにのみ依存するのではなく、最新の関連情報を取り入れることで応答を強化します。 このアプローチは次のことに役立ちます。
- 幻覚を最小限に抑える: 事実に基づいた応答をする。
- 最新の情報を確保する: 最新のデータを取得して、最新の応答を確保します。
- 外部データベースを利用する: 個人データへの直接アクセスは許可されませんが、RAG では外部のユーザー固有のナレッジ ベースとの統合が可能です。
- トークンの使用を最適化する: 最も関連性の高いドキュメントに焦点を当てることで、RAG はトークンの使用をより効率的にします。
このチュートリアルでは、Azure DocumentDB を使用して RAG を実装して、データに合わせた質問に回答するアプリケーションを構築する方法について説明します。
アプリケーション アーキテクチャの概要
次のアーキテクチャ図は、RAG 実装の主要なコンポーネントを示しています。
主要コンポーネントとフレームワーク
次に、このチュートリアルで使用するさまざまなフレームワーク、モデル、コンポーネントについて、それぞれの役割とニュアンスを強調しながら説明します。
Azure DocumentDB
Azure DocumentDB では、AI を利用したアプリケーションに不可欠なセマンティック類似性検索がサポートされています。 さまざまな形式のデータをベクトル埋め込みとして表現することができ、ソース データやメタデータと一緒に格納できます。 階層的にナビゲート可能な小さな世界 (HNSW) のような近似最近傍アルゴリズムを使用して、これらの埋め込みを照会して、高速なセマンティック類似性検索を実行できます。
LangChain フレームワーク
LangChain は、チェーン用の標準インターフェイス、複数のツール統合、一般的なタスク用のエンドツーエンド チェーンを提供することで、LLM アプリケーションの作成を簡略化します。 これにより、AI 開発者は外部データ ソースを使用する LLM アプリケーションを構築できます。
LangChain の主要な側面:
- チェーン: 特定のタスクを解決するコンポーネントのシーケンス。
- コンポーネント: LLM ラッパー、ベクトル ストア ラッパー、プロンプト テンプレート、データ ローダー、テキスト スプリッター、取得などのモジュール。
- モジュール性: 開発、デバッグ、メンテナンスを簡略化します。
- 使用頻度: 急速に普及し、ユーザーのニーズに合わせて進化しているオープンソース プロジェクトです。
Azure App Services インターフェイス
App Services には、Gen-AI アプリケーションのためのユーザーフレンドリな Web インターフェイスを構築するための堅牢なプラットフォームが用意されています。 このチュートリアルでは、Azure App Service を使用して、アプリケーション用の対話型の Web インターフェイスを作成します。
OpenAI モデル
OpenAI は AI 研究のリーダーであり、言語生成、テキスト ベクター化、画像作成、音声テキスト変換などのさまざまなモデルが用意されています。 このチュートリアルでは、言語ベースのアプリケーションを理解し、生成するために重要な OpenAI の埋め込みと言語モデルを使用します。
モデルの埋め込みと言語生成モデルの比較
| カテゴリ | テキスト埋め込みモデル | 言語モデル |
|---|---|---|
| Purpose | テキストをベクター埋め込み形式に変換します。 | 自然言語を理解し、生成します。 |
| Function | テキスト データを数値の高次元配列に変換し、テキストの意味をキャプチャします。 | 指定された入力を理解し、人間が生成したようなテキストを作成します。 |
| アウトプット | 数値 (ベクトル埋め込み) の配列。 | テキスト、回答、翻訳、コードなど。 |
| 出力例 | 各埋め込みは、モデルによって決定された次元を用いて、テキストの意味を数値で表します。 たとえば、 text-embedding-ada-002 は 1,536 次元のベクトルを生成します。 |
提供された入力に基づいて生成された、コンテキストに関連した一貫性のあるテキスト。 たとえば、gpt-3.5-turbo は質問に対する回答を生成したり、テキストを翻訳したり、コードを書いたりすることができます。 |
| 一般的なユース ケース | - セマンティック検索 | - チャットボット |
| - レコメンデーション システム | - コンテンツの自動作成 | |
| - テキスト データのクラスタリングと分類 | - 言語の翻訳 | |
| - 情報の取得 | - 要約 | |
| データ表現 | 数値表現 (埋め込み) | 自然言語テキスト |
| 次元 | 配列の長さは、埋め込み空間内の次元の数 (たとえば、1,536 次元) に対応します。 | 通常はトークンの列として表現され、コンテキストによって長さが決まります。 |
アプリケーションの主なコンポーネント
- Azure DocumentDB: ベクター埋め込みの格納とクエリ。
-
LangChain: アプリケーションの LLM ワークフローの構築。 次のようなツールを活用します。
- ドキュメント ローダー: ディレクトリからドキュメントを読み込んで処理する場合。
- ベクター ストア統合: Azure DocumentDB にベクター埋め込みを格納してクエリを実行します。
- AzureDocumentDBVectorSearch: Azure DocumentDB ベクター検索のラッパー
- Azure App Services: Cosmic Food アプリのユーザー インターフェイスの構築。
-
Azure OpenAI: 次のような LLM と埋め込みモデルの提供。
- text-embedding-ada-002: テキストを 1,536 次元のベクター埋め込みに変換するテキスト埋め込みモデル。
- gpt-3.5-turbo: 自然言語の理解と生成のための言語モデル。
環境をセットアップする
Azure DocumentDB を使用した RAG の最適化を開始するには、次の手順に従います。
-
Microsoft Azure で次のリソースを作成します。
- Azure DocumentDB クラスター: 詳細については、クラスターの作成に関するページを参照してください
-
Azure OpenAI リソース (以下を使用):
-
埋め込みモデル デプロイ (例:
text-embedding-ada-002)。 -
チャット モデル デプロイ (例:
gpt-35-turbo)。
-
埋め込みモデル デプロイ (例:
サンプル ドキュメント
このチュートリアルでは、 ドキュメント ローダーを使用して 1 つのテキスト ファイルを読み込みます。 ファイルは、src フォルダー内の data という名前のディレクトリに保存する必要があります。 ファイルの内容は次のとおりです。
food_items.json
{
"category": "Cold Dishes",
"name": "Hamachi Fig",
"description": "Hamachi sashimi lightly tossed in a fig sauce with rum raisins, and serrano peppers then topped with fried lotus root.",
"price": "16.0 USD"
},
ドキュメントを読み込む
Azure DocumentDB 接続文字列、データベース名、コレクション名、およびインデックスを設定します。
mongo_client = MongoClient(mongo_connection_string) database_name = "Contoso" db = mongo_client[database_name] collection_name = "ContosoCollection" index_name = "ContosoIndex" collection = db[collection_name]埋め込みクライアントを初期化します。
from langchain_openai import AzureOpenAIEmbeddings openai_embeddings_model = os.getenv("AZURE_OPENAI_EMBEDDINGS_MODEL_NAME", "text-embedding-ada-002") openai_embeddings_deployment = os.getenv("AZURE_OPENAI_EMBEDDINGS_DEPLOYMENT_NAME", "text-embedding") azure_openai_embeddings: AzureOpenAIEmbeddings = AzureOpenAIEmbeddings( model=openai_embeddings_model, azure_deployment=openai_embeddings_deployment, )データから埋め込みを作成し、データベースに保存し、ベクター ストア Azure DocumentDB への接続を返します。
vector_store: AzureDocumentDBVectorSearch = AzureDocumentDBVectorSearch.from_documents( json_data, azure_openai_embeddings, collection=collection, index_name=index_name, )コレクションに次の HNSW ベクター インデックス を作成します。 (インデックスの名前は同じであることに注意してください)。
num_lists = 100 dimensions = 1536 similarity_algorithm = DocumentDBSimilarityType.COS kind = DocumentDBVectorSearchType.VECTOR_HNSW m = 16 ef_construction = 64 vector_store.create_index( num_lists, dimensions, similarity_algorithm, kind, m, ef_construction )
Azure DocumentDB を使用してベクター検索を実行する
ベクトル ストアに接続します。
vector_store: AzureDocumentDBVectorSearch = AzureDocumentDBVectorSearch.from_connection_string( connection_string=mongo_connection_string, namespace=f"{database_name}.{collection_name}", embedding=azure_openai_embeddings, )クエリで Azure DocumentDB Vector Search を使用してセマンティック類似性検索を実行する関数を定義します。 (このコード スニペットは単なるテスト関数であることに注意してください)。
query = "beef dishes" docs = vector_store.similarity_search(query) print(docs[0].page_content)RAG 関数を実装するようにチャット クライアントを初期化します。
azure_openai_chat: AzureChatOpenAI = AzureChatOpenAI( model=openai_chat_model, azure_deployment=openai_chat_deployment, )RAG 関数を作成します。
history_prompt = ChatPromptTemplate.from_messages( [ MessagesPlaceholder(variable_name="chat_history"), ("user", "{input}"), ( "user", """Given the above conversation, generate a search query to look up to get information relevant to the conversation""", ), ] ) context_prompt = ChatPromptTemplate.from_messages( [ ("system", "Answer the user's questions based on the below context:\n\n{context}"), MessagesPlaceholder(variable_name="chat_history"), ("user", "{input}"), ] )ベクター ストアをレトリバーに変換します。これは、指定されたパラメーターに基づいて関連するドキュメントを検索できます。
vector_store_retriever = vector_store.as_retriever( search_type=search_type, search_kwargs={"k": limit, "score_threshold": score_threshold} )会話履歴を認識するレトリバー チェーンを作成し、 azure_openai_chat モデルと vector_store_retrieverを使用してコンテキストに関連するドキュメントの取得を保証します。
retriever_chain = create_history_aware_retriever(azure_openai_chat, vector_store_retriever, history_prompt)言語モデル (azure_openai_chat) と指定されたプロンプト (context_prompt) を使用して、取得したドキュメントを一貫性のある応答に結合するチェーンを作成します。
context_chain = create_stuff_documents_chain(llm=azure_openai_chat, prompt=context_prompt)履歴認識取得チェーンとドキュメント結合チェーンを統合し、取得プロセス全体を処理するチェーンを作成します。 この RAG チェーンを実行することで、コンテキストに沿った正確な回答を取得および生成できます。
rag_chain: Runnable = create_retrieval_chain( retriever=retriever_chain, combine_docs_chain=context_chain, )
サンプル出力
次のスクリーンショットは、さまざまな質問の出力を示しています。 純粋な意味類似性検索は、ソース ドキュメントから生テキストを返します。一方、RAG アーキテクチャを使用した質問応答アプリは、取得したドキュメント コンテンツと言語モデルを組み合わせることで、正確でパーソナライズされた回答を生成します。
Conclusion
このチュートリアルでは、Azure DocumentDB をベクター ストアとして使用してプライベート データと対話する質問に答えるアプリを構築する方法について説明しました。 LangChain と Azure OpenAI で RAG アーキテクチャを使用して、LLM アプリケーションにベクター ストアが不可欠である方法を示しました。
RAG は、AI、特に自然言語処理における大きな進歩であり、これらのテクノロジーを組み合わせることで、さまざまなユース ケースに対応した強力な AI 駆動型アプリケーションを作成できます。