RAG2026-5일22차시 · RAG를 Graph로 바꾸기9 / 20← 이전목차다음 →MetaContents

22차시. RAG를 Graph로 바꾸기

6. 실습 ④ — 회귀 테스트

출처: 원본 PDF 22차시_RAG를Graph로바꾸기.pdf 10~11쪽 · 쪽 그림 10쪽 11쪽

가장 중요한 단계입니다. 1부 버전과 결과가 같아야 이식이 성공한 것입니다.

📝 src/test_migration.py

출력
import rag           # 15차시 함수 버전
import graph         # 22차시 그래프 버전

TESTS = [
    "환불은 며칠 이내에 신청해야 하나요?",
    "교환 기간은 얼마인가요?",
    "고객센터 운영 시간은?",
    "대표이사가 누구인가요?",       # 문서에 없는 질문
    "반품하고 싶은데 언제까지?",     # 표현 변경
    # ... 12차시 질문 세트 20개
]

same, diff = 0, []
for q in TESTS:
    a = rag.ask(q)["answer"]
    b = graph.ask(q)["answer"]

    if a.strip() == b.strip():
        same += 1
        print(f"✓ {q[:28]}")
    else:
        diff.append(q)
        print(f"✗ {q[:28]}")
        print(f"    [함수] {a[:60]}...")
        print(f"    [그래프] {b[:60]}...")

print(f"\n일치: {same}/{len(TESTS)}")
if diff:
    print("불일치 질문:", diff)

실행 결과
──────────────────────────────────────────
✓ 환불은 며칠 이내에 신청해야 하나요?
✓ 교환 기간은 얼마인가요?
✓ 고객센터 운영 시간은?
✓ 대표이사가 누구인가요?
✓ 반품하고 싶은데 언제까지?
...
일치: 20/20

⚠️ 결과가 다르다면 확인할 것
① query가 비어 있지 않은가
init_state에서 query = question 설정 확인
② config를 같은 값으로 읽고 있는가
TOP_K, MIN_SCORE, PROMPT_VER
③ 프롬프트 버전이 같은가
generate_node가 config.PROMPT_VER을 쓰는지
④ temperature가 0인가
0이 아니면 매번 답이 달라 비교가 무의미합니다
결과가 달라졌다면 옮기는 과정에서 뭔가 빠진 것입니다.

실습 코드 · 22/test_migration.py

실습 코드: 실습/src/22/test_migration.py · 위의 원본 PDF 22차시 10~11쪽 「6️⃣ 실습 ④ — 회귀 테스트」과 이어집니다.

Python
# ============================================================
# 22차시 | RAG를 Graph로 바꾸기
# 교안: 22차시_RAG를Graph로바꾸기.pptx
# 역할: 15차시 함수형 rag.ask 와 그래프형 graph22.ask 의 답변이 같은지 비교한다.
# 입력: TESTS 안의 질문 문자열
# 출력: 질문마다 ✓ 또는 ✗, 마지막에 일치 개수
#
#   이 파일은 그래프를 만들지 않는다. 두 ask() 를 불러 답변 문자열만 비교한다.
#   graph22 쪽 흐름 (rag_app 안의 그래프):
#   START → retrieve
#              ├─ generate → END
#              └─ fallback → END
# ============================================================

# 이 파일은 15차시의 일반 함수 방식과 22차시의 LangGraph 방식을 비교합니다.
# 같은 질문을 두 방식으로 실행한 뒤, 답변이 같은지 확인하는 회귀 테스트 파일입니다.

import os
import sys
import warnings
warnings.filterwarnings("ignore")

# ==================================================
# 다른 폴더의 모듈을 가져오기 위한 설정
# ==================================================

# 현재 test_migration.py 파일이 있는 폴더입니다.
CURRENT_DIR = os.path.dirname(__file__)

# rag.py와 graph.py가 있는 rag_app 폴더 경로입니다.
RAG_APP_DIR = os.path.join(CURRENT_DIR, "..", "rag_app")

# Python이 rag_app 폴더의 파일을 찾을 수 있도록 경로를 추가합니다.
sys.path.insert(0, RAG_APP_DIR)

# ==================================================
# 비교할 두 가지 RAG 모듈 가져오기
# ==================================================

# 15차시에서 만든 일반 함수 방식입니다.
import rag

# 22차시에서 만든 LangGraph 방식입니다.
import graph22

