晴天技术
AI6 min read

向量数据库入门:AI 时代的数据存储

向量数据库入门:AI 时代的数据存储

向量数据库EmbeddingRAGAI开发

向量数据库是 AI 应用的基础设施。本文介绍向量数据库的原理和使用。

什么是向量数据库?

向量数据库专门存储和查询向量(高维数值数组)。

传统数据库 vs 向量数据库

传统数据库:存储结构化数据,精确查询
向量数据库:存储向量数据,相似度查询

为什么需要向量数据库?

AI 模型把文本、图片等转换为向量(Embedding),向量数据库能快速找到相似的向量。

应用场景:

  • 语义搜索(找意思相近的内容)
  • RAG(检索相关文档)
  • 推荐系统(找相似物品)
  • 图片搜索(找相似图片)

核心概念

1. 向量(Vector)

文本 "Hello World" → [0.1, 0.3, -0.2, 0.5, ...] (1536 维)

AI 模型把文本转换为数值数组,这个数组就是向量。

2. Embedding

把文本转换为向量的过程叫 Embedding:

from openai import OpenAI

client = OpenAI()
response = client.embeddings.create(
    model="text-embedding-3-small",
    input="Hello World"
)

vector = response.data[0].embedding  # 1536 维向量

3. 相似度搜索

通过计算向量之间的距离找到相似的内容:

# 余弦相似度
def cosine_similarity(a, b):
    dot_product = sum(x * y for x, y in zip(a, b))
    norm_a = sum(x ** 2 for x in a) ** 0.5
    norm_b = sum(x ** 2 for x in b) ** 0.5
    return dot_product / (norm_a * norm_b)

向量数据库对比

数据库类型特点适合场景
FAISSFacebook 开源,本地运行原型开发
Chroma数据库轻量级,易上手小规模应用
Pinecone云服务全托管,易扩展生产环境
Weaviate数据库开源,功能丰富中大规模
Milvus数据库开源,高性能大规模生产
Qdrant数据库Rust 实现,高性能高性能需求
pgvector扩展PostgreSQL 扩展已有 PG 的项目

使用 FAISS

安装

pip install faiss-cpu

基本使用

import faiss
import numpy as np

# 创建向量数据
d = 64  # 维度
nb = 1000  # 数据量
data = np.random.random((nb, d)).astype('float32')

# 创建索引
index = faiss.IndexFlatL2(d)
index.add(data)

# 查询
query = np.random.random((1, d)).astype('float32')
distances, indices = index.search(query, k=5)  # 找 5 个最近的

配合 LangChain

from langchain.vectorstores import FAISS
from langchain.embeddings import OpenAIEmbeddings

embeddings = OpenAIEmbeddings()

# 创建向量存储
texts = ["文档1内容", "文档2内容", "文档3内容"]
vectorstore = FAISS.from_texts(texts, embeddings)

# 搜索
results = vectorstore.similarity_search("查询内容", k=3)

使用 Chroma

安装

pip install chromadb

基本使用

import chromadb

client = chromadb.Client()
collection = client.create_collection("my_collection")

# 添加文档
collection.add(
    documents=["文档1", "文档2", "文档3"],
    ids=["id1", "id2", "id3"]
)

# 查询
results = collection.query(
    query_texts=["查询内容"],
    n_results=2
)

持久化存储

client = chromadb.PersistentClient(path="./chroma_db")

使用 Pinecone

安装

pip install pinecone-client

基本使用

from pinecone import Pinecone

pc = Pinecone(api_key="your-api-key")
index = pc.Index("my-index")

# 添加向量
index.upsert(vectors=[
    {"id": "vec1", "values": [0.1, 0.2, ...], "metadata": {"text": "文档1"}},
    {"id": "vec2", "values": [0.3, 0.4, ...], "metadata": {"text": "文档2"}},
])

# 查询
results = index.query(vector=[0.1, 0.2, ...], top_k=5)

RAG 中的向量数据库

完整流程

from langchain.document_loaders import TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import FAISS

# 1. 加载文档
loader = TextLoader("docs.txt")
documents = loader.load()

# 2. 分块
splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
chunks = splitter.split_documents(documents)

# 3. 向量化并存储
embeddings = OpenAIEmbeddings()
vectorstore = FAISS.from_documents(chunks, embeddings)

# 4. 查询
results = vectorstore.similarity_search("查询内容", k=3)

性能优化

1. 选择合适的索引

# 精确搜索(小数据集)
index = faiss.IndexFlatL2(d)

# 近似搜索(大数据集)
index = faiss.IndexIVFFlat(d, nlist=100)

2. 量化压缩

# 使用量化减少内存
index = faiss.IndexIVFPQ(d, nlist=100, m=8, nbits=8)

3. 批量查询

# 批量查询比逐个查询快
queries = np.random.random((100, d)).astype('float32')
distances, indices = index.search(queries, k=5)

最佳实践

1. 选择合适的维度

  • 维度越高,信息越丰富,但存储和计算成本越高
  • 常用维度:384, 768, 1536

2. 合理分块

  • 太小:丢失上下文
  • 太大:检索不精确
  • 推荐:300-1000 字符

3. 使用元数据

collection.add(
    documents=["文档内容"],
    metadatas=[{"source": "file1.txt", "page": 1}],
    ids=["id1"]
)

# 按元数据过滤
results = collection.query(
    query_texts=["查询"],
    where={"source": "file1.txt"}
)

总结

向量数据库是 AI 应用的基础:

  • 存储:把 Embedding 向量存起来
  • 查询:快速找到相似的向量
  • 应用:RAG、搜索、推荐

选择建议:

  • 原型开发:FAISS 或 Chroma
  • 小规模生产:Chroma 或 Qdrant
  • 大规模生产:Milvus 或 Pinecone
  • 已有 PostgreSQL:pgvector