feat(memory): add search score explanations (#5102)
Co-authored-by: kartik-mem0 <kartik.labhshetwar@mem0.ai>
This commit is contained in:
co-authored by
kartik-mem0
parent
d817aa9c12
commit
a44855af9e
+16
-4
@@ -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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user