Nachdem Sie die Einbettungen für Ihre Blöcke generiert haben, besteht der nächste Schritt darin, den Index in der Vektordatenbank zu generieren und damit zu experimentieren, um die optimalen Suchvorgänge zu ermitteln. Wenn Sie mit dem Abrufen von Informationen experimentieren, gibt es mehrere zu berücksichtigende Bereiche, einschließlich Konfigurationsoptionen für den Suchindex, die Arten von Suchvorgängen, die Sie ausführen sollten, und Ihre Strategie für die Neuordnungsstrategie. In diesem Artikel werden drei Themen erörtert.
Dieser Artikel ist Teil einer Serie. Die Einführung finden Sie hier.
Suchindex
Hinweis
Azure KI-Suche ist ein Azure-Erstanbietersuchdienst. In diesem Abschnitt werden einige Einzelheiten für die KI-Suche erwähnt. Wenn Sie einen anderen Speicher verwenden, lesen Sie die Dokumentation, um die Schlüsselkonfiguration für diesen Dienst zu finden.
Der Suchindex in Ihrem Speicher enthält eine Spalte für jedes Feld in Ihren Daten. Suchspeicher bieten in der Regel Unterstützung für nonvector-Datentypen wie String, Boolean, Integer, Single, Double, Datetime, und Sammlungen wie Collection(single) und und Vektordatentypen wie Collection(single). Für jede Spalte müssen Sie Informationen wie den Datentyp konfigurieren, unabhängig davon, ob das Feld gefiltert, abgerufen und/oder durchsuchbar ist.
Im Folgenden finden Sie einige wichtige Entscheidungen, die Sie für die Vektorsuchkonfiguration treffen müssen, die auf Vektorfelder angewendet wird:
- Vektorsuchalgorithmus – Der Algorithmus, der zum Suchen nach relativen Übereinstimmungen verwendet wird. Azure KI-Suche verfügt über eine Brute-Force-Algorithmusoption namens „Vollständiger KNN“, die den gesamten Vektorraum durchsucht, und eine leistungsfähigere Algorithmusoption für ungefähr nächste Nachbarn (ANN) mit dem Namen Hierarchical Navigable Small World (HNSW) durchführt.
- Metrik – Diese Konfiguration ist die Ähnlichkeitsmetrik, die zum Berechnen der Nähe durch den Algorithmus verwendet wird. Die Optionen in Azure KI-Suche sind Kosinus, dotProduct und Euklidischer Abstand. Wenn Sie Azure OpenAI-Einbettungsmodelle verwenden, wählen Sie
cosine
. - efConstruction – Parameter, der während der Hierarchical Navigable Small Worlds-(HNSW-)Indexkonstruktion verwendet wird, die die Anzahl der nächsten, während der Indizierung mit einem Vektor verbundenen Nachbarn festlegt. Ein größerer efConstruction-Wert führt zu einem besseren Index als eine kleinere Zahl. Der Kompromiss besteht darin, dass ein größerer Wert mehr Zeit, Speicher und Berechnung erfordert. efConstruction sollte für eine große Anzahl von Blöcken höher und für eine niedrige Anzahl von Blöcken niedriger sein. Für die Ermittlung des optimalen Werts sind Experimente mit Ihren Daten und erwarteten Abfragen erforderlich.
- efSearch – Parameter, der zur Abfragezeit verwendet wird, um die Anzahl der nächsten Nachbarn (d. h. ähnliche Blöcke) festzulegen, die während der Suche verwendet werden.
- m – Die Anzahl bidirektionaler Verknüpfungen. Der Bereich ist 4 bis 10, wobei niedrigere Zahlen weniger Rauschen in den Ergebnissen zurückgeben.
In Azure KI-Suche werden die Vektorkonfigurationen in einer vectorSearch
-Konfiguration gekapselt. Beim Konfigurieren der Vektorspalten verweisen Sie auf die entsprechende Konfiguration für diese Vektorspalte und legen die Anzahl der Dimensionen fest. Das Dimensionsattribut der Vektorspalte stellt die Anzahl der Dimensionen dar, die vom ausgewählten Einbettungsmodell generiert werden. Das speicheroptimierte text-embedding-3-small
Modell generiert beispielsweise 1.536 Dimensionen.
Suchvorgänge
Beim Ausführen von Abfragen aus Ihrem Prompt-Orchestrator für den Suchspeicher stehen Ihnen viele Optionen zur Verfügung. Sie müssen Folgendes festlegen:
- Welche Suchart soll ausgeführt werden: Vektor, Schlüsselwort oder Hybrid
- Gibt an, ob eine Abfrage für eine oder mehrere Spalten durchgeführt wird
- Gibt an, ob mehrere Abfragen manuell ausgeführt werden, z. B. eine Schlüsselwortabfrage und eine Vektorsuche
- Gibt an, ob die Abfrage in Unterabfragen unterteilt werden muss
- Gibt an, ob Filterung in Ihren Abfragen verwendet werden soll
Ihr Prompt-Orchestrator kann einen statischen oder dynamischen Ansatz verwenden, der die Ansätze basierend auf Kontexthinweisen aus dem Prompt mischt. In den folgenden Abschnitten werden diese Optionen behandelt, mit denen Sie experimentieren können, um den richtigen Ansatz für Ihre Workload zu finden.
Suchtypen
Suchplattformen unterstützen in der Regel Volltext- und Vektorsuchen. Einige Plattformen, z. B. Azure KI-Suche, unterstützen Hybridsuchen. Informationen zum Anzeigen der Funktionen verschiedener Vektorsuchangebote finden Sie unter Auswählen eines Azure-Diensts für die Vektorsuche.
Vektorsuche
Vektorsuchen stimmen mit der Ähnlichkeit zwischen der vektorisierten Abfrage (Prompt) und Vektorfeldern überein.
Wichtig
Sie sollten die gleichen Bereinigungsvorgänge ausführen, die Sie für die Abfrage vor dem Einbetten ausgeführt haben. Wenn Sie beispielsweise jedes Wort in Ihrem eingebetteten Block klein geschrieben haben, sollten Sie vor dem Einbetten jedes Wort in der Abfrage kleinschreiben.
Hinweis
Sie können eine Vektorsuche für mehrere Vektorfelder in derselben Abfrage ausführen. In Azure KI-Suche ist dies technisch eine Hybridsuche. Weitere Informationen finden Sie im diesem Abschnitt.
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"],
)
Der Beispielcode führt eine Vektorsuche für das Feld contentVector
aus. Beachten Sie, dass der Code, der die Abfrage einbettet, die Abfrage zuerst vorverarbeitet. Diese Vorverarbeitung sollte derselbe Code sein, mit dem die Blöcke vor dem Einbetten vorverarbeitet werden. Das Einbettungsmodell muss dasselbe Einbettungsmodell sein, das die Blöcke eingebettet hat.
Volltextsuche
Volltextsuchen stimmen mit Nur-Text überein, der in einem Index gespeichert ist. Es ist üblich, Schlüsselwörter aus einer Abfrage zu extrahieren und diese extrahierten Schlüsselwörter in einer Volltextsuche für eine oder mehrere indizierte Spalten zu verwenden. Volltextsuchen können so konfiguriert werden, dass Übereinstimmungen zurückgegeben werden, bei denen einige oder alle Ausdrücke übereinstimmen.
Sie müssen experimentieren, um zu ermitteln, welche Felder für die Volltextsuche effektiv sind. Wie in der Anreicherungsphase erläutert, sind Schlüsselwörter und Entitätsmetadatenfelder gute Kandidaten für die Volltextsuche in Szenarien, in denen Inhalte eine ähnliche semantische Bedeutung haben, aber Entitäten oder Schlüsselwörter sich unterscheiden. Andere allgemeine Felder, die für die Volltextsuche berücksichtigt werden sollen, sind Titel, Zusammenfassung und der Blocktext.
formatted_search_results = []
results = client.search(
search_text=query,
top=retrieve_num_of_documents,
select=["title", "content", "summary"],
)
formatted_search_results = format_results(results)
Der Beispielcode führt eine Volltextsuche anhand der Titel-, Inhalts- und Zusammenfassungsfelder aus.
Hybridsuche
Azure KI-Suche unterstützt Hybridabfragen, bei denen Ihre Abfrage eine oder mehrere Textsuchen und eine oder mehrere Vektorsuchen enthalten kann. Die Plattform führt jede Abfrage aus, ruft die Zwischenergebnisse ab, ordnet die Ergebnisse mithilfe von Reciprocal Rank Fusion (RRF) neu und gibt die wichtigsten N-Ergebnisse zurück.
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"],
)
Der Beispielcode führt eine Volltextsuche anhand der Titel-, Inhalts- und Zusammenfassungsfelder und Vektorsuchen für die Felder contentVector und questionVector durch. Die Azure KI Search-Plattform führt alle Abfragen parallel aus, ordnet die Ergebnisse neu und gibt die besten retrieve_num_of_documents-Dokumente zurück.
Manuelles Vielfaches
Sie können natürlich mehrere Abfragen manuell ausführen, z. B. eine Vektorsuche und eine Schlüsselwort-Volltextsuche. Sie aggregieren die Ergebnisse, ordnen die Ergebnisse manuell neu und geben die obersten Ergebnisse zurück. Im Folgenden sind Anwendungsfälle für manuelles Vielfaches aufgeführt:
- Sie verwenden eine Suchplattform, die keine Hybridsuchen unterstützt. Sie sollten diese Option auswählen, um Ihre eigene Hybridsuche auszuführen.
- Sie möchten Volltextsuchen für verschiedene Abfragen ausführen. Sie können z. B. Schlüsselwörter aus der Abfrage extrahieren und eine Volltextsuche für das Metadatenfeld ihrer Schlüsselwörter ausführen. Sie können dann Entitäten extrahieren und eine Abfrage für das Entitätsmetadatenfeld ausführen.
- Sie möchten den Neuanordnungsprozess selbst steuern.
- Die Abfrage erfordert, dass mehrere Unterabfragen ausgeführt werden, um Grounding-Daten aus mehreren Quellen abzurufen.
Mehrere Unterabfragen
Einige Prompts sind komplex und erfordern mehr als eine Sammlung von Daten, um das Modell zu erden. Die Abfrage „Wie funktionieren Elektroautos und wie lassen sie sich mit ICE-Fahrzeugen vergleichen?“ erfordert wahrscheinlich Grounding-Daten aus mehreren Quellen.
Es empfiehlt sich, zu ermitteln, ob für die Abfrage mehrere Suchen erforderlich sind, bevor Suchvorgänge ausgeführt werden. Wenn mehrere Unterabfragen erforderlich sind, können Sie mehrere manuelle Abfragen für alle Abfragen ausführen. Verwenden Sie ein großes Sprachmodell, um zu ermitteln, ob mehrere Unterabfragen erforderlich sind. Der folgende Prompt stammt aus dem GitHub-Repository „RAG Experiment Accelerator“, das verwendet wird, um eine Abfrage als einfach oder komplex (erfordert mehrere Abfragen) zu kategorisieren:
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"
}
Ein großes Sprachmodell kann auch verwendet werden, um Unterabfragen aus einer komplexen Abfrage zu extrahieren. Der folgende Prompt stammt aus dem GitHub-Repository „RAG Experiment Accelerator“, das eine komplexe Abfrage in mehrere Unterabfragen konvertiert:
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?"
]
}
Übergeben von Bildern in Abfragen
Einige multimodale Modelle wie GPT-4V und GPT-4o können Bilder interpretieren. Beim Nutzen dieser Modelle können Sie auswählen, ob Sie die Segmentierung Ihrer Bilder vermeiden und das Bild als Teil des Prompts an das multimodale Modell übergeben möchten. Probieren Sie verschiedene Optionen aus, um zu erfahren, wie dieser Ansatz im Vergleich zum Segmentierung der Bilder mit und ohne zusätzlichen Kontext funktioniert. Sie sollten auch die Kostendifferenz zwischen den Ansätzen vergleichen und eine Kosten-Nutzen-Analyse durchführen.
Filterung
Felder im Suchspeicher, die als filterbar konfiguriert sind, können zum Filtern von Abfragen verwendet werden. Erwägen Sie das Filtern nach Schlüsselwort und Entitäten für Abfragen, die diese Felder verwenden, um das Ergebnis einzugrenzen. Mithilfe der Filterung können Sie nur die Daten abrufen, die bestimmte Bedingungen aus einem Index erfüllen, indem irrelevante Daten entfernt werden. Dadurch wird die Gesamtleistung der Abfrage mit relevanteren Ergebnissen verbessert. Wie bei jeder Entscheidung ist es wichtig, zu experimentieren und zu testen. Abfragen haben möglicherweise keine Schlüsselwörter bzw. verfügen über falsche Schlüsselwörter, Abkürzungen oder Akronyme. Sie müssen diese Fälle berücksichtigen.
Neuanordnung nach Rang
Durch die Neuanordnung können Sie eine oder mehrere Abfragen ausführen, die Ergebnisse aggregieren und diese Ergebnisse bewerten. Berücksichtigen Sie die folgenden Gründe, um Ihre Suchergebnisse neu anzuordnen:
- Sie haben mehrere Suchvorgänge manuell durchgeführt und möchten die Ergebnisse aggregieren und nach Rang anordnen.
- Vektor- und Schlüsselwortsuchen sind nicht immer genau. Sie können die Anzahl der von der Suche zurückgegebenen Dokumente erhöhen, einschließlich einiger gültiger Ergebnisse, die andernfalls ignoriert würden, und die Neuanordnung verwenden, um die Ergebnisse auszuwerten.
Sie können ein großes Sprachmodell oder einen Quercoder verwenden, um eine Neuanordnung durchzuführen. Einige Plattformen, z. B. Azure KI-Suche, verfügen über proprietäre Methoden zum Neuanordnen von Ergebnissen. Sie können diese Optionen für Ihre Daten auswerten, um zu bestimmen, was für Ihr Szenario am besten geeignet ist. Die folgenden Abschnitte enthalten Details zu diesen Methoden.
Neuanordnung beim großen Sprachmodell
Im Folgenden sehen Sie eine Beispielaufforderung für ein großes Sprachmodell aus dem RAG Experiment Accelerator, mit dem die Ergebnisse neu angeordnet werden.
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"
}
}
Encoder-übergreifendes Reranking
Im folgenden Beispiel aus dem GitHub-Repository „RAG Experiment Accelerator“ wird der von Hugging Face bereitgestellte CrossEncoder verwendet, um das Roberta-Modell zu laden: Anschließend durchläuft er jeden Block und verwendet das Modell zum Berechnen der Ähnlichkeit, sodass jeder Block einen Wert erhält. Wir sortieren Ergebnisse und geben die obersten N zurück.
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 Rangfolge
Azure KI-Suche verfügt über ein proprietäres Feature namens semantisches Ranking. Dieses Feature verwendet Deep Learning-Modelle, die von Microsoft Bing angepasst wurden und die semantisch relevantesten Ergebnisse fördern. Im Folgenden erhalten Sie Informationen zur Funktionsweise des semantischen Sortierers.
Suchleitfaden
Beachten Sie beim Implementieren Ihrer Suchlösung die folgenden allgemeinen Anleitungen:
- Titel, Zusammenfassung, Quelle und der Rohdateninhalt (nicht bereinigt) eignen sich gut, um von einer Suche zurückgegeben zu werden.
- Ermitteln Sie im Vorfeld, ob eine Abfrage in Unterabfragen unterteilt werden muss.
- Im Allgemeinen empfiehlt es sich, Abfragen für mehrere Felder auszuführen, sowohl Vektor- als auch Textabfragen. Wenn Sie eine Abfrage erhalten, wissen Sie nicht, ob die Vektorsuche oder die Textsuche besser ist. Sie wissen noch nicht, welche Felder am besten von der Vektor- oder Schlüsselwortsuche durchsucht werden. Sie können nach mehreren Feldern suchen, potenziell mit mehreren Abfragen, die Ergebnisse neu anordnen und die Ergebnisse mit den höchsten Bewertungen zurückgeben.
- Schlüsselwort- und Entitätsfelder eignen sich gut für die Filterung.
- Es empfiehlt sich, Schlüsselwörter zusammen mit Vektorsuchen zu verwenden. Mit den Schlüsselwörtern werden die Ergebnisse auf eine kleinere Teilmenge gefiltert. Der Vektorspeicher funktioniert mit dieser Teilmenge, um die besten Übereinstimmungen zu finden.
Auswertung der Suche
In der Vorbereitungsphase sollten Sie Testabfragen zusammen mit Testdokumentinformationen gesammelt haben. Sie können die folgenden Informationen verwenden, die Sie in dieser Phase gesammelt haben, um Ihre Suchergebnisse auszuwerten:
- Die Abfrage – Die Beispielabfrage
- Der Kontext – die Sammlung des gesamten Textes in den Testdokumenten, die die Musterabfrage betreffen
Im Folgenden finden Sie drei bewährte Abrufauswertungsmethoden, mit denen Sie Ihre Suchlösung evaluieren können:
- Genauigkeit bei K – Der Prozentsatz der korrekt identifizierten relevanten Elemente aus den Gesamtsuchergebnissen. Diese Metrik konzentriert sich auf die Genauigkeit Ihrer Suchergebnisse.
- Rückruf bei K – Rückruf bei K misst den Prozentsatz der relevanten Elemente in den oberen K aus den möglichen relativen Elementen insgesamt. Diese Metrik konzentriert sich auf die Abdeckung von Suchergebnissen.
- Mean Reciprocal Rank (MRR) – MRR misst den Mittelwert der gegenseitigen Rangfolge der ersten relevanten Antwort in Ihren bewerteten Suchergebnissen. Diese Metrik konzentriert sich darauf, wo das erste relevante Ergebnis in den Suchergebnissen auftritt.
Sie sollten sowohl positive als auch negative Beispiele testen. Für die positiven Beispiele sollen die Metriken so nah wie möglich bei 1 liegen. Für die negativen Beispiele, bei denen Ihre Daten nicht in der Lage sein sollen, die Abfragen zu adressieren, möchten Sie, dass die Metriken so nah wie möglich bei 0 liegen. Sie sollten alle Ihre Testabfragen testen und den Durchschnitt der positiven und negativen Abfrageergebnisse ermitteln, um zu verstehen, wie Ihre Suchergebnisse im Ganzen abschneiden.