- 使用
VectorStore.similaritySearchWithScore
获取带分数的结果 - 过滤掉低分(低相关性)结果,只保留
score > threshold
的文档 - 提高输入给 LLM 的上下文质量,从而提升回答准确率
1. Spring AI 中的 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)
✅(关键!)
2. ✅ 正确做法:使用 SearchRequest
设置 similarityThreshold
这是 Spring AI 提高检索准确率的核心方式。
✅ 示例代码(Spring Boot + Spring AI 1.0.1)
@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);
}
}
📌 配置示例(application.yml)
spring:
ai:
vectorstore:
qdrant:
host: localhost
port: 6333
# 或 chroma, milvus, etc.
3. ⚠️ 注意:相似度分数范围
不同向量数据库的 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);
4. ✅ 结合 ChatClient 提升准确率
@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 上下文的推荐方式,不会干扰主语义。
5. ✅ 提高准确率的其他建议
方法 | 说明 |
---|---|
提高 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://www.syntaxspace.com/article/2509021347478201.html
评论