RAG2026-5일20차시 · Edge 이해14 / 18← 이전목차다음 →MetaContents

20차시. Edge 이해

실습 1 — Edge 이해 실습 따라 하기

관련 수업 자료: 20차시 「4. 실습 ① — 19차시 if문을 Edge로 옮기기」(8~9쪽), 20차시 「7. 실습 ③ — 무한루프 체험하기」(14쪽) · 실습 코드 20/routes.py, 20/graph_v1.py, 20/graph_v2.py, 20/graph_v3.py, 20/loop.py

이 실습은 교안 해설(20_Edge이해.md)의 실습 순서를 옮긴 것입니다. OpenAI 임베딩이나 채팅 모델을 부르는 파일은 .env 에 API 키가 있어야 돌아갑니다. 키가 없으면 실행 결과 샘플로 출력 모양을 확인합니다.

수업 자료와 이어지는 곳

실행 흐름

출력
START → retrieve
retrieve → route after retrieve
route after retrieve → generate  (ok)
route after retrieve → fallback  (empty)
generate → END
fallback → END

실습 순서

python loop.py를 실행해 반복이 멈추는 지점을 봅니다. routes.py를 읽고 반환 문자열이 graph_v1.py의 경로 맵 키와 같은지 확인합니다. 코드를 짜기 전에 출발 노드, 조건, 경로 이름, 도착 노드를 표로 적는 습관을 오늘 만듭니다.

스스로 확인

  • 분기 함수가 State를 바꾸면 안 되는 이유를 아는가?
  • 상한 검사를 맨 위에 두는 이유를 말할 수 있는가?
  • if를 Edge로 옮기면 그림으로 그릴 수 있다는 점을 아는가?

코드 설명

  • routes.py 의 route_after_retrieve 는 state.get("retrieval_ok") 로 읽습니다. 대괄호로 읽으면 키가 없을 때 KeyError가 나지만, get 은 None 을 주어 "empty" 쪽으로 갑니다. 규칙 ③ "모든 경우에 갈 곳이 있다"를 지키는 한 줄입니다.
  • graph_v1.py 와 graph_v2.py 는 compile() 까지만 하고 invoke 하지 않습니다. 질문을 실제로 흘려 보는 파일은 graph_v3.py 입니다. 세 파일 모두 import 할 때 19차시 retrieve.py 가 인덱스를 읽으므로 API 키가 필요합니다.
  • sys.path.insert(0, os.path.join(CURRENT_DIR, "..", "18")) 는 18차시와 19차시 폴더의 graph_state, retrieve 같은 파일을 import 하려고 경로를 더하는 줄입니다. 폴더를 옮기면 여기서 ModuleNotFoundError 가 납니다.
  • graph_v2.py 의 draw_ascii() 는 연결을 글자 상자로 찍고, draw_mermaid_png() 는 그림 바이트를 만들어 graph.png 로 저장합니다. 빠진 연결이나 END 로 못 가는 노드를 찾는 데 씁니다.
  • graph_v3.py 의 run() 은 log 를 직접 합치지 않습니다. RAGState 의 log 에 reducer 가 붙어 있어 retrieve 와 generate(또는 fallback) 의 한 줄이 자동으로 이어 붙습니다. 19차시 manual_flow 의 new_log 처리와 견주어 보세요.
  • loop.py 는 add_edge("step", "step") 로 자기 자신에게 돌아가고 END 가 없습니다. {"recursion_limit": 10} 에 걸려 10회차까지 찍힌 뒤 GraphRecursionError 가 except 로 잡힙니다.
← 이전 절20차시 · 체크리스트와 과제다음 절 →20차시 · 퀴즈 1 — 상한을 먼저 보는 재시도 분기