Weaviate:面向 AI 的开源向量数据库

FreeGuideOnline 最新 2026-07-02

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
)

混合搜索结合了稠密向量的语义理解和稀疏关键词匹配(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)的长期记忆。典型工作流:

  1. 将文档拆分并存入 Weaviate。
  2. 用户提问时,在 Weaviate 中执行语义搜索,取回最相关的上下文片段。
  3. 将片段和用户问题拼成 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