Выполните поиск сходства векторов с помощью Vertex AI

Добро пожаловать в поиск векторного сходства Firebase Data Connect — реализацию семантического поиска Firebase, которая интегрируется с Google Vertex AI .

В основе этой функции лежат векторные вложения, представляющие собой массивы чисел с плавающей точкой, представляющие семантическое значение текста или медиа. Запустив поиск ближайшего соседа с использованием вложения входного вектора, вы можете найти весь семантически похожий контент. Data Connect использует расширение PostgreSQL pgvector для этой возможности.

Этот мощный семантический поиск может управлять вариантами использования, такими как рекомендательные и поисковые системы. Он также является ключевым компонентом в генерации дополненного поиска в генеративных потоках ИИ. Документация Vertex AI — отличное место, чтобы узнать больше .

Вы можете положиться на встроенную поддержку Data Connect для автоматического создания векторных вложений с помощью API вложений Vertex AI или использовать этот API для их создания вручную.

Предпосылки

  • Настройте Data Connect для вашего проекта.

  • Включить API Vertex AI .

Настраивать

Вы можете выбрать между локальным потоком разработки (если вы веб-разработчик, Kotlin Android или iOS-разработчик) или потоком IDX (для веб-разработчиков). Вы можете использовать локальную базу данных или ваш производственный проект Data Connect и его экземпляр Cloud SQL для PostgreSQL для разработки.

В этих инструкциях предполагается, что вы создали свой проект Data Connect следуя краткому руководству .

Интеграция с локальной PostgreSQL

  1. Настройте локальный экземпляр PostgreSQL.
  2. Предоставьте себе роль IAM пользователя Vertex AI .
  3. Настройте учетные данные по умолчанию для приложения Google Cloud в вашей среде.
  4. Установите расширение pgvector в локальном экземпляре PostgreSQL.
  5. Включите расширение с помощью CREATE EXTENSION vector следуя инструкциям репозитория pgvector .

Интеграция с IDX

  1. Настройте рабочее пространство IDX с помощью шаблона Data Connect.
  2. Предоставьте себе роль IAM пользователя Vertex AI .
  3. Включите расширение с помощью CREATE EXTENSION vector следуя инструкциям репозитория pgvector .

Разработайте свою схему

Для выполнения векторного поиска добавьте в схему новое поле типа Vector . Например, если вы хотите выполнить семантический поиск с использованием описаний фильмов, добавьте поле для хранения векторных вложений, связанных с описанием фильма. В этой схеме descriptionEmbedding добавляется для хранения векторных вложений для поля 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)
 // ...
}

Генерация и извлечение вложений

Data Connect обеспечивает интегрированную поддержку векторных вложений с помощью значения сервера _embed . Это предписывает Data Connect генерировать векторные вложения путем внутреннего вызова API вложений Vertex AI. Значение сервера _embed может использоваться как в мутациях, так и в запросах.

Мутации

Создание и сохранение вложений через Data Connect

В вашем приложении векторного поиска вы, вероятно, захотите запросить генерацию вложений сразу после добавления записей в базу данных. Вот мутация createMovie , которая добавляет запись о фильме в таблицу Movie , а также передает описание фильма с указанной model вложения.

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

В некоторых случаях вам может потребоваться обновить описание фильма и вставку.

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

Чтобы вызвать последнюю мутацию из клиента:

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

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

// Use the response

Запросы

Извлеките векторные вложения с помощью запроса, подобного следующему. Обратите внимание, что возвращаемое запросом descriptionEmbedding представляет собой массив чисел с плавающей точкой, который обычно не читается человеком. Таким образом, SDK, созданные Data Connect не поддерживают возврат его напрямую.

Вы можете использовать возвращенные векторные вложения для поиска сходства, как описано в следующем разделе.

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

Выполнить поиск по сходству

Теперь мы можем выполнить поиск по схожести.

Для каждого поля Vector Data Connect генерирует функцию GraphQL, которая реализует поиск по сходству. Имя этой сгенерированной функции — ${pluralType}_${vectorFieldName}_similarity . Она поддерживает несколько параметров, как показано в следующих примерах и в списке ссылок .

