Tools für unstrukturiertes Abrufen des KI-Agents
Wichtig
Dieses Feature befindet sich in der Public Preview.
In diesem Artikel wird gezeigt, wie Sie KI-Agent-Tools für den unstrukturierten Datenabruf mithilfe des Mosaik AI Agent Frameworks erstellen. Unstrukturierte Retriever ermöglichen Agents das Abfragen unstrukturierter Datenquellen, z. B. eines Dokumentkorpus, mithilfe von Vektorsuchindizes.
Weitere Informationen zu Agenttools finden Sie unter Erstellen von KI-Agent-Tools.
Vektorsuche-Retriever-Tool mit Unity-Katalogfunktionen
Im folgenden Beispiel wird eine Unity-Katalogfunktion für ein Retriever-Tool erstellt, mit dem Daten aus einem Mosaik AI Vector Search-Indexabgefragt werden können.
Die Unity-Katalogfunktion databricks_docs_vector_search
fragt einen hypothetischen Vektorsuchindex ab, der die Dokumentation zu Databricks enthält. Sie umschließt die SQL-Funktion vector_search() der Databricks-Funktion und verwendet die Aliase page_content
und metadata
, um die Ausgabe mit dem MLflow-Retrieverschemaabzugleichen.
Anmerkung
Um dem MLflow-Abrufschema zu entsprechen, müssen alle zusätzlichen Metadatenspalten der metadata
-Spalte mithilfe der SQL-Zuordnungsfunktion und nicht als Ausgabeschlüssel der obersten Ebene hinzugefügt werden.
Führen Sie den folgenden Code in einem Notizbuch oder SQL-Editor aus.
CREATE OR REPLACE FUNCTION main.default.databricks_docs_vector_search (
-- The agent uses this comment to determine how to generate the query string parameter.
query STRING
COMMENT 'The query string for searching Databricks documentation.'
) RETURNS TABLE
-- The agent uses this comment to determine when to call this tool. It describes the types of documents and information contained within the index.
COMMENT 'Executes a search on Databricks documentation to retrieve text documents most relevant to the input query.' RETURN
SELECT
chunked_text as page_content,
map('doc_uri', url, 'chunk_id', chunk_id) as metadata
FROM
vector_search(
-- Specify your Vector Search index name here
index => 'catalog.schema.databricks_docs_index',
query => query,
num_results => 5
)
Dieses Retriever-Tool weist die folgenden Vorbehalte auf:
- MLflow verfolgt diese Unity Catalog-Funktion als
TOOL
-Span-Typ und nicht alsRETRIEVER
-Span-Typ nach. Daher werden Agent-Framework-Downstreamanwendungen wie die Agent-Überprüfungs-App und KI Playground keine retrieverspezifischen Details wie Verknüpfungen zu Blöcken anzeigen. Weitere Informationen zu Span-Typen finden Sie unter MLflow-Ablaufverfolgungsschema. - SQL-Clients können die maximale Anzahl zurückgegebener Zeilen oder Bytes einschränken. Um das Abschneiden von Daten zu verhindern, sollten Sie Spaltenwerte abschneiden, die von UDF zurückgegeben werden. Sie können z. B.
substring(chunked_text, 0, 8192)
verwenden, um die Größe großer Inhaltsspalten zu verringern und zeilenabkürzungen während der Ausführung zu vermeiden. - Da es sich bei diesem Tool um einen Wrapper für die
vector_search()
-Funktion handelt, unterliegt es den gleichen Einschränkungen wie dievector_search()
-Funktion. Siehe Einschränkungen.
Wenn dieses Beispiel für Ihren Anwendungsfall nicht geeignet ist, erstellen Sie stattdessen ein Vektorsuch-Retriever-Tool mit benutzerdefiniertem Agent-Code.
Vektor-Sucher-Retriever mit Agentencode (PyFunc)
Im folgenden Beispiel wird ein Vektorsuche-Retriever für einen PyFunc-Agent im Code eines Agents erstellt.
In diesem Beispiel wird databricks-vectorsearch- verwendet, um einen einfachen Retriever zu erstellen, der eine Vector Search-Ähnlichkeitssuche mit Filterndurchführt. Es werden MLflow-Decorator-Elemente verwendet, um die Agent-Nachverfolgung zu aktivieren.
Anmerkung
Um dem MLflow-Retriever-Schema zu entsprechen, sollte die Retriever-Funktion einen Document Typ zurückgeben und das feld metadata
in der Document-Klasse verwenden, um dem zurückgegebenen Dokument zusätzliche Attribute hinzuzufügen, z. B. like doc_uri
und similarity_score.
Verwenden Sie den folgenden Code im Agentmodul oder Agent-Notizbuch.
import mlflow
import json
from mlflow.entities import Document
from typing import List, Dict, Any
from dataclasses import asdict
from databricks.vector_search.client import VectorSearchClient
class VectorSearchRetriever:
"""
Class using Databricks Vector Search to retrieve relevant documents.
"""
def __init__(self):
self.vector_search_client = VectorSearchClient(disable_notice=True)
# TODO: Replace this with the list of column names to return in the result when querying Vector Search
self.columns = ["chunk_id", "text_column", "doc_uri"]
self.vector_search_index = self.vector_search_client.get_index(
index_name="catalog.schema.chunked_docs_index"
)
mlflow.models.set_retriever_schema(
name="vector_search",
primary_key="chunk_id",
text_column="text_column",
doc_uri="doc_uri"
)
@mlflow.trace(span_type="RETRIEVER", name="vector_search")
def __call__(
self,
query: str,
filters: Dict[Any, Any] = None,
score_threshold = None
) -> List[Document]:
"""
Performs vector search to retrieve relevant chunks.
Args:
query: Search query.
filters: Optional filters to apply to the search. Filters must follow the Databricks Vector Search filter spec
score_threshold: Score threshold to use for the query.
Returns:
List of retrieved Documents.
"""
results = self.vector_search_index.similarity_search(
query_text=query,
columns=self.columns,
filters=filters,
num_results=5,
query_type="ann"
)
documents = self.convert_vector_search_to_documents(
results, score_threshold
)
return [asdict(doc) for doc in documents]
@mlflow.trace(span_type="PARSER")
def convert_vector_search_to_documents(
self, vs_results, score_threshold
) -> List[Document]:
docs = []
column_names = [column["name"] for column in vs_results.get("manifest", {}).get("columns", [])]
result_row_count = vs_results.get("result", {}).get("row_count", 0)
if result_row_count > 0:
for item in vs_results["result"]["data_array"]:
metadata = {}
score = item[-1]
if score >= score_threshold:
metadata["similarity_score"] = score
for i, field in enumerate(item[:-1]):
metadata[column_names[i]] = field
page_content = metadata.pop("text_column", None)
if page_content:
doc = Document(
page_content=page_content,
metadata=metadata
)
docs.append(doc)
return docs
Führen Sie zum Ausführen des Retrievers den folgenden Python-Code aus. Sie können optional Vektorsuchfilter in die Anforderung einschließen, um Ergebnisse zu filtern.
retriever = VectorSearchRetriever()
query = "What is Databricks?"
filters={"text_column LIKE": "Databricks"},
results = retriever(query, filters=filters, score_threshold=0.1)
Festlegen des Retriever-Schemas
Rufen Sie mlflow.models.set_retriever_schema auf, wenn Sie Ihren Agent definieren, um sicherzustellen, dass Retriever ordnungsgemäß nachverfolgt und in Downstreamanwendungen reibungslos gerendert werden. Verwenden Sie set_retriever_schema
, um die Spaltennamen in der zurückgegebenen Tabelle den erwarteten Feldern von MLflow wie primary_key
, text_column
und doc_uri
zuzuordnen.
# Define the retriever's schema by providing your column names
mlflow.models.set_retriever_schema(
name="vector_search",
primary_key="chunk_id",
text_column="text_column",
doc_uri="doc_uri"
# other_columns=["column1", "column2"],
)
Sie können auch zusätzliche Spalten im Schema des Retrievers angeben, indem Sie eine Liste der Spaltennamen mit dem feld other_columns
angeben.
Wenn Sie über mehrere Retriever verfügen, können Sie mehrere Schemas definieren, indem Sie eindeutige Namen für jedes Retriever-Schema verwenden.
Der Retriever-Schemasatz während der Agent-Erstellung wirkt sich auf Downstreamanwendungen und Workflows aus, z. B. auf die Prüf-App und auf Auswertungssätze. Insbesondere dient die spalte doc_uri
als primärer Bezeichner für dokumente, die vom Retriever zurückgegeben werden.
- Die Überprüfungs-App zeigt die
doc_uri
an, damit Prüfer Antworten bewerten und Dokumentenherkunft nachverfolgen können. Weitere Informationen finden Sie unter Überprüfen der App-Benutzeroberfläche. - Auswertungssätze verwenden
doc_uri
, um Retriever-Ergebnisse mit vordefinierten Auswertungsdatasets zu vergleichen, um den Abruf und die Genauigkeit des Retrievers zu bestimmen. Weitere Informationen finden Sie unter Auswertungssätze.
Nachverfolgen des Retrievers
Die MLflow-Ablaufverfolgung fügt Einblicke hinzu, indem die Ausführung Ihres Agents detailliert erfasst wird. Sie bietet eine Möglichkeit zum Aufzeichnen der Eingaben, Ausgaben und Metadaten, die jedem Zwischenschritt einer Anforderung zugeordnet sind, sodass Sie schnell die Quelle von Fehlern und unerwarteten Verhaltensweisen anheften können.
In diesem Beispiel wird dem @mlflow.trace-Decorator-Element verwendet, um eine Ablaufverfolgung für den Retriever und den Parser zu erstellen. Weitere Optionen zum Einrichten von Ablaufverfolgungsmethoden finden Sie unter MLflow-Ablaufverfolgung für Agents.
Das Decorator-Element erstellt einen Span, der beginnt, wenn die Funktion aufgerufen wird, und endet, wenn sie zurückgegeben wird. MLflow zeichnet automatisch die Eingabe und Ausgabe der Funktion und alle ausgelösten Ausnahmen auf.
Anmerkung
LangChain-, LlamaIndex- und OpenAI-Bibliotheksbenutzende können die automatische Protokollierung von MLflow nutzen, anstatt die Ablaufverfolgungen manuell mit dem Decorator-Element zu definieren. Weitere Informationen finden Sie unter Verwenden der automatischen Protokollierung zum Hinzufügen von Ablaufverfolgungen zu Ihren Agents.
...
@mlflow.trace(span_type="RETRIEVER", name="vector_search")
def __call__(self, query: str) -> List[Document]:
...
Um sicherzustellen, dass Downstreamanwendungen wie „Agent-Auswertung“ und „KI Playground“ die Retriever-Nachverfolgung korrekt rendern, stellen Sie sicher, dass das Decorator-Element die folgenden Anforderungen erfüllt:
- Verwenden Sie
span_type="RETRIEVER"
, und stellen Sie sicher, dass die FunktionList[Document]
Objekt zurückgibt. Weitere Informationen finden Sie unter Retriever-Span. - Der Ablaufverfolgungsname und der retriever_schema-Name müssen übereinstimmen, um die Ablaufverfolgung korrekt zu konfigurieren.
Ergebnisse der Vektorsuche filtern
Sie können den Suchbereich auf eine Teilmenge von Daten beschränken, indem Sie einen Vektorsuchfilter verwenden.
Der filters
Parameter in VectorSearchRetriever
definiert die Filterbedingungen mithilfe der Databricks Vector Search Filterspezifikation.
filters = {"text_column LIKE": "Databricks"}
Innerhalb der __call__
-Methode wird das Filterwörterbuch direkt an die similarity_search
-Funktion übergeben:
results = self.vector_search_index.similarity_search(
query_text=query,
columns=self.columns,
filters=filters,
num_results=5,
query_type="ann"
)
Nach der anfänglichen Filterung bietet der score_threshold
-Parameter zusätzliche Filterung, indem eine Mindestgleichheitsbewertung festgelegt wird.
if score >= score_threshold:
metadata["similarity_score"] = score
Das Endergebnis enthält Dokumente, die den filters
und score_threshold
Bedingungen entsprechen.
Nächste Schritte
Nachdem Sie ein Unity Catalog-Funktions-Agent-Tool erstellt haben, fügen Sie das Tool einem KI-Agent hinzu. Weitere Informationen finden Sie unter Hinzufügen von Unity Catalog-Tools zu Agents.