대안 F: BM25 + embedding + reranker + validator
흐름
raw chunkText
-> BM25 top 80
-> embedding top 80
-> 후보 union
-> reranker가 raw chunk와 각 JSONL 후보를 직접 비교
-> top JSONL 반환
-> Qwen direct-evidence validator가 직접근거 검증역할 분담
BM25:
정확 문자열/API 토큰 후보를 찾는다.code embedding:
표현이 다르지만 의미가 가까운 후보를 보완한다.reranker:
BM25와 embedding이 가져온 후보를 raw chunk와 비교해 다시 정렬한다.Qwen direct-evidence validator:
JSONL 안에 현재 chunk와 직접 맞는 문자열/패턴 근거가 있는지 확인한다.
근거 없는 JSONL은 폐기한다.기준 chunk에서 기대되는 정렬
높게 올라가야 할 후보:
first_2d_game / coding_the_player
same page / clamp and AnimatedSprite2D explanation낮아져야 할 후보:
first_3d_game / player_movement_code
unrelated api_mapping
unrelated label_prototypesPoC 시뮬레이션
기준 chunk를 최종 추천 흐름에 넣는다고 가정한다.
raw chunkText
-> BM25 top 80
-> voyage-code-3 embedding top 80
-> 후보 union
-> reranker
-> Qwen direct-evidence validator1단계: BM25 후보
BM25가 가져올 후보:
A. first_2d_game / coding_the_player
reason: Input.is_action_pressed, move_left, move_right, AnimatedSprite2D.play/stop
B. first_2d_game / clamp section
reason: position.clamp, Vector2.ZERO, screen_size
C. first_3d_game / player_movement_code
reason: Input.is_action_pressed, move_left, move_right, normalized2단계: embedding 후보
embedding이 가져올 후보:
D. first_2d_game / movement explanation
reason: 2D movement, keyboard input, animation
E. first_2d_game / screen bounds explanation
reason: keep player inside screen
F. first_3d_game / movement
reason: player movement semantic similarity3단계: 후보 union
union 후에는 중복을 합친다.
A/D -> first_2d_game / coding_the_player
B/E -> first_2d_game / clamp/screen bounds
C/F -> first_3d_game / player_movement4단계: reranker 재정렬
reranker가 raw chunk와 후보를 함께 본다.
예상 rerank:
| rerank | 후보 | 이유 |
|---|---|---|
| 1 | first_2d_game / coding_the_player |
입력 처리, velocity, AnimatedSprite2D play/stop이 직접 맞음 |
| 2 | first_2d_game / clamp/screen bounds |
position.clamp, Vector2.ZERO, screen_size가 직접 맞음 |
| 3 | first_3d_game / player_movement |
입력/이동은 비슷하지만 3D 문맥이고 AnimatedSprite2D/screen_size가 없음 |
5단계: Qwen direct-evidence validator
Qwen validator에는 다음처럼 묻는다.
SOURCE_CODE와 retrieved JSONL을 보고,
JSONL 안에 SOURCE_CODE와 직접 맞는 문자열/API 호출/패턴 근거가 있는가?
예 또는 아니오로 먼저 판정하라.예상 결과:
first_2d_game / coding_the_player:
validator = 예
direct evidence = Input.is_action_pressed, AnimatedSprite2D.play, AnimatedSprite2D.stop
first_2d_game / clamp/screen bounds:
validator = 예
direct evidence = position.clamp, Vector2.ZERO, screen_size
first_3d_game / player_movement:
validator = 아니오 또는 낮은 관련
reason = movement input은 비슷하지만 3D 문서이며 AnimatedSprite2D/screen_size 직접 근거가 없음PoC에서 확인할 로그
이 대안은 단계가 많으므로 다음을 한 화면에서 봐야 한다.
1. raw chunkText
2. BM25 후보와 matched terms
3. embedding 후보와 similarity
4. union 결과
5. reranker 점수와 순위 변화
6. Qwen validator 예/아니오
7. 최종 accept/reject JSONL눈에 보이는 결론:
BM25와 embedding은 후보를 넓게 모은다.
reranker는 비슷한 후보의 순서를 바로잡는다.
Qwen validator는 직접근거 없는 JSONL을 최종 폐기한다.장점
- 품질이 가장 좋을 가능성이 높다.
- BM25 false positive를 줄일 수 있다.
- embedding false positive도 줄일 수 있다.
- raw chunk 조건을 유지한다.
- 하드코딩 의존이 낮다.
- Qwen validator로 직접근거 없는 JSONL을 마지막에 제거할 수 있다.
단점
- 비용이 든다.
- latency가 생긴다.
- 후보를 너무 많이 넣으면 느리다.
- reranker도 근거 검증기는 아니므로 마지막 validator가 필요하다.
판정
품질 최우선 최종 추천안원문 메모의 최종 추천은 이 구조에 가깝다.