26차시. Verifier Node 설계
실습 1 — Verifier Node 설계 실습 따라 하기
관련 수업 자료: 26차시 「7. 실습 ③ — 단독 테스트」(15~16쪽) · 실습 코드 26/verifier.py
이 실습은 교안 해설(26_VerifierNode이해.md)의 실습 순서를 옮긴 것입니다. OpenAI 임베딩이나 채팅 모델을 부르는 파일은 .env 에 API 키가 있어야 돌아갑니다. 키가 없으면 실행 결과 샘플로 출력 모양을 확인합니다.
수업 자료와 이어지는 곳
| 실습 코드 | 원본 PDF | 이어지는 내용 |
|---|---|---|
26/verifier.py | 15~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 만 바꿉니다. 복사하지 않으면 앞 케이스의 값이 다음 케이스에 남습니다. 여기서 많이들 헷갈리십니다.