コードを使ってインデックスを構築して使用する方法
重要
この記事で "(プレビュー)" と付記されている項目は、現在、パブリック プレビュー段階です。 このプレビューはサービス レベル アグリーメントなしで提供されており、運用環境ではお勧めしません。 特定の機能はサポート対象ではなく、機能が制限されることがあります。 詳しくは、Microsoft Azure プレビューの追加使用条件に関するページをご覧ください。
この記事では、インデックスを作成し、それをコードから使う方法について説明します。 インデックスをローカルに作成するには、promptflow-rag
パッケージを使います。 クラウド上にリモート インデックスを作成するには、azure-ai-ml
パッケージを使います。 langchain
を使ってインデックスを使います。
前提条件
以下が必要です。
サンプル製品と顧客データのインデックスを作成するための Azure AI 検索サービスへの接続。 Azure AI 検索サービスがない場合は、Azure portal から作成するか、こちらの手順を参照してください。
埋め込み用モデル:
インデックスをローカルで構築して使う
インデックスをローカルで構築して使用できます。
ローカル インデックス操作に必要なパッケージ
次の、ローカル インデックスの作成に必要なパッケージをインストールします。
pip install promptflow-rag langchain langchain-openai
AI 検索をローカルで使うように構成する
Azure AI 検索をインデックス ストアとして使います。 まず、次のコードを使って Azure AI 検索サービスを設定します。
import os
# set credentials to your Azure AI Search instance
os.environ["AZURE_AI_SEARCH_KEY"] = "<your-ai-search-key>"
os.environ["AZURE_AI_SEARCH_ENDPOINT"] = "https://<your-ai-search-service>.search.windows.net"
Azure OpenAI 埋め込みを使ってローカルでインデックスを構築する
Azure OpenAI 埋め込みを使うインデックスを作成するには、モデルに接続するための環境変数を構成します。
import os
# set credentials to your Azure OpenAI instance
os.environ["OPENAI_API_VERSION"] = "2023-07-01-preview"
os.environ["AZURE_OPENAI_API_KEY"] = "<your-azure-openai-api-key>"
os.environ["AZURE_OPENAI_ENDPOINT"] = "https://<your-azure-openai-service>.openai.azure.com/"
次に、build_index
関数を使ってインデックスを構築します。
from promptflow.rag.config import LocalSource, AzureAISearchConfig, EmbeddingsModelConfig
from promptflow.rag import build_index
local_index_aoai=build_index(
name="<your-index-name>" + "aoai", # name of your index
vector_store="azure_ai_search", # the type of vector store
embeddings_model_config=EmbeddingsModelConfig(
model_name="text-embedding-ada-002",
deployment_name="text-embedding-ada-002", # verify if your deployment name is same as model name
),
input_source=LocalSource(input_data="<path-to-your-local-files>"), # the location of your file/folders
index_config=AzureAISearchConfig(
ai_search_index_name="<your-index-name>" + "-aoai-store", # the name of the index store inside the azure ai search service
),
tokens_per_chunk = 800, # Optional field - Maximum number of tokens per chunk
token_overlap_across_chunks = 0, # Optional field - Number of tokens to overlap between chunks
)
上記のコードはインデックスをローカルに構築します。 環境変数を使って AI 検索サービスを取得し、Azure OpenAI 埋め込みモデルに接続します。
AI Studio プロジェクトにデプロイされた他の埋め込みモデルを使ってローカルでインデックスを構築する
AI Studio プロジェクトにデプロイされた埋め込みモデルを使うインデックスを作成するには、以下に示すように、ConnectionConfig
を使ってモデルへの接続を構成します。 subscription
、resource_group
、workspace
は、埋め込みモデルがインストールされているプロジェクトを参照します。 connection_name
はモデルの接続名を参照します。これは AI Studio プロジェクトの設定ページにあります。
from promptflow.rag.config import ConnectionConfig
my_connection_config=ConnectionConfig(
subscription_id="<subscription_id>",
resource_group_name="<resource_group_name>",
workspace_name="<ai_studio_project_name>",
connection_name="<serverless_connection_name>"
)
次に、build_index
関数を使ってインデックスを構築します。
from promptflow.rag.config import LocalSource, AzureAISearchConfig, EmbeddingsModelConfig
from promptflow.rag import build_index
local_index_cohere=build_index(
name="<your-index-name>" + "cohere", # name of your index
vector_store="azure_ai_search", # the type of vector store
embeddings_model_config=EmbeddingsModelConfig(
model_name="cohere-embed-v3-multilingual", # in this example we use cohere multi lingual embedding
connection_config=my_connection_config # created in previous step
),
input_source=LocalSource(input_data="<path-to-your-local-files>"), # the location of your file/folders
index_config=AzureAISearchConfig(
ai_search_index_name="<your-index-name>" + "cohere-store", # the name of the index store inside the azure ai search service
),
tokens_per_chunk = 800, # Optional field - Maximum number of tokens per chunk
token_overlap_across_chunks = 0, # Optional field - Number of tokens to overlap between chunks
)
上記のコードはインデックスをローカルに構築します。 環境変数を使って AI 検索サービスと接続構成を取得し、埋め込みモデルに接続します。
ローカル インデックスの使用
作成されたローカル インデックスは、検索クエリに使うための langchain 取得コンポーネントとして使用できます。
from promptflow.rag import get_langchain_retriever_from_index
# Get the OpenAI embedded Index
retriever=get_langchain_retriever_from_index(local_index_aoai)
retriever.get_relevant_documents("<your search query>")
# Get the Cohere embedded Index
retriever=get_langchain_retriever_from_index(local_index_cohere)
retriever.get_relevant_documents("<your search query>")
AI Studio プロジェクトへのインデックスの登録 (省略可能)
必要に応じて、自分またはプロジェクトにアクセスできる他のユーザーがクラウドから使用できるように、AI Studio プロジェクトにインデックスを登録できます。 続行する前に、リモート操作に必要なパッケージをインストールしてください。
プロジェクトに接続する
# connect to the AI Studio project
from azure.identity import DefaultAzureCredential
from azure.ai.ml import MLClient
client=MLClient(
DefaultAzureCredential(),
subscription_id="<subscription_id>",
resource_group_name="<resource_group_name>",
workspace_name="<ai_studio_project_name>"
)
上記のコードの subscription
、resource_group
、workspace
は、接続するプロジェクトを参照します。
インデックスを登録する
from azure.ai.ml.entities import Index
# register the index with Azure OpenAI embeddings
client.indexes.create_or_update(
Index(name="<your-index-name>" + "aoai",
path=local_index_aoai,
version="1")
)
# register the index with cohere embeddings
client.indexes.create_or_update(
Index(name="<your-index-name>" + "cohere",
path=local_index_cohere,
version="1")
)
Note
環境変数は、ローカル環境での利便性のために用意されています。 ただし、環境変数を使用して作成されたローカル インデックスを登録すると、環境変数のシークレットがクラウド インデックスに転送されないことが原因で、インデックスが期待どおりに機能しない場合があります。 この問題に対処するには、登録する前に、ConnectionConfig
または connection_id
を使用してローカル インデックスを作成します。
AI Studio プロジェクトにインデックスを (リモートで) 構築する
クラウドで AI Studio プロジェクトにインデックスを構築します。
リモート インデックス操作に必要なパッケージ
次の、リモート インデックス作成に必要なパッケージをインストールします。
pip install azure-ai-ml promptflow-rag langchain langchain-openai
AI Studio プロジェクトに接続する
まず、プロジェクトに接続します。 次のコードの subscription
、resource_group
、workspace
は、接続するプロジェクトを参照します。
# connect to the AI Studio project
from azure.identity import DefaultAzureCredential
from azure.ai.ml import MLClient
client=MLClient(
DefaultAzureCredential(),
subscription_id="<subscription_id>",
resource_group_name="<resource_group_name>",
workspace_name="<ai_studio_project_name>"
)
AI 検索サービス接続を取得する
このプロジェクトには AI 検索サービスへの接続が必要です。 プロジェクトから詳細を取得します。
ai_search_connection = client.connections.get("<ai_search_connection>")
埋め込みモデルに接続する
Microsoft Entra ID 接続または API キーベースの接続を使って Azure OpenAI に接続できます。
from azure.ai.ml.entities import IndexModelConfiguration
## aoai connections - entra id
aoai_connection = client.connections.get("<your_aoai_entra_id_connection>")
embeddings_model_config = IndexModelConfiguration.from_connection(
aoai_connection,
model_name="text-embedding-ada-002",
deployment_name="text-embedding-ada-002") # verify if your deployment name is same as model name
## OR you can connect using API Key based connections
from azure.ai.ml.entities import IndexModelConfiguration
## aoai connections - API Key
aoai_connection = client.connections.get("<your_aoai_connection>", populate_secrets=True)
embeddings_model_config = IndexModelConfiguration.from_connection(
aoai_connection,
model_name="text-embedding-ada-002",
deployment_name="text-embedding-ada-002")
サーバーレス接続を使って、AI Studio プロジェクトにデプロイされた埋め込みモデル (Azure OpenAI 以外のモデル) に接続できます。
from azure.ai.ml.entities import IndexModelConfiguration
serverless_connection = client.connections.get("<my_embedding_model_severless_connection_name>")
embeddings_model_config = IndexModelConfiguration.from_connection(cohere_serverless_connection)
インデックスを構築する入力データを選ぶ
次の種類の入力からインデックスを構築できます。
- ローカル ファイルおよびフォルダー
- GitHub リポジトリ
- Azure Storage
次のコード サンプルを使って、これらのソースのいずれかを使い、input_source
を構成できます。
# Local source
from azure.ai.ml.entities import LocalSource
input_source=LocalSource(input_data="<path-to-your-local-files>")
# GitHub repository
from azure.ai.ml.entities import GitSource
input_source=GitSource(
git_url="https://github.com/rust-lang/book.git", # connecting to the RUST repo as an example
git_branch_name="main",
git_connection_id="")
# Azure Storage
input_source_subscription = "<subscription>"
input_source_resource_group = "<resource_group>"
input_source_workspace = "<workspace>"
input_source_datastore = "<datastore_name>"
input_source_path = "path"
input_source = f"azureml://subscriptions/{input_source_subscription}/resourcegroups/{input_source_resource_group}/workspaces/{input_source_workspace}/datastores/{input_source_datastore}/paths/{input_source_path}"
クラウド上にインデックスを構築する
これで、ai_search_connection
、embeddings_model_config
、input_source
を使ってインデックスを構築できるようになりました。 build_index
関数を使います。 Azure Storage URL を入力ソースとして使っている場合は、UserIdentityConfiguration
も指定する必要があります。
# from azure.ai.ml.entities.credentials import UserIdentityConfiguration # user specified identity used to access the data. Required when using an azure storage URL
from azure.ai.ml.entities import AzureAISearchConfig
client.indexes.build_index(
name="<index_name>", # name of your index
embeddings_model_config=embeddings_model_config,
input_source=input_source,
# input_source_credential=UserIdentityConfiguration(), # user specified identity used to access the data. Required when using an azure storage URL
index_config=AzureAISearchConfig(
ai_search_index_name="<index_name>", # the name of the index store in AI search service
ai_search_connection_id=ai_search_connection.id,
),
tokens_per_chunk = 800, # Optional field - Maximum number of tokens per chunk
token_overlap_across_chunks = 0, # Optional field - Number of tokens to overlap between chunks
)
入力ソース データのサイズによっては、上記の手順が完了するまでに時間がかかる場合があります。 ジョブが完了すると、インデックス オブジェクトを取得できます。
my_index=client.indexes.get(name="<index_name>", label="latest")
プロジェクトから登録済みインデックスを使う
プロジェクトから登録済みのインデックスを使うには、プロジェクトに接続してインデックスを取得する必要があります。 取得したインデックスは、それを使う langhcain 取得コンポーネントとして使用できます。 ここに示すように、client
を使ってプロジェクトに接続できます。
from promptflow.rag import get_langchain_retriever_from_index
my_index=client.indexes.get(
name="<registered_index_name>",
label="latest")
index_langchain_retriever=get_langchain_retriever_from_index(my_index.path)
index_langchain_retriever.get_relevant_documents("<your search query>")
インデックスを使用するための質疑応答機能
ローカルまたはクラウドでインデックスを構築する方法について説明しました。 このインデックスを使って、ユーザーの質問を受け入れ、インデックス データから回答を提供する QnA 関数を構築します。 まず、ここに示すように、langchain_retriever としてインデックスを取得します。 ここでは、この retriever
を関数で使います。 この関数は、AzureChatOpenAI
コンストラクターで定義されている LLM を使います。 インデックスを langchain_retriever として使ってデータのクエリを実行します。 コンテキストと質問を受け入れるプロンプト テンプレートを構築します。 langchain の RetrievalQA.from_chain_type
を使って、これらすべてをまとめて答えを取得します。
def qna(question: str, temperature: float = 0.0, prompt_template: object = None) -> str:
from langchain import PromptTemplate
from langchain.chains import RetrievalQA
from langchain_openai import AzureChatOpenAI
llm = AzureChatOpenAI(
openai_api_version="2023-06-01-preview",
api_key="<your-azure-openai-api-key>",
azure_endpoint="https://<your-azure-openai-service>.openai.azure.com/",
azure_deployment="<your-chat-model-deployment>", # verify the model name and deployment name
temperature=temperature,
)
template = """
System:
You are an AI assistant helping users answer questions given a specific context.
Use the following pieces of context to answer the questions as completely,
correctly, and concisely as possible.
Your answer should only come from the context. Don't try to make up an answer.
Do not add documentation reference in the response.
{context}
---
Question: {question}
Answer:"
"""
prompt_template = PromptTemplate(template=template, input_variables=["context", "question"])
qa = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff",
retriever=index_langchain_retriever,
return_source_documents=True,
chain_type_kwargs={
"prompt": prompt_template,
},
)
response = qa(question)
return {
"question": response["query"],
"answer": response["result"],
"context": "\n\n".join([doc.page_content for doc in response["source_documents"]]),
}
確実に回答を得るための質問をしてみましょう。
result = qna("<your question>")
print(result["answer"])