Como criar e consumir um índice usando código
Importante
Os itens marcados (visualização) neste artigo estão atualmente em visualização pública. Essa visualização é fornecida sem um contrato de nível de serviço e não a recomendamos para cargas de trabalho de produção. Algumas funcionalidades poderão não ser suportadas ou poderão ter capacidades limitadas. Para obter mais informações, veja Termos Suplementares de Utilização para Pré-visualizações do Microsoft Azure.
Neste artigo, você aprenderá a criar um índice e consumi-lo a partir do código. Para criar um índice localmente, usamos o promptflow-rag
pacote. Para criar um índice remoto na nuvem, usamos o azure-ai-ml
pacote. Consumimos os índices usando langchain
.
Pré-requisitos
Tem de ter:
Uma conexão de serviço do Azure AI Search para indexar o produto de exemplo e os dados do cliente. Se não tiver um serviço Azure AI Search, pode criar um a partir do portal do Azure ou ver as instruções aqui.
Modelos para incorporação:
- Você pode usar um modelo de incorporação ada-002 do Azure OpenAI. As instruções para implantar podem ser encontradas aqui.
- OU você pode usar qualquer outro modelo de incorporação implantado em seu projeto do AI Studio. Neste exemplo, usamos a incorporação multilingue Cohere. As instruções para implantar este modelo podem ser encontradas aqui.
Criar e consumir um índice localmente
Podemos construir e consumir um índice localmente.
Pacotes necessários para operações de índice local
Instale os seguintes pacotes necessários para a criação de índice local.
pip install promptflow-rag langchain langchain-openai
Configurar a Pesquisa de IA para uso local
Usamos o Azure AI Search como o repositório de índice. Para começar, podemos configurar o serviço Azure AI Search usando o seguinte código:
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"
Criar um índice localmente usando incorporações do Azure OpenAI
Para criar um índice que usa incorporações do Azure OpenAI, configuramos variáveis de ambiente para se conectar ao modelo.
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/"
Agora vamos construir o índice usando a build_index
função.
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
)
O código acima cria um índice localmente. Ele usa variáveis de ambiente para obter o serviço AI Search e também para se conectar ao modelo de incorporação do Azure OpenAI.
Crie um índice localmente usando outros modelos de incorporação implantados em seu projeto do AI Studio
Para criar um índice que usa um modelo de incorporação implantado em seu projeto do AI Studio, configuramos a conexão com o modelo usando um ConnectionConfig
como mostrado abaixo. O subscription
, resource_group
e workspace
refere-se ao projeto onde o modelo de incorporação está instalado. O connection_name
refere-se ao nome da conexão para o modelo, que pode ser encontrado na página de configurações do projeto 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>"
)
Agora vamos construir o índice usando a build_index
função.
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
)
O código acima cria um índice localmente. Ele usa variáveis de ambiente para obter o serviço AI Search e a configuração de conexão para se conectar ao modelo de incorporação.
Consumindo um índice local
O índice local criado pode ser usado como um langchain retriever para consumi-lo para consultas de pesquisa.
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>")
Registrando o índice em seu projeto do AI Studio (opcional)
Opcionalmente, você pode registrar o índice em seu projeto do AI Studio para que você ou outras pessoas que tenham acesso ao seu projeto possam usá-lo a partir da nuvem. Antes de continuar, instale os pacotes necessários para operações remotas.
Conecte-se ao projeto
# 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>"
)
O subscription
, resource_group
e workspace
no código acima refere-se ao projeto ao qual você deseja se conectar.
Registar o índice
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")
)
Nota
As variáveis de ambiente destinam-se à conveniência em um ambiente local. No entanto, se você registrar um índice local criado usando variáveis de ambiente, o índice pode não funcionar como esperado porque os segredos das variáveis de ambiente não serão transferidos para o índice de nuvem. Para resolver esse problema, você pode usar um ConnectionConfig
ou connection_id
para criar um índice local antes de se registrar.
Crie um índice (remotamente) em seu projeto do AI Studio
Criamos um índice na nuvem em seu projeto AI Studio.
Pacotes necessários para operações de índice remoto
Instale os seguintes pacotes necessários para a criação remota de índice.
pip install azure-ai-ml promptflow-rag langchain langchain-openai
Conecte-se ao projeto AI Studio
Para começar, conectamo-nos ao projeto. O subscription
, resource_group
e workspace
no código abaixo refere-se ao projeto ao qual você deseja se conectar.
# 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>"
)
Obtenha a conexão do serviço AI Search
Este projeto deve ter uma conexão com o serviço AI Search. Recuperamos os detalhes do projeto.
ai_search_connection = client.connections.get("<ai_search_connection>")
Ligue-se aos modelos de incorporação
Você pode se conectar ao Azure OpenAI usando conexões de ID do Microsoft Entra ou conexões baseadas em chave de API.
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")
Você pode se conectar ao modelo de incorporação implantado em seu projeto do AI Studio (modelos OpenAI não do Azure) usando a conexão sem servidor.
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)
Selecione os dados de entrada para criar o índice
Você pode criar o índice a partir dos seguintes tipos de entradas:
- Arquivos e pastas locais
- Repositórios GitHub
- Armazenamento do Azure
Podemos usar o exemplo de código a seguir para usar qualquer uma dessas fontes e configurar nosso 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}"
Crie o índice na nuvem
Agora podemos construir o índice usando o ai_search_connection
, embeddings_model_config
e input_source
. Nós usamos a build_index
função. Se você estiver usando uma URL de Armazenamento do Azure como fonte de entrada, também precisará fornecer um UserIdentityConfiguration
arquivo .
# 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
)
Dependendo do tamanho dos dados da fonte de entrada, as etapas acima podem levar algum tempo para serem concluídas. Quando o trabalho for concluído, você poderá recuperar o objeto de índice.
my_index=client.indexes.get(name="<index_name>", label="latest")
Consumir um índice registado do seu projeto
Para consumir um índice registrado do seu projeto, você precisa se conectar ao projeto e recuperar o índice. O índice recuperado pode ser usado como um langhcain retriever para consumi-lo. Você pode se conectar ao projeto com um client
como mostrado aqui.
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>")
Uma função de pergunta e resposta para usar o índice
Vimos como criar um índice localmente ou na nuvem. Usando esse índice, criamos uma função QnA que aceita uma pergunta do usuário e fornece uma resposta a partir dos dados do índice. Primeiro, vamos obter o índice como um langchain_retriever como mostrado aqui. Agora usamos isso retriever
em nossa função. Esta função usa o LLM conforme definido no AzureChatOpenAI
construtor. Ele usa o índice como um langchain_retriever para consultar os dados. Construímos um modelo rápido que aceita um contexto e uma pergunta. Usamos langchain's RetrievalQA.from_chain_type
para juntar tudo isso e nos obter as respostas.
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"]]),
}
Vamos fazer uma pergunta para garantir que obtemos uma resposta.
result = qna("<your question>")
print(result["answer"])