Weaviate:面向 AI 的开源向量数据库
yaml version: '3.4' services: weaviate: image: semitechnologies/weaviate:latest restart: on-failure:0 ports: - "8080:8080" environment: QUERY_DEFAULTS_LIMIT: 25 AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'true' PERSISTENCE_DATA_PATH: '/var/lib/weaviate' DEFAULT_VECTORIZER_MODULE: 'none' CLUSTER_HOSTNAME: 'node1'
然后运行:
```bash
docker compose up -d
方式二:Weaviate Cloud(WCD)
如果不希望自己维护基础设施,可以注册 Weaviate Cloud 并创建一个 Sandbox 或免费实例,获取 API 地址和密钥。
安装客户端库
Weaviate 提供 Python、JavaScript 等多种语言的客户端。以 Python 为例:
pip install weaviate-client
连接本地实例:
import weaviate
client = weaviate.connect_to_local()
print(client.is_ready()) # 应返回 True
首次启动:模式定义与数据导入
创建一个示例类
让我们创建一个包含向量的 Article 类,并使用 OpenAI 自动生成向量。你需要先设置 OpenAI API Key 作为环境变量或在客户端提供。
import os
from weaviate.classes.config import Configure, Property, DataType
client = weaviate.connect_to_local(
headers={"X-OpenAI-Api-Key": os.getenv("OPENAI_APIKEY")}
)
# 定义类 Schema
articles = client.collections.create(
name="Article",
vectorizer_config=Configure.Vectorizer.text2vec_openai(),
properties=[
Property(name="title", data_type=DataType.TEXT),
Property(name="content", data_type=DataType.TEXT),
Property(name="author", data_type=DataType.TEXT, skip_vectorization=True),
Property(name="publicationDate", data_type=DataType.DATE, skip_vectorization=True),
]
)
skip_vectorization=True 表示这些字段不参与向量化,仅用于元数据存储与过滤。
批量导入数据
import datetime
data = [
{
"title": "如何饲养金毛犬",
"content": "金毛犬需要大量运动,每日至少散步两次,定期梳理毛发。饮食方面应选择高质量狗粮。",
"author": "宠物达人",
"publicationDate": datetime.datetime(2024, 1, 15)
},
{
"title": "Python 入门教程",
"content": "Python 是一种解释型、面向对象的高级编程语言,语法简洁,非常适用于数据科学。",
"author": "编程课堂",
"publicationDate": datetime.datetime(2024, 2, 20)
},
{
"title": "深度学习的数学基础",
"content": "要理解深度学习,需要掌握线性代数、微积分、概率论等数学知识。",
"author": "AI 研究院",
"publicationDate": datetime.datetime(2024, 3, 10)
}
]
articles_col = client.collections.get("Article")
# 自动将 title 和 content 向量化
articles_col.data.insert_many(data)
print("数据导入完成")
每个对象都会被自动赋予一个 OpenAI 生成的向量,向量反映了 title 和 content 的语义。
向量搜索:寻找语义相关的内容
近文本搜索(Near Text)
根据一段文本查询语义最相近的对象:
articles = client.collections.get("Article")
response = articles.query.near_text(
query="怎样训练宠物狗",
limit=2
)
for obj in response.objects:
print(obj.properties["title"], obj.properties["author"])
输出可能是“如何饲养金毛犬”,因为两者语义接近,尽管查询文本和标题没有完全相同的词。这展示了向量搜索的强大之处。
近向量搜索(Near Vector)
如果你已经提前计算好向量(例如从其他模型获得),可以直接用向量查询:
import numpy as np
dummy_vector = np.random.rand(1536).tolist() # 1536 是 text-embedding-3-small 的维度
response = articles.query.near_vector(
near_vector=dummy_vector,
limit=5
)
混合搜索(Hybrid Search)
混合搜索结合了稠密向量的语义理解和稀疏关键词匹配(BM25),特别适合需要精确匹配关键术语的场景。
response = articles.query.hybrid(
query="Python 编程",
alpha=0.5, # 0 为纯稀疏搜索,1 为纯向量搜索
limit=3
)
alpha 平衡语义与关键词的权重。
进阶技巧:过滤、聚合与 GraphQL
Weaviate 底层使用 GraphQL,你可以使用高级过滤条件对结果进行限制。
标量过滤(Where Filter)
只搜索 2024 年 2 月以后发布的文章:
from weaviate.classes.query import Filter
response = articles.query.near_text(
query="机器学习的知识",
filters=Filter.by_property("publicationDate").greater_than(datetime.datetime(2024, 2, 1)),
limit=5
)
交叉引用查询
假设我们修改 Schema,让 Article 引用一个 Author 类,那么查询文章时可以直接获取作者详情:
# 创建 Author 类
authors = client.collections.create(
name="Author",
properties=[
Property(name="name", data_type=DataType.TEXT),
]
)
# 在 Article 类中添加交叉引用属性(会要求重建 Schema,这里仅演示概念)
# 然后插入数据时关联对应 author 对象。
# 查询示例:
articles = client.collections.get("Article")
response = articles.query.near_text(
query="宠物养护",
return_properties=["title", "author { name }"] # 获取嵌套信息
)
与 AI 生态集成:让数据为 LLM 赋能
Weaviate 可作为检索增强生成(RAG)的长期记忆。典型工作流:
- 将文档拆分并存入 Weaviate。
- 用户提问时,在 Weaviate 中执行语义搜索,取回最相关的上下文片段。
- 将片段和用户问题拼成 Prompt 发送给 LLM(如 GPT-4),生成基于事实的回答。
# 简易 RAG 示例(psuedocode)
query = "金毛犬每天需要运动多久?"
context = articles.query.near_text(query=query, limit=1).objects[0].properties
prompt = f"根据以下资料回答问题:\n{context['content']}\n\n问题:{query}\n回答:"
# 将 prompt 发送给 LLM API