Condividi tramite


Esercitazione: Ottimizzare la pertinenza (RAG in Ricerca di intelligenza artificiale di Azure)

In questa esercitazione viene illustrato come migliorare la pertinenza dei risultati della ricerca usati nelle soluzioni RAG. L'ottimizzazione della pertinenza può essere un fattore importante nella distribuzione di una soluzione RAG che soddisfa le aspettative degli utenti. In Ricerca di intelligenza artificiale di Azure l'ottimizzazione della pertinenza include la classificazione semantica L2 e i profili di punteggio.

Per implementare queste funzionalità, rivedere lo schema dell'indice per aggiungere configurazioni per i profili di classificazione semantica e punteggio. È quindi possibile rieseguire le query usando i nuovi costrutti.

In questa esercitazione si modificano l'indice di ricerca e le query esistenti da usare:

  • Classificazione semantica L2
  • Profilo di assegnazione dei punteggi per il boosting dei documenti

Questa esercitazione aggiorna l'indice di ricerca creato dalla pipeline di indicizzazione. Gli aggiornamenti non influiscono sul contenuto esistente, quindi non è necessaria alcuna ricompilazione e non è necessario rieseguire l'indicizzatore.

Nota

In anteprima sono disponibili altre funzionalità di pertinenza, tra cui il peso delle query vettoriali e l'impostazione delle soglie minime, ma vengono omesse da questa esercitazione perché sono in anteprima.

Prerequisiti

  • Visual Studio Code con l'estensione Python e il pacchetto Jupyter.

  • Ricerca di intelligenza artificiale di Azure, livello Basic o superiore per l'identità gestita e la classificazione semantica, nella stessa area di Azure OpenAI e dei servizi di intelligenza artificiale di Azure.

  • Azure OpenAI, con una distribuzione di text-embedding-002 e gpt-35-turbo, nella stessa area di Ricerca di intelligenza artificiale di Azure.

Scaricare l'esempio

Il notebook di esempio include un indice aggiornato e una richiesta di query.

Eseguire una query di base per il confronto

Iniziamo con una nuova query: "Ci sono formazioni di nuvole specifiche per gli oceani e grandi corpi d'acqua?".

Per confrontare i risultati dopo l'aggiunta di funzionalità di pertinenza, eseguire la query sullo schema di indice esistente prima di aggiungere una classificazione semantica o un profilo di punteggio.

Per il cloud Azure per enti pubblici, modificare l'endpoint API nel provider di token 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)

L'output di questa richiesta potrebbe essere simile all'esempio seguente.

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

Aggiornare l'indice per la classificazione semantica e i profili di punteggio

In un'esercitazione precedente è stato progettato uno schema di indice per i carichi di lavoro RAG. Sono stati omessi miglioramenti della pertinenza da tale schema in modo da potersi concentrare sui concetti fondamentali. Rinviare la pertinenza a un esercizio separato offre un confronto prima e dopo la qualità dei risultati della ricerca dopo l'esecuzione degli aggiornamenti.

  1. Aggiornare le istruzioni import in modo da includere le classi per i profili di classificazione semantica e di punteggio.

     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
     )
    
  2. Aggiungere la configurazione semantica seguente all'indice di ricerca. Questo esempio è disponibile nel passaggio dello schema di aggiornamento nel 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])
    

    Una configurazione semantica ha un nome e un elenco di campi con priorità per ottimizzare gli input in base al rango semantico. Per altre informazioni, vedere Configurare la classificazione semantica.

  3. Aggiungere quindi una definizione del profilo di punteggio. Come per la configurazione semantica, è possibile aggiungere un profilo di punteggio a uno schema di indice in qualsiasi momento. Questo esempio si trova anche nel passaggio dello schema di aggiornamento nel notebook, seguendo la configurazione semantica.

    # New scoring profile
    scoring_profiles = [  
        ScoringProfile(  
            name="my-scoring-profile",
            functions=[
                TagScoringFunction(  
                    field_name="locations",  
                    boost=5.0,  
                    parameters=TagScoringParameters(  
                        tags_parameter="tags",  
                    ),  
                ) 
            ]
        )
    ]
    

    Questo profilo usa la funzione tag che aumenta i punteggi dei documenti in cui è stata trovata una corrispondenza nel campo locations. Tenere presente che l'indice di ricerca ha un campo vettoriale e più campi non di filtro per titolo, blocchi e posizioni. Il campo locations è una raccolta di stringhe e le raccolte di stringhe possono essere incrementate usando la funzione tags in un profilo di assegnazione dei punteggi. Per altre informazioni, vedere Aggiungere un profilo di punteggio e Migliorare la pertinenza della ricerca con Il boosting dei documenti (post di blog).

  4. Aggiornare la definizione dell'indice nel servizio di ricerca.

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

Aggiornare le query per la classificazione semantica e i profili di punteggio

In un'esercitazione precedente sono state eseguite query eseguite nel motore di ricerca, passando la risposta e altre informazioni a un LLM per il completamento della chat.

In questo esempio viene modificata la richiesta di query per includere la configurazione semantica e il profilo di punteggio.

Per il cloud Azure per enti pubblici, modificare l'endpoint API nel provider di token 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)

L'output di una query con classificazione semantica e con boosting potrebbe essere simile all'esempio seguente.

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.

L'aggiunta di profili di classificazione semantica e punteggio influisce positivamente sulla risposta da LLM promuovendo i risultati che soddisfano i criteri di assegnazione dei punteggi e sono semanticamente rilevanti.

Ora che si ha una migliore comprensione dell'indice e della progettazione di query, è possibile procedere all'ottimizzazione della velocità e della concisione. Si rivisita la definizione dello schema per implementare la quantizzazione e la riduzione dell'archiviazione, ma il resto della pipeline e dei modelli rimane intatto.

Passaggio successivo