Wyszukiwanie podobieństw wektorowych za pomocą Vertex AI

Witamy w wyszukiwaniu wektorowym Firebase Data Connect – implementacji wyszukiwania semantycznego w Firebase, która integruje się z Google Vertex AI.

Podstawą tej funkcji są wektory dystrybucyjne, czyli tablice liczb zmiennoprzecinkowych, które reprezentują znaczenie semantyczne tekstu lub multimediów. Wykonując wyszukiwanie najbliższych sąsiadów za pomocą wektora dystrybucyjnego wejściowego, możesz znaleźć wszystkie treści podobne semantycznie. Data Connect używa do tego celu rozszerzenia pgvector w PostgreSQL.

Ta zaawansowana wyszukiwarka semantyczna może być wykorzystywana w przypadkach takich jak systemy rekomendacji i wyszukiwarki. Jest to też kluczowy element generowania wspomaganego przez wyszukiwanie w ramach procesów generatywnej AI. Więcej informacji znajdziesz w dokumentacji Vertex AI.

Możesz polegać na wbudowanym w Data Connect mechanizmie automatycznego generowania wektorów dystrybucyjnych za pomocą interfejsu Embeddings API Vertex AI lub użyć tego interfejsu do ich ręcznego generowania.

Wymagania wstępne

  • Skonfiguruj Data Connect w przypadku swojego projektu.

  • Włącz interfejsy Vertex AI API.

Konfiguracja

Możesz wybrać lokalny proces tworzenia aplikacji (jeśli jesteś deweloperem witryn internetowych, Kotlina, Androida lub iOS) albo proces IDX (dla deweloperów witryn internetowych). Do celów programistycznych możesz użyć lokalnej bazy danych lub produkcyjnego projektu Data Connect i jego instancji Cloud SQL for PostgreSQL.

W tych instrukcjach przyjęto założenie, że masz utworzony projekt Data Connectzgodnie z instrukcjami z krótkiego przewodnika.

Integracja z lokalną bazą danych PostgreSQL

  1. skonfigurować lokalną instancję PostgreSQL;
  2. Przypisz sobie rolę uprawnień użytkownika Vertex AI.
  3. Skonfiguruj domyślne uwierzytelnianie aplikacji Google Cloud w swoim środowisku.
  4. Zainstaluj rozszerzenie pgvector w lokalnej instancji PostgreSQL.
  5. Włącz rozszerzenie za pomocą CREATE EXTENSION vector zgodnie z instrukcjami w repozytorium pgvector.

Integracja z IDX

  1. Skonfiguruj obszar roboczy IDX za pomocą szablonu Data Connect.
  2. Przypisz sobie rolę uprawnień użytkownika Vertex AI.
  3. Włącz rozszerzenie za pomocą CREATE EXTENSION vector zgodnie z instrukcjami w repozytorium pgvector.

Projektowanie schematu

Aby przeprowadzić wyszukiwanie wektorów, dodaj w schemacie nowe pole typu Vector. Jeśli na przykład chcesz przeprowadzić wyszukiwanie semantyczne za pomocą opisów filmów, dodaj pole do przechowywania wektorów dystrybucyjnych powiązanych z opisem filmu. W tym schemacie pole descriptionEmbedding służy do przechowywania wektorów dystrybucyjnych w polu description.

