32차시. 고도화된 Modular RAG
4. 실습 ③ — 경로 커버리지 테스트
출처: 원본 PDF 32차시_ModularRAG종합.pdf 8~9쪽 · 쪽 그림 8쪽 9쪽
모든 경로가 최소 한 번씩 실행되는지 확인합니다. 통합 테스트의 핵심입니다.
📝 src/test_coverage.py
from graph import app
from state import init_state
from collections import Counter
CASES = [
("안녕하세요", "greeting 경로"),
("120 * 3 + 45", "calc 경로"),
("오늘 날씨 어때요?", "scope 경로"),
("환불은 며칠 이내인가요?", "정상 RAG 경로"),
("반품하고 싶은데 언제까지?", "재검색 경로"),
("환불 방법과 수수료는?", "재생성 경로"),
("대표이사가 누구인가요?", "fallback 경로"),
]
visited = Counter()
for q, desc in CASES:
nodes = []
for step in app.stream(init_state(q), {"recursion_limit": 40}):
for n in step.keys():
nodes.append(n)
visited[n] += 1
print(f"\n[{desc}]")
print(f" Q: {q}")
print(f" 경로: {' -> '.join(nodes)}")
print(f"\n{'='*55}")
print("노드별 방문 횟수")
ALL_NODES = ["classify", "greeting", "calc", "scope", "retrieve",
"generate", "verify", "bump", "rewrite", "fallback"]
for n in ALL_NODES:
mark = "✓" if visited[n] > 0 else "✗ 미방문!"
print(f" {n:<10} {visited[n]:>3}회 {mark}")
실행 결과
═════════════════════════════════════════════
══════════
[greeting 경로]
경로: classify -> greeting
[calc 경로]
경로: classify -> calc
[정상 RAG 경로]
경로: classify -> retrieve -> generate -> verify
[재검색 경로]
경로: classify -> retrieve -> rewrite -> retrieve
-> generate -> verify
[재생성 경로]
경로: classify -> retrieve -> generate -> verify
-> bump -> generate -> verify
[fallback 경로]
경로: classify -> retrieve -> rewrite -> retrieve
-> rewrite -> retrieve -> fallback
═════════════════════════════════════════════
══════════
노드별 방문 횟수
classify 7회 ✓
greeting 1회 ✓
calc 1회 ✓
scope 1회 ✓
retrieve 9회 ✓
generate 5회 ✓
verify 5회 ✓
bump 1회 ✓
rewrite 3회 ✓
fallback 1회 ✓💡 미방문 노드가 있다면
그 노드로 가는 경로가 실제로는 도달 불가능하거나
테스트 케이스가 부족한 것입니다.
어느 쪽인지 확인하세요.
도달 불가능한 노드는 죽은 코드입니다.