Tutorial: Maximieren der Relevanz (RAG in Azure KI-Suche)
In diesem Tutorial erfahren Sie, wie Sie die Relevanz von Suchergebnissen verbessern können, die in RAG-Lösungen (Reality Augmented Generation) verwendet werden. Die Relevanzoptimierung kann bei der Bereitstellung einer RAG-Lösung, die die Erwartungen der Benutzer erfüllt, ein wichtiger Faktor sein. In Azure KI-Suche umfasst die Relevanzoptimierung die semantische Sortierung bzw. Rangfolge (L2) und Bewertungsprofile.
Zum Implementieren dieser Funktionen überprüfen Sie das Indexschema, um Konfigurationen für die semantische Sortierung und Bewertungsprofile hinzuzufügen. Anschließend führen Sie die Abfragen mit den neuen Konstrukten erneut aus.
In diesem Tutorial ändern Sie den vorhandenen Suchindex und die zu verwendenden Abfragen:
- Semantische Sortierung (L2)
- Bewertungsprofil für das Dokumentboosting
In diesem Tutorial wird der Suchindex aktualisiert, der von der Indizierungspipeline erstellt wurde. Aktualisierungen wirken sich nicht auf die vorhandenen Inhalte aus. Daher ist keine Neuerstellung erforderlich, und Sie müssen den Indexer nicht erneut ausführen.
Hinweis
Es gibt weitere Relevanzfeatures, die derzeit in der Vorschau sind, darunter die Gewichtung von Vektorabfragen und das Festlegen von Mindestschwellenwerten. Diese Features werden in diesem Tutorial jedoch nicht behandelt, da es sich um Previewfunktionen handelt.
Voraussetzungen
Visual Studio Code mit der Python-Erweiterung und dem Jupyter-Paket
Azure KI-Suche (mindestens Basic-Tarif für verwaltete Identität und semantische Sortierung) in der gleichen Region wie Azure OpenAI und Azure KI Services.
Azure OpenAI mit einer Bereitstellung von „text-embedding-002“ und „gpt-35-turbo“ in der gleichen Region wie Azure KI-Suche.
Herunterladen des Beispiels
Das Beispielnotebook enthält einen aktualisierten Index und eine aktualisierte Abfrageanforderung.
Ausführen einer Baselineabfrage zum Vergleich
Beginnen wir mit einer neuen Abfrage: „Are there any cloud formations specific to oceans and large bodies of water?“ (Gibt es Wolkenformationen, die für Meere und große Gewässer typisch sind?).
Um die Ergebnisse nach dem Hinzufügen von Relevanzfeatures zu vergleichen, führen Sie die Abfrage mit dem vorhandenen Indexschema aus, bevor Sie die semantische Sortierung oder ein Bewertungsprofil hinzufügen.
Ändern Sie für die Azure Government-Cloud den API-Endpunkt des Tokenanbieters in "https://cognitiveservices.azure.us/.default"
.
from azure.search.documents import SearchClient
from openai import AzureOpenAI
token_provider = get_bearer_token_provider(credential, "https://cognitiveservices.azure.com/.default")
openai_client = AzureOpenAI(
api_version="2024-06-01",
azure_endpoint=AZURE_OPENAI_ACCOUNT,
azure_ad_token_provider=token_provider
)
deployment_name = "gpt-4o"
search_client = SearchClient(
endpoint=AZURE_SEARCH_SERVICE,
index_name=index_name,
credential=credential
)
GROUNDED_PROMPT="""
You are an AI assistant that helps users learn from the information found in the source material.
Answer the query using only the sources provided below.
Use bullets if the answer has multiple points.
If the answer is longer than 3 sentences, provide a summary.
Answer ONLY with the facts listed in the list of sources below. Cite your source when you answer the question
If there isn't enough information below, say you don't know.
Do not generate answers that don't use the sources below.
Query: {query}
Sources:\n{sources}
"""
# Focused query on cloud formations and bodies of water
query="Are there any cloud formations specific to oceans and large bodies of water?"
vector_query = VectorizableTextQuery(text=query, k_nearest_neighbors=50, fields="text_vector")
search_results = search_client.search(
search_text=query,
vector_queries= [vector_query],
select=["title", "chunk", "locations"],
top=5,
)
sources_formatted = "=================\n".join([f'TITLE: {document["title"]}, CONTENT: {document["chunk"]}, LOCATIONS: {document["locations"]}' for document in search_results])
response = openai_client.chat.completions.create(
messages=[
{
"role": "user",
"content": GROUNDED_PROMPT.format(query=query, sources=sources_formatted)
}
],
model=deployment_name
)
print(response.choices[0].message.content)
Die Ausgabe dieser Anforderung könnte wie das folgende Beispiel aussehen.
Yes, there are cloud formations specific to oceans and large bodies of water.
A notable example is "cloud streets," which are parallel rows of clouds that form over
the Bering Strait in the Arctic Ocean. These cloud streets occur when wind blows from
a cold surface like sea ice over warmer, moister air near the open ocean, leading to
the formation of spinning air cylinders. Clouds form along the upward cycle of these cylinders,
while skies remain clear along the downward cycle (Source: page-21.pdf).
Aktualisieren des Indexes für die semantische Sortierung und Bewertungsprofile
In einem vorherigen Tutorial haben Sie ein Indexschema für RAG-Workloads entworfen. Wir haben bewusst auf Relevanzverbesserungen in diesem Schema verzichtet, damit Sie sich auf das Wesentliche konzentrieren können. Indem wir die Relevanz zurückstellen und in einer separaten Übung behandeln, erhalten Sie einen Vorher-Nachher-Vergleich der Qualität der Suchergebnisse, nachdem die Aktualisierungen vorgenommen wurden.
Aktualisieren Sie die Importanweisungen, um Klassen für die semantische Sortierung und Bewertungsprofile einzuschließen.
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, SemanticConfiguration, SemanticPrioritizedFields, SemanticField, SemanticSearch, ScoringProfile, TagScoringFunction, TagScoringParameters )
Fügen Sie dem Suchindex die folgende Semantikkonfiguration hinzu. Dieses Beispiel finden Sie im Schritt „Aktualisieren des Schemas“ im Notebook.
# New semantic configuration semantic_config = SemanticConfiguration( name="my-semantic-config", prioritized_fields=SemanticPrioritizedFields( title_field=SemanticField(field_name="title"), keywords_fields=[SemanticField(field_name="locations")], content_fields=[SemanticField(field_name="chunk")] ) ) # Create the semantic settings with the configuration semantic_search = SemanticSearch(configurations=[semantic_config])
Eine Semantikkonfiguration hat einen Namen und verfügt über eine priorisierte Liste von Feldern, um die Eingaben für den semantischen Sortierer zu optimieren. Weitere Informationen finden Sie unter Konfigurieren der semantischen Rangfolge.
Fügen Sie als Nächstes eine Bewertungsprofildefinition hinzu. Genau wie die Semantikkonfiguration, kann ein Bewertungsprofil einem Indexschema jederzeit hinzugefügt werden. Dieses Beispiel ist ebenfalls im Schritt „Aktualisieren des Schemas“ im Notebook enthalten (nach der Semantikkonfiguration).
# New scoring profile scoring_profiles = [ ScoringProfile( name="my-scoring-profile", functions=[ TagScoringFunction( field_name="locations", boost=5.0, parameters=TagScoringParameters( tags_parameter="tags", ), ) ] ) ]
Dieses Profil verwendet die Tagfunktion, die die Bewertungen von Dokumenten verstärkt, bei denen eine Übereinstimmung im Feld „locations“ gefunden wurde. Denken Sie daran, dass der Suchindex über ein Vektorfeld und mehrere Nichtvektorfelder für Titel, Blöcke und Speicherorte verfügt. Das Feld „locations“ ist eine Zeichenfolgensammlung, und Zeichenfolgensammlungen können mithilfe der Tags-Funktion in einem Bewertungsprofil verstärkt werden. Weitere Informationen finden Sie unter Hinzufügen eines Bewertungsprofils und im Blogbeitrag Enhancing Search Relevance with Document Boosting (Verbessern der Suchrelevanz mit Dokumentboosting).
Aktualisieren Sie die Indexdefinition für den Suchdienst.
# Update the search index with the semantic configuration index = SearchIndex(name=index_name, fields=fields, vector_search=vector_search, semantic_search=semantic_search, scoring_profiles=scoring_profiles) result = index_client.create_or_update_index(index) print(f"{result.name} updated")
Aktualisieren von Abfragen für die semantische Sortierung und Bewertungsprofile
In einem vorherigen Tutorial haben Sie auf der Suchmaschine ausgeführte Abfragen ausgeführt und die Antwort sowie andere Informationen an ein LLM (Large Language Model) für die Chatvervollständigung übergeben.
In diesem Beispiel wird die Abfrageanforderung so geändert, dass sie die Semantikkonfiguration und das Bewertungsprofil enthält.
Ändern Sie für die Azure Government-Cloud den API-Endpunkt des Tokenanbieters in "https://cognitiveservices.azure.us/.default"
.
# Import libraries
from azure.search.documents import SearchClient
from openai import AzureOpenAI
token_provider = get_bearer_token_provider(credential, "https://cognitiveservices.azure.com/.default")
openai_client = AzureOpenAI(
api_version="2024-06-01",
azure_endpoint=AZURE_OPENAI_ACCOUNT,
azure_ad_token_provider=token_provider
)
deployment_name = "gpt-4o"
search_client = SearchClient(
endpoint=AZURE_SEARCH_SERVICE,
index_name=index_name,
credential=credential
)
# Prompt is unchanged in this update
GROUNDED_PROMPT="""
You are an AI assistant that helps users learn from the information found in the source material.
Answer the query using only the sources provided below.
Use bullets if the answer has multiple points.
If the answer is longer than 3 sentences, provide a summary.
Answer ONLY with the facts listed in the list of sources below.
If there isn't enough information below, say you don't know.
Do not generate answers that don't use the sources below.
Query: {query}
Sources:\n{sources}
"""
# Queries are unchanged in this update
query="Are there any cloud formations specific to oceans and large bodies of water?"
vector_query = VectorizableTextQuery(text=query, k_nearest_neighbors=50, fields="text_vector")
# Add query_type semantic and semantic_configuration_name
# Add scoring_profile and scoring_parameters
search_results = search_client.search(
query_type="semantic",
semantic_configuration_name="my-semantic-config",
scoring_profile="my-scoring-profile",
scoring_parameters=["tags-ocean, 'sea surface', seas, surface"],
search_text=query,
vector_queries= [vector_query],
select="title, chunk, locations",
top=5,
)
sources_formatted = "=================\n".join([f'TITLE: {document["title"]}, CONTENT: {document["chunk"]}, LOCATIONS: {document["locations"]}' for document in search_results])
response = openai_client.chat.completions.create(
messages=[
{
"role": "user",
"content": GROUNDED_PROMPT.format(query=query, sources=sources_formatted)
}
],
model=deployment_name
)
print(response.choices[0].message.content)
Die Ausgabe einer semantisch sortierten und verbesserten Abfrage kann wie im folgenden Beispiel aussehen.
Yes, there are specific cloud formations influenced by oceans and large bodies of water:
- **Stratus Clouds Over Icebergs**: Low stratus clouds can frame holes over icebergs,
such as Iceberg A-56 in the South Atlantic Ocean, likely due to thermal instability caused
by the iceberg (source: page-39.pdf).
- **Undular Bores**: These are wave structures in the atmosphere created by the collision
of cool, dry air from a continent with warm, moist air over the ocean, as seen off the
coast of Mauritania (source: page-23.pdf).
- **Ship Tracks**: These are narrow clouds formed by water vapor condensing around tiny
particles from ship exhaust. They are observed over the oceans, such as in the Pacific Ocean
off the coast of California (source: page-31.pdf).
These specific formations are influenced by unique interactions between atmospheric conditions
and the presence of large water bodies or objects within them.
Das Hinzufügen von semantischer Sortierung und Bewertungsprofilen wirkt sich positiv auf die Antwort des LLM aus, da es zu Ergebnissen führt, die die Bewertungskriterien erfüllen und semantisch relevant sind.
Nachdem Sie nun ein besseres Verständnis des Index- und Abfrageentwurfs haben, befassen wir uns als Nächstes mit der Optimierung im Hinblick auf Geschwindigkeit und Klarheit. Wir überarbeiten die Schemadefinition, um Quantisierung und Speicherreduzierung zu implementieren, die restliche Pipeline und die Modelle bleiben jedoch unverändert.