本記事では、Azure AI SearchとLangChainを使用して、Retrieval-Augmented Generation (RAG) システムを構築する方法を解説します。
RAGは生成AIの精度を向上させるための有力な技術であり、Azure AI Searchの強力な検索機能とLangChainの柔軟な処理フレームワークを組み合わせることで、効率的で高精度な情報検索と生成が可能になります。
これで、Azure AI SearchとLangChainを使ったRAGの実装が完了しました。以上の手順を参考にして、実際のプロジェクトに適用してみてください。
【徹底解説】Document Intelligenceを利用してRAGを構築する
基本概念から理解するAzure AI Search - Azure OpenAI Serviceとの連携まで
RAGは生成AIの精度を向上させるための有力な技術であり、Azure AI Searchの強力な検索機能とLangChainの柔軟な処理フレームワークを組み合わせることで、効率的で高精度な情報検索と生成が可能になります。
Azure AI Searchとは
Azure AI Searchはクラウド型の検索サービスです。全文検索、ベクトル検索、ハイブリッド検索、セマンティック検索( ランク付け)を利用できます。
Azure AI Searchでは、インデックス内に複数のJSON形式のドキュメントを格納する形式でデータを保存します。インデックスでは、フィールド名、データ型(String, Int, Double等)、フィールド属性(取得可能,フィルター可能,ソート可能,キー等)を設定して作成できます。
Azure AI Searchのデプロイ
1. Azureポータルにログインし、「Azure AI services」を検索し、「AI Search」の「作成」ボタンを押下。
2.「基本」タブで、「リソースグループ」と「サービス名」を入力。また、「価格レベル」を選択します。
2.「基本」タブで、「リソースグループ」と「サービス名」を入力。また、「価格レベル」を選択します。
3. 「スケール」タブで、レプリカ(インスタンス数)とパーティション(ストレージ)の設定を行います。例えば、ユーザー数が多い場合はレプリカを増やし、データ量が多い場合はパーティションを増やします。
4.「ネットワーク」タブで、エンドポイントの接続を、「公開」か「プライベート」を選択します。
4.「ネットワーク」タブで、エンドポイントの接続を、「公開」か「プライベート」を選択します。
5. 「確認および作成」タブで、「作成」を押下します。
LangChainとAzure AI SearchでのRAGの手順
LangChainとAzure AI Searchを用いたRAGの手順は以下の通りです。
①AI Document IntelligenceでドキュメントをMarkdownに変換する
②LangChainでMarkdownを見出し位置でチャンク分割する(セマンティックチャンク)
③チャンク化した内容をベクトル化し、Azure AI Searchに登録する
④ユーザーからの質問を受けて、Azure AI Searchを検索する
⑤検索結果をLLMに入力して回答を生成する
本記事では、Microsoftのサンプルコードを元に③~⑤を解説します。
①~②は、前回記事をご確認ください。
前回の記事:Azure AI Document IntelligenceとLangChainを活用したRAGの実装
※なお、Azure AI Document Intelligenceを使用して、ドキュメント内の図からマークダウンを出力し、図を切り抜き、図のコンテンツ(キャプション付き)をAzure Open AI GPT-4Vモデルに送信して、セマンティックチャンキングする方法については、こちらのサンプルコードをご確認ください。
前回の記事:Azure AI Document IntelligenceとLangChainを活用したRAGの実装
※なお、Azure AI Document Intelligenceを使用して、ドキュメント内の図からマークダウンを出力し、図を切り抜き、図のコンテンツ(キャプション付き)をAzure Open AI GPT-4Vモデルに送信して、セマンティックチャンキングする方法については、こちらのサンプルコードをご確認ください。
③チャンク化した内容をベクトル化し、Azure AI Searchに登録する
チャンク化したドキュメントをベクトル化し、ベクトルストア(Azure AI search)に格納します。
ベクトル化は、Azure OpenAI Service の embedding modelを活用します。LangchainのAzureOpenAIEmbeddings関数で、Azure OpenAI のEmbeddingモデルをラップして利用できます。
import os from langchain_openai import AzureChatOpenAI, AzureOpenAIEmbeddings #from langchain.vectorstores.azuresearch import AzureSearch
from langchain_community.vectorstores.azuresearch import AzureSearch from langchain.schema import StrOutputParser from langchain.schema.runnable import RunnablePassthrough
# AOAIのEmbeddings LLMをラップ aoai_embeddings = AzureOpenAIEmbeddings( azure_deployment="<Azure OpenAI embeddings model>", openai_api_version="<Azure OpenAI API version>", ) vector_store_address: str = os.getenv("AZURE_SEARCH_ENDPOINT") vector_store_password: str = os.getenv("AZURE_SEARCH_ADMIN_KEY")
index_name: str = "<your index name>" #Azure AI Serch上に作成するIndex名 # ベクトルストアのインスタンスを構築 vector_store: AzureSearch = AzureSearch( azure_search_endpoint=vector_store_address, azure_search_key=vector_store_password, index_name=index_name, embedding_function=aoai_embeddings.embed_query ## Azure OpenAI Serviceのembeddingsモデルを利用 ) # 前の記事でチャンク化した情報(splits)を格納する # 格納するタイミングでベクトル化も行われる vector_store.add_documents(documents=splits)
④ユーザーからの質問を受けて、Azure AI Searchを検索する
次に実際にベクトルストアから、質問に対して関連した情報を抽出します。
この時 Retriever というインスタンスを作成して情報を取り出していきます。
SearchTypeをsimilarityで類似検索が行われ、search_kwargsで検索件数を設定します。
その後、実際に Retriever に質問を与え、関連する情報を retrieved_docs に格納し表示しています。
# Retrieve relevant chunks based on the question # 先ほど作成したベクトルストアをRetrieverとして定義 retriever = vector_store.as_retriever(search_type="similarity", search_kwargs={"k": 4}) retrieved_docs = retriever.get_relevant_documents( "この調査の目的は何ですか?" ) print(retrieved_docs[0].page_content)
⑤検索結果をLLMに入力して回答を生成する
実際に RAG の Chain を構築していきます。Chain とはその名の通り、LLM や Prompt などのコンポーネントを繋げて、システムを作り上げる機能になります。
なお Chain を実装するにあたり、LangChain Expression Language (LCEL)といった記述方法を利用しています。 LLM や Prompt 等のコンポーネントを | で繋げるだけで簡単に Chain を構築することが可能です。
# prompt prompt = """
You are an assistant for question-answering tasks. Use the following pieces of retrieved context to answer the question. If you don't know the answer, just say that you don't know. Use three sentences maximum and keep the answer concise. Question: {question} Context: {context} Answer:
""" llm = AzureChatOpenAI( openai_api_version="<Azure OpenAI API version>", azure_deployment="<your chat model deployment name>", temperature=0, ) # ベクトルストアから取り出したdocumentからpage_contentの内容だけを抽出して連結する def format_docs(docs): return "\n\n".join(doc.page_content for doc in docs) rag_chain = ( {"context": retriever | format_docs, "question": RunnablePassthrough()} | prompt | llm | StrOutputParser() )
# 質問に対する回答を生成 question = "この調査の目的は何ですか?" answer = rag_chain({"context": retrieved_docs, "question": question}) print(answer)
これで、Azure AI SearchとLangChainを使ったRAGの実装が完了しました。以上の手順を参考にして、実際のプロジェクトに適用してみてください。
参考記事
Form-Recognizer-Toolkit/SampleCode/Python/sample_rag_langchain.ipynb【徹底解説】Document Intelligenceを利用してRAGを構築する
基本概念から理解するAzure AI Search - Azure OpenAI Serviceとの連携まで