Udostępnij za pośrednictwem


Jak kompilować i korzystać z indeksu przy użyciu kodu

Ważne

Elementy oznaczone (wersja zapoznawcza) w tym artykule są obecnie dostępne w publicznej wersji zapoznawczej. Ta wersja zapoznawcza jest udostępniana bez umowy dotyczącej poziomu usług i nie zalecamy korzystania z niej w przypadku obciążeń produkcyjnych. Niektóre funkcje mogą być nieobsługiwane lub ograniczone. Aby uzyskać więcej informacji, zobacz Uzupełniające warunki korzystania z wersji zapoznawczych platformy Microsoft Azure.

Z tego artykułu dowiesz się, jak utworzyć indeks i korzystać z niego z kodu. Aby utworzyć indeks lokalnie, użyjemy promptflow-rag pakietu. Aby utworzyć indeks zdalny w chmurze, użyjemy azure-ai-ml pakietu . Używamy indeksów przy użyciu polecenia langchain.

Wymagania wstępne

Musisz mieć następujące rozwiązania:

  • Centrum i projekt rozwiązania Azure AI Foundry.

  • Połączenie usługi Azure AI usługa wyszukiwania z indeksem przykładowego produktu i danych klientów. Jeśli nie masz usługa wyszukiwania usługi Azure AI, możesz go utworzyć w witrynie Azure Portal lub zapoznać się z instrukcjami dostępnymi tutaj.

  • Modele osadzania:

    • Możesz użyć modelu osadzania ada-002 z poziomu usługi Azure OpenAI. Instrukcje dotyczące wdrażania można znaleźć tutaj.
    • Możesz też użyć dowolnego innego modelu osadzania wdrożonego w projekcie usługi Azure AI Foundry. W tym przykładzie używamy osadzania wielojęzycznego Cohere. Instrukcje dotyczące wdrażania tego modelu można znaleźć tutaj.

Kompilowanie i używanie indeksu lokalnie

Możemy utworzyć i korzystać z indeksu lokalnie.

Wymagane pakiety dla operacji indeksu lokalnego

Zainstaluj następujące pakiety wymagane do utworzenia indeksu lokalnego.

pip install promptflow-rag langchain langchain-openai

Konfigurowanie wyszukiwania sztucznej inteligencji do użycia lokalnego

Usługa Azure AI Search jest używana jako magazyn indeksów. Aby rozpocząć pracę, możemy skonfigurować usługa wyszukiwania azure AI przy użyciu następującego kodu:

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"

Tworzenie indeksu lokalnie przy użyciu osadzania usługi Azure OpenAI

Aby utworzyć indeks używający osadzania usługi Azure OpenAI, skonfigurujemy zmienne środowiskowe w celu nawiązania połączenia z modelem.

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/"

Teraz utwórzmy indeks przy użyciu build_index funkcji .

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
)

Powyższy kod tworzy indeks lokalnie. Używa zmiennych środowiskowych, aby uzyskać usługa wyszukiwania sztucznej inteligencji, a także połączyć się z modelem osadzania usługi Azure OpenAI.

Tworzenie indeksu lokalnie przy użyciu innych modeli osadzania wdrożonych w projekcie usługi Azure AI Foundry

Aby utworzyć indeks, który korzysta z modelu osadzania wdrożonego w projekcie usługi Azure AI Foundry, skonfigurujemy połączenie z modelem ConnectionConfig , jak pokazano poniżej. resource_group Element subscriptioni workspace odwołuje się do projektu, w którym jest zainstalowany model osadzania. Odnosi connection_name się do nazwy połączenia dla modelu, który można znaleźć na stronie ustawień projektu usługi Azure AI Foundry.

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>"
    )

Teraz utwórzmy indeks przy użyciu build_index funkcji .

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
)

Powyższy kod tworzy indeks lokalnie. Używa zmiennych środowiskowych, aby uzyskać usługa wyszukiwania sztucznej inteligencji i konfigurację połączenia w celu nawiązania połączenia z modelem osadzania.

Korzystanie z indeksu lokalnego

Utworzony indeks lokalny może służyć jako langchain retriever do korzystania z niego w przypadku zapytań wyszukiwania.

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>")

Rejestrowanie indeksu w projekcie usługi Azure AI Foundry (opcjonalnie)

Opcjonalnie możesz zarejestrować indeks w projekcie usługi Azure AI Foundry, aby umożliwić Tobie lub innym osobom mającym dostęp do projektu z chmury. Przed kontynuowaniem zainstaluj wymagane pakiety dla operacji zdalnych.

Nawiązywanie połączenia z projektem

# connect to the Azure AI Foundry 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>"
    )

Element subscription, resource_group i workspace w powyższym kodzie odnosi się do projektu, z którym chcesz nawiązać połączenie.

Rejestrowanie indeksu

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")
          )

Uwaga

Zmienne środowiskowe są przeznaczone dla wygody w środowisku lokalnym. Jeśli jednak zarejestrujesz lokalny indeks utworzony przy użyciu zmiennych środowiskowych, indeks może nie działać zgodnie z oczekiwaniami, ponieważ wpisy tajne ze zmiennych środowiskowych nie zostaną przeniesione do indeksu chmury. Aby rozwiązać ten problem, możesz użyć elementu ConnectionConfig lub connection_id , aby utworzyć indeks lokalny przed zarejestrowaniem.

Tworzenie indeksu (zdalnie) w projekcie usługi Azure AI Foundry

Tworzymy indeks w chmurze w projekcie usługi Azure AI Foundry.

Wymagane pakiety dla zdalnych operacji indeksowania

Zainstaluj następujące pakiety wymagane do zdalnego tworzenia indeksu.

pip install azure-ai-ml promptflow-rag langchain langchain-openai

Nawiązywanie połączenia z projektem azure AI Foundry

Aby rozpocząć, połączymy się z projektem. Element subscription, resource_group i workspace w poniższym kodzie odnosi się do projektu, z którym chcesz nawiązać połączenie.

# connect to the Azure AI Foundry 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>"
    )

Uzyskiwanie połączenia usługa wyszukiwania sztucznej inteligencji

Ten projekt powinien mieć połączenie z usługa wyszukiwania sztucznej inteligencji. Pobieramy szczegóły z projektu.

ai_search_connection = client.connections.get("<ai_search_connection>")

Nawiązywanie połączenia z modelami osadzania

Połączenie z usługą Azure OpenAI można nawiązać przy użyciu połączeń microsoft Entra ID lub połączeń opartych na kluczach interfejsu 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")

Za pomocą połączenia bezserwerowego można nawiązać połączenie z modelem osadzania wdrożonym w projekcie rozwiązania Azure AI Foundry (modelach innych niż 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)

Wybieranie danych wejściowych w celu skompilowania indeksu

Indeks można utworzyć na podstawie następujących typów danych wejściowych:

  • Lokalne pliki i foldery
  • Repozytoria usługi GitHub
  • Azure Storage

Możemy użyć następującego przykładu kodu, aby użyć dowolnego z tych źródeł i skonfigurować nasz input_sourceelement :

# 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}"

Tworzenie indeksu w chmurze

Teraz możemy skompilować indeks przy użyciu parametrów ai_search_connectioni embeddings_model_configinput_source. Używamy build_index funkcji . Jeśli używasz adresu URL usługi Azure Storage jako źródła danych wejściowych, musisz również podać adres 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
)

W zależności od rozmiaru danych źródła danych wejściowych wykonanie powyższych kroków może zająć trochę czasu. Po zakończeniu zadania można pobrać obiekt indeksu.

my_index=client.indexes.get(name="<index_name>", label="latest")

Korzystanie z zarejestrowanego indeksu z projektu

Aby korzystać z zarejestrowanego indeksu z projektu, musisz nawiązać połączenie z projektem i pobrać indeks. Pobrany indeks może służyć jako langhcain retriever do korzystania z niego. Możesz nawiązać połączenie z projektem za pomocą elementu , client jak pokazano tutaj.

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>")

Funkcja pytań i odpowiedzi do korzystania z indeksu

Widzieliśmy, jak utworzyć indeks lokalnie lub w chmurze. Korzystając z tego indeksu, utworzymy funkcję pytań i odpowiedzi, która akceptuje pytanie użytkownika i udostępnia odpowiedź z danych indeksu. Najpierw pobierzmy indeks jako langchain_retriever, jak pokazano tutaj. Teraz używamy tego retriever w naszej funkcji. Ta funkcja używa funkcji LLM zgodnie z definicją w konstruktorze AzureChatOpenAI . Używa indeksu jako langchain_retriever do wykonywania zapytań dotyczących danych. Tworzymy szablon monitu, który akceptuje kontekst i pytanie. Używamy langchain's RetrievalQA.from_chain_type , aby zebrać wszystkie te wszystkie razem i uzyskać nam odpowiedzi.

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"]]),
    }

Zadajmy pytanie, aby upewnić się, że otrzymamy odpowiedź.

result = qna("<your question>")
print(result["answer"])