Accéder au contenu principal

Plugin AI Search

Plugin AI Search

Plugin bêta

Ce plugin est actuellement en bêta. Les API peuvent changer d'une version mineure à l'autre. Importez depuis @databricks/appkit/beta. Consultez Niveaux de stabilité des plugins.

Interrogez des index Databricks Vector Search avec recherche hybride, reranking et pagination par curseur depuis votre application AppKit.

Fonctionnalités clés :

  • Alias nommés pour plusieurs index Vector Search
  • Modes de query hybride, ANN et texte intégral
  • Reranking facultatif avec contrôle au niveau des colonnes
  • Pagination par curseur pour les grands ensembles de résultats
  • Authentification par service principal (par défaut) et on-behalf-of-user
  • Index d'embeddings autogérés via une fonction embeddingFn personnalisée

Utilisation de base

import { createApp, server } from "@databricks/appkit";
import { aiSearch } from "@databricks/appkit/beta";

await createApp({
  plugins: [
    server(),
    aiSearch({
      indexes: {
        products: {
          indexName: "catalog.schema.products_idx",
          columns: ["id", "name", "description"],
          queryType: "hybrid",
          numResults: 20,
        },
      },
    }),
  ],
});

Options de configuration

OptionTypeValeur par défautDescription
indexesRecord<string, IndexConfig>Obligatoire. Correspondance entre les noms d'alias et les configurations d'index
timeoutnumber30000Délai d'expiration des requêtes, en ms

Alias d'index

Les alias d'index vous permettent de référencer plusieurs index Vector Search par leur nom. L'alias est utilisé dans les routes d'API et les appels programmatiques :

aiSearch({
  indexes: {
    products: {
      indexName: "catalog.schema.products_idx",
      columns: ["id", "name", "description"],
    },
    docs: {
      indexName: "catalog.schema.docs_idx",
      columns: ["id", "title", "content", "url"],
      queryType: "full_text",
    },
  },
});
note

Un alias sans indexName propre utilise par défaut la variable d'environnement DATABRICKS_VS_INDEX_NAME. Si plusieurs alias omettent indexName, ils pointent tous vers ce même index physique (tout en conservant leurs propres columns, queryType, etc.). Attribuez un indexName explicite à chaque alias lorsque vous souhaitez cibler des index distincts.

IndexConfig

ChampTypeValeur par défautDescription
indexNamestringDATABRICKS_VS_INDEX_NAMENom Unity Catalog à trois niveaux (catalog.schema.index). Utilise par défaut la variable d'environnement DATABRICKS_VS_INDEX_NAME s'il est omis.
columnsstring[]découvertes automatiquement en développementColonnes à renvoyer dans les résultats de query. Facultatif en développement : si elles sont omises, le plugin les lit dans la table source de l'index et émet un avertissement. À définir explicitement en production, où une valeur manquante n'est pas renseignée automatiquement.
queryType"ann" | "hybrid" | "full_text""hybrid"Mode de recherche
numResultsnumber20Nombre maximal de résultats par query
rerankerboolean | { columnsToRerank: string[] }Active le reranking. Indiquez true pour reclasser toutes les colonnes de résultats, ou précisez un sous-ensemble
auth"service-principal" | "on-behalf-of-user""service-principal"Mode d'authentification pour l'exécution des query
paginationbooleanActive la pagination par curseur
endpointNamestringNom de l'endpoint Vector Search. Requis lorsque pagination vaut true
embeddingFn(text: string) => Promise<number[]>Fonction d'embedding personnalisée pour les index d'embeddings auto-gérés

Types de requêtes

  • hybrid — Combine la similarité vectorielle et la recherche par mots-clés. Idéale pour une recherche polyvalente.
  • ann — Recherche approximative des plus proches voisins, basée uniquement sur les embeddings. Idéale pour la similarité sémantique.
  • full_text — Recherche par mots-clés, sans embedding requis.

Reranking

Le reranking améliore la pertinence des résultats en appliquant un modèle de seconde passe aux candidats initiaux :

aiSearch({
  indexes: {
    products: {
      indexName: "catalog.schema.products_idx",
      columns: ["id", "name", "description", "category"],
      reranker: { columnsToRerank: ["name", "description"] },
    },
  },
});

Passez reranker: true pour effectuer un reclassement sur l'ensemble des colonnes renvoyées.

Authentification on-behalf-of-user

Par défaut, les queries s'exécutent sous l'identité du service principal de l'application. Définissez auth: "on-behalf-of-user" pour les exécuter sous l'identité de l'utilisateur connecté :

aiSearch({
  indexes: {
    documents: {
      indexName: "catalog.schema.documents_idx",
      columns: ["id", "title", "body"],
      auth: "on-behalf-of-user",
    },
  },
});

Pagination

Activez la pagination par curseur pour parcourir de grands ensembles de résultats :

