Bewerken

Delen via


Ophalen van gegevens

Azure AI services
Azure AI Search
Azure OpenAI Service
Azure Machine Learning

Zodra u de insluitingen voor uw segmenten hebt gegenereerd, is de volgende stap het genereren van de index in de vectordatabase en het experiment om de optimale zoekopdrachten te bepalen die moeten worden uitgevoerd. Wanneer u experimenteert met het ophalen van gegevens, zijn er verschillende gebieden waarmee u rekening moet houden, waaronder configuratieopties voor de zoekindex, de typen zoekopdrachten die u moet uitvoeren en uw strategie voor het herrankeren. In dit artikel worden deze drie onderwerpen behandeld.

Dit artikel maakt deel uit van een serie. Lees de inleiding.

Zoekindex

Notitie

Azure AI Search is een eigen Azure Search-service. In deze sectie worden enkele specifieke informatie over AI Search genoemd. Als u een ander archief gebruikt, raadpleegt u de documentatie om de sleutelconfiguratie voor die service te vinden.

De zoekindex in uw winkel heeft een kolom voor elk veld in uw gegevens. Zoekarchieven bieden over het algemeen ondersteuning voor niet-vectorgegevenstypen , zoals tekenreeks, Booleaanse waarde, geheel getal, enkel, dubbel, datum/tijd en verzamelingen zoals Verzameling(één) en vectorgegevenstypen , zoals Verzameling (enkel). Voor elke kolom moet u informatie configureren, zoals het gegevenstype, of het veld filterbaar, ophaalbaar en/of doorzoekbaar is.

Hier volgen enkele belangrijke beslissingen die u moet nemen voor de configuratie van vectorzoekopdrachten die worden toegepast op vectorvelden:

  • Vectorzoekalgoritmen : het algoritme dat wordt gebruikt om te zoeken naar relatieve overeenkomsten. Azure AI Search heeft een brute-force algoritmeoptie die de volledige vectorruimte scant met de naam uitgebreide KNN en een meer presterende algoritmeoptie die een bijna dichtstbijzijnde buur (ANN) zoekopdracht uitvoert met de naam Hierarchical Navigable Small World (HNSW).
  • metrische waarde: deze configuratie is de metrische overeenkomst die wordt gebruikt voor het berekenen van de nabijheid door het algoritme. De opties in Azure AI Search zijn cosinus, dotProduct en Euclidean. Als u Azure OpenAI-insluitingsmodellen gebruikt, kiest u cosine.
  • efConstruction : parameter die wordt gebruikt tijdens de indexconstructie hierarchical Navigable Navigable Small Worlds (HNSW) waarmee het aantal dichtstbijzijnde buren wordt ingesteld dat is verbonden met een vector tijdens het indexeren. Een grotere efConstruction-waarde resulteert in een index van betere kwaliteit dan een kleiner getal. Het nadeel is dat een grotere waarde meer tijd, opslag en rekenkracht vereist. efConstruction moet hoger zijn voor een groot aantal segmenten en lager voor een laag aantal segmenten. Het bepalen van de optimale waarde vereist experimenten met uw gegevens en verwachte query's.
  • efSearch : parameter die wordt gebruikt tijdens het uitvoeren van query's om het aantal dichtstbijzijnde buren (dat wil gezegd, vergelijkbare segmenten) in te stellen dat tijdens de zoekopdracht wordt gebruikt.
  • m - Het aantal bidirectionele koppelingen. Het bereik is 4 tot 10, met lagere getallen die minder ruis retourneren in de resultaten.

In Azure AI Search worden de vectorconfiguraties ingekapseld in een vectorSearch configuratie. Wanneer u de vectorkolommen configureert, verwijst u naar de juiste configuratie voor die vectorkolom en stelt u het aantal dimensies in. Het dimensiekenmerk van de vectorkolom vertegenwoordigt het aantal dimensies dat is gegenereerd door het insluitmodel dat u hebt gekozen. Het model dat is geoptimaliseerd voor text-embedding-3-small opslag genereert bijvoorbeeld 1536 dimensies.

Zoekopdrachten

