-
Notifications
You must be signed in to change notification settings - Fork 62
Description
Description
Issue #407 identified that SemanticCache.check() (sync) and acheck() (async) interpret distance_threshold inconsistently due to different normalize_vector_distance settings. While PR #408 added a new LangCacheWrapper with a distance_scale parameter to address this, the original SemanticCache class was not fixed and still exhibits the bug.
Current Behavior (redisvl 0.12.1)
In redisvl/extensions/cache/llm/semantic.py: Sync check() (line ~410):
query = VectorRangeQuery(
vector=vector,
vector_field_name=CACHE_VECTOR_FIELD_NAME,
return_fields=self.return_fields,
distance_threshold=distance_threshold,
num_results=num_results,
return_score=True,
filter_expression=filter_expression,
dtype=self._vectorizer.dtype,
# normalize_vector_distance defaults to False
)
Async acheck() (line ~503):
query = VectorRangeQuery(
vector=vector,
vector_field_name=CACHE_VECTOR_FIELD_NAME,
return_fields=self.return_fields,
distance_threshold=distance_threshold,
num_results=num_results,
return_score=True,
filter_expression=filter_expression,
normalize_vector_distance=True, # <-- Different from sync!
)
Impact
With distance_threshold=0.05 (intended to match only very similar queries):
Sync check(): Uses 0.05 as raw cosine distance (correct - strict matching)
Async acheck(): Converts to 2 - 2*0.05 = 1.9 (wrong - matches almost everything!)
Reproduction
import asyncio
from redisvl.extensions.cache.llm import SemanticCache
async def test():
cache = SemanticCache(
name="test",
distance_threshold=0.05, # Strict threshold
redis_url="redis://localhost:6379",
)
# Store entry
cache.store(prompt="Who is CEO?", response="John Smith")
# Query with different prompt (cosine distance ~0.23)
sync_result = cache.check(prompt="Who is CFO?")
async_result = await cache.acheck(prompt="Who is CFO?")
print(f"Sync: {len(sync_result)} hits") # Expected: 0, Actual: 0 ✓
print(f"Async: {len(async_result)} hits") # Expected: 0, Actual: 1 ✗
asyncio.run(test())
Environment
redisvl: 0.12.1
Python: 3.11
Suggested Fix
Remove normalize_vector_distance=True from acheck() to match check() behavior:
# In redisvl/extensions/cache/llm/semantic.py, acheck() method
query = VectorRangeQuery(
vector=vector,
vector_field_name=CACHE_VECTOR_FIELD_NAME,
return_fields=self.return_fields,
distance_threshold=distance_threshold,
num_results=num_results,
return_score=True,
filter_expression=filter_expression,
# Remove: normalize_vector_distance=True
)
This is a one-line fix that ensures sync/async parity.