aiSearch({
  indexes: {
    products: {
      indexName: "catalog.schema.products_idx",
      columns: ["id", "name", "description"],
      pagination: true,
      endpointName: "my-vector-search-endpoint",
    },
  },
});

endpointName est requis lorsque pagination vaut true. Utilisez la route /:alias/next-page pour récupérer les pages suivantes.

Index à embeddings autogérés

Pour les index qui gèrent leurs propres embeddings, fournissez une fonction embeddingFn qui prend une chaîne de requête en entrée et renvoie un vecteur :

import { embed } from "./my-embedding-client";

aiSearch({
  indexes: {
    products: {
      indexName: "catalog.schema.products_idx",
      columns: ["id", "name", "description"],
      queryType: "ann",
      embeddingFn: (text) => embed(text),
    },
  },
});

Routes HTTP

Les routes sont montées sur /api/ai-search.

MéthodeCheminDescription
POST/:alias/queryInterroger un index par son alias
POST/:alias/next-pageRécupérer la page de résultats suivante (nécessite pagination: true)
GET/:alias/configRenvoyer la configuration résolue pour un alias d'index

Interroger un index

POST /api/ai-search/:alias/query Content-Type: application/json { "queryText": "machine learning guide", "numResults": 10 }

Réponse :

{
  "results": [
    {
      "score": 0.87,
      "data": { "id": "42", "name": "Intro to ML", "description": "..." }
    }
  ],
  "totalCount": 1,
  "queryTimeMs": 35,
  "queryType": "hybrid",
  "nextPageToken": "eyJvZmZzZXQiOjEwfQ=="
}

Chaque résultat comporte son score de pertinence ainsi que les colonnes renvoyées sous data. nextPageToken vaut null, sauf si pagination est activé et que d'autres résultats sont disponibles.

Récupérer la page suivante

POST /api/ai-search/:alias/next-page Content-Type: application/json { "queryText": "machine learning guide", "pageToken": "eyJvZmZzZXQiOjEwfQ==" }

Obtenir la configuration de l'index

GET /api/ai-search/:alias/config

Renvoie la configuration IndexConfig résolue pour l'alias (hors embeddingFn).

Accès programmatique

Le plugin expose une méthode query destinée à un usage côté serveur :

import { createApp, server } from "@databricks/appkit";
import { aiSearch } from "@databricks/appkit/beta";

const AppKit = await createApp({
  plugins: [
    server(),
    aiSearch({
      indexes: {
        products: {
          indexName: "catalog.schema.products_idx",
          columns: ["id", "name", "description"],
        },
      },
    }),
  ],
});

const result = await AppKit.aiSearch.query("products", {
  queryText: "machine learning guide",
});

console.log(result.results);

Passez des valeurs de remplacement facultatives en deuxième argument de query pour ajuster numResults ou d'autres paramètres spécifiques à l'appel.

Mise en cache

Les résultats des requêtes sont mis en cache avec un TTL court (60 s) : ainsi, des requêtes identiques répétées — y compris lorsqu'un composant effectue un nouveau rendu ou est monté deux fois — réutilisent un seul appel à Vector Search au lieu d'interroger l'index à chaque fois. La route de page suivante, elle, n'est pas mise en cache : un jeton de page est un curseur à usage unique qui identifie déjà la page exacte.

La clé de cache couvre tout ce qui influe sur les résultats : l'index résolu, queryText, queryVector (haché), queryType, numResults, les columns résolues, les filters et l'activation ou non du reranking. Deux requêtes qui diffèrent sur l'un de ces éléments sont mises en cache séparément.

Isolation par utilisateur

Pour les index auth: "on-behalf-of-user", l'identité de l'appelant fait partie de la clé de cache : un utilisateur ne voit donc jamais les résultats mis en cache d'un autre utilisateur, et une query on-behalf-of-user ne lit jamais une entrée alimentée par un service principal. Les index en service principal, eux, partagent une seule et même entrée de cache entre tous les appelants.

Hook React

useAiSearchQuery lit les index configurés dans la configuration client du plugin et envoie une requête POST vers la route /:alias/query appropriée : l'interface n'a donc jamais besoin de coder un alias en dur. Lorsqu'un seul index est configuré, aucun argument n'est requis ; passez { alias } pour cibler un index précis.

import { useAiSearchQuery } from "@databricks/appkit-ui/react/beta";

function Search() {
  const { search, data, loading, error } = useAiSearchQuery();

  return (
    <>
      <input onKeyDown={(e) => e.key === "Enter" && search(e.currentTarget.value)} />
      {error && <p>{error}</p>}
      {data?.results.map((r, i) => (
        <div key={i}>{JSON.stringify(r.data)}</div>
      ))}
    </>
  );
}

search accepte également un objet de requête complet ({ queryText, numResults, filters, ... }) pour un contrôle appel par appel. Le champ indexes du hook répertorie tous les index configurés, ce qui vous permet de construire un sélecteur d'index.

Databricks Developer Hub

Prêt à lancer votre prochaine application agentique en quelques minutes ?

Lire la documentation