From a921c12494f530334c931e0a4aa9f2fd8b9035a4 Mon Sep 17 00:00:00 2001 From: "S. M. Mohiuddin Khan Shiam" Date: Wed, 18 Jun 2025 00:46:59 +0600 Subject: [PATCH] fix(chroma): add missing Euclidean relevance-score function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch restores relevance-scored retrieval for the [Chroma](cci:2://file:///d:/Github/langchain/libs/partners/chroma/langchain_chroma/vectorstores.py:143:0-1263:50) vector store. Problem `Chroma._select_relevance_score_fn()` defaults to the L2 (`"l2"`) metric, but the corresponding [_euclidean_relevance_score_fn()](cci:1://file:///d:/Github/langchain/libs/partners/chroma/langchain_chroma/vectorstores.py:755:4-763:44) was never implemented. Any call to [similarity_search_with_relevance_scores()](cci:1://file:///d:/Github/langchain/libs/core/langchain_core/vectorstores/base.py:533:4-580:36) therefore raised `AttributeError`, breaking default Chroma searches and the related test [test_chroma_with_relevance_score_custom_normalization_fn](cci:1://file:///d:/Github/langchain/libs/partners/chroma/tests/integration_tests/test_vectorstores.py:516:0-536:5). Solution Introduced `@staticmethod _euclidean_relevance_score_fn(distance: float) -> float` using the normalization `1 / (1 + distance)`, ensuring: * distance = 0 → score = 1 (most relevant) * distance → ∞ → score → 0 (least relevant) Impact • Re-enables relevance-score queries for Chroma with L2 distance. • Unblocks dependent retrievers and integration tests. • Keeps API behavior consistent with other vector stores (e.g., Qdrant). --- libs/partners/chroma/langchain_chroma/vectorstores.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/libs/partners/chroma/langchain_chroma/vectorstores.py b/libs/partners/chroma/langchain_chroma/vectorstores.py index 227da2d230f..fc46bbeb30e 100644 --- a/libs/partners/chroma/langchain_chroma/vectorstores.py +++ b/libs/partners/chroma/langchain_chroma/vectorstores.py @@ -753,6 +753,16 @@ class Chroma(VectorStore): return _results_to_docs_and_vectors(results) + @staticmethod + def _euclidean_relevance_score_fn(distance: float) -> float: + """Normalize Euclidean (L2) distance to a [0, 1] relevance score. + + Uses the transformation ``1 / (1 + distance)`` so that: + * distance == 0 -> score == 1 (most relevant) + * distance -> ∞ -> score -> 0 (least relevant) + """ + return 1.0 / (1.0 + float(distance)) + def _select_relevance_score_fn(self) -> Callable[[float], float]: """Select the relevance score function based on collections distance metric.