ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

LangChain 向量检索核心解析:similarity_search_with_score 和 similarity_search_with_relevance_scores 到底有什么区别?

LangChain 向量检索核心解析:similarity_search_with_score 和 similarity_search_with_relevance_scores 到底有什么区别?

一、前言:为什么同样是相似度搜索,分数却不一样?

在开发 RAG 知识库系统时,我们经常会看到类似代码:

docs = vectorstore.similarity_search_with_score( query )

或者:

docs = vectorstore.similarity_search_with_relevance_scores( query )

两者名字非常接近:

  • similarity_search
  • score
  • relevance_scores

很多刚接触 LangChain 的开发者会认为:

“它们返回的不都是相似度分数吗?为什么还要设计两个方法?”

实际上:

两者最大的区别就在于:分数是否经过标准化处理。


二、similarity_search_with_score() 是什么?

1. 基本作用

similarity_search_with_score():

根据用户输入的 query,在向量数据库中搜索最相似的文档,并返回原始距离或者原始相似度分数。

示例:

results = vectorstore.similarity_search_with_score( "什么是 RAG", k=3 ) for doc, score in results: print(score) print(doc.page_content)

返回:

0.23 RAG 是一种结合搜索和大语言模型的方法 0.45 向量数据库用于存储 Embedding 0.78 机器学习基础知识

三、similarity_search_with_score() 的分数有什么特点?

重点来了:

分数没有统一标准。

原因:

不同向量数据库:

  • FAISS
  • Chroma
  • Milvus
  • Pinecone
  • Weaviate

使用的距离算法可能不同。

例如:

1. 欧氏距离(L2 Distance)

公式:

距离越小,越相似

结果可能:

0.12 0.35 0.89

这里:

0.12 比 0.89 更相关。


2. 余弦距离(Cosine Distance)

可能:

0.01 0.20 0.60

通常:

越接近 0:

代表越相似。


3. 内积(Inner Product)

可能:

0.95 0.82 0.61

可能:

越大越相似。


所以:

similarity_search_with_score()

返回的 score:

可能:

0-1

也可能:

0-100

甚至:

负数

都属于正常情况。


四、为什么不同数据库分数不同?

因为向量搜索本质上是在计算:

两个向量之间的距离。

例如:

用户问题:

什么是人工智能?

Embedding:

[ 0.21, 0.34, 0.56, ... ]

数据库中的文档:

[ 0.22, 0.35, 0.55, ... ]

然后计算:

query vector | | ↓ distance calculation | | ↓ score

但是:

距离怎么算?

由数据库和算法决定。


五、similarity_search_with_relevance_scores() 是什么?

这个方法解决了一个问题:

不同数据库返回的 score 没有统一标准。

所以 LangChain 对结果进行了:

相关性归一化处理。

使用:

similarity_search_with_relevance_scores()

示例:

results = vectorstore.similarity_search_with_relevance_scores( "什么是RAG", k=3 ) for doc, score in results: print(score)

返回:

0.92 0.81 0.63

六、relevance score 有什么特点?

它经过统一处理:

范围:

0 <= score <= 1

含义:

分数含义
0.9-1.0高度相关
0.7-0.9比较相关
0.5-0.7一般相关
<0.5相关性较低

并且:

分数越大,表示文档越相关。


七、两者核心区别总结

对比similarity_search_with_scoresimilarity_search_with_relevance_scores
返回内容文档 + 原始score文档 + 归一化score
是否标准化❌ 否✅ 是
范围不固定0~1
是否依赖数据库强依赖弱依赖
适合场景底层调试业务判断
跨数据库比较困难方便

八、代码对比

方法一:原始score

docs = vectorstore.similarity_search_with_score( query, k=5 ) for doc, score in docs: print( f"score:{score}" )

可能输出:

score:0.231 score:0.452 score:0.891

问题:

不同数据库:

可能变成:

score:15.2 score:8.6 score:3.1

代码无法统一判断。


方法二:relevance score

docs = vectorstore.similarity_search_with_relevance_scores( query, k=5 ) for doc, score in docs: print( f"score:{score}" )

输出:

score:0.96 score:0.82 score:0.71

可以直接:

if score > 0.8: print("保留")

九、RAG 项目中应该使用哪个?

这是很多开发者关心的问题。

场景一:调试向量搜索

推荐:

similarity_search_with_score()

原因:

可以看到底层真实距离。

例如:

检查:

  • Embedding 是否正常
  • 向量是否生成正确
  • 数据是否入库

场景二:知识库问答系统

推荐:

similarity_search_with_relevance_scores()

例如:

RAG:

用户问题 ↓ 向量检索 ↓ 相关性过滤 ↓ LLM生成答案

可以:

docs = [ doc for doc, score in results if score > 0.75 ]

过滤低质量文档。


十、实际开发中的一个坑

很多新人会这样写:

docs = vectorstore.similarity_search_with_score( query ) if score > 0.8: use_document()

问题:

如果当前数据库:

score 是距离:

例如:

0.2

代表高度相关。

那么:

0.2 > 0.8

结果:

直接过滤掉。

导致:

明明相关的文档,却没有被召回。


正确方式:

如果不知道底层算法:

使用:

similarity_search_with_relevance_scores()

十一、底层原理简单理解

可以这样理解:

similarity_search_with_score

类似:

数据库: A文档 距离 = 0.15 B文档 距离 = 0.42 C文档 距离 = 0.89

这是:

原始测量值。


similarity_search_with_relevance_scores

类似:

经过加工:

A文档 相关度 = 0.95 B文档 相关度 = 0.75 C文档 相关度 = 0.30

变成:

业务更容易理解的数据。


十二、总结

今天我们学习了 LangChain 中两个重要方法:

similarity_search_with_score()

和:

similarity_search_with_relevance_scores()

核心区别:

一句话总结:

similarity_search_with_score 返回的是向量数据库原始评分,不同算法和数据库结果可能不同;similarity_search_with_relevance_scores 会对评分进行归一化,将结果转换为 0~1 的相关性分数,更适合业务判断。

在实际 RAG 项目中:

  • 调试检索效果 → 使用similarity_search_with_score
  • 判断文档相关性 → 使用similarity_search_with_relevance_scores
  • 做阈值过滤 → 优先使用relevance_scores

掌握这两个方法的区别,是理解 LangChain 向量检索机制的重要一步,也是优化 RAG 系统准确率的基础。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进