langchain 0.2.10 配 langchain-chroma 0.1,用 as_retriever(search_type=”similarity_score_threshold”, score_threshold=0.7) 后一条结果都没有,换成 similarity 能返回文档但读不到分数。

把日志和配置对完,能解释这个现象的基本就这几处。集合写入时用的是余弦距离,分数越小越相似,阈值方向反了;检索器默认返回 distance,字段名与代码里读的 score 不一致;阈值过滤没法下推到集合层,只能在客户端筛;langchain-chroma 与 chromadb 的版本映射没对齐,结果字段缺失。

直接问集合要带距离的结果看字段名

python -c "import chromadb;c=chromadb.PersistentClient(path='./db').get_collection('kb');print(c.query(query_texts=['退款流程'],n_results=2)['distances'])"

再往下改用 similarity_search_with_score 自己筛

python -c "from langchain_chroma import Chroma;from langchain_openai import OpenAIEmbeddings;v=Chroma(collection_name='kb',embedding_function=OpenAIEmbeddings(),persist_directory='./db');print(v.similarity_search_with_score('退款流程',k=3))"

随后按距离设阈值,方向改成小于

python -c "print([d for d,s in [('a',0.21),('b',0.35)] if s<0.3])"

建集合时就固定距离度量

python -c "import chromadb;chromadb.PersistentClient(path='./db').get_or_create_collection('kb',metadata={'hnsw:space':'cosine'})"

中间停过一次,把已经改的东西回滚干净,再重新来一遍。

恢复的判定其实很直接。similarity_search_with_score 返回的分数都在 0 到 1 之间,按小于 0.3 过滤后剩下的文档确实相关,阈值 0.7 不再把结果清空。

提醒一点。cosine 与 l2 的分数尺度完全不同,换度量等于换一套阈值,迁移集合时阈值要一起重标。如果同一现象隔几天又出现,说明根因没找到,别当偶发处理。

作者 9823189