type Movie @table {
 id: ID! @col(name: "movie_id") @default(id: ID! @col(name: "movie_id") @default(expr: "uuidV4()")
 title: String!
 description: String
 descriptionEmbedding: Vector! @col(size:768)
 // ...
}

Generowanie i pobieranie wektorów

Data Connect zapewnia zintegrowane wsparcie dla wektorów osadzonych z wartością serwera _embed. W ten sposób usługa Data Connect generuje wektory dystrybucyjne, wywołując wewnętrznie interfejsy osadzania Vertex AI. Wartość serwera _embed może być używana zarówno w mutacjach, jak i w zapytaniach.

Mutacje

Generowanie i przechowywanie kodu osadzania za pomocą Data Connect

W aplikacji do wyszukiwania wektorów prawdopodobnie będziesz chciał(-a) poprosić o wygenerowanie wektorów w chwili dodania rekordów do bazy danych. Oto przykład createMovie mutacji, która dodaje rekord filmu do tabeli Movie, a także przekazuje opis filmu z określonym elementem osadzania model.

mutation createMovie($movieData: Movie_Data! @pick(fields: ["title", "genre", "description"])) {
  movie_insert(data: {
    ...movieData,
    descriptionEmbedding_embed: {model: "textembedding-gecko@003", text: $movieData.description}
  })
}

W niektórych przypadkach warto zaktualizować opis filmu i opcję osadzenia.

mutation updateDescription($id: String!, $description: String!) {
  movie_update(id: $id, data: {
    description: $description,
    descriptionEmbedding_embed: {model: "textembedding-gecko@003", text: $description}
  })
}

Aby wywołać tę mutację z poziomu klienta:

import { updateMovieDescriptionWithEmbed } from 'lib/dataconnect-sdk/';

await updateMovieDescriptionWithEmbed({ id: movieId, description: description});

// Use the response

Zapytania

Aby pobrać wektory rozkładu, użyj zapytania podobnego do tego: Pamiętaj, że zmienna descriptionEmbedding zwracana przez zapytanie to tablica typu float, która zazwyczaj nie jest czytelna dla człowieka. Dlatego pakiety SDK utworzone przez Data Connect nie obsługują bezpośredniego zwracania.

Zwrócone wektory dystrybucyjne możesz wykorzystać do wyszukiwania podobieństw, jak opisano w następnej sekcji.

query getMovieDescription($id: String!) @auth(is: PUBLIC) {
 movie(id: $id)
   id
   description
   descriptionEmbedding
}

Przeprowadzanie wyszukiwania podobieństwa

Teraz możemy przeprowadzić wyszukiwanie podobieństw.

W przypadku każdego pola Vector funkcja Data Connect generuje funkcję GraphQL, która implementuje wyszukiwanie podobieństw. Nazwa tej wygenerowanej funkcji to ${pluralType}_${vectorFieldName}_similarity. Obsługuje on kilka parametrów, jak pokazano w następujących przykładach i w liście referencyjnej.

Możesz zdefiniować funkcję GraphQL, która wywołuje wyszukiwanie podobieństw. Jak wspomnieliśmy powyżej, wartość serwera _embed kieruje Data Connect do generowania wektorów dystrybucyjnych za pomocą interfejsów API Vertex AI, w tym przypadku do tworzenia wektorów dystrybucyjnych dla ciągu wyszukiwania używanego do porównania z wektorami dystrybucyjnymi opisu filmu.

W tym przykładzie wyszukiwanie podobieństw zwróci do 5 filmów, których opis jest semantycznie najbardziej zbliżony do zapytania wejściowego. Zestaw wyników jest sortowany w rosnącej kolejności według odległości – od najbliższej do najdalszej.

query searchMovieDescriptionUsingL2Similarity ($query: String!) @auth(level: PUBLIC) {
    movies_descriptionEmbedding_similarity(
      compare_embed: {model: "textembedding-gecko@003", text: $query},
      method: L2,
      within: 2,
      where: {content: {ne: "No info available for this movie."}}, limit: 5)
      {
        id
        title
        description
      }
  }

Wywoływanie zapytania o podobność

Aby wywołać wyszukiwanie podobieństw w kodzie klienta:

import { searchMovieDescriptionUsingL2similarity} from 'lib/dataconnect-sdk';

const response = await searchMovieDescriptionUsingL2similarity({ query });

// Use the response

Korzystanie z wektorów dystrybucyjnych niestandardowych

Data Connect umożliwia też bezpośrednią pracę z wbudowanymi elementami jako Vectorzamiast generowania ich za pomocą wartości serwera _embed.

Przechowywanie niestandardowego osadzenia

Za pomocą interfejsu Vertex Embeddings API określ odpowiedni model i poproś o wyniki wbudowania w odpowiednim wymiarze.

Następnie przekonwertuj zwrócony tablicowy wektor liczb zmiennoprzecinkowych na Vector, aby przekazać go operacji aktualizacji w celu zapisania.

mutation updateDescription($id: String!, $description: String!, $descriptionEmbedding: Vector!) {
  movie_update(id: $id, data: {
    // title, genre...
    description: $description,
    descriptionEmbedding: $descriptionEmbedding
  })
}

Wykonywanie wyszukiwania podobieństwa za pomocą niestandardowych wektorów dystrybucyjnych

Wykonaj tę samą operację, aby pobrać wektory dystrybucyjne dla wyszukiwanych haseł, i przypisz je do Vectors.

Następnie wywołaj zapytanie _similarity, aby wykonać każde wyszukiwanie.

query searchMovieDescriptionUsingL2Similarity($compare: Vector!, $within: Float, $excludesContent: String, $limit: Int) @auth(level: PUBLIC) {
    movies_descriptionEmbedding_similarity(
      compare: $compare,
      method: L2,
      within: $within,
      where: {content: {ne: $excludesContent}}, limit: $limit)
      {
        id
        title
        description
      }
  }

Wdrażanie w gałęzi produkcyjnej

Wdrażanie schematu i sprzęgającego

Ostatnim krokiem w typowym cyklu Data Connect jest wdrożenie zasobów do wersji produkcyjnej.

Podczas wdrażania schematu zawierającego typy Vector do CloudSQL za pomocą polecenia firebase deploy interfejs wiersza poleceń Firebase wykonuje niezbędne czynności, aby włączyć w instancji CloudSQL generowanie wektorów dystrybucyjnych na podstawie Vertex AI.

firebase deploy --only dataconnect

Jeśli chcesz ręcznie włączyć obsługę umieszczania w instancji CloudSQL lub napotkasz błąd w interfejsie wiersza poleceń, wykonaj te instrukcje.

Składnia wyszukiwania wektorowego

Rozszerzenia schematu

Typ danych VectorData Connect jest mapowany na typ vector w PostgreSQL zgodnie z definicją w rozszerzeniu pgvector. Typ vector w pgvector jest przechowywany w PostgreSQL jako tablica liczb zmiennoprzecinkowych o pojedynczej precyzji.

W elementach Data Connect typ Vector jest reprezentowany jako tablica liczb w formacie JSON. Dane wejściowe są przekształcane w tablicę wartości float32. Jeśli nie uda się przekształcić wartości, zostanie zgłoszony błąd.

Aby ustawić wymiary wektora, użyj parametru size dyrektywy @col.

type Question @table {
    text: String!
    category: String!
    textEmbedding: Vector! @col(size: 768)
}

Wartość size jest obsługiwana tylko w przypadku typów Vector. Operacje Vector, takie jak wyszukiwanie podobnych elementów, wymagają, aby wszystkie Vector miały taką samą liczbę wymiarów.

directive @col(
  # … existing args
  """
  Defines a fixed column size for certain scalar types.

  - For Vector, size is required.
  - For all other types, size is currently unsupported and hence supplying it will result in a schema error.
  """
  size: Int
) on FIELD_DEFINITION

Wartość serwera _embed dla zapytań i mutacji

_embed

Ta wartość serwera kieruje usługę Data Connect do generowania i przechowywania wektorów za pomocą interfejsów Vertex AI Embedding API. Tej wartości serwera można używać zarówno w przypadku zapytań, jak i mutacji.

Parametry wyszukiwania podobieństw

method: COSINE|INNER_PRODUCT|L2

Funkcja odległości używana do wyszukiwania najbliższych sąsiadów. Obecnie obsługiwane algorytmy to podzbiór algorytmów wyszukiwania pgvector.

within: float

Ograniczenie odległości, w której przeprowadzane jest wyszukiwanie najbliższych sąsiadów.

where: FDC filter condition

Zapoznaj się z przewodnikiem po schematach, zapytaniach i mutacjach.

limit: int

Liczba wyników do zwrócenia.