Nagendravarma commited on
Commit
3ccaa67
·
1 Parent(s): 9b91537

Fix semantic cache false hits by adding plan tier, drug, specialty, and location entity matching

Browse files
Files changed (1) hide show
  1. orchestration/semantic_cache.py +52 -10
orchestration/semantic_cache.py CHANGED
@@ -179,12 +179,41 @@ class SemanticCache:
179
  logger.warning(f"Failed to normalize query: {e}. Using original query.")
180
  return query
181
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
182
  def check(self, query: str, plan_tier: str = "Unknown", normalized_query: Optional[str] = None) -> Optional[dict]:
183
  """
184
  Check the semantic cache for a match.
185
 
186
  Returns:
187
- dict containing the response data and hit metadata if found, else None.
188
  """
189
  if not query or len(query.strip()) < 4:
190
  return None
@@ -211,6 +240,13 @@ class SemanticCache:
211
  if item.get("plan_tier", "Unknown").lower() != plan_tier.lower():
212
  continue
213
 
 
 
 
 
 
 
 
214
  sim = self._cosine_similarity(query_vector, item["vector"])
215
  if sim > best_score:
216
  best_score = sim
@@ -249,15 +285,21 @@ class SemanticCache:
249
  similarity = 1.0 - (distance / 2.0)
250
 
251
  if similarity >= SEMANTIC_CACHE_THRESHOLD:
252
- response_json = doc.metadata.get("response_json")
253
- if response_json:
254
- response = json.loads(response_json)
255
- response["cached"] = True
256
- response["cache_similarity"] = round(similarity * 100, 1)
257
- response["matched_query"] = doc.metadata.get("original_query", doc.page_content)
258
-
259
- logger.info(f"⚡ Local ChromaDB Cache HIT (Plan: {plan_tier}, Similarity: {response['cache_similarity']}%) in {time.time() - start_time:.3f}s")
260
- return response
 
 
 
 
 
 
261
 
262
  except Exception as e:
263
  logger.error(f"Error checking semantic cache: {e}")
 
179
  logger.warning(f"Failed to normalize query: {e}. Using original query.")
180
  return query
181
 
182
+ def _extract_entities(self, text: str) -> set:
183
+ """Extract key plan tiers, drugs, specialties, and locations from query to prevent false semantic matches."""
184
+ key_entities = {
185
+ # Tiers
186
+ "bronze", "silver", "gold",
187
+ # Drugs
188
+ "metformin", "lisinopril", "amlodipine", "atorvastatin", "lipitor", "omeprazole",
189
+ "levothyroxine", "sertraline", "escitalopram", "fluoxetine", "alprazolam",
190
+ "lorazepam", "metoprolol", "carvedilol", "furosemide", "hydrochlorothiazide",
191
+ "tirzepatide", "etanercept", "spironolactone",
192
+ # Specialties
193
+ "pulmonology", "oncology", "pediatrics", "ophthalmology", "cardiology",
194
+ "urology", "hematology", "rheumatology", "nephrology", "dermatology", "dermatologist",
195
+ # Cities
196
+ "chicago", "rockford", "miami", "joliet", "naperville", "brooklyn",
197
+ "queens", "oakland", "springfield"
198
+ }
199
+ text_lower = text.lower()
200
+ found = set()
201
+ for ent in key_entities:
202
+ if ent in text_lower:
203
+ found.add(ent)
204
+ # Handle some common typos/synonyms
205
+ if "silbr" in text_lower:
206
+ found.add("silver")
207
+ if "dermatologist" in found:
208
+ found.add("dermatology")
209
+ return found
210
+
211
  def check(self, query: str, plan_tier: str = "Unknown", normalized_query: Optional[str] = None) -> Optional[dict]:
212
  """
213
  Check the semantic cache for a match.
214
 
215
  Returns:
216
+ dict containing the response data and hit metadata if found, else None.
217
  """
218
  if not query or len(query.strip()) < 4:
219
  return None
 
240
  if item.get("plan_tier", "Unknown").lower() != plan_tier.lower():
241
  continue
242
 
243
+ # Entity safeguard check: ensure the key entities (tiers, drugs, specialties, locations)
244
+ # mentioned in the user's query match the cached item's query.
245
+ user_entities = self._extract_entities(norm_query)
246
+ cached_entities = self._extract_entities(item["query"])
247
+ if user_entities != cached_entities:
248
+ continue
249
+
250
  sim = self._cosine_similarity(query_vector, item["vector"])
251
  if sim > best_score:
252
  best_score = sim
 
285
  similarity = 1.0 - (distance / 2.0)
286
 
287
  if similarity >= SEMANTIC_CACHE_THRESHOLD:
288
+ # Entity safeguard check
289
+ user_entities = self._extract_entities(norm_query)
290
+ cached_query = doc.metadata.get("original_query", doc.page_content)
291
+ cached_entities = self._extract_entities(cached_query)
292
+
293
+ if user_entities == cached_entities:
294
+ response_json = doc.metadata.get("response_json")
295
+ if response_json:
296
+ response = json.loads(response_json)
297
+ response["cached"] = True
298
+ response["cache_similarity"] = round(similarity * 100, 1)
299
+ response["matched_query"] = doc.metadata.get("original_query", doc.page_content)
300
+
301
+ logger.info(f"⚡ Local ChromaDB Cache HIT (Plan: {plan_tier}, Similarity: {response['cache_similarity']}%) in {time.time() - start_time:.3f}s")
302
+ return response
303
 
304
  except Exception as e:
305
  logger.error(f"Error checking semantic cache: {e}")