Wanneer u query's uitvoert vanuit uw promptorchestrator voor uw zoekarchief, hebt u veel opties om rekening mee te houden. U moet het volgende bepalen:

  • Welk type zoekopdracht u wilt uitvoeren: vector of trefwoord of hybride
  • Of u nu query's wilt uitvoeren op een of meer kolommen
  • Of u nu handmatig meerdere query's wilt uitvoeren, zoals een trefwoordquery en een vectorzoekopdracht
  • Of de query moet worden opgesplitst in subquery's
  • Of filteren moet worden gebruikt in uw query's

Uw promptorchestrator kan een statische benadering hebben of een dynamische benadering waarbij de benaderingen worden vermengd op basis van contextopwijzing van de prompt. In de volgende secties worden deze opties besproken, zodat u kunt experimenteren om de juiste aanpak voor uw workload te vinden.

Zoektypen

Zoekplatformen ondersteunen over het algemeen volledige tekst en vectorzoekopdrachten. Sommige platforms, zoals Azure AI Search, ondersteunen hybride zoekopdrachten. Als u mogelijkheden van verschillende vectorzoekopdrachten wilt zien, raadpleegt u Een Azure-service kiezen voor vectorzoekopdrachten.

Vectorzoekopdrachten komen overeen met overeenkomsten tussen de vectorquery (prompt) en vectorvelden.

Belangrijk

U moet dezelfde schoonmaakbewerkingen uitvoeren die u op segmenten hebt uitgevoerd voordat u de query insluit. Als u bijvoorbeeld elk woord in het ingesloten segment hebt ingekapseld, moet u elk woord in de query in kleine letters plaatsen voordat u het insluiten.

Notitie

U kunt een vectorzoekopdracht uitvoeren op meerdere vectorvelden in dezelfde query. In Azure AI Search is dat technisch gezien een hybride zoekopdracht. Zie deze sectie voor meer informatie.

embedding = embedding_model.generate_embedding(
    chunk=str(pre_process.preprocess(query))
)

vector = RawVectorQuery(
    k=retrieve_num_of_documents,
    fields="contentVector",
    vector=embedding,
)

results = client.search(
    search_text=None,
    vector_queries=[vector],
    top=retrieve_num_of_documents,
    select=["title", "content", "summary"],
)

De voorbeeldcode voert een vectorzoekactie uit op het contentVector veld. Houd er rekening mee dat de code waarmee de query vooraf wordt ingesloten, de query eerst verwerkt. Deze voorverwerking moet dezelfde code zijn die de segmenten voorbewerkt voordat ze worden ingesloten. Het insluitmodel moet hetzelfde insluitmodel zijn dat de segmenten heeft ingesloten.

Zoekopdrachten in volledige tekst komen overeen met tekst zonder opmaak die is opgeslagen in een index. Het is gebruikelijk om trefwoorden uit een query te extraheren en deze geëxtraheerde trefwoorden in een zoekopdracht in volledige tekst te gebruiken voor een of meer geïndexeerde kolommen. Zoekopdrachten in volledige tekst kunnen worden geconfigureerd om overeenkomsten te retourneren waarbij alle termen of alle termen overeenkomen.

U moet experimenteren om te bepalen welke velden effectief zijn om zoekopdrachten in volledige tekst uit te voeren. Zoals besproken in de verrijkingsfase, zijn trefwoord- en entiteitmetagegevensvelden goede kandidaten voor zoeken in volledige tekst in scenario's waarin inhoud vergelijkbare semantische betekenis heeft, maar entiteiten of trefwoorden verschillen. Andere algemene velden die u kunt overwegen voor zoeken in volledige tekst, zijn titel, samenvatting en de segmenttekst.

formatted_search_results = []

results = client.search(
    search_text=query,
    top=retrieve_num_of_documents,
    select=["title", "content", "summary"],
)

formatted_search_results = format_results(results)

De voorbeeldcode voert een zoekopdracht in volledige tekst uit op de titel-, inhouds- en samenvattingsvelden.

Azure AI Search ondersteunt hybride query's waarbij uw query een of meer zoekopdrachten voor tekst en een of meer vectorzoekopdrachten kan bevatten. Het platform voert elke query uit, haalt de tussenliggende resultaten op, rangschikt de resultaten opnieuw met behulp van Wederzijdse Rank Fusion (RRF) en retourneert de bovenste N-resultaten.

 embedding = embedding_model.generate_embedding(
    chunk=str(pre_process.preprocess(query))
)
vector1 = RawVectorQuery(
    k=retrieve_num_of_documents,
    fields="contentVector",
    vector=embedding,
)
vector2 = RawVectorQuery(
    k=retrieve_num_of_documents,
    fields="questionVector",
    vector=embedding,
)

