Thực hiện tìm kiếm điểm tương đồng vectơ bằng Vertex AI

Chào mừng bạn đến với tính năng tìm kiếm tương tự theo vectơ của Firebase Data Connect — đây là cách triển khai tính năng tìm kiếm ngữ nghĩa của Firebase, tích hợp với Google Vertex AI.

Cốt lõi của tính năng này là các vectơ nhúng, là mảng gồm các số dấu phẩy động biểu thị ý nghĩa ngữ nghĩa của văn bản hoặc nội dung nghe nhìn. Bằng cách chạy một tìm kiếm lân cận gần nhất bằng cách sử dụng một vectơ nhúng đầu vào, bạn có thể tìm thấy tất cả nội dung tương tự về mặt ngữ nghĩa. Data Connect sử dụng tiện ích pgvector của PostgreSQL cho chức năng này.

Tính năng tìm kiếm ngữ nghĩa mạnh mẽ này có thể thúc đẩy các trường hợp sử dụng như công cụ đề xuất và công cụ tìm kiếm. Đây cũng là một thành phần chính trong quá trình tạo tăng cường khả năng truy xuất trong các luồng AI tạo sinh. Tài liệu về Vertex AI là nơi tuyệt vời để bạn tìm hiểu thêm.

Bạn có thể dựa vào sự hỗ trợ tích hợp của Data Connect để tự động tạo các mục nhúng vectơ bằng Embeddings API của Vertex AI hoặc sử dụng API đó để tạo các mục nhúng theo cách thủ công.

Điều kiện tiên quyết

  • Thiết lập Data Connect cho dự án của bạn.

  • Bật Vertex AI API.

Thiết lập

Bạn có thể chọn giữa quy trình phát triển cục bộ (nếu bạn là nhà phát triển web, Kotlin Android hoặc iOS) hoặc quy trình IDX (dành cho nhà phát triển web). Bạn có thể sử dụng cơ sở dữ liệu cục bộ hoặc dự án Data Connect trong quy trình sản xuất và phiên bản Cloud SQL cho PostgreSQL của dự án đó để phát triển.

Hướng dẫn này giả định rằng bạn đã tạo dự án Data Connect của mình theo hướng dẫn bắt đầu nhanh.

Tích hợp với PostgreSQL cục bộ

  1. Thiết lập một phiên bản PostgreSQL cục bộ.
  2. Cấp cho chính bạn vai trò người dùng Vertex AI trong IAM.
  3. Thiết lập Thông tin xác thực mặc định của ứng dụng Google Cloud trong môi trường của bạn.
  4. Cài đặt tiện ích pgvector trong phiên bản PostgreSQL cục bộ.
  5. Bật tiện ích bằng cách sử dụng CREATE EXTENSION vector theo hướng dẫn về kho lưu trữ pgvector.

Tích hợp với IDX

  1. Thiết lập không gian làm việc IDX bằng mẫu Data Connect.
  2. Cấp cho chính bạn vai trò người dùng Vertex AI trong IAM.
  3. Bật tiện ích bằng cách sử dụng CREATE EXTENSION vector theo hướng dẫn về kho lưu trữ pgvector.

Thiết kế giản đồ

Để thực hiện tìm kiếm vectơ, hãy thêm một trường mới thuộc loại Vector vào giản đồ của bạn. Ví dụ: nếu bạn muốn thực hiện tìm kiếm ngữ nghĩa bằng nội dung mô tả phim, hãy thêm một trường để lưu trữ các vectơ nhúng được liên kết với nội dung mô tả phim. Trong giản đồ này, descriptionEmbedding được thêm vào để lưu trữ các vectơ nhúng cho trường 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)
 // ...
}

Tạo và truy xuất các vectơ nhúng

Data Connect mang đến khả năng hỗ trợ tích hợp cho các mục nhúng vectơ bằng giá trị máy chủ _embed. Thao tác này hướng dẫn Data Connect tạo các mục nhúng vectơ bằng cách gọi nội bộ Embedding API của Vertex AI. Bạn có thể dùng giá trị máy chủ _embed trong cả các đột biến và truy vấn.

