RAG2026-5일26차시 · Verifier Node 설계15 / 19← 이전목차다음 →MetaContents

26차시. Verifier Node 설계

실습 1 — Verifier Node 설계 실습 따라 하기

관련 수업 자료: 26차시 「7. 실습 ③ — 단독 테스트」(15~16쪽) · 실습 코드 26/verifier.py

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

수업 자료와 이어지는 곳

실습 코드원본 PDF이어지는 내용
26/verifier.py15~16쪽26차시 「7. 실습 ③ — 단독 테스트」 아래에 실었습니다

실행 흐름

출력
answer와 근거 → 규칙 검사
규칙 검사 → retry  (실패)
규칙 검사 → LLM 심판 JSON  (통과)
LLM 심판 JSON → pass retry research giveup

실습 순서

verifier.py에서 규칙 단계와 LLM 단계를 주석으로 구분합니다. JSON 파싱이 실패하면 어떤 기본 판정을 쓰는지 확인합니다. 그 기본값이 무한 재시도를 만들지 않는지 봅니다.

스스로 확인

  • 형식 통과와 내용 통과가 다른 이유를 예를 드는가?
  • Verifier가 답을 수정하지 않는 이유를 아는가?
  • 2단 검사가 호출 횟수를 줄이는 이유를 말하는가?

코드 설명

  • re.search(r"\{.*\}", raw_text, re.S) 는 모델 응답에서 첫 { 부터 마지막 } 까지를 찾습니다. re.S 를 주어야 . 이 줄바꿈까지 넘어가서 여러 줄 JSON도 잡힙니다. 모델이 "판정 결과는 다음과 같습니다" 같은 말을 앞에 붙여도 json.loads 가 깨지지 않는 이유입니다.
  • 1차 검사의 순서는 gen_error → insufficient → has_citation → 길이입니다. 생성 오류는 다시 써도 안 되니 giveup, 근거 부족 신고는 검색 문제이니 research, 인용 불량과 짧은 답은 쓰기 문제이니 retry 입니다. 여기서 걸리면 judge_chain.invoke 까지 가지 않습니다.
  • bool(judge_result.get("grounded")) 처럼 get 으로 읽습니다. 심판이 키를 빼먹어도 KeyError 없이 False 가 됩니다. judge_result["grounded"] 로 쓰면 「9. 자주 겪는 문제」의 KeyError 가 그대로 납니다.
  • except Exception as error: 에서 grade 를 pass 로 돌려줍니다. 검증을 못 했다고 사용자가 답을 못 받으면 안 되기 때문입니다. 대신 log 에 오류 이름을 남겨 둡니다. 심판 실패가 잦으면 프롬프트를 고칠 신호입니다.
  • LLM 판정에서 grounded 가 False 면 retry, grounded 는 True 인데 relevant 가 False 면 research 입니다. 둘 다 False 일 때는 elif not grounded 가 먼저 걸려 retry 가 됩니다. 조건 순서가 판정을 정한다는 점을 눈여겨보십시오.
  • state.update(retrieval_result) 로 검색 결과를 State 에 합친 뒤, 테스트마다 dict(state) 로 복사해서 answer 만 바꿉니다. 복사하지 않으면 앞 케이스의 값이 다음 케이스에 남습니다. 여기서 많이들 헷갈리십니다.
← 이전 절26차시 · 체크리스트와 과제다음 절 →26차시 · 퀴즈 1 — 인용 실패·짧은 답은 심판 없이 retry