Nagendravarma commited on
Commit
9b91537
Β·
1 Parent(s): b8ddc78

Optimize comparison search: bypass redundant KG search, avoid thread-safety ChromaDB init lock error, and prevent false positive tier lighting up in dev console

Browse files
backend/main.py CHANGED
@@ -391,7 +391,9 @@ async def chat_stream(session_id: str, query: str, plan_tier: str = "Unknown"):
391
 
392
  for step in new_steps:
393
  yield emit({"type": "substep", "node": node, "intent": intent, "step": step, "all_steps": current_steps})
394
- await asyncio.sleep(0.05)
 
 
395
 
396
  final_answer = state.get("answer", "")
397
  yield emit({
 
391
 
392
  for step in new_steps:
393
  yield emit({"type": "substep", "node": node, "intent": intent, "step": step, "all_steps": current_steps})
394
+ # Skip artificial delay for raw graph DB edge logs and entity listings to prevent stream lagging
395
+ if not step.startswith(("[GraphDB-Edge]", "[GraphDB]")):
396
+ await asyncio.sleep(0.05)
397
 
398
  final_answer = state.get("answer", "")
399
  yield emit({
frontend/dev_console.html CHANGED
@@ -1242,6 +1242,7 @@ function activateFromStep(step, lgNode) {
1242
  return;
1243
  }
1244
  if (id === 'graphdb' && currentIntent === 'POLICY_QUESTION') return;
 
1245
  setNode(id, 'active');
1246
  const fromNode = lgNode === 'retrieve' ? 'retrieve_agent' : lgNode;
1247
  activateEdge(fromNode, id);
@@ -1392,6 +1393,7 @@ async function run() {
1392
 
1393
  if (type === 'substep') {
1394
  activateFromStep(step||'', node||'');
 
1395
  const tagMap = {
1396
  retrieve:'tag-retrieve', synthesize:'tag-synthesize',
1397
  query_guard:'tag-guard', query_decomposer:'tag-classify',
@@ -1399,7 +1401,9 @@ async function run() {
1399
  confidence_scorer:'tag-critique',
1400
  };
1401
  const tagClass = tagMap[node] || 'tag-classify';
1402
- addLog('β†’', 'STEP', tagClass, step||'');
 
 
1403
 
1404
  if (step && step.includes('🧠 Multi-Query Variant')) {
1405
  const variantText = step.split(':').slice(1).join(':').trim();
 
1242
  return;
1243
  }
1244
  if (id === 'graphdb' && currentIntent === 'POLICY_QUESTION') return;
1245
+ if (['bronze', 'silver', 'gold'].includes(id) && currentIntent !== 'COMPARISON') return;
1246
  setNode(id, 'active');
1247
  const fromNode = lgNode === 'retrieve' ? 'retrieve_agent' : lgNode;
1248
  activateEdge(fromNode, id);
 
1393
 
1394
  if (type === 'substep') {
1395
  activateFromStep(step||'', node||'');
1396
+ const isGraphEdge = step && step.startsWith('[GraphDB-Edge]');
1397
  const tagMap = {
1398
  retrieve:'tag-retrieve', synthesize:'tag-synthesize',
1399
  query_guard:'tag-guard', query_decomposer:'tag-classify',
 
1401
  confidence_scorer:'tag-critique',
1402
  };
1403
  const tagClass = tagMap[node] || 'tag-classify';
1404
+ if (!isGraphEdge) {
1405
+ addLog('β†’', 'STEP', tagClass, step||'');
1406
+ }
1407
 
1408
  if (step && step.includes('🧠 Multi-Query Variant')) {
1409
  const variantText = step.split(':').slice(1).join(':').trim();
orchestration/tools.py CHANGED
@@ -22,7 +22,7 @@ sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
22
  from langchain_core.tools import tool
23
  from langchain_core.documents import Document
24
 
25
- from retrieval.retriever import get_hybrid_retriever
26
  from retrieval.graph_retriever import GraphRetriever
27
 
28
  # ── Lazy singletons ────────────────────────────────────────────────────────────
@@ -189,11 +189,13 @@ def plan_comparison_search(query: str, tier: str) -> str:
189
  prioritises documents whose metadata or content mentions that tier.
190
  Enhanced: uses ChromaDB metadata pre-filter for plan_tier before hybrid search.
191
  """
192
- hybrid, _ = _get_retrievers()
 
 
193
 
194
  # Tier-augmented query forces relevant docs up the ranking
195
  tier_query = f"{tier} plan {query}"
196
- docs = hybrid.invoke(tier_query)
197
 
198
  # Guarantee tier-specific documents via metadata pre-filter (high precision boost)
199
  try:
 
22
  from langchain_core.tools import tool
23
  from langchain_core.documents import Document
24
 
25
+ from retrieval.retriever import get_hybrid_retriever, get_base_ensemble_retriever
26
  from retrieval.graph_retriever import GraphRetriever
27
 
28
  # ── Lazy singletons ────────────────────────────────────────────────────────────
 
189
  prioritises documents whose metadata or content mentions that tier.
190
  Enhanced: uses ChromaDB metadata pre-filter for plan_tier before hybrid search.
191
  """
192
+ # Use base ensemble retriever without multi-query and graph wrappers for plan comparison searches
193
+ # to avoid redundant graph lookups/GPT rephrasings and dramatically reduce latency.
194
+ base_ensemble = get_base_ensemble_retriever()
195
 
196
  # Tier-augmented query forces relevant docs up the ranking
197
  tier_query = f"{tier} plan {query}"
198
+ docs = base_ensemble.invoke(tier_query)
199
 
200
  # Guarantee tier-specific documents via metadata pre-filter (high precision boost)
201
  try:
retrieval/retriever.py CHANGED
@@ -148,6 +148,8 @@ def _get_all_documents(vectorstore: Chroma) -> list[Document]:
148
  # Main Pipeline Builder
149
  # ══════════════════════════════════════════════════════════════
150
 
 
 
151
  def get_hybrid_retriever(
152
  ensemble_weights: list[float] | None = None,
153
  retriever_k: int | None = None,
@@ -265,10 +267,12 @@ def get_hybrid_retriever(
265
 
266
  return merged_docs
267
 
 
268
  ensemble_retriever = LoggingEnsembleRetriever(
269
  retrievers=[logging_bm25_retriever, logging_vector_retriever],
270
  weights=weights,
271
  )
 
272
  console.print(f" βœ… Ensemble retriever ready (weights: BM25={weights[0]}, Vector={weights[1]})")
273
 
274
  # ── Stage 4: Knowledge Graph Integration ────────────────────
@@ -366,3 +370,16 @@ def get_bm25_only_retriever(k: int | None = None):
366
  vectorstore = _load_vectorstore()
367
  all_docs = _get_all_documents(vectorstore)
368
  return BM25Retriever.from_documents(all_docs, k=k or RERANKER_TOP_N)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
148
  # Main Pipeline Builder
149
  # ══════════════════════════════════════════════════════════════
150
 
151
+ _base_ensemble_retriever = None
152
+
153
  def get_hybrid_retriever(
154
  ensemble_weights: list[float] | None = None,
155
  retriever_k: int | None = None,
 
267
 
268
  return merged_docs
269
 
270
+ global _base_ensemble_retriever
271
  ensemble_retriever = LoggingEnsembleRetriever(
272
  retrievers=[logging_bm25_retriever, logging_vector_retriever],
273
  weights=weights,
274
  )
275
+ _base_ensemble_retriever = ensemble_retriever
276
  console.print(f" βœ… Ensemble retriever ready (weights: BM25={weights[0]}, Vector={weights[1]})")
277
 
278
  # ── Stage 4: Knowledge Graph Integration ────────────────────
 
370
  vectorstore = _load_vectorstore()
371
  all_docs = _get_all_documents(vectorstore)
372
  return BM25Retriever.from_documents(all_docs, k=k or RERANKER_TOP_N)
373
+
374
+
375
+ import threading
376
+ _retriever_lock = threading.Lock()
377
+
378
+ def get_base_ensemble_retriever():
379
+ """Get the cached base ensemble retriever without multi-query, graph, or reranking wrappers."""
380
+ global _base_ensemble_retriever
381
+ if _base_ensemble_retriever is None:
382
+ with _retriever_lock:
383
+ if _base_ensemble_retriever is None:
384
+ get_hybrid_retriever()
385
+ return _base_ensemble_retriever