# ==================================================
# 테스트 질문 목록
# ==================================================
TESTS = [
    # 정상적인 문서 질문입니다.
    "환불은 며칠 이내에 신청해야 하나요?",

    # 문서에 있을 가능성이 있는 질문입니다.
    "교환 기간은 얼마인가요?",

    # 문서에 있을 가능성이 있는 질문입니다.
    "고객센터 운영 시간은?",

    # 문서에 없는 질문입니다.
    "대표이사가 누구인가요?",

    # 표현을 바꾼 질문입니다.
    "반품하고 싶은데 언제까지?",

    # 여기에 추가 테스트 질문을 작성할 수 있습니다.
]

# ==================================================
# 테스트 결과를 비교하는 함수
# ==================================================
def run_test(question):
    """
    하나의 질문을 두 방식으로 실행하고 결과를 비교합니다.
    """

    # 15차시 일반 함수 방식으로 답변을 생성합니다.
    function_result = rag.ask(question)

    # 22차시 LangGraph 방식으로 답변을 생성합니다.
    graph_result = graph22.ask(question)

    # 각 결과에서 답변만 꺼냅니다.
    function_answer = function_result["answer"]
    graph_answer = graph_result["answer"]

    # 답변 앞뒤의 공백을 제거합니다.
    function_answer = function_answer.strip()
    graph_answer = graph_answer.strip()

    # 두 답변이 같은지 비교합니다.
    if function_answer == graph_answer:
        return True, function_answer, graph_answer

    # 두 답변이 다르면 불일치 결과를 반환합니다.
    return False, function_answer, graph_answer

# ==================================================
# 전체 테스트 실행
# ==================================================
def main():
    """
    모든 테스트 질문을 실행하고 최종 결과를 출력합니다.
    """

    # 답변이 일치한 질문의 개수입니다.
    same_count = 0

    # 답변이 다른 질문을 저장할 리스트입니다.
    different_questions = []

    # 테스트 질문을 하나씩 꺼냅니다.
    for question in TESTS:
        # 현재 질문을 두 방식으로 비교합니다.
        is_same, function_answer, graph_answer = run_test(question)

        # 답변이 같은 경우입니다.
        if is_same:
            same_count += 1
            print("✓", question[:28])

        # 답변이 다른 경우입니다.
        else:
            different_questions.append(question)

            print("✗", question[:28])
            print("    [함수]  ", function_answer[:60], "...")
            print("    [그래프]", graph_answer[:60], "...")

    # 전체 테스트 결과를 출력합니다.
    print()
    print("일치:", same_count, "/", len(TESTS))

    # 불일치한 질문이 있으면 출력합니다.
    if different_questions:
        print("불일치 질문:")

        for question in different_questions:
            print("-", question)

# ==================================================
# 이 파일을 직접 실행했을 때 테스트 시작
# ==================================================
if __name__ == "__main__":
    main()

실행 결과 샘플 (교안 기록. API 키가 필요한 코드는 키 없이 맞춘 예시이고, 모델의 답은 실행할 때마다 달라집니다)

출력
===== 실행 결과 샘플 =====
실행: cd 실습/src/22
      python test_migration.py
예시 출력 (API 키 필요, 실행하지 않음)
(질문 앞 28자마다 ✓ 또는 ✗. 일치 건수는 기록 없음)
일치: (미기록) / 5
기록된 사실만: 환불 계열은 grade pass, rewrites 0, elapsed 6.69.
              대표이사는 grade giveup, rewrites 2, elapsed 3.41.
이 파일은 grade, rewrites, elapsed, 유사도 점수를 출력하지 않는다.
경로: retrieve → generate → END

코드 해설

15차시 함수형 rag.ask 와 그래프형 graph22.ask 의 답변이 같은지 비교한다. 입력은 TESTS 안의 질문 문자열이고, 출력은 질문마다 ✓ 또는 ✗, 마지막에 일치 개수입니다.

코드 앞에서 고정해 두는 말입니다.

  • 22차시 | RAG를 Graph로 바꾸기
  • 교안: 22차시_RAG를Graph로바꾸기.pptx
  • 이 파일은 그래프를 만들지 않는다. 두 ask() 를 불러 답변 문자열만 비교한다.
  • graph22 쪽 흐름 (rag_app 안의 그래프):
  • START → retrieve
  • ├─ generate → END
  • └─ fallback → END

함수와 클래스로 나누어 읽습니다.

  • run_test: 테스트 결과를 비교하는 함수
  • main: 전체 테스트 실행

파일 맨 아래 실행 결과 샘플 주석은 실행되지 않습니다. 화면 출력은 다음 절에 다시 적어 두었습니다.

← 이전 절22차시 · 5. 실습 ③ — 단계별로 붙이기다음 절 →22차시 · 7. 실습 ⑤ — 흐름 확인