fix(rag): fb-41 PR-7 multi-hop pre-decompose score-gate (S7 hallucination 회귀 핀) #174
Reference in New Issue
Block a user
Delete Branch "feat/fb-41-pr-7-multi-hop-score-gate-fix"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
요약
v0.18.0 cut 전 fb-41 multi-hop RAG 도그푸딩에서 발견된 safety regression fix.
kebab ask --multi-hop의 score-gate 우회로 KB 밖 query 가 hallucination 답변 받는 path 차단.자세한 도그푸딩 결과:
tasks/HOTFIXES.md의 2026-05-25 fb-41 pre-v0.18 entry +/build/cache/dogfood-v018/results/SUMMARY.md(도그푸딩 보고서).설계: docs/superpowers/specs/2026-05-25-p9-fb-41-multi-hop-rag-design.md
계획: docs/superpowers/plans/2026-05-25-p9-fb-41-multi-hop-rag.md (post-cut hotfix)
문제 (도그푸딩 S7)
Query:
What is the chemical formula of caffeine?(KB 에 없는 fact).kebab ask: retrieve top score <rag.score_gate(0.30) →refuse_score_gate→ 안전.kebab ask --multi-hop:grounded = true, 본문 "카페인의 화학식은 C₉H₁₅N₃O 입니다 [#6]" (hallucination — 실제 C₈H₁₀N₄O₂) +[#6]가 Adam optimizer chunk 의g_t = ∂L/∂θ_i본문을 잘못 인용.원인:
ask_multi_hop의 score-gate 검사가 pool 의 top_score 만 봤음. multi-hop pool 은 5 sub-queries 의 union — 한 sub-query 의 top score 가 gate 위면 다른 chunks 가 원본 query 와 무관해도 통과 → synth → hallucinate.Fix
ask_multi_hopentry 에 pre-decompose probe:refuse_no_chunks(None)(decompose 안 함).refuse_score_gate(None)(decompose 안 함).Multi-hop 의 safety floor 가 single-pass 와 정확히 일치. multi-hop 은 원본 query 가 이미 KB 범위 내 일 때만 cross-doc reasoning 추가.
Tests
신규 3 회귀 핀 (
crates/kebab-rag/tests/multi_hop.rs):multi_hop_below_probe_gate_refuses_before_any_llm_call— S7 직접 회귀 핀. low-score chunk + empty LM script → fix revert 시 즉시 panic (ScriptedLm exhaustion).multi_hop_empty_probe_pool_refuses_before_any_llm_call— empty retrieve → NoChunks, LM calls 0회.multi_hop_above_probe_gate_proceeds_to_decompose— probe pass 시 full flow 정상.기존 7 multi-hop test 의
ScriptedRetriever에 probe entry prepend +retriever_handle.calls()+1. 두 refuse-trace test (*_preserves_hops_trace) 의 의미 좁힘 — decompose-driven refusal 만 검증, probe-driven 은 신규 test 가 핀.변경 없음
Answer.hops/refusal_reasonenum) 동일.검증
cargo test -p kebab-rag -j 1— 10 multi-hop (7 갱신 + 3 신규) + 19 pipeline + 31 unit + 3 prompt_template + 3 streaming 모두 통과. 회귀 없음.cargo clippy -p kebab-rag --all-targets -j 1 -- -D warningsclean.시험 항목 (Test Plan)
다음 — v0.18.0 cut
PR-7 머지 후:
Cargo.tomlversion 0.17.2 → 0.18.0 (minor bump — surface 확장 + newprompt_template_version = \"rag-multi-hop-v1\"+ safety fix).open→completed.gitea-release v0.18.0 --auto-notes.Assisted-by: Claude Code
회차 1 — code doc 1 건 nit (informational, not blocking).
PR-7 의 fix scope (pre-decompose probe + gate, refuse 시 hops=None, 3 신규 + 7 갱신 test, HOTFIXES dated entry) 자체는 매우 깨끗. dogfood S7 의 hallucination 직접 회귀 핀 강력 — fix revert 시 ScriptedLm exhaustion 으로 즉시 panic. test 6/7 의 의미 좁힘도 doc 으로 명확화 ("probe-driven refusal 은 hops=None, decompose-driven 만 hops 보존"). HOTFIXES entry 가 dogfood 결과 + 다른 P1 항목까지 cover.
본 유일 nit: probe_hits 가 gate 검사 후 throw away 되는 의도 (pool 초기값 으로 활용 안 함) 가 코드 reader 에게 명시되면 더 깨끗. inline 코멘트에 doc 추가 제안.
설계·계획 정합 / clippy / 신규 test 의 coverage / 기존 test 갱신 모두 정합. v0.18.0 cut blocker fix 라 회차 2 doc 반영 후 빠른 머지 가치.
@@ -622,0 +635,4 @@// above the gate.//// Fix: probe the original query exactly the way single-pass// `ask` would, before any decompose / decide LLM call. Ifdoc nit (actionable): probe 의 retrieve 결과 (
probe_hits) 가 gate 검사만 하고 throw away 됨 — pool 초기값으로 사용 안 함. 이는 의도된 단순화 (회귀 위험 회피) 지만 코드 reader 가 "왜 같은 query 의 retrieve 가 두 번? (probe + decompose 의 첫 sub-query 가 보통 원본 query)" 의문 가질 수 있다.doc 한 줄 추가 권장:
또는 한 줄 짧게:
// probe_hits are inspected for the gate decision only — the decompose-driven pool below builds from scratch, even if the first sub-query == original query.회차 2 — probe_hits 의 invariant clarity doc 완벽 반영. "향후 retrieve cost 가 multi-hop bottleneck 이 될 경우 재검토 hint" 까지 포함 — reader 가 향후 효율화 decision 의 cost / benefit 명확히 weigh 가능.
추가 actionable 항목 없음 — 머지에 동의.
요약:
multi_hop_below_probe_gate_refuses_before_any_llm_call가 S7 직접 핀) + 기존 7 multi-hop test 의 probe entry cascade + 두 refuse-trace test 의 의미 좁힘 (decompose-driven only).cargo test -p kebab-rag -j 1모든 test 통과 + clippy clean. wire schema 변경 없음.v0.18.0 cut blocker 해소 — 머지 후 cut step 진행 가능.