Connectez les agents aux données non structurées
Les agents doivent souvent query des données non structurées, comme des collections de documents, des bases de connaissances ou des corpus de texte, pour répondre aux questions et fournir des réponses contextuelles.
Pour les nouveaux agents Python, utilisez AI Bridge (recommandé) pour query directement les index de recherche AI Search. Pour les intégrations MCP existantes, consultez l’ endpoint de workspace hérité. Vous pouvez également vous connecter à des magasins de vecteurs externes ou lire des fichiers à partir de volumes Unity Catalog.
Développez un retriever avec AI Bridge (recommandé)
Pour les nouveaux agents Python qui interrogent des index Databricks AI Search, Databricks recommande AI Bridge. Utilisez VectorSearchRetrieverTool à partir de databricks-langchain ou de databricks-openai pour exposer un index en tant qu'outil d'agent.
Avant d’exécuter ces exemples, connectez-vous à votre Workspace et choisissez un index de recherche IA que vous pouvez query. Remplacez le nom de l’index d’exemple par son nom en trois parties. Les premiers exemples utilisent des intégrations gérées par Databricks et un endpoint de modèle qui prend en charge l’appel d’outils.
Exécutez les commandes d’installation dans un terminal. Dans un Notebook, utilisez %pip à la place de pip et redémarrez Python après l’installation.
- LangChain/LangGraph
- OpenAI
Installez la dernière version de databricks-langchain et LangGraph :
pip install --upgrade databricks-langchain langgraph
Créez un outil de récupération et donnez-lui une description qui indique à l’agent quand effectuer une recherche. Cet exemple teste la récupération directement, puis exécute un agent capable d'appeler l'outil et d'utiliser ses résultats.
from databricks_langchain import VectorSearchRetrieverTool, ChatDatabricks
from langgraph.prebuilt import create_react_agent
vs_tool = VectorSearchRetrieverTool(
index_name="catalog.schema.my_databricks_docs_index",
tool_name="databricks_docs_retriever",
tool_description="Search Databricks documentation to answer product questions.",
)
print(vs_tool.invoke("What is Databricks Agent Framework?"))
agent = create_react_agent(
ChatDatabricks(endpoint="databricks-claude-sonnet-4-5"),
tools=[vs_tool],
)
result = agent.invoke({"messages": [{
"role": "user",
"content": "Search the documentation and explain Databricks Agent Framework.",
}]})
for message in result["messages"]:
print(message)
Veuillez vérifier la conversation enregistrée afin d’y rechercher un appel d’outil, les documents récupérés, ainsi qu’une réponse fondée sur ces derniers.
Pour les scénarios qui utilisent des index à accès direct ou des index Delta Sync utilisant des intégrations autogérées, vous devez configurer le VectorSearchRetrieverTool et spécifier un modèle d'intégration personnalisé et une colonne de texte. Consultez les options pour fournir des intégrations.
L'exemple suivant vous montre comment configurer un VectorSearchRetrieverTool avec des clés columns et embedding.
from databricks_langchain import VectorSearchRetrieverTool
from databricks_langchain import DatabricksEmbeddings
embedding_model = DatabricksEmbeddings(
endpoint="databricks-bge-large-en",
)
vs_tool = VectorSearchRetrieverTool(
index_name="catalog.schema.index_name", # Index name in the format 'catalog.schema.index'
num_results=5, # Max number of documents to return
columns=["primary_key", "text_column"], # List of columns to include in the search
filters={"text_column LIKE": "Databricks"}, # Filters to apply to the query
query_type="ANN", # Query type ("ANN" or "HYBRID").
tool_name="databricks_docs_retriever", # Used by the LLM to understand the purpose of the tool
tool_description="Purpose of the tool", # Used by the LLM to understand the purpose of the tool
text_column="text_column", # Specify text column for embeddings. Required for direct-access index or delta-sync index with self-managed embeddings.
embedding=embedding_model # The embedding model. Required for direct-access index or delta-sync index with self-managed embeddings.
)
Pour plus de détails, consultez les documents de l'API pour VectorSearchRetrieverTool.
Installez la dernière version de databricks-openai:
pip install --upgrade databricks-openai
Cet exemple utilise le client Databricks compatible avec OpenAI. Il exécute les appels d’outils du modèle et renvoie les documents récupérés à ce dernier.
import json
from databricks_openai import DatabricksOpenAI, VectorSearchRetrieverTool
client = DatabricksOpenAI()
dbvs_tool = VectorSearchRetrieverTool(
index_name="catalog.schema.my_databricks_docs_index",
tool_name="databricks_docs_retriever",
tool_description="Search Databricks documentation to answer product questions.",
)
messages = [{
"role": "user",
"content": "Search the documentation and explain Databricks Agent Framework.",
}]
for _ in range(10):
response = client.chat.completions.create(
model="databricks-claude-sonnet-4-5",
messages=messages,
tools=[dbvs_tool.tool],
)
message = response.choices[0].message
messages.append(message.model_dump(exclude_none=True))
if not message.tool_calls:
print(message.content)
break
for call in message.tool_calls:
if call.function.name != dbvs_tool.tool["function"]["name"]:
raise ValueError(f"Unknown tool: {call.function.name}")
args = json.loads(call.function.arguments)
documents = dbvs_tool.execute(**args, openai_client=client)
print(documents)
messages.append({
"role": "tool",
"tool_call_id": call.id,
"content": json.dumps(documents),
})
else:
raise RuntimeError("The agent reached the tool-calling limit.")
Pour les scénarios qui utilisent des index à accès direct ou des index Delta Sync utilisant des intégrations autogérées, vous devez configurer le VectorSearchRetrieverTool et spécifier un modèle d'intégration personnalisé et une colonne de texte. Consultez les options pour fournir des intégrations.
L'exemple suivant vous montre comment configurer un VectorSearchRetrieverTool avec des clés columns et embedding.
from databricks_openai import VectorSearchRetrieverTool
vs_tool = VectorSearchRetrieverTool(
index_name="catalog.schema.index_name", # Index name in the format 'catalog.schema.index'
num_results=5, # Max number of documents to return
columns=["primary_key", "text_column"], # List of columns to include in the search
filters={"text_column LIKE": "Databricks"}, # Filters to apply to the query
query_type="ANN", # Query type ("ANN" or "HYBRID").
tool_name="databricks_docs_retriever", # Used by the LLM to understand the purpose of the tool
tool_description="Purpose of the tool", # Used by the LLM to understand the purpose of the tool
text_column="text_column", # Specify text column for embeddings. Required for direct-access index or delta-sync index with self-managed embeddings.
embedding_model_name="databricks-bge-large-en" # The embedding model. Required for direct-access index or delta-sync index with self-managed embeddings.
)
Lors de l'utilisation d'un endpoint d'embedding Databricks, transmettez openai_client=client à vs_tool.execute(), comme dans la boucle d'agent ci-dessus. Utilisez le même modèle d'embedding que celui qui a créé les vecteurs d'index.
Pour plus de détails, consultez les documents de l'API pour VectorSearchRetrieverTool.
After testing the retriever, add it to your custom agent.
query un index de recherche vectorielle en dehors de Databricks
Si votre index vectoriel est hébergé en dehors de Databricks, vous pouvez créer une connexion Unity Catalog pour vous connecter au service externe et l'utiliser dans le code de votre agent. Consultez Se connecter à des services HTTP externes.
L’exemple suivant query un index Azure AI Search via une connexion HTTP. Vous avez besoin d’une connexion disposant des autorisations nécessaires pour query cet index et de USE CONNECTION sur la connexion. Installez requests, databricks-sdk et mlflow avant d’exécuter l’exemple Python.
-
Créer une connexion Unity Catalog vers Azure AI Search à l'aide de la configuration de connexion HTTP. Cet exemple utilise un jeton porteur ; choisissez la méthode d'authentification requise par votre déploiement Azure AI Search.
SQLCREATE CONNECTION azure_search_connection
TYPE HTTP
OPTIONS (
host 'https://example.search.windows.net',
base_path '/',
bearer_token secret ('<secret-scope>','<secret-key>')
); -
Définissez l’outil de récupération dans le code d’agent à l’aide de la connexion Unity Catalog. Cet exemple utilise les décorateurs MLflow pour activer le traçage d’agent.
Pour se conformer au schéma du récupérateur MLflow, la fonction du récupérateur doit renvoyer un objet List[Document] et utiliser le champ metadata dans la classe Document pour ajouter des attributs supplémentaires au document renvoyé, tels que doc_uri et similarity_score. Voir la documentation MLflow.
import mlflow
import requests
from databricks.sdk import WorkspaceClient
from mlflow.entities import Document
class VectorSearchRetriever:
def __init__(self, connection_name, index_name):
self.workspace = WorkspaceClient()
self.connection_name = connection_name
self.index_name = index_name
@mlflow.trace(span_type="RETRIEVER", name="vector_search")
def __call__(self, query_vector: list[float], score_threshold: float = 0.0) -> list[Document]:
response = requests.post(
f"{self.workspace.config.host}/api/2.0/unity-catalog/connections/"
f"{self.connection_name}/proxy/indexes/{self.index_name}/docs/search",
params={"api-version": "2024-07-01"},
headers=self.workspace.config.authenticate(),
json={
"select": "HotelId,HotelName,Description,Category",
"vectorQueries": [{
"vector": query_vector,
"k": 7,
"fields": "DescriptionVector",
"kind": "vector",
"exhaustive": True,
}],
},
timeout=30,
)
response.raise_for_status()
return self.parse_results(response.json(), score_threshold)
@mlflow.trace(span_type="PARSER")
def parse_results(self, results, score_threshold) -> list[Document]:
return [
Document(
page_content=item.get("Description", ""),
id=item.get("HotelId"),
metadata={
"similarity_score": item.get("@search.score", 0),
"HotelName": item.get("HotelName"),
"Category": item.get("Category"),
},
)
for item in results.get("value", [])
if item.get("@search.score", 0) >= score_threshold
]
-
Générez un embedding de query avec le même modèle et les mêmes dimensions que ceux utilisés par votre index. Enregistrez le tableau numérique sous la forme
query-vector.json, puis exécutez le récupérateur :Pythonimport json
from pathlib import Path
query_vector = json.loads(Path("query-vector.json").read_text())
retriever = VectorSearchRetriever("azure_search_connection", "hotels_vector_index")
results = retriever(query_vector, score_threshold=0.1)
for document in results:
print(document.page_content)
Ajouter le traçage à un outil de recherche
Ajouter le traçage MLflow pour surveiller et déboguer votre récupérateur. Le traçage vous permet de visualiser les entrées, les sorties et les métadonnées pour chaque étape d'exécution.
L'exemple précédent ajoute le décorateur @mlflow.trace aux méthodes __call__ et d'analyse. Le décorateur crée un span qui start lorsque la fonction est invoquée et se termine lorsqu'elle renvoie un résultat. MLflow enregistre automatiquement les entrées et les sorties de la fonction, ainsi que toutes les exceptions levées.
LangChain, LlamaIndex, and OpenAI library users can use MLflow auto logging in addition to manually defining traces with the decorator. Consultez la vue d’ensemble du traçage.
Renvoyez une liste d'objets Document avec page_content et metadata, comme le fait l'exemple ci-dessus. Cela suit le schéma d'étendue de récupérateur MLflow, afin que les outils d'évaluation et de révision puissent reconnaître les documents récupérés.
Lisez les fichiers d'un volume Unity Catalog
Si votre agent doit lire des fichiers non structurés (documents texte, rapports, fichiers de configuration, etc.) stockés dans un volume Unity Catalog, vous pouvez créer des outils qui utilisent l’ API Files du SDK Databricks pour lister et lire les fichiers directement.
Choisissez un volume existant et accordez à l’identité de votre agent USE CATALOG, USE SCHEMA et READ VOLUME. Remplacez <catalog>.<schema>.<volume> dans le code. Pour la tâche d’exemple, utilisez un fichier texte UTF-8 nommé about_databricks.txt ou modifiez l’invite pour pointer vers un fichier de votre volume.
Les exemples suivants créent deux outils que votre agent peut utiliser :
list_volume_files: Répertorie les fichiers et les répertoires dans le volume.read_volume_file: Lit le contenu d'un fichier texte depuis le volume.
- LangChain/LangGraph
- OpenAI
Installez la dernière version de databricks-langchain qui inclut Databricks AI Bridge.
pip install --upgrade databricks-langchain langgraph
from pathlib import PurePosixPath
from databricks.sdk import WorkspaceClient
from langchain_core.tools import tool
VOLUME = "<catalog>.<schema>.<volume>"
w = WorkspaceClient()
def volume_path(relative_path: str = "") -> str:
path = PurePosixPath(relative_path)
if path.is_absolute() or ".." in path.parts:
raise ValueError("Use a path relative to the configured volume.")
return str(PurePosixPath("/Volumes", *VOLUME.split(".")) / path)
@tool
def list_volume_files(directory: str = "") -> str:
"""Lists files and directories in the Unity Catalog volume.
Provide a relative directory path, or leave empty to list the volume root."""
path = volume_path(directory)
entries = []
for f in w.files.list_directory_contents(path):
kind = "dir" if f.is_directory else "file"
size = f" ({f.file_size} bytes)" if not f.is_directory else ""
entries.append(f" [{kind}] {f.name}{size}")
return "\n".join(entries) if entries else "No files found."
@tool
def read_volume_file(file_path: str) -> str:
"""Reads a text file from the Unity Catalog volume.
Provide the path relative to the volume root, for example 'reports/q1_summary.txt'."""
full_path = volume_path(file_path)
resp = w.files.download(full_path)
return resp.contents.read().decode("utf-8")
Liez les outils à un LLM et exécutez une boucle d'appel d'outil :
from databricks_langchain import ChatDatabricks
from langchain_core.messages import HumanMessage, ToolMessage
llm = ChatDatabricks(endpoint="databricks-claude-sonnet-4-5")
llm_with_tools = llm.bind_tools([list_volume_files, read_volume_file])
messages = [HumanMessage(content="What files are in the volume? Can you read about_databricks.txt and summarize it in 2 sentences?")]
tool_map = {"list_volume_files": list_volume_files, "read_volume_file": read_volume_file}
for _ in range(5): # max iterations
response = llm_with_tools.invoke(messages)
messages.append(response)
if not response.tool_calls:
break
for tc in response.tool_calls:
result = tool_map[tc["name"]].invoke(tc["args"])
messages.append(ToolMessage(content=result, tool_call_id=tc["id"]))
else:
raise RuntimeError("The agent reached the tool-calling limit.")
print(response.content)
Installez la dernière version de databricks-openai qui inclut Databricks AI Bridge.
pip install --upgrade databricks-openai
import json
from pathlib import PurePosixPath
from databricks.sdk import WorkspaceClient
from databricks_openai import DatabricksOpenAI
VOLUME = "<catalog>.<schema>.<volume>"
w = WorkspaceClient()
client = DatabricksOpenAI()
# Define the tool specifications
tools = [
{
"type": "function",
"function": {
"name": "list_volume_files",
"description": "Lists files and directories in the Unity Catalog volume. Provide a relative directory path, or leave empty to list the volume root.",
"parameters": {
"type": "object",
"properties": {
"directory": {
"type": "string",
"description": "Relative directory path within the volume. Leave empty for root.",
}
},
"required": [],
},
},
},
{
"type": "function",
"function": {
"name": "read_volume_file",
"description": "Reads a text file from the Unity Catalog volume. Provide the path relative to the volume root, for example 'reports/q4_summary.txt'.",
"parameters": {
"type": "object",
"properties": {
"file_path": {
"type": "string",
"description": "Path to the file relative to the volume root.",
}
},
"required": ["file_path"],
},
},
},
]
def volume_path(relative_path: str = "") -> str:
path = PurePosixPath(relative_path)
if path.is_absolute() or ".." in path.parts:
raise ValueError("Use a path relative to the configured volume.")
return str(PurePosixPath("/Volumes", *VOLUME.split(".")) / path)
def execute_tool(name: str, args: dict) -> str:
if name == "list_volume_files":
directory = args.get("directory", "")
path = volume_path(directory)
entries = []
for f in w.files.list_directory_contents(path):
kind = "dir" if f.is_directory else "file"
size = f" ({f.file_size} bytes)" if not f.is_directory else ""
entries.append(f"[{kind}] {f.name}{size}")
return "\n".join(entries) if entries else "No files found."
elif name == "read_volume_file":
full_path = volume_path(args["file_path"])
resp = w.files.download(full_path)
return resp.contents.read().decode("utf-8")
return f"Unknown tool: {name}"
# Call the model with tools
messages = [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "List the files in the volume, then read about_databricks.txt and summarize it."},
]
for _ in range(10):
response = client.chat.completions.create(
model="databricks-claude-sonnet-4-5", messages=messages, tools=tools
)
message = response.choices[0].message
messages.append(message.model_dump(exclude_none=True))
if not message.tool_calls:
print(message.content)
break
for call in message.tool_calls:
args = json.loads(call.function.arguments)
result = execute_tool(call.function.name, args)
messages.append({"role": "tool", "tool_call_id": call.id, "content": result})
else:
raise RuntimeError("The agent reached the tool-calling limit.")
Query un index de recherche AI à l’aide du protocole MCP (ancienne version)
Le serveur MCP AI Search utilise un endpoint MCP de workspace hérité. Il nécessite un index avec des embeddings gérés par Databricks. Consultez Créer des Endpoint et des index de recherche AI.
The legacy workspace MCP URL for AI Search is https://<workspace-hostname>/api/2.0/mcp/ai-search/{catalog}/{schema}/{index_name}. Connect to it and list the tools it exposes:
from databricks.sdk import WorkspaceClient
from databricks_mcp import DatabricksMCPClient
workspace_client = WorkspaceClient()
host = workspace_client.config.host
mcp_client = DatabricksMCPClient(
server_url=f"{host}/api/2.0/mcp/ai-search/<catalog>/<schema>/<index-name>",
workspace_client=workspace_client,
)
tools = mcp_client.list_tools()
Pour créer et déployer un agent qui utilise ce serveur, consultez Utiliser des outils MCP dans un agent Python. Accordez à l'agent SELECT sur l'élément sécurisable Unity Catalog de l'index.
AI Search s’appelait auparavant Vector Search. Le préfixe d’URL /api/2.0/mcp/vector-search/ précédent fonctionne toujours.
Query Databricks AI Search à l’aide de fonctions UC (déprécié)
Pour les nouveaux agents Python, utilisez AI Bridge. L'exemple suivant sert de référence pour les intégrations existantes.
Vous pouvez créer une fonction Unity Catalog qui encapsule une query d’ index de recherche IA. Cette approche :
- Prend en charge les cas d'usage de production avec gouvernance et découvrabilité.
- Utilise la fonction SQL vector_search() sous le capot.
- Prend en charge le suivi MLflow automatique
- Vous devez aligner la sortie de la fonction sur le schéma de l'extracteur MLflow en utilisant les alias
page_contentetmetadata. - Toutes les colonnes de métadonnées supplémentaires doivent être ajoutées à la colonne
metadataà l'aide de la fonction de mappage SQL, plutôt que comme clés de sortie de niveau supérieur.
- Vous devez aligner la sortie de la fonction sur le schéma de l'extracteur MLflow en utilisant les alias
Exécutez le code suivant dans un Notebook ou un éditeur SQL pour créer la fonction :
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 AI Search index name here
index => 'catalog.schema.databricks_docs_index',
query => query,
num_results => 5
)
Suivez la configuration de l'outil de fonction, puis enveloppez ce récupérateur avec UCFunctionToolkit pour l'utiliser dans votre agent. Cela permet le traçage automatique via MLflow en générant automatiquement des types de portée RETRIEVER dans les logs de MLflow.
from databricks_langchain import UCFunctionToolkit
from unitycatalog.ai.core.databricks import DatabricksFunctionClient
toolkit = UCFunctionToolkit(
function_names=[
"main.default.databricks_docs_vector_search"
],
client=DatabricksFunctionClient(),
)
tools = toolkit.tools
Les outils de récupération Unity Catalog présentent les mises en garde suivantes :
- Les clients SQL peuvent limiter le nombre maximal de lignes ou d’octets renvoyés. Pour éviter la troncation des données, tronquez les valeurs de colonne renvoyées par l’UDF. Par exemple, vous pouvez utiliser
substring(chunked_text, 0, 8192)pour réduire la taille des colonnes de contenu volumineuses et éviter la troncation des lignes pendant l’exécution. - Étant donné que cet outil est un wrapper pour la fonction
vector_search(), il est soumis aux mêmes limitations que la fonctionvector_search(). Consultez les Limitations.
Pour plus d'informations sur UCFunctionToolkit, consultez la documentation Unity Catalog.
Schémas de récupérateur personnalisés (hérité)
mlflow.models.set_retriever_schema est obsolète. Pour les nouveaux récupérateurs, renvoyez des objets Document en utilisant le schéma de récupérateur standard. La configuration suivante concerne les intégrations existantes qui renvoient des champs personnalisés.
Pour définir le schéma du récupérateur manuellement :
-
Appelez mlflow.models.set_retriever_schema. lorsque vous définissez votre agent. Utilisez
set_retriever_schemapour mapper les noms de colonnes de la table renvoyée aux champs attendus de MLflow, tels queprimary_key,text_columnetdoc_uri.Pythonimport mlflow
# 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"],
) -
Spécifiez des colonnes supplémentaires dans le schéma de votre récupérateur en fournissant une liste de noms de colonnes avec le champ
other_columns. -
Si vous avez plusieurs extracteurs, vous pouvez définir plusieurs schémas en utilisant des noms uniques pour chaque schéma d'extracteur.
Le schéma de l'outil de récupération défini lors de la création de l'agent affecte les applications et les workflows en aval, tels que l'application de révision et les ensembles d'évaluation. Plus précisément, la colonne doc_uri sert d'identifiant principal pour les documents renvoyés par l'outil de récupération.
- L' application d'examen affiche le
doc_uripour aider les évaluateurs à évaluer les réponses et à retracer les origines des documents. Consultez l'interface utilisateur de l'application d'examen. - Les evaluation sets utilisent
doc_uripour comparer les résultats du système de recherche (retriever) aux datasets d’évaluation prédéfinis afin de déterminer le rappel et la précision du système. Consultez la référence des datasets d’évaluation.