results = client.search(
    search_text=query,
    vector_queries=[vector1, vector2],
    top=retrieve_num_of_documents,
    select=["title", "content", "summary"],
)

De voorbeeldcode voert een zoekopdracht in volledige tekst uit op de titel-, inhouds- en samenvattingsvelden en vectorzoekopdrachten op basis van de velden contentVector en questionVector. Het Azure AI Search-platform voert alle query's parallel uit, ranglijnt de resultaten opnieuw en retourneert de belangrijkste retrieve_num_of_documents documenten.

Handmatig meerdere

U kunt natuurlijk meerdere query's uitvoeren, zoals een vectorzoekopdracht en een zoekopdracht in volledige tekst voor trefwoorden, handmatig. U voegt de resultaten samen en rangtelt de resultaten handmatig en retourneert de belangrijkste resultaten. Hier volgen use cases voor handmatig meerdere:

  • U gebruikt een zoekplatform dat geen ondersteuning biedt voor hybride zoekopdrachten. U volgt deze optie om uw eigen hybride zoekopdracht uit te voeren.
  • U wilt zoekopdrachten in volledige tekst uitvoeren op verschillende query's. U kunt bijvoorbeeld trefwoorden uit de query extraheren en een zoekopdracht in volledige tekst uitvoeren voor het metagegevensveld van uw trefwoorden. Vervolgens kunt u entiteiten extraheren en een query uitvoeren op het veld met metagegevens van entiteiten.
  • U wilt zelf het herrankeringsproces beheren.
  • Voor de query moeten meerdere subquery's worden uitgevoerd om grondgegevens op te halen uit meerdere bronnen.

Meerdere subquery's

Sommige prompts zijn complex en vereisen meer dan één verzameling gegevens om het model te gronden. De query 'Hoe werken elektrische auto's en hoe kunnen ze zich verhouden tot ICE-voertuigen?' vereisen waarschijnlijk grondgegevens uit meerdere bronnen.

Het is raadzaam om te bepalen of voor de query meerdere zoekopdrachten zijn vereist voordat u zoekopdrachten uitvoert. Als u denkt dat meerdere subquery's vereist zijn, kunt u handmatig meerdere query's uitvoeren voor alle query's. Gebruik een groot taalmodel om te bepalen of meerdere subquery's vereist zijn. De volgende prompt wordt opgehaald uit de RAG-experimentversneller die wordt gebruikt om een query als eenvoudig of complex te categoriseren, waarbij complexe query's meerdere query's vereisen:

Consider the given question to analyze and determine if it falls into one of these categories:
1. Simple, factual question
  a. The question is asking for a straightforward fact or piece of information
  b. The answer could likely be found stated directly in a single passage of a relevant document
  c. Breaking the question down further is unlikely to be beneficial
  Examples: "What year did World War 2 end?", "What is the capital of France?, "What is the features of productX?"
2. Complex, multi-part question
  a. The question has multiple distinct components or is asking for information about several related topics
  b. Different parts of the question would likely need to be answered by separate passages or documents
  c. Breaking the question down into sub-questions for each component would allow for better results
  d. The question is open-ended and likely to have a complex or nuanced answer
  e. Answering it may require synthesizing information from multiple sources
  f. The question may not have a single definitive answer and could warrant analysis from multiple angles
  Examples: "What were the key causes, major battles, and outcomes of the American Revolutionary War?", "How do electric cars work and how do they compare to gas-powered vehicles?"

Based on this rubric, does the given question fall under category 1 (simple) or category 2 (complex)? The output should be in strict JSON format. Ensure that the generated JSON is 100 percent structurally correct, with proper nesting, comma placement, and quotation marks. There should not be any comma after last element in the JSON.

Example output:
{
  "category": "simple"
}

Een groot taalmodel kan ook worden gebruikt om subquery's uit een complexe query te extraheren. De volgende prompt wordt opgehaald uit de RAG-experimentversneller waarmee een complexe query wordt geconverteerd naar meerdere subquery's.

