feat(memory): add search score explanations (#5102)

Co-authored-by: kartik-mem0 <kartik.labhshetwar@mem0.ai>
This commit is contained in:
Chirag Arora
2026-06-05 21:30:10 +05:30
committed by GitHub
co-authored by kartik-mem0
parent d817aa9c12
commit a44855af9e
11 changed files with 220 additions and 14 deletions
+16 -4
View File
@@ -1132,6 +1132,7 @@ class Memory(MemoryBase):
filters: Optional[Dict[str, Any]] = None,
threshold: float = 0.1,
rerank: bool = False,
explain: bool = False,
**kwargs,
):
"""
@@ -1162,6 +1163,7 @@ class Memory(MemoryBase):
- {"NOT": [filter1]} - logical NOT
threshold (float, optional): Minimum score for a memory to be included. Defaults to 0.1.
rerank (bool, optional): Whether to rerank results. Defaults to False.
explain (bool, optional): Whether to include score_details for each result. Defaults to False.
Returns:
dict: A dictionary containing the search results under a "results" key.
@@ -1221,11 +1223,12 @@ class Memory(MemoryBase):
"encoded_ids": encoded_ids,
"sync_type": "sync",
"threshold": threshold,
"explain": explain,
"advanced_filters": bool(filters and self._has_advanced_operators(filters)),
},
)
original_memories = self._search_vector_store(query, effective_filters, limit, threshold)
original_memories = self._search_vector_store(query, effective_filters, limit, threshold, explain=explain)
# Apply reranking if enabled and reranker is available
if rerank and self.reranker and original_memories:
@@ -1341,7 +1344,7 @@ class Memory(MemoryBase):
return True
return False
def _search_vector_store(self, query, filters, limit, threshold=0.1):
def _search_vector_store(self, query, filters, limit, threshold=0.1, explain=False):
# Guard against None threshold (backward compat)
if threshold is None:
threshold = 0.1
@@ -1396,6 +1399,7 @@ class Memory(MemoryBase):
entity_boosts=entity_boosts,
threshold=threshold,
top_k=limit,
explain=explain,
)
# Step 9: Format results
@@ -1433,6 +1437,8 @@ class Memory(MemoryBase):
if not memory_item_dict.get("metadata"):
memory_item_dict["metadata"] = {}
memory_item_dict["metadata"].update(additional_metadata)
if explain and "score_details" in scored:
memory_item_dict["score_details"] = scored["score_details"]
original_memories.append(memory_item_dict)
@@ -2568,6 +2574,7 @@ class AsyncMemory(MemoryBase):
filters: Optional[Dict[str, Any]] = None,
threshold: float = 0.1,
rerank: bool = False,
explain: bool = False,
**kwargs,
):
"""
@@ -2598,6 +2605,7 @@ class AsyncMemory(MemoryBase):
- {"NOT": [filter1]} - logical NOT
threshold (float, optional): Minimum score for a memory to be included. Defaults to 0.1.
rerank (bool, optional): Whether to rerank results. Defaults to False.
explain (bool, optional): Whether to include score_details for each result. Defaults to False.
Returns:
dict: A dictionary containing the search results under a "results" key.
@@ -2659,11 +2667,12 @@ class AsyncMemory(MemoryBase):
"encoded_ids": encoded_ids,
"sync_type": "async",
"threshold": threshold,
"explain": explain,
"advanced_filters": bool(filters and self._has_advanced_operators(filters)),
},
)
original_memories = await self._search_vector_store(query, effective_filters, limit, threshold)
original_memories = await self._search_vector_store(query, effective_filters, limit, threshold, explain=explain)
# Apply reranking if enabled and reranker is available
if rerank and self.reranker and original_memories:
@@ -2782,7 +2791,7 @@ class AsyncMemory(MemoryBase):
return True
return False
async def _search_vector_store(self, query, filters, limit, threshold=0.1):
async def _search_vector_store(self, query, filters, limit, threshold=0.1, explain=False):
if threshold is None:
threshold = 0.1
@@ -2836,6 +2845,7 @@ class AsyncMemory(MemoryBase):
entity_boosts=entity_boosts,
threshold=threshold,
top_k=limit,
explain=explain,
)
# Step 9: Format results
@@ -2872,6 +2882,8 @@ class AsyncMemory(MemoryBase):
if not memory_item_dict.get("metadata"):
memory_item_dict["metadata"] = {}
memory_item_dict["metadata"].update(additional_metadata)
if explain and "score_details" in scored:
memory_item_dict["score_details"] = scored["score_details"]
original_memories.append(memory_item_dict)