本文深入探讨Weaviate的混合搜索(Hybrid Search)技术,结合稀疏向量(BM25关键词匹配)和密集向量(语义嵌入),提升检索系统的准确性和相关性。我们将从需求背景出发,介绍Weaviate的核心概念,详细讲解索引构建、文档加载、混合搜索实现等关键步骤,并提供完整的代码示例。最后,总结Weaviate在知识库、问答系统等场景中的应用价值。
1. 引言:为什么需要Weaviate混合搜索?
在信息爆炸的时代,传统的关键词搜索(如Elasticsearch的BM25)已无法满足复杂查询需求。例如:
- 用户搜索“AI in healthcare”,可能期望找到包含“artificial intelligence”“medical field”等语义相近内容的文档。
- 企业知识库需要同时支持精确关键词匹配和语义联想,以提高检索效率。
Weaviate 是一个开源的向量搜索引擎,支持混合搜索,结合关键词匹配和语义相似度计算,完美解决上述问题。本文将手把手教你如何构建Weaviate索引、加载文档,并实现高效的混合搜索。
2. Weaviate核心概念
2.1 什么是Weaviate?
Weaviate是一个向量搜索引擎,支持:
- 语义搜索(基于嵌入向量计算相似度)
- 关键词搜索(基于BM25算法)
- 混合搜索(结合两者优势)
- 图数据库特性(支持对象关系建模)
2.2 混合搜索的优势
搜索方式 | 优点 | 缺点 |
---|---|---|
关键词搜索(BM25) | 精确匹配,速度快 | 无法理解语义(如同义词、上下文) |
语义搜索(向量检索) | 理解自然语言,支持模糊查询 | 可能召回不相关文档(语义漂移) |
混合搜索 | 结合两者优势,提高召回率和准确性 | 计算成本略高 |
3. 实战案例:Weaviate混合搜索实现步骤
3.1 环境准备
3.1.1 安装依赖
pip install weaviate-client langchain langchain_community
3.1.2 配置环境变量
export WEAVIATE_URL="http://localhost:8080" # Weaviate服务地址
export WEAVIATE_API_KEY="your-api-key" # Weaviate API密钥(可选)
export OPENAI_API_KEY="your-openai-api-key" # 若使用OpenAI Embedding模型
3.2 构建Weaviate索引
3.2.1 初始化Weaviate客户端
import weaviate
from langchain_community.vectorstores import Weaviate
# 连接Weaviate
client = weaviate.Client(
url=os.getenv("WEAVIATE_URL"),
additional_headers={"X-Openai-Api-Key": os.getenv("OPENAI_API_KEY")} # 若使用OpenAI Embedding
)
3.2.2 定义Schema(索引结构)
Weaviate使用**类(Class)**定义数据结构,例如:
class_obj = {
"class": "Article", # 类名
"properties": [
{
"name": "content", # 文档内容字段
"dataType": ["text"] # 数据类型
},
{
"name": "source", # 来源字段(用于过滤)
"dataType": ["string"]
}
]
}
# 创建索引(如果不存在)
if not client.schema.exists(class_obj["class"]):
client.schema.create_class(class_obj)
3.3 加载文档到Weaviate
3.3.1 准备数据
documents = [
{
"content": "AI is transforming healthcare by improving diagnostics.",
"source": "healthcare-report.pdf"
},
{
"content": "The future of AI lies in multimodal learning.",
"source": "ai-research.pdf"
}
]
3.3.2 使用LangChain批量导入
from langchain_community.document_loaders import DictLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
# 转换为LangChain Document格式
langchain_docs = [
Document(page_content=doc["content"], metadata={"source": doc["source"]})
for doc in documents
]
# 文本分块(可选,适用于长文档)
text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
split_docs = text_splitter.split_documents(langchain_docs)
# 加载到Weaviate
vectorstore = Weaviate.from_documents(
client=client,
documents=split_docs,
index_name="Article", # 对应Schema中的类名
text_key="content", # 文档内容字段
embedding=None # 使用Weaviate内置Embedding(或自定义模型)
)
3.4 实现混合搜索
3.4.1 基础混合搜索
retriever = vectorstore.as_retriever(search_type="hybrid") # 启用混合搜索
results = retriever.invoke("AI applications in healthcare")
for doc in results:
print(doc.page_content, doc.metadata)
3.4.2 带过滤条件的混合搜索
# 只检索来自"healthcare-report.pdf"的文档
filtered_results = retriever.invoke(
"AI in healthcare",
search_kwargs={"where": {"path": ["source"], "operator": "Equal", "valueString": "healthcare-report.pdf"}}
)
print(filtered_results)
3.4.3 获取搜索得分
results_with_score = retriever.invoke("AI in healthcare", score=True)
for doc in results_with_score:
print(doc.page_content, doc.metadata.get("_additional", {}).get("score"))
4. 总结
本文介绍了Weaviate混合搜索的完整实现流程:
- 需求背景:传统关键词搜索的局限性,混合搜索的优势。
- Weaviate基础:索引构建、Schema设计、文档加载。
- 混合搜索实现:基础检索、过滤条件、得分分析。
Weaviate特别适合以下场景:
✅ 企业知识库(支持关键词+语义检索)
✅ 智能问答系统(理解自然语言查询)
✅ 内容推荐(结合用户意图和文档语义)