你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
如何使用代码生成和使用索引
重要
本文中标记了“(预览版)”的项目目前为公共预览版。 此预览版未提供服务级别协议,不建议将其用于生产工作负载。 某些功能可能不受支持或者受限。 有关详细信息,请参阅 Microsoft Azure 预览版补充使用条款。
本文介绍如何从代码创建索引并使用它。 若要在本地创建索引,请使用 promptflow-rag
包。 若要在云中创建远程索引,请使用 azure-ai-ml
包。 我们通过 langchain
来使用索引。
先决条件
您必须具有:
用于为示例产品和客户数据编制索引的 Azure AI 搜索服务连接。 如果没有 Azure AI 搜索服务,可以在 Azure 门户中创建一个,或点击此处以查看说明。
用于嵌入的模型:
在本地生成和使用索引
可以在本地生成和使用索引。
本地索引操作所需的包
安装在创建本地索引时所需的以下包。
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")
)
注意
环境变量旨在本地环境中提升便利性。 但是,如果注册使用环境变量创建的本地索引,则该索引可能无法按预期运行,因为环境变量中的机密不会传输到云索引。 若要解决此问题,可以在注册之前使用 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 存储
可以使用以下代码示例来使用这些源中的任何一个,并配置我们的 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 存储 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"])