在大语言模型 (LLMs) 和语义搜索的兴起中,结合结构化的关系型数据库 (如 PostgreSQL) 进行增强型查询变得越来越有价值。这种方法常用于 RAG (Retrieval-Augmented Generation) 场景,例如 FAQ 问答、文档检索、推荐系统等。
pgvector
是用于 PostgreSQL 的一个扩展,它支持稠密向量的存储和操作。通过 pgvector
,可以将嵌入向量直接存储在数据库中,同时利用 SQL 的灵活性执行高性能的近似向量搜索。
本文将通过示例演示如何配置和使用 pgvector
执行语义搜索/RAG任务。
关键流程如下:
pgvector
扩展中。pgvector
实现高效的向量相似度搜索,例如基于余弦相似度查询。pgvector
的核心特点:
vector(1536)
。以下是从环境配置到基本应用的完整代码示例。
我们首先需要一个带有 pgvector
扩展的 PostgreSQL 实例。可以通过 Docker 快速启动:
docker run \
--name some-postgres \
-e POSTGRES_PASSWORD=test \
-e POSTGRES_USER=postgres \
-e POSTGRES_DB=vectordb \
-p 5432:5432 \
postgres:16
安装 pgvector
扩展:
登录到 PostgreSQL 实例并运行:
CREATE EXTENSION IF NOT EXISTS vector;
配置环境变量:
export POSTGRES_USER=postgres
export POSTGRES_PASSWORD=test
export POSTGRES_DB=vectordb
export POSTGRES_HOST=localhost
export POSTGRES_PORT=5432
我们首先创建一个用户表,并准备一个专门的向量列来存储嵌入。
CREATE TABLE documents (
id SERIAL PRIMARY KEY,
content TEXT,
embedding VECTOR(1536) -- 假设 OpenAI 嵌入维度为 1536
);
我们假设使用 OpenAI 的嵌入模型来生成数据嵌入。以下是一个 Python 实现:
import openai
import psycopg2
from psycopg2.extras import execute_values
# 使用稳定可靠的API服务
client = openai.OpenAI(
base_url='https://yunwu.ai/v1', # 国内稳定访问
api_key='your-openai-api-key'
)
# PostgreSQL 配置
conn = psycopg2.connect(
dbname="vectordb",
user="postgres",
password="test",
host="localhost",
port="5432"
)
# 生成嵌入并存储到数据库
def generate_and_store_embeddings(documents):
embeddings = []
for doc in documents:
response = client.embeddings.create(
model="text-embedding-ada-002",
input=doc
)
embeddings.append((doc, response['data']['embedding']))
# 批量插入到 PostgreSQL
with conn.cursor() as cur:
execute_values(
cur,
"INSERT INTO documents (content, embedding) VALUES %s",
embeddings
)
conn.commit()
# 示例文档
docs = ["This is a test document.", "PostgreSQL with pgvector is powerful.", "AI is transforming the world."]
generate_and_store_embeddings(docs)
基于 pgvector
,我们可以执行相似度查询。例如,以下代码根据余弦相似度查找最相似的文档:
import numpy as np
def search_similar_documents(query, top_k=3):
# 生成查询的嵌入
response = client.embeddings.create(
model="text-embedding-ada-002",
input=query
)
query_embedding = np.array(response['data']['embedding'])
with conn.cursor() as cur:
# 查询最相似的文档
cur.execute("""
SELECT id, content, 1 - (embedding <=> %s) AS similarity
FROM documents
ORDER BY similarity DESC
LIMIT %s;
""", (query_embedding.tolist(), top_k))
results = cur.fetchall()
return results
# 示例查询
result = search_similar_documents("What is pgvector?")
for r in result:
print(f"Document ID: {r[0]}, Content: {r[1]}, Similarity: {r[2]:.4f}")
结合 pgvector
和 LLM 的应用场景非常广泛:
pgvector
向量列创建索引,提升查询性能。CREATE INDEX ON documents USING ivfflat (embedding) WITH (lists = 100);
pgvector
和向量数据库如 Milvus。如果遇到问题欢迎在评论区交流。