VectorStore.similaritySearchWithScore
获取带分数的结果score > threshold
的文档VectorStore
与相似度分数在 Spring AI 1.0.1 中,VectorStore
接口默认不返回分数,但大多数实现(如 QdrantVectorStore
、ChromaVectorStore
、MilvusVectorStore
等)都支持 带分数的搜索方法。
similaritySearch(…)
的扩展虽然 VectorStore
接口本身没有暴露 WithScore
方法,但具体实现类通常提供:
List<Document> similaritySearch(String query, int k, String... filters);
但为了获取 score,您需要使用:
👉 VectorStore#similaritySearch(SearchRequest request)
其中 SearchRequest
支持:
setQuery(String)
setTopK(int)
setSimilarityThreshold(double)
✅(关键!)SearchRequest
设置 similarityThreshold
这是 Spring AI 提高检索准确率的核心方式。
@Service
public class RetrievalService {
private final VectorStore vectorStore;
public RetrievalService(VectorStore vectorStore) {
this.vectorStore = vectorStore;
}
public List<Document> retrieveRelevantDocuments(String query, double minScore, int maxResults) {
SearchRequest request = new SearchRequest();
request.setQuery(query);
request.setTopK(maxResults);
request.setSimilarityThreshold(minScore); // ← 只返回 score >= minScore 的结果
return vectorStore.similaritySearch(request);
}
}
spring:
ai:
vectorstore:
qdrant:
host: localhost
port: 6333
# 或 chroma, milvus, etc.
不同向量数据库的 score 范围不同,设置阈值时要小心:
向量库 | 相似度类型 | 分数范围 | 越高越好? |
---|---|---|---|
Qdrant | 余弦相似度 | [0, 1] |
✅ 是(1 最相似) |
Chroma | 余弦相似度 | [-1, 1] |
✅ 是(1 最相似) |
Milvus | 内积/余弦 | [-1, 1] 或 [0,1] |
✅ 是 |
Pinecone | 余弦 | [0,1] |
✅ 是 |
FAISS (原始) | L2 距离 | [0, ∞) |
❌ 越小越好 |
0.75 ~ 0.95
:高质量匹配(推荐用于 RAG)< 0.6
:通常噪声较大,建议过滤// 示例:只返回高相关性文档
List<Document> docs = retrieveRelevantDocuments("人工智能", 0.75, 10);
@Service
public class ChatService {
private final ChatClient chatClient;
private final RetrievalService retrievalService;
public ChatService(ChatClient chatClient, RetrievalService retrievalService) {
this.chatClient = chatClient;
this.retrievalService = retrievalService;
}
public String chat(String userMessage) {
// 1. 检索高相关性上下文
List<Document> relevantDocs = retrievalService.retrieveRelevantDocuments(
userMessage, 0.75, 5
);
// 2. 构建上下文
String context = relevantDocs.stream()
.map(Document::getContent)
.reduce("", (a, b) -> a + "\n\n" + b);
// 3. 调用 LLM
return chatClient.prompt()
.user(userMessage)
.advisory(context) // 使用 advisory 添加上下文(Spring AI 推荐方式)
.call()
.content();
}
}
💡
advisory()
是 Spring AI 中用于添加 RAG 上下文的推荐方式,不会干扰主语义。
方法 | 说明 |
---|---|
提高 embedding 质量 | 使用高质量模型(如 text-embedding-3-large ) |
优化文本分块 | 块大小 256~512 token,避免截断关键信息 |
添加元数据过滤 | 如 request.setFilter("category = 'tech'") |
重排序(Rerank) | 检索后使用 Cross-Encoder 重排序(Spring AI 即将支持) |
查询扩展 | 生成同义查询并合并结果 |
目标 | 实现方式 |
---|---|
获取相似度分数 | 使用 SearchRequest 而非简单 similaritySearch |
过滤低分结果 | request.setSimilarityThreshold(0.75) |
提高 RAG 准确率 | 结合高阈值 + 高质量 embedding + 合理分块 |
集成 ChatClient | 使用 advisory() 注入过滤后的上下文 |
✅ 最终建议配置:
SearchRequest request = new SearchRequest();
request.setQuery(userMessage);
request.setTopK(5);
request.setSimilarityThreshold(0.75); // 关键:提高门槛
List<Document> results = vectorStore.similaritySearch(request);
这样可以有效过滤噪声,提升 RAG 系统的整体准确率和稳定性。
https://blog.xqlee.com/article/2509021347478201.html