Your task is to take a question as input and generate maximum 3 sub-questions that cover all aspects of the original question. The output should be in strict JSON format, with the sub-questions contained in an array.
Here are the requirements:
1. Analyze the original question and identify the key aspects or components.
2. Generate sub-questions that address each aspect of the original question.
3. Ensure that the sub-questions collectively cover the entire scope of the original question.
4. Format the output as a JSON object with a single key "questions" that contains an array of the generated sub-questions.
5. Each sub-question should be a string within the "questions" array.
6. The JSON output should be valid and strictly formatted.
7. Ensure that the generated JSON is 100 percent structurally correct, with proper nesting, comma placement, and quotation marks. The JSON should be formatted with proper indentation for readability.
8. There should not be any comma after last element in the array.

Example input question:
What are the main causes of deforestation, and how can it be mitigated?

Example output:
{
  "questions": [
    "What are the primary human activities that contribute to deforestation?",
    "How does agriculture play a role in deforestation?",
    "What is the impact of logging and timber harvesting on deforestation?",
    "How do urbanization and infrastructure development contribute to deforestation?",
    "What are the environmental consequences of deforestation?",
    "What are some effective strategies for reducing deforestation?",
    "How can reforestation and afforestation help mitigate the effects of deforestation?",
    "What role can governments and policies play in preventing deforestation?",
    "How can individuals and communities contribute to reducing deforestation?"
  ]
}

Filteren

Velden in het zoekarchief die zijn geconfigureerd als filterbaar, kunnen worden gebruikt om query's te filteren. U kunt filteren op trefwoorden en entiteiten voor query's die deze velden gebruiken om het resultaat te verfijnen. Met filteren kunt u alleen de gegevens ophalen die aan bepaalde voorwaarden van een index voldoen door irrelevante gegevens te elimineren. Dit verbetert de algehele prestaties van de query met relevantere resultaten. Net als bij elke beslissing is het belangrijk om te experimenteren en testen. Query's hebben mogelijk geen trefwoorden of verkeerde trefwoorden, afkortingen of acroniemen. U moet rekening houden met deze zaken.

Herrankering

Met opnieuw rangschikken kunt u een of meer query's uitvoeren, de resultaten aggregeren en deze resultaten rangschikken. Houd rekening met de volgende redenen om uw zoekresultaten opnieuw in te voeren:

  • U hebt handmatig meerdere zoekopdrachten uitgevoerd en u wilt de resultaten aggregeren en rangschikken.
  • Vector- en trefwoordzoekopdrachten zijn niet altijd nauwkeurig. U kunt het aantal documenten dat wordt geretourneerd uit uw zoekopdracht verhogen, mogelijk inclusief enkele geldige resultaten die anders worden genegeerd, en u kunt de rangrangering gebruiken om de resultaten te evalueren.

U kunt een groot taalmodel of een cross-encoder gebruiken om de rangherrankering uit te voeren. Sommige platforms, zoals Azure AI Search, hebben eigen methoden om resultaten opnieuw te rangschikt. U kunt deze opties voor uw gegevens evalueren om te bepalen wat het beste werkt voor uw scenario. In de volgende secties vindt u meer informatie over deze methoden.

Grote taalmodelherrankering

Hier volgt een voorbeeld van een voorbeeld van een grote taalmodelprompt van de RAG-experimentversneller waarmee de resultaten opnieuw worden geherrankt.

A list of documents is shown below. Each document has a number next to it along with a summary of the document. A question is also provided.
Respond with the numbers of the documents you should consult to answer the question, in order of relevance, as well as the relevance score as json string based on json format as shown in the schema section. The relevance score is a number from 1–10 based on how relevant you think the document is to the question. The relevance score can be repetitive. Don't output any additional text or explanation or metadata apart from json string. Just output the json string and strip rest every other text. Strictly remove any last comma from the nested json elements if it's present.
Don't include any documents that are not relevant to the question. There should exactly be one documents element.
Example format:
Document 1:
content of document 1
Document 2:
content of document 2
Document 3:
content of document 3
Document 4:
content of document 4
Document 5:
content of document 5
Document 6:
content of document 6
Question: user defined question

