PGvector

本節將引導您設定 PGvector VectorStore 來儲存文件 Embedding 並執行相似度搜索。

PGvector 是 PostgreSQL 的一個開源擴充套件,用於儲存和搜尋機器學習生成的 Embedding。它提供了不同的功能,使使用者能夠查詢精確和近似的最近鄰。它旨在與 PostgreSQL 的其他功能(包括索引和查詢)無縫協作。

先決條件

首先,您需要訪問啟用了 vectorhstoreuuid-ossp 擴充套件的 PostgreSQL 例項。

您可以透過 Docker ComposeTestcontainers 將 PGvector 資料庫作為 Spring Boot 開發服務執行。或者,在 本地設定 Postgres/PGVector 資料庫 附錄中展示瞭如何使用 Docker 容器在本地設定資料庫。

在啟動時,PgVectorStore 將嘗試安裝所需的資料庫擴充套件,並在不存在時建立帶有索引的必需表 vector_store

或者,您可以手動執行此操作,如下所示:

CREATE EXTENSION IF NOT EXISTS vector;
CREATE EXTENSION IF NOT EXISTS hstore;
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

CREATE TABLE IF NOT EXISTS vector_store (
	id uuid DEFAULT uuid_generate_v4() PRIMARY KEY,
	content text,
	metadata json,
	embedding vector(1536) // 1536 is the default embedding dimension
);

CREATE INDEX ON vector_store USING HNSW (embedding vector_cosine_ops);
如果您使用的是不同的 Embedding 維度,請將 1536 替換為實際維度。PGvector 的 HNSW 索引最多支援 2000 個維度。

接下來,如果需要,需要為 EmbeddingModel 提供一個 API 金鑰,以生成由 PgVectorStore 儲存的 Embedding。

自動配置

Spring AI 自動配置、starter 模組的 artifact 名稱發生了重大變化。有關更多資訊,請參閱升級說明

然後將 PgVectorStore boot starter 依賴項新增到您的專案中

<dependency>
	<groupId>org.springframework.ai</groupId>
	<artifactId>spring-ai-starter-vector-store-pgvector</artifactId>
</dependency>

或新增到您的 Gradle build.gradle 構建檔案中。

dependencies {
    implementation 'org.springframework.ai:spring-ai-starter-vector-store-pgvector'
}

向量儲存實現可以為您初始化所需的 schema,但您必須透過在適當的建構函式中指定 initializeSchema 布林值,或在 application.properties 檔案中設定 …​initialize-schema=true 來選擇啟用此功能。

這是一個破壞性變更!在早期版本的 Spring AI 中,此 schema 初始化是預設發生的。

向量儲存還需要一個 EmbeddingModel 例項來計算文件的 Embedding。您可以選擇其中一種可用的 EmbeddingModel 實現

例如,要使用 OpenAI EmbeddingModel,請將以下依賴項新增到您的專案中

<dependency>
	<groupId>org.springframework.ai</groupId>
	<artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>

或新增到您的 Gradle build.gradle 構建檔案中。

dependencies {
    implementation 'org.springframework.ai:spring-ai-starter-model-openai'
}
有關將 Spring AI BOM 新增到構建檔案的資訊,請參閱依賴管理部分。有關將 Maven Central 和/或 Snapshot 倉庫新增到構建檔案的資訊,請參閱倉庫部分。

要連線和配置 PgVectorStore,您需要提供例項的訪問詳細資訊。可以透過 Spring Boot 的 application.yml 檔案提供簡單的配置。

spring:
  datasource:
    url: jdbc:postgresql://:5432/postgres
    username: postgres
    password: postgres
  ai:
	vectorstore:
	  pgvector:
		index-type: HNSW
		distance-type: COSINE_DISTANCE
		dimensions: 1536
		max-document-batch-size: 10000 # Optional: Maximum number of documents per batch
如果您透過 Docker ComposeTestcontainers 將 PGvector 作為 Spring Boot 開發服務執行,則無需配置 URL、使用者名稱和密碼,因為它們由 Spring Boot 自動配置。
請檢視配置引數列表,瞭解預設值和配置選項。

現在您可以在應用程式中自動注入 VectorStore 並使用它

@Autowired VectorStore vectorStore;

// ...

List<Document> documents = List.of(
    new Document("Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!!", Map.of("meta1", "meta1")),
    new Document("The World is Big and Salvation Lurks Around the Corner"),
    new Document("You walk forward facing the past and you turn back toward the future.", Map.of("meta2", "meta2")));

// Add the documents to PGVector
vectorStore.add(documents);

// Retrieve documents similar to a query
List<Document> results = this.vectorStore.similaritySearch(SearchRequest.builder().query("Spring").topK(5).build());

配置屬性

您可以在 Spring Boot 配置中使用以下屬性來自定義 PGVector 向量儲存。

屬性 描述 預設值

spring.ai.vectorstore.pgvector.index-type