Đột biến

Tạo và lưu trữ một vectơ nhúng thông qua Data Connect

Trong ứng dụng tìm kiếm vectơ, có thể bạn sẽ muốn yêu cầu tạo các mục nhúng ngay khi thêm bản ghi vào cơ sở dữ liệu. Sau đây là một thao tác createMovie đột biến sẽ thêm một bản ghi phim vào bảng Movie và cũng truyền một nội dung mô tả phim có một mục nhúng được chỉ định model.

mutation createMovie($title: String!, $description: String!) {
  movie_insert(data: {
    title: $title,
    description: $description,
    descriptionEmbedding_embed: {model: "textembedding-gecko@003", text: $description}
  })
}

Trong một số trường hợp, bạn có thể muốn cập nhật nội dung mô tả và thông tin nhúng của phim.

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

Để gọi đột biến sau từ một ứng dụng:

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

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

// Use the response

Cụm từ tìm kiếm

Tìm nạp các vectơ nhúng bằng một truy vấn như sau. Xin lưu ý rằng descriptionEmbedding do truy vấn trả về là một mảng gồm các số thực, thường không thể đọc được. Do đó, các SDK do Data Connect tạo không hỗ trợ việc trả về trực tiếp.

Bạn có thể sử dụng các vectơ nhúng được trả về để thực hiện tìm kiếm tương tự, như mô tả trong phần tiếp theo.

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

Thực hiện tìm kiếm tương tự

Giờ đây, chúng ta có thể thực hiện tìm kiếm tương tự.

Đối với mỗi trường Vector, Data Connect sẽ tạo một hàm GraphQL triển khai tính năng tìm kiếm tương tự. Tên của hàm được tạo này là ${pluralType}_${vectorFieldName}_similarity. Hàm này hỗ trợ một số tham số như trong các ví dụ sau và trong danh sách tham chiếu.

Bạn có thể xác định một hàm GraphQL để gọi tính năng tìm kiếm tương tự. Như đã đề cập ở trên, giá trị máy chủ _embed hướng dẫn Data Connect tạo các mục nhúng vectơ bằng cách sử dụng API Nhúng của Vertex AI, trong trường hợp này là để tạo các mục nhúng cho chuỗi tìm kiếm được dùng để so sánh với các mục nhúng nội dung mô tả phim.

Trong ví dụ này, tính năng tìm kiếm tương tự sẽ trả về tối đa 5 bộ phim có nội dung mô tả gần nhất về mặt ngữ nghĩa với cụm từ tìm kiếm đầu vào. Tập kết quả được sắp xếp theo thứ tự tăng dần của khoảng cách – từ gần nhất đến xa nhất.

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

Điều chỉnh truy vấn tương tự

Các giá trị mặc định cho những tham số tìm kiếm như methodwithin hoạt động hiệu quả đối với hầu hết các trường hợp sử dụng. Tuy nhiên, nếu bạn nhận thấy truy vấn của mình trả về kết quả quá khác biệt hoặc thiếu kết quả mà bạn muốn đưa vào, hãy thử điều chỉnh các thông số này.

Để tìm giá trị phù hợp cho within, chúng ta có thể thêm _metadata.distance vào các trường đã chọn để xem mỗi kết quả cách xa vectơ truy vấn bao nhiêu. Dựa trên các giá trị distance được trả về, chúng ta có thể đặt tham số within; chỉ những kết quả có khoảng cách nhỏ hơn giá trị của within mới được đưa vào:

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

Bạn cũng có thể thử nghiệm các hàm khoảng cách khác nhau bằng cách đặt tham số 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
        }
      }
  }

Xin lưu ý rằng các phương thức khác nhau sẽ trả về các giá trị rất khác nhau cho khoảng cách: nếu đã đặt within, bạn sẽ cần điều chỉnh lại giá trị đó sau khi thay đổi method.

