Come compilare e utilizzare un indice usando il codice
Importante
Gli elementi contrassegnati (anteprima) in questo articolo sono attualmente disponibili in anteprima pubblica. Questa anteprima viene fornita senza un contratto di servizio e non è consigliabile per i carichi di lavoro di produzione. Alcune funzionalità potrebbero non essere supportate o potrebbero presentare funzionalità limitate. Per altre informazioni, vedere le Condizioni supplementari per l'uso delle anteprime di Microsoft Azure.
Questo articolo illustra come creare un indice e usarlo dal codice. Per creare un indice in locale, viene usato il pacchetto promptflow-rag
. Per creare un indice remoto nel cloud, viene usato il pacchetto azure-ai-ml
. Gli indici vengono usati tramite langchain
.
Prerequisiti
Devi avere:
Una connessione al servizio Azure AI Search per indicizzare i dati del prodotto e del cliente di esempio. Se non si dispone di un servizio di Azure AI Search, è possibile crearne uno dal portale di Azure o vedere le istruzioni qui.
Modelli per l'incorporamento:
- È possibile usare un modello di incorporamento ada-002 dal Servizio OpenAI di Azure. Le istruzioni per la distribuzione sono disponibili qui.
- OPPURE è possibile usare qualsiasi altro modello di incorporamento distribuito nel progetto di Studio AI. In questo esempio viene usato l'incorporamento multilingue Cohere. Le istruzioni per la distribuzione di questo modello sono disponibili qui.
Compilare e usare un indice in locale
È possibile compilare e utilizzare un indice in locale.
Pacchetti necessari per le operazioni sugli indici locali
Installare i pacchetti seguenti necessari per la creazione dell'indice locale.
pip install promptflow-rag langchain langchain-openai
Configurare AI Search per l'uso locale
Azure AI Search viene usata come archivio di indici. Per iniziare, è possibile configurare il servizio Azure AI Search usando il codice seguente:
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"
Creare un indice in locale usando gli incorporamenti di OpenAI di Azure
Per creare un indice che usa incorporamenti OpenAI di Azure, si configurano le variabili di ambiente per la connessione al modello.
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/"
A questo punto è possibile compilare l'indice usando la funzione 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
)
Il codice precedente compila un indice in locale. Usa le variabili di ambiente per ottenere il servizio AI Search e anche per connettersi al modello di incorporamento di OpenAI di Azure.
Compilare un indice in locale usando altri modelli di incorporamento distribuiti nel progetto di Studio AI
Per creare un indice che usa un modello di incorporamento distribuito nel progetto di Studio AI, viene configurata la connessione al modello usando ConnectionConfig
come illustrato di seguito. subscription
, resource_group
e workspace
fanno riferimento al progetto in cui è installato il modello di incorporamento. connection_name
fa riferimento al nome della connessione per il modello, disponibile nella pagina delle impostazioni del progetto di Studio AI.
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>"
)
A questo punto è possibile compilare l'indice usando la funzione 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
)
Il codice precedente compila un indice in locale. Usa le variabili di ambiente per ottenere il servizio AI Search e la configurazione della connessione per connettersi al modello di incorporamento.
Utilizzo di un indice locale
L'indice locale creato può essere usato come retriever langchain per le query di ricerca.
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>")
Registrazione dell'indice nel progetto di Studio AI (facoltativo)
In modo facoltativo, è possibile registrare l'indice nel progetto di Studio AI in modo che l'utente o altri utenti autorizzati ad accedere al progetto possano usarlo dal cloud. Prima di procedere installare i pacchetti necessari per le operazioni remote.
Connettersi al progetto
# 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
e workspace
nel codice precedente fanno riferimento al progetto a cui si vuole connettersi.
Registrare l'indice
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
Le variabili di ambiente sono destinate per praticità a un ambiente locale. Tuttavia, se si registra un indice locale creato usando variabili di ambiente, l'indice potrebbe non funzionare come previsto perché i segreti delle variabili di ambiente non verranno trasferiti all'indice cloud. Per risolvere questo problema, è possibile usare ConnectionConfig
o connection_id
per creare un indice locale prima della registrazione.
Compilare un indice (in remoto) nel progetto di Studio AI
Viene creato un indice nel cloud nel progetto di Studio AI.
Pacchetti necessari per le operazioni sugli indici remoti
Installare i pacchetti seguenti necessari per la creazione dell'indice remoto.
pip install azure-ai-ml promptflow-rag langchain langchain-openai
Connettersi al progetto di Studio AI
Per iniziare, ci si connette al progetto. subscription
, resource_group
e workspace
nel codice seguente fanno riferimento al progetto a cui si vuole connettersi.
# 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>"
)
Ottenere la connessione al servizio AI Search
Questo progetto deve avere una connessione al servizio di ricerca di intelligenza artificiale. I dettagli vengono recuperati dal progetto.
ai_search_connection = client.connections.get("<ai_search_connection>")
Connettersi ai modelli di incorporamento
È possibile connettersi a OpenAI di Azure usando connessioni Microsoft Entra ID o connessioni basate su chiavi 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")
È possibile connettersi al modello di incorporamento distribuito nel progetto di Studio AI (modelli diversi da OpenAI di Azure) usando la connessione serverless.
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)
Selezionare i dati di input per compilare l'indice
È possibile compilare l'indice dai tipi di input seguenti:
- File e cartelle locali
- Repository GitHub
- Archiviazione di Azure
È possibile usare l'esempio di codice seguente per usare una di queste origini e configurare 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}"
Compilare l'indice nel cloud
È ora possibile compilare l'indice usando ai_search_connection
, embeddings_model_config
e input_source
. Usiamo la funzione build_index
. Se si usa un URL di Archiviazione di Azure come origine di input, è anche necessario fornire un 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
)
A seconda delle dimensioni dei dati dell'origine di input, il completamento dei passaggi precedenti potrebbe richiedere del tempo. Al termine del processo, è possibile recuperare l'oggetto indice.
my_index=client.indexes.get(name="<index_name>", label="latest")
Utilizzo di un indice registrato dal progetto
Per utilizzare un indice registrato dal progetto, è necessario connettersi al progetto e recuperare l'indice. L'indice recuperato può essere usato come retriever langchain per utilizzarlo. È possibile connettersi al progetto con un client
come illustrato di seguito.
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>")
Funzione Domande e risposte per l'uso dell'indice
È stato illustrato come creare un indice in locale o nel cloud. Usando questo indice, viene compilata una funzione di domande e risposte che accetta una domanda utente e fornisce una risposta dai dati dell'indice. Prima di tutto, si ottiene l'indice come langchain_retriever come illustrato qui. Questo retriever
viene ora usato nella funzione. Questa funzione usa l'LLM come definito nel costruttore AzureChatOpenAI
. Usa l'indice come langchain_retriever per eseguire query sui dati. Viene creato un modello di richiesta che accetta un contesto e una domanda. Usiamo il valore RetrievalQA.from_chain_type
di langchain per mettere insieme tutti questi elementi e ottenere le risposte.
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"]]),
}
Facciamo una domanda per assicurarci di ottenere una risposta.
result = qna("<your question>")
print(result["answer"])