向量检索
向量检索基于语义相似度,能够理解查询意图,匹配语义相关的文档分片。
原理
相似度算法
Knowledge 支持多种向量相似度算法:
| 算法 | 配置值 | 说明 | 适用场景 |
|---|---|---|---|
| 余弦相似度 | COSINE_DISTANCE | 计算向量夹角余弦值 | 通用场景,推荐 |
| 欧氏距离 | EUCLIDEAN_DISTANCE | 计算向量间欧氏距离 | 向量模长有意义时 |
| 内积 | NEGATIVE_INNER_PRODUCT | 计算向量点积 | 检索引擎推荐 |
推荐配置:
yaml
spring:
ai:
vectorstore:
pgvector:
distance-type: COSINE_DISTANCE # 余弦相似度实现
Knowledge 使用 Spring AI 的 VectorStore 抽象,支持多种向量数据库:
java
// 伪代码 - 向量检索实现
public List<RetrievedDocument> vectorSearch(RetrievalOptions options, String query) {
// 1. 构建搜索请求
SearchRequest.Builder builder = SearchRequest.builder()
.query(query)
.topK(options.getTopK())
.similarityThreshold(options.getThreshold());
// 2. 添加过滤条件
Filter.Expression filter = buildFilterExpression(options);
if (filter != null) {
builder.filterExpression(filter);
}
// 3. 执行相似度搜索
List<Document> documents = vectorStore.similaritySearch(builder.build());
// 4. 转换为检索结果
return convertToRetrievedDocuments(documents);
}元数据过滤
支持按元数据字段过滤检索范围:
java
private Filter.Expression buildFilterExpression(RetrievalOptions options) {
FilterExpressionBuilder builder = new FilterExpressionBuilder();
// 按知识库过滤
if (options.getLibraryIds() != null && !options.getLibraryIds().isEmpty()) {
builder.in("library_id", options.getLibraryIds());
}
// 按文档过滤
if (options.getDocumentId() != null) {
builder.eq("document_id", options.getDocumentId());
}
// 按作者过滤
if (options.getAuthor() != null) {
builder.eq("author", options.getAuthor());
}
// 按分类过滤
if (options.getCategory() != null) {
builder.eq("category", options.getCategory());
}
// 按标签过滤
if (options.getTag() != null) {
builder.in("tags", options.getTag());
}
return builder.build();
}使用示例:
java
RetrievalOptions options = RetrievalOptions.builder()
.libraryIds(List.of("1", "2"))
.author("张三")
.category("技术文档")
.build();
List<RetrievedDocument> docs = knowledgeRetrievalService.search("分布式锁原理", options);配置
yaml
molandev:
rag:
retrieval:
# 返回结果数量
top-k: 20
# 相似度阈值 (0-1)
threshold: 0.4调优建议
| 场景 | top-k | threshold | 说明 |
|---|---|---|---|
| 高召回 | 30 | 0.3 | 适合知识探索 |
| 默认 | 20 | 0.4 | 平衡召回与精度 |
| 高精度 | 10 | 0.6-0.7 | 适合精确问答 |
PgVector 实现细节
HNSW 索引
Knowledge 使用 HNSW (Hierarchical Navigable Small World) 索引加速检索:
sql
-- 创建 HNSW 索引
CREATE INDEX ON vector_store
USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);HNSW 参数:
m— 每个节点的最大连接数 (默认 16)ef_construction— 构建索引时的搜索范围 (默认 64)
检索时参数
检索时可动态设置搜索范围:
sql
SET hnsw.ef_search = 40; -- 默认 40,值越大越精确但越慢向量库内容返回
PgVectorStore 支持返回原文内容:
java
// 检测向量库是否支持返回原文
boolean supportsContent = vectorSearchService.supportsContent();
if (supportsContent) {
// PgVectorStore 支持,直接从向量库获取内容
// 无需额外查询数据库
}优势:
- 减少数据库查询
- 降低延迟
向量删除操作
按文档删除
java
vectorSearchService.deleteByDocumentId(documentId);按知识库删除
java
vectorSearchService.deleteByLibraryId(libraryId);常见问题
1. 检索结果不相关怎么办?
- 调高相似度阈值 —
threshold: 0.6 - 优化查询词 — 使用更具体的描述
- 启用混合检索 — 加入关键词检索补充
2. 检索速度慢怎么办?
- 检查 HNSW 索引 — 确保已创建索引
- 添加元数据过滤 — 缩小检索范围
- 调整
top-k— 减少返回数量
3. 向量维度不匹配怎么办?
确保 dimensions 配置与 Embedding 模型匹配:
| 模型 | 维度 |
|---|---|
| OpenAI text-embedding-3-small | 1536 |
| 通义千问 text-embedding-v3 | 1024 或 1536 |
| Ollama nomic-embed-text | 768 |