schema:
{
    "documents": {
        "document_1": "Relevance",
        "document_2": "Relevance"
    }
}

Herrankering tussen coderingsprogramma's

In het volgende voorbeeld van de RAG-experimentversneller wordt de CrossEncoder van Hugging Face gebruikt om het Roberta-model te laden. Vervolgens wordt elke segment herhaald en wordt het model gebruikt om overeenkomsten te berekenen, waardoor ze een waarde hebben. We sorteren resultaten en retourneren de bovenste N.

from sentence_transformers import CrossEncoder
...

model_name = 'cross-encoder/stsb-roberta-base'
model = CrossEncoder(model_name)

cross_scores_ques = model.predict(
    [[user_prompt, item] for item in documents],
    apply_softmax=True,
    convert_to_numpy=True,
)

top_indices_ques = cross_scores_ques.argsort()[-k:][::-1]
sub_context = []
for idx in list(top_indices_ques):
    sub_context.append(documents[idx])

Semantische rangschikking

Azure AI Search heeft een eigen functie met de naam semantische rangschikking. Deze functie maakt gebruik van deep learning-modellen die zijn aangepast van Microsoft Bing die de meest semantisch relevante resultaten promoten. Lees het volgende om te zien hoe semantische ranker werkt.

Zoekrichtlijnen

Houd rekening met de volgende algemene richtlijnen bij het implementeren van uw zoekoplossing:

  • Titel, samenvatting, bron en de onbewerkte inhoud (niet opgeschoond) zijn goede velden om terug te keren van een zoekopdracht.
  • Bepaal vooraf of een query moet worden opgesplitst in subquery's.
  • Over het algemeen is het een goede gewoonte om query's uit te voeren op meerdere velden, zowel vector- als tekstquery's. Wanneer u een query ontvangt, weet u niet of vectorzoekopdrachten of tekstzoekopdrachten beter zijn. U weet verder niet welke velden de vectorzoekopdracht of trefwoordzoekopdracht het beste zijn om te zoeken. U kunt zoeken op meerdere velden, mogelijk met meerdere query's, de resultaten opnieuw rangverkennen en de resultaten retourneren met de hoogste scores.
  • Trefwoorden en entiteitsvelden zijn goede kandidaten om te overwegen om te filteren.
  • Het is een goede gewoonte om trefwoorden samen met vectorzoekopdrachten te gebruiken. De trefwoorden filteren de resultaten op een kleinere subset. Het vectorarchief werkt met die subset om de beste overeenkomsten te vinden.

Zoekevaluatie

In de voorbereidingsfase moet u testquery's hebben verzameld, samen met informatie over het testdocument. U kunt de volgende informatie gebruiken die u in die fase hebt verzameld om uw zoekresultaten te evalueren:

  • De query - De voorbeeldquery
  • De context: de verzameling van alle tekst in de testdocumenten die betrekking hebben op de voorbeeldquery

Hieronder vindt u drie bekende evaluatiemethoden voor het ophalen van uw zoekoplossing:

  • Precisie bij K : het percentage correct geïdentificeerde relevante items uit de totale zoekresultaten. Deze metrische waarde is gericht op de nauwkeurigheid van uw zoekresultaten.
  • Relevante overeenkomsten bij K - Terugroepen bij K meet het percentage relevante items in de bovenste K van de totaal mogelijke relatieve items. Deze metrische waarde is gericht op de dekking van zoekresultaten.
  • Mean Reciprocal Rank (MRR) - MRR meet het gemiddelde van de wederzijdse rangschikkingen van het eerste relevante antwoord in uw gerangschikte zoekresultaten. Deze metrische waarde is gericht op de plaats waar het eerste relevante resultaat voorkomt in de zoekresultaten.

U moet zowel positieve als negatieve voorbeelden testen. Voor de positieve voorbeelden wilt u dat de metrische gegevens zo dicht mogelijk bij 1 liggen. Voor de negatieve voorbeelden, waarbij uw gegevens de query's niet kunnen aanpakken, wilt u dat de metrische gegevens zo dicht mogelijk bij 0 liggen. U moet al uw testquery's testen en het gemiddelde berekenen van de positieve queryresultaten en de negatieve queryresultaten om te begrijpen hoe uw zoekresultaten samen worden uitgevoerd.

Volgende stappen