Gọi truy vấn tương tự

Cách gọi tính năng tìm kiếm tương tự từ mã ứng dụng:

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

const response = await searchMovieDescriptionUsingL2similarity({ query });

// Use the response

Sử dụng tính năng nhúng tuỳ chỉnh

Data Connect cũng cho phép bạn làm việc trực tiếp với các mục nhúng dưới dạng Vector thay vì sử dụng giá trị máy chủ _embed để tạo các mục nhúng đó.

Lưu trữ một mục nhúng tuỳ chỉnh

Khi sử dụng Vertex Embeddings API, hãy chỉ định một mô hình so khớp và yêu cầu kết quả nhúng có kích thước phù hợp.

Sau đó, truyền mảng số thực đã trả về đến một Vector để truyền đến thao tác cập nhật để lưu trữ.

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

Thực hiện tìm kiếm tương tự bằng cách sử dụng các mục nhúng tuỳ chỉnh

Thực hiện thao tác tương tự để truy xuất các mục nhúng cho cụm từ tìm kiếm và truyền chúng đến Vectors.

Sau đó, hãy gọi truy vấn _similarity để thực hiện từng lượt tìm kiếm.

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

Triển khai cho kênh phát hành công khai

Triển khai giản đồ và trình kết nối

Bước cuối cùng trong một lần lặp lại Data Connect điển hình là triển khai các tài sản của bạn vào bản phát hành công khai.

Khi triển khai giản đồ chứa các loại Vector vào CloudSQL bằng lệnh firebase deploy, CLI Firebase sẽ thực hiện các bước cần thiết để bật tính năng tạo mục nhúng dựa trên Vertex AI trên phiên bản CloudSQL của bạn.

firebase deploy --only dataconnect

nếu bạn muốn bật tính năng hỗ trợ nhúng trong phiên bản CloudSQL theo cách thủ công hoặc gặp lỗi CLI, hãy làm theo các hướng dẫn này.

Cú pháp tìm kiếm vectơ

Tiện ích giản đồ

Loại dữ liệu Vector của Data Connect ánh xạ đến loại vector của PostgreSQL như được xác định bởi tiện ích pgvector. Loại vector của pgvector được lưu trữ dưới dạng một mảng gồm các số thực có độ chính xác đơn trong PostgreSQL.

Trong Data Connect, loại Vector được biểu thị dưới dạng một mảng các số JSON. Đầu vào được chuyển đổi thành một mảng các giá trị float32. Nếu quá trình cưỡng ép không thành công, thì sẽ xảy ra lỗi.

Sử dụng tham số kích thước của chỉ thị @col để đặt kích thước của vectơ.

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

size chỉ được hỗ trợ cho các loại Vector. Các thao tác Vector, chẳng hạn như tìm kiếm tương tự, đòi hỏi tất cả các Vector đều phải có cùng số lượng phương diện.

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

Giá trị máy chủ _embed cho các truy vấn và đột biến

_embed

Giá trị máy chủ này hướng dẫn dịch vụ Data Connect tạo và lưu trữ các mục nhúng bằng API Nhúng của Vertex AI. Bạn có thể sử dụng giá trị máy chủ này cho cả truy vấn và đột biến.

Các tham số cho tìm kiếm tương tự

method: COSINE|INNER_PRODUCT|L2

Hàm khoảng cách dùng để tìm kiếm các điểm dữ liệu láng giềng gần đó. Các thuật toán hiện được hỗ trợ là một tập hợp con của các thuật toán tìm kiếm pgvector.

within: float

Một ràng buộc về khoảng cách mà trong đó quá trình tìm kiếm láng giềng gần nhất được thực hiện.

where: FDC filter condition

Hãy xem hướng dẫn về lược đồ, truy vấn và đột biến.

limit: int

Số lượng kết quả cần trả về.