Вы можете определить функцию GraphQL, которая вызывает поиск по сходству. Как упоминалось выше, значение сервера _embed указывает Data Connect на необходимость генерировать векторные вложения с использованием API вложения Vertex AI, в данном случае для создания вложений для строки поиска, используемой для сравнения с вложениями описания фильма.

В этом примере поиск по сходству вернет до 5 фильмов, описание которых семантически наиболее близко к входному запросу. Набор результатов сортируется в порядке возрастания расстояния — от ближайшего к самому дальнему.

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

Настройте запрос на сходство

Значения по умолчанию для параметров поиска, таких как method и within , хорошо подходят для большинства случаев использования. Однако, если вы заметили, что ваш запрос возвращает слишком разные результаты или не содержит результатов, которые вы хотели бы включить, попробуйте настроить эти параметры.

Чтобы найти подходящее значение для within , мы можем добавить _metadata.distance к выбранным полям, чтобы увидеть, насколько далеко от вектора запроса находится каждый результат. На основе возвращенных значений distance мы можем установить параметр within ; будут включены только результаты с расстоянием меньше значения within :

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

Вы также можете экспериментировать с различными функциями расстояния, задавая параметр method .

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

Обратите внимание, что разные методы возвращают совершенно разные значения расстояния: если вы установили within , вам придется снова настроить это значение после изменения method .

Вызовите запрос на сходство

Чтобы вызвать поиск по сходству из клиентского кода:

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

const response = await searchMovieDescriptionUsingL2similarity({ query });

// Use the response

Используйте пользовательские вставки

Data Connect также позволяет работать с встраиваниями напрямую как с Vector , а не использовать значение сервера _embed для их генерации.

Сохраните пользовательское вложение

Используя API Vertex Embeddings, укажите соответствующую модель и запросите результаты встраивания правильного размера.

Затем преобразуйте возвращенный массив чисел с плавающей точкой в Vector , чтобы передать его в операцию обновления для хранения.

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

Выполнение поиска по схожести с использованием пользовательских вложений

Выполните ту же операцию, чтобы получить вложения для поисковых терминов и преобразовать их в Vectors .

Затем вызовите запрос _similarity для выполнения каждого поиска.

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
      }
  }

Развертывание в производство

Разверните вашу схему и коннектор

Последним шагом в типичной итерации Data Connect является развертывание ваших активов в рабочей среде.

При развертывании схемы, содержащей типы Vector , в CloudSQL с помощью команды firebase deploy интерфейс командной строки Firebase предпринимает необходимые шаги для включения генерации встраивания на основе Vertex AI в вашем экземпляре CloudSQL.

firebase deploy --only dataconnect

Если вы хотите вручную включить поддержку встраивания в свой экземпляр CloudSQL или столкнулись с ошибкой CLI, следуйте этим инструкциям .

Синтаксис поиска векторов

Расширения схемы

Тип данных Vector в Data Connect соответствует vector типу PostgreSQL, определенному расширением pgvector . vector тип pgvector хранится в PostgreSQL как массив чисел с плавающей запятой одинарной точности.

В Data Connect тип Vector представлен как массив чисел JSON. Входные данные приводятся к массиву значений float32 . Если приведение не удается, возникает ошибка.

Используйте параметр size директивы @col для установки размеров вектора.

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

size поддерживается только для типов Vector . Vector операции, такие как поиск по сходству, требуют, чтобы все Vector имели одинаковое количество измерений.

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

_embed значение сервера для запросов и мутаций

_embed

Это значение сервера указывает службе Data Connect на необходимость генерировать и хранить вложения с использованием API вложения Vertex AI . Это значение сервера можно использовать как в запросах, так и в мутациях.

Параметры для поиска по сходству

method: COSINE|INNER_PRODUCT|L2

Функция расстояния, используемая для поиска ближайших соседей. Поддерживаемые в настоящее время алгоритмы являются подмножеством алгоритмов поиска pgvector .

within: float

Ограничение на расстояние, в пределах которого выполняется поиск ближайшего соседа.

where: FDC filter condition

См. руководство по схемам, запросам и мутациям .

limit: int

Количество возвращаемых результатов.