最近鄰搜尋索引型別。選項包括 NONE - 精確最近鄰搜尋,IVFFlat - 索引將向量分成列表,然後搜尋最接近查詢向量的列表子集。它具有更快的構建時間並使用更少的記憶體,但查詢效能(在速度-召回權衡方面)低於 HNSW。HNSW - 建立一個多層圖。它構建時間較慢,使用記憶體較多,但查詢效能(在速度-召回權衡方面)優於 IVFFlat。與 IVFFlat 不同,它沒有訓練步驟,因此可以在表中沒有任何資料的情況下建立索引。

HNSW

spring.ai.vectorstore.pgvector.distance-type

搜尋距離型別。預設為 COSINE_DISTANCE。但如果向量被歸一化到長度 1,您可以使用 EUCLIDEAN_DISTANCENEGATIVE_INNER_PRODUCT 以獲得最佳效能。

COSINE_DISTANCE

spring.ai.vectorstore.pgvector.dimensions

Embedding 維度。如果未明確指定,PgVectorStore 將從提供的 EmbeddingModel 中檢索維度。維度在表建立時設定到 embedding 列上。如果您更改維度,則也必須重新建立 vector_store 表。

-

spring.ai.vectorstore.pgvector.remove-existing-vector-store-table

啟動時刪除現有的 vector_store 表。

false

spring.ai.vectorstore.pgvector.initialize-schema

是否初始化所需的 schema

false

spring.ai.vectorstore.pgvector.schema-name

向量儲存 schema 名稱

public

spring.ai.vectorstore.pgvector.table-name

向量儲存表名稱

vector_store

spring.ai.vectorstore.pgvector.schema-validation

啟用 schema 和表名稱驗證,以確保它們是有效且存在的物件。

false

spring.ai.vectorstore.pgvector.max-document-batch-size

單批處理的最大文件數量。

10000

如果您配置了自定義 schema 和/或表名稱,請考慮透過設定 spring.ai.vectorstore.pgvector.schema-validation=true 來啟用 schema 驗證。這可以確保名稱的正確性並降低 SQL 注入攻擊的風險。

元資料過濾

您可以將通用的、可移植的元資料過濾器與 PgVector 儲存一起使用。

例如,您可以使用文字表示式語言

vectorStore.similaritySearch(
    SearchRequest.builder()
    .query("The World")
    .topK(TOP_K)
    .similarityThreshold(SIMILARITY_THRESHOLD)
    .filterExpression("author in ['john', 'jill'] && article_type == 'blog'").build());

或使用 Filter.Expression DSL 進行程式設計配置

FilterExpressionBuilder b = new FilterExpressionBuilder();

vectorStore.similaritySearch(SearchRequest.builder()
    .query("The World")
    .topK(TOP_K)
    .similarityThreshold(SIMILARITY_THRESHOLD)
    .filterExpression(b.and(
        b.in("author","john", "jill"),
        b.eq("article_type", "blog")).build()).build());
這些過濾器表示式被轉換為 PostgreSQL JSON path 表示式,以便進行高效的元資料過濾。

手動配置

除了使用 Spring Boot 自動配置之外,您還可以手動配置 PgVectorStore。為此,您需要將 PostgreSQL 連線和 JdbcTemplate 自動配置依賴項新增到您的專案中

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

<dependency>
	<groupId>org.postgresql</groupId>
	<artifactId>postgresql</artifactId>
	<scope>runtime</scope>
</dependency>

<dependency>
	<groupId>org.springframework.ai</groupId>
	<artifactId>spring-ai-pgvector-store</artifactId>
</dependency>
有關將 Spring AI BOM 新增到構建檔案的資訊,請參閱依賴管理部分。

要在您的應用程式中配置 PgVector,可以使用以下設定:

@Bean
public VectorStore vectorStore(JdbcTemplate jdbcTemplate, EmbeddingModel embeddingModel) {
    return PgVectorStore.builder(jdbcTemplate, embeddingModel)
        .dimensions(1536)                    // Optional: defaults to model dimensions or 1536
        .distanceType(COSINE_DISTANCE)       // Optional: defaults to COSINE_DISTANCE
        .indexType(HNSW)                     // Optional: defaults to HNSW
        .initializeSchema(true)              // Optional: defaults to false
        .schemaName("public")                // Optional: defaults to "public"
        .vectorTableName("vector_store")     // Optional: defaults to "vector_store"
        .maxDocumentBatchSize(10000)         // Optional: defaults to 10000
        .build();
}

在本地執行 Postgres & PGVector 資料庫

docker run -it --rm --name postgres -p 5432:5432 -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres pgvector/pgvector

您可以像這樣連線到此伺服器

psql -U postgres -h localhost -p 5432

訪問原生客戶端

PGVector 儲存實現透過 getNativeClient() 方法提供了對底層原生 JDBC 客戶端 (JdbcTemplate) 的訪問

PgVectorStore vectorStore = context.getBean(PgVectorStore.class);
Optional<JdbcTemplate> nativeClient = vectorStore.getNativeClient();

if (nativeClient.isPresent()) {
    JdbcTemplate jdbc = nativeClient.get();
    // Use the native client for PostgreSQL-specific operations
}

原生客戶端使您可以訪問可能未透過 VectorStore 介面公開的 PostgreSQL 特有功能和操作。