Index
2026-04-20 — Progress

Query Plan V3: 3-Bug Fix 구현

Graph-VLM | _fuzzy_match_all · Plan Union · Keyword-Subgraph Fallback

TL;DR

+10%p
hardfilt10 정확도
Context 크기 감소
0/10
Fallback 사용 (V3)
2~3
Plans per Query

1 배경 / 목적

Hard QA debug 결과(V1), hardfilt10 10개 중 5개가 all fallback으로 74K chars 전체 그래프 덤프를 VLM에 전달했다. 나머지 5개도 single-seed entity linking으로 entity split 케이스를 놓쳤다. 이 retrieval infra 문제를 Tier 2(그래프 빌드 수정)보다 먼저 고쳐야 했다 — retrieval이 깨진 상태에서 그래프를 수정해도 개선을 측정할 수 없기 때문.

V1 주요 실패: fallback 5/10 (74K 덤프 → VLM 익사), single-seed miss (red_onion vs red_onion_half), plan 1개 실패 시 복구 없음.

2 작업 내용

모든 변경은 src/vqa_pipeline.py에 집중. 외부 API 호출/그래프 구조는 변경 없음.

Bug #1: _fuzzy_match_all (multi-seed entity linking)

파일: src/vqa_pipeline.py 변경: _fuzzy_match_node (1개 반환) → _fuzzy_match_all (최대 10개 반환) Score 계산: - 정확 일치 / base-form 일치 (rstrip "s"): 1.0 - 양방향 substring: 0.3 ~ 1.0 (길이 비율) - description에 포함: 0.35 threshold 0.3 이상만 반환, 최대 10개 효과: red_onion → [red_onion, red_onion_half, red_onion_pieces] 동시 seed celery → [celery, celery_bunch, celery_stalk] 자동 포함

Bug #2: Plan Union (여러 plan 병렬 실행)

파일: src/vqa_pipeline.py 변경: - _plan_query 프롬프트 → {"plans": [...]} 리스트 반환 - "all" plan 명시적 금지 (planner 프롬프트) - object_ids / action_ids 복수형 인자 허용 - _execute_plan: 각 plan 실행 → _merge_results (union + dedup) - _merge_results(cap_nodes=80): action > object > keyframe > scene 우선 - plan 프롬프트 tight: "max 3 plans, max 1-3 object_ids per plan" 추가 튜닝: - plan generation max_tokens: 512 → 8192 (Gemini 2.5 thinking tokens가 512 예산 잠식하던 문제 해결) - planner 모델: gemini-2.0-flash → gemini-2.5-flash (2.0-flash rate limit 회피)

Bug #3: Keyword-Subgraph Fallback (74K 덤프 폐기)

파일: src/vqa_pipeline.py 변경: _fallback_context() (74K dump) → _keyword_subgraph(question, cap_nodes=40) 알고리즘: 1. 질문에서 stopword 제외한 명사/형용사 토큰 추출 2. 각 토큰을 _fuzzy_match_all로 graph node에 seed 매칭 3. seed들에서 1-hop BFS (predecessors + successors) 4. cap 40 nodes, 관련 edge만 유지 5. build_context + collect_keyframes 결과: 평균 context 74K chars → ~5K chars (~15× 감소)

3 결과

V1 vs V3 인프라 비교

항목V1 (이전)V3 (이후)
평균 context 크기37K chars (절반이 74K 덤프)9K chars (최대 14K)
Fallback 사용 (hardfilt10)5/100/10
Plans per query1개2~3개
hardfilt10 정확도10% (1/10)20% (2/10)

hardfilt10 질문별 V1→V3 변화

qa_idV1V3핵심 변화
hardfilt_003 (SEQUENTIAL)✗ (all fallback 74K)plan 2개(celery+pan, cutting_board) → red_onion placement 정확히 뽑음
hardfilt_000 (VISUAL-LOCATION)정답 유지 (plan 1→3개, context 12K→9K)
hardfilt_001 (COUNT)context 74K→14K 축소, 그러나 count 정보 그래프에 없음
hardfilt_004 (COUNT)context 74K→9.7K 축소, 시각 카운팅은 그래프 한계
hardfilt_006 (SEQUENTIAL)VLM이 plan params에 CUTTING_ACTION_END_SEC placeholder 리터럴로 남기는 버그
hardfilt_007 (COUNT)reasoning은 "two" 맞게 추론했지만 final answer letter 오추출
hardfilt_008 (VISUAL-LOCATION)버너 front/back 위치 정보 그래프에 없음 (visual position attribute 부재)

V3 잔여 실패 8개 원인 분류

원인해당 질문Tier 2 해결 항목
Occurrence count 없음Q1, Q4, Q7Action occurrence_count
Container edges 없음 (stored_in)Q2, Q5Container edges
Visual position attribute 없음Q8Visual position
Action chain 정보 없음Q9Action chain tracking
Plan placeholder 버그 + entity alias 미처리Q6Entity alias + prompt fix
MCQ 추출 실수 (reasoning은 맞음)Q7 (부분)MCQ 추출 개선
핵심 인사이트: V3 8개 실패 중 6개는 그래프 빌드 자체의 정보 부족(Tier 2). Retrieval infra 자체는 올바르게 동작 확인됨. Q3 개선이 이를 증명: V1에서 74K 덤프에 익사했는데 V3에서 participant(celery, frying_pan) + participant(cutting_board) 조합으로 정답.

4 Takeaway

Retrieval Infra가 Tier 2의 전제조건

Query plan infra +10%p 개선 자체보다 중요한 것은 이제 그래프 빌드 수정의 효과를 정확히 측정할 수 있게 됐다는 점. V1에서 fallback 74K 덤프 상태였으면 Tier 2 수정 후에도 "retrieval 문제인지 그래프 문제인지" 구분 불가. V3로 retrieval을 고정시켰으니 이제 그래프에 정보를 추가하면 바로 정확도에 반영된다.

한계: Tier 2 모두 구현 시 hardfilt10 V3 2/10 → 6~8/10 기대이지만, clean 5개(hallucination 제거 후) 기준으로는 이미 Graph 40% vs Describe 20% → Graph가 공정 비교에서 +20%p. 전체 hardfilt10 수치가 낮은 이유는 부분적으로 QA 품질 문제.

5 Next Steps

Tier 2 그래프 빌드 수정 우선순위:

항목예상 효과 (hardfilt10)해당 질문
Container edges (stored_in, inside)+1~2 정답Q2, Q5
Action chain tracking (first/last)+1~2 정답Q6 (partial), Q9
Occurrence count+1~2 정답Q1, Q7
Visual position attribute+1 정답Q8
Entity alias edges+1 정답Q6
MCQ 추출 개선 + Prompt bug fix+0.5~1 정답Q6, Q7

Frame-agreement filter: gen_hard_qa_filtered.py에 3rd stage 추가 — Frame-300이 GT에 동의하지 않으면 drop. Q7/Q9 같은 hallucination 케이스 제거.

평가 확장: V3 개선 후 hardest10 / L34hard10 재평가 → 3개 hard 벤치마크 일관 비교. 자세한 per-question 분석은 260421-hardfilt10_walkthrough.html 참조.