Kurz: Vytvoření kanálu indexování pro RAG ve službě Azure AI Search
Zjistěte, jak vytvořit automatizovaný kanál indexování pro řešení RAG ve službě Azure AI Search. Automatizace indexování je prostřednictvím indexeru, který řídí provádění indexování a sady dovedností a poskytuje integrované bloky dat a vektorizaci jednorázově nebo opakovaně pro přírůstkové aktualizace.
V tomto kurzu se naučíte:
- Poskytnutí schématu indexu z předchozího kurzu
- Vytvoření připojení ke zdroji dat
- Vytvoření indexeru
- Vytvoření sady dovedností, která blokuje, vektorizuje a rozpozná entity
- Spuštění indexeru a kontrola výsledků
Pokud ještě nemáte předplatné Azure, vytvořte si napřed bezplatný účet.
Tip
K vytvoření kanálu můžete použít Průvodce importem a vektorizací dat. Vyzkoušejte několik rychlých startů: Vyhledávání obrázků a vektorové vyhledávání.
Požadavky
Visual Studio Code s rozšířením Pythonu a balíčkem Jupyter Další informace najdete v pythonu v editoru Visual Studio Code.
Účet azure Storage pro obecné účely Toto cvičení nahraje soubory PDF do úložiště objektů blob pro automatizované indexování.
Azure AI Search, úroveň Basic nebo vyšší pro spravované identity a sémantické řazení Zvolte oblast, která se sdílí s Azure OpenAI a službami Azure AI.
Azure OpenAI s nasazením velkého textu ve stejné oblasti jako Azure AI Search Další informace o vkládání modelů používaných v řešeních RAG najdete v tématu Volba modelů vkládání pro RAG ve službě Azure AI Search.
Účet služby Azure AI Service s více službami ve stejné oblasti jako Azure AI Search. Tento prostředek se používá pro dovednost Rozpoznávání entit, která zjišťuje umístění ve vašem obsahu.
Stažení ukázky
Stáhněte si poznámkový blok Jupyter z GitHubu a odešlete žádosti do služby Azure AI Search. Další informace najdete v tématu Stahování souborů z GitHubu.
Zadejte schéma indexu.
Otevřete nebo vytvořte poznámkový blok Jupyter (.ipynb
) v editoru Visual Studio Code, který bude obsahovat skripty, které tvoří kanál. Počáteční kroky nainstalují balíčky a shromažďují proměnné pro připojení. Po dokončení kroků nastavení můžete začít se součástmi kanálu indexování.
Začněme schématem indexu z předchozího kurzu. Je uspořádaná kolem vektorizovaných a nevectorizovaných bloků dat. Obsahuje locations
pole, ve které se ukládá obsah vygenerovaný AI vytvořený sadou dovedností.
from azure.identity import DefaultAzureCredential
from azure.identity import get_bearer_token_provider
from azure.search.documents.indexes import SearchIndexClient
from azure.search.documents.indexes.models import (
SearchField,
SearchFieldDataType,
VectorSearch,
HnswAlgorithmConfiguration,
VectorSearchProfile,
AzureOpenAIVectorizer,
AzureOpenAIVectorizerParameters,
SearchIndex
)
credential = DefaultAzureCredential()
# Create a search index
index_name = "py-rag-tutorial-idx"
index_client = SearchIndexClient(endpoint=AZURE_SEARCH_SERVICE, credential=credential)
fields = [
SearchField(name="parent_id", type=SearchFieldDataType.String),
SearchField(name="title", type=SearchFieldDataType.String),
SearchField(name="locations", type=SearchFieldDataType.Collection(SearchFieldDataType.String), filterable=True),
SearchField(name="chunk_id", type=SearchFieldDataType.String, key=True, sortable=True, filterable=True, facetable=True, analyzer_name="keyword"),
SearchField(name="chunk", type=SearchFieldDataType.String, sortable=False, filterable=False, facetable=False),
SearchField(name="text_vector", type=SearchFieldDataType.Collection(SearchFieldDataType.Single), vector_search_dimensions=1024, vector_search_profile_name="myHnswProfile")
]
# Configure the vector search configuration
vector_search = VectorSearch(
algorithms=[
HnswAlgorithmConfiguration(name="myHnsw"),
],
profiles=[
VectorSearchProfile(
name="myHnswProfile",
algorithm_configuration_name="myHnsw",
vectorizer_name="myOpenAI",
)
],
vectorizers=[
AzureOpenAIVectorizer(
vectorizer_name="myOpenAI",
kind="azureOpenAI",
parameters=AzureOpenAIVectorizerParameters(
resource_url=AZURE_OPENAI_ACCOUNT,
deployment_name="text-embedding-3-large",
model_name="text-embedding-3-large"
),
),
],
)
# Create the search index
index = SearchIndex(name=index_name, fields=fields, vector_search=vector_search)
result = index_client.create_or_update_index(index)
print(f"{result.name} created")
Vytvoření připojení ke zdroji dat
V tomto kroku nastavte ukázková data a připojení ke službě Azure Blob Storage. Indexer načte soubory PDF z kontejneru. V tomto kroku vytvoříte kontejner a nahrajete soubory.
Původní elektronická kniha je velká, více než 100 stránek a velikost 35 MB. Rozdělili jsme ho na menší soubory PDF, jednu na stránku textu, abychom zůstali pod limitem dokumentu pro indexery 16 MB na volání rozhraní API a také limity dat rozšiřování AI. Pro zjednodušení vynecháme vektorizaci obrázků pro toto cvičení.
Přihlaste se k webu Azure Portal a vyhledejte svůj účet Azure Storage.
Vytvořte kontejner a nahrajte soubory PDF z earth_book_2019_text_pages.
Ujistěte se, že azure AI Search má pro prostředek oprávnění čtenáře dat objektů blob úložiště.
Dále v editoru Visual Studio Code definujte zdroj dat indexeru, který poskytuje informace o připojení během indexování.
from azure.search.documents.indexes import SearchIndexerClient from azure.search.documents.indexes.models import ( SearchIndexerDataContainer, SearchIndexerDataSourceConnection ) # Create a data source indexer_client = SearchIndexerClient(endpoint=AZURE_SEARCH_SERVICE, credential=credential) container = SearchIndexerDataContainer(name="nasa-ebooks-pdfs-all") data_source_connection = SearchIndexerDataSourceConnection( name="py-rag-tutorial-ds", type="azureblob", connection_string=AZURE_STORAGE_CONNECTION, container=container ) data_source = indexer_client.create_or_update_data_source_connection(data_source_connection) print(f"Data source '{data_source.name}' created or updated")
Pokud nastavíte spravovanou identitu pro Azure AI Search pro připojení, připojovací řetězec obsahuje příponuResourceId=
. Měl by vypadat podobně jako v následujícím příkladu: "ResourceId=/subscriptions/FAKE-SUBCRIPTION=ID/resourceGroups/FAKE-RESOURCE-GROUP/providers/Microsoft.Storage/storageAccounts/FAKE-ACCOUNT;"
Vytvoření sady dovedností
Dovednosti jsou základem pro integrované vytváření bloků dat a vektorizaci. Minimálně chcete, aby dovednost Rozdělení textu blokovala obsah, a dovednost vkládání, která vytváří vektorové reprezentace blokovaného obsahu.
V této sadě dovedností se k vytváření strukturovaných dat v indexu používá další dovednost. Dovednost Rozpoznávání entit se používá k identifikaci míst, která mohou být v rozsahu od správných názvů až po obecné odkazy, například "oceán" nebo "hora". Když budete mít strukturovaná data, získáte další možnosti pro vytváření zajímavých dotazů a zvýšení relevance.
AZURE_AI_MULTISERVICE_KEY je potřeba, i když používáte řízení přístupu na základě role. Azure AI Search používá klíč pro účely fakturace a vyžaduje se, pokud vaše úlohy zůstanou pod limitem bezplatného využití. Pokud používáte nejnovější rozhraní API verze Preview nebo beta balíčky, můžete také použít připojení bez klíčů. Další informace najdete v tématu Připojení prostředku Azure AI s více službami k sadě dovedností.
from azure.search.documents.indexes.models import (
SplitSkill,
InputFieldMappingEntry,
OutputFieldMappingEntry,
AzureOpenAIEmbeddingSkill,
EntityRecognitionSkill,
SearchIndexerIndexProjection,
SearchIndexerIndexProjectionSelector,
SearchIndexerIndexProjectionsParameters,
IndexProjectionMode,
SearchIndexerSkillset,
CognitiveServicesAccountKey
)
# Create a skillset
skillset_name = "py-rag-tutorial-ss"
split_skill = SplitSkill(
description="Split skill to chunk documents",
text_split_mode="pages",
context="/document",
maximum_page_length=2000,
page_overlap_length=500,
inputs=[
InputFieldMappingEntry(name="text", source="/document/content"),
],
outputs=[
OutputFieldMappingEntry(name="textItems", target_name="pages")
],
)
embedding_skill = AzureOpenAIEmbeddingSkill(
description="Skill to generate embeddings via Azure OpenAI",
context="/document/pages/*",
resource_url=AZURE_OPENAI_ACCOUNT,
deployment_name="text-embedding-3-large",
model_name="text-embedding-3-large",
dimensions=1536,
inputs=[
InputFieldMappingEntry(name="text", source="/document/pages/*"),
],
outputs=[
OutputFieldMappingEntry(name="embedding", target_name="text_vector")
],
)
entity_skill = EntityRecognitionSkill(
description="Skill to recognize entities in text",
context="/document/pages/*",
categories=["Location"],
default_language_code="en",
inputs=[
InputFieldMappingEntry(name="text", source="/document/pages/*")
],
outputs=[
OutputFieldMappingEntry(name="locations", target_name="locations")
]
)
index_projections = SearchIndexerIndexProjection(
selectors=[
SearchIndexerIndexProjectionSelector(
target_index_name=index_name,
parent_key_field_name="parent_id",
source_context="/document/pages/*",
mappings=[
InputFieldMappingEntry(name="chunk", source="/document/pages/*"),
InputFieldMappingEntry(name="text_vector", source="/document/pages/*/text_vector"),
InputFieldMappingEntry(name="locations", source="/document/pages/*/locations"),
InputFieldMappingEntry(name="title", source="/document/metadata_storage_name"),
],
),
],
parameters=SearchIndexerIndexProjectionsParameters(
projection_mode=IndexProjectionMode.SKIP_INDEXING_PARENT_DOCUMENTS
),
)
cognitive_services_account = CognitiveServicesAccountKey(key=AZURE_AI_MULTISERVICE_KEY)
skills = [split_skill, embedding_skill, entity_skill]
skillset = SearchIndexerSkillset(
name=skillset_name,
description="Skillset to chunk documents and generating embeddings",
skills=skills,
index_projection=index_projections,
cognitive_services_account=cognitive_services_account
)
client = SearchIndexerClient(endpoint=AZURE_SEARCH_SERVICE, credential=credential)
client.create_or_update_skillset(skillset)
print(f"{skillset.name} created")
Vytvoření a spuštění indexeru
Indexery jsou komponenta, která nastavuje všechny procesy v pohybu. Indexer můžete vytvořit v zakázaném stavu, ale výchozí hodnota je okamžitě spustit. V tomto kurzu vytvořte a spusťte indexer, který načte data z úložiště objektů blob, provede dovednosti, včetně bloků dat a vektorizace, a načte index.
Spuštění indexeru trvá několik minut. Až to bude hotové, můžete přejít k poslednímu kroku: dotazování indexu.
from azure.search.documents.indexes.models import (
SearchIndexer,
FieldMapping
)
# Create an indexer
indexer_name = "py-rag-tutorial-idxr"
indexer_parameters = None
indexer = SearchIndexer(
name=indexer_name,
description="Indexer to index documents and generate embeddings",
skillset_name=skillset_name,
target_index_name=index_name,
data_source_name=data_source.name,
# Map the metadata_storage_name field to the title field in the index to display the PDF title in the search results
field_mappings=[FieldMapping(source_field_name="metadata_storage_name", target_field_name="title")],
parameters=indexer_parameters
)
# Create and run the indexer
indexer_client = SearchIndexerClient(endpoint=AZURE_SEARCH_SERVICE, credential=credential)
indexer_result = indexer_client.create_or_update_indexer(indexer)
print(f' {indexer_name} is created and running. Give the indexer a few minutes before running a query.')
Spuštění dotazu pro kontrolu výsledků
Odešlete dotaz, abyste potvrdili, že je index funkční. Tento požadavek převede textový řetězec "what's NASA's website?
" na vektor pro vektorové vyhledávání. Výsledky se skládají z polí v příkazu select, z nichž některé se vytisknou jako výstup.
V tuto chvíli neexistuje žádný chat ani generování umělé inteligence. Výsledky jsou doslovný obsah z indexu vyhledávání.
from azure.search.documents import SearchClient
from azure.search.documents.models import VectorizableTextQuery
# Vector Search using text-to-vector conversion of the querystring
query = "what's NASA's website?"
search_client = SearchClient(endpoint=AZURE_SEARCH_SERVICE, credential=credential, index_name=index_name)
vector_query = VectorizableTextQuery(text=query, k_nearest_neighbors=50, fields="text_vector")
results = search_client.search(
search_text=query,
vector_queries= [vector_query],
select=["chunk"],
top=1
)
for result in results:
print(f"Score: {result['@search.score']}")
print(f"Chunk: {result['chunk']}")
Tento dotaz vrátí jednu shodu (top=1
) skládající se z jednoho bloku dat určeného vyhledávacím webem tak, aby byl nejrelevavantnější. Výsledky z dotazu by měly vypadat podobně jako v následujícím příkladu:
Score: 0.01666666753590107
Chunk: national Aeronautics and Space Administration
earth Science
NASA Headquarters
300 E Street SW
Washington, DC 20546
www.nasa.gov
np-2018-05-2546-hQ
Zkuste několik dalších dotazů, abyste získali představu o tom, co vyhledávací web vrací přímo, abyste ho mohli porovnat s odpovědí s podporou LLM. Znovu spusťte předchozí skript s tímto dotazem: "patagonia geography"
a nastavte top
3, aby se vrátilo více než jedna odpověď.
Výsledky z tohoto druhého dotazu by měly vypadat podobně jako následující výsledky, které jsou mírně upraveny pro zřetězení. Výstup se zkopíruje z poznámkového bloku, který zkrátí odpověď na to, co vidíte v tomto příkladu. Můžete rozbalit výstup buňky a zkontrolovat úplnou odpověď.
Score: 0.03306011110544205
Chunk:
Swirling Bloom off Patagonia
Argentina
Interesting art often springs out of the convergence of different ideas and influences.
And so it is with nature.
Off the coast of Argentina, two strong ocean currents converge and often stir up a colorful
brew, as shown in this Aqua image from
December 2010.
This milky green and blue bloom formed on the continental shelf off of Patagonia, where warmer,
saltier waters from the subtropics
meet colder, fresher waters flowing from the south. Where these currents collide, turbulent
eddies and swirls form, pulling nutrients
up from the deep ocean. The nearby Rio de la Plata also deposits nitrogen- and iron-laden
sediment into the sea. Add in some
...
while others terminate in water. The San Rafael and San Quintín glaciers (shown at the right)
are the icefield’s largest. Both have
been receding rapidly in the past 30 years.
V tomto příkladu je jednodušší zjistit, jak se bloky vrací doslovně a jak hledání klíčových slov a podobnosti identifikuje nejvyšší shody. Tento konkrétní blok dat rozhodně obsahuje informace o Patagonii a zeměpisné oblasti, ale není přesně relevantní pro dotaz. Sémantický ranker by podporoval relevantnější bloky pro lepší odpověď, ale jako další krok se podíváme, jak připojit Azure AI Search k LLM pro konverzační vyhledávání.