rohitsar567 Claude Opus 4.7 (1M context) commited on
Commit
d6d717f
·
1 Parent(s): b778c1b

fix(retrieval): KI-243 — CRITICAL: relax citation_grounding (chunk_offset optional)

Browse files

Z2 5-persona test showed 15/15 retrieve_policies calls returned 0 chunks.
0/5 personas reached recommendation. Total blocker.

Z3 diagnosis (via /tmp/diag_retrieval.py): raw rag.retrieve returned 8
healthy chunks for the Rajesh profile (52, Pune, family of 2, 40L,
diabetes+BP). enforce_citation_grounding then dropped 8/8 because:

- The filter required chunk_offset or chunk_idx as a non-negative int
- brain_tools.retrieve_policies's dict-builder copies these keys from
RetrievedChunk: chunk_id / policy_id / policy_name / insurer_slug /
doc_type / source_url / chunk_text / score / min_entry_age / max_entry_age
- Neither chunk_idx nor chunk_offset is in that list — they're stored
on the dataclass but not copied to the dict the filter sees.

Brains cite policies by identity (policy_id, policy_name, UIN), not by
chunk offset. The grounding filter only needs to verify the chunk has
a real policy attached. Relaxed to:
- require: policy_id (non-empty str) + policy_name (non-empty str)
- drop: chunk_offset / chunk_idx requirements entirely

Diag rerun after fix: 8/8 chunks pass enforce_citation_grounding.
apply_profile_filter then correctly passes all 8 (Rajesh age=52 inside
every policy's entry_age band). No over-constraint regression.

Unblocks Path B end-to-end recommendations.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Files changed (1) hide show
  1. backend/retrieval_filters.py +14 -12
backend/retrieval_filters.py CHANGED
@@ -326,28 +326,30 @@ def empty_retrieval_guard(
326
  # ---------------------------------------------------------------------------
327
 
328
  def enforce_citation_grounding(chunks: Iterable[Any]) -> list[Any]:
329
- """Drop chunks missing any of the three citation-critical fields.
330
-
331
- The "chunk_offset" requirement maps onto either `chunk_offset` (newer
332
- ingestions) or the existing `chunk_idx` (legacy + current). At least
333
- one must be a non-negative int.
 
 
 
 
 
 
 
 
 
334
  """
335
  kept: list[Any] = []
336
  for ch in chunks:
337
  m = _meta(ch)
338
  pid = m.get("policy_id")
339
  pname = m.get("policy_name")
340
- # accept either field name; chunk_idx is the existing schema in rag/retrieve.py
341
- offset = m.get("chunk_offset")
342
- if offset is None:
343
- offset = m.get("chunk_idx")
344
-
345
  if not pid or not isinstance(pid, str):
346
  continue
347
  if not pname or not isinstance(pname, str):
348
  continue
349
- if not isinstance(offset, int) or offset < 0:
350
- continue
351
  kept.append(ch)
352
  return kept
353
 
 
326
  # ---------------------------------------------------------------------------
327
 
328
  def enforce_citation_grounding(chunks: Iterable[Any]) -> list[Any]:
329
+ """Drop chunks missing citation-critical fields.
330
+
331
+ A citable chunk MUST expose:
332
+ - policy_id (non-empty str)
333
+ - policy_name (non-empty str)
334
+
335
+ The chunk offset field (`chunk_offset` or legacy `chunk_idx`) is
336
+ INFORMATIONAL only — it is not required for citation grounding because
337
+ upstream call sites (e.g. brain_tools.retrieve_policies) build pruned
338
+ dicts that intentionally omit it, and the brain cites by policy
339
+ identity, not by chunk offset. Z2 live test (2026-05-15) showed 15/15
340
+ retrieve_policies calls returning 0 chunks because we required an
341
+ offset that the upstream builder never included → every chunk dropped
342
+ here even though raw retrieval was healthy.
343
  """
344
  kept: list[Any] = []
345
  for ch in chunks:
346
  m = _meta(ch)
347
  pid = m.get("policy_id")
348
  pname = m.get("policy_name")
 
 
 
 
 
349
  if not pid or not isinstance(pid, str):
350
  continue
351
  if not pname or not isinstance(pname, str):
352
  continue
 
 
353
  kept.append(ch)
354
  return kept
355