26차시. Verifier Node 설계
퀴즈 1 — 인용 실패·짧은 답은 심판 없이 retry
인용 실패나 너무 짧은 답은 LLM 없이 retry를 반환하세요. 아니면 judge를 호출합니다.
빈칸 코드에서 시작합니다.
def verify(answer, has_citation, judge):
pass결과 보기 (예시 풀이)
# 1차 규칙 검사를 통과한 답만 judge(LLM 심판 자리)에 넘깁니다.
def verify(answer, has_citation, judge):
# 인용이 없거나 10자 미만이면 심판을 부르지 않고 바로 retry 입니다.
# 규칙으로 거를 수 있는 것은 돈이 드는 호출 전에 거릅니다.
if not has_citation or len(answer) < 10:
return {"grade": "retry"}
# 규칙을 통과했을 때만 심판에게 판정을 맡깁니다.
return judge(answer)
# 진짜 LLM 대신 쓰는 가짜 심판입니다. 몇 번 불렸는지 세어 둡니다.
judge_calls = []
def fake_judge(answer):
judge_calls.append(answer)
# 근거에 없는 '수수료' 이야기가 있으면 grounded=False 로 봅니다.
if "수수료" in answer:
return {"grade": "retry", "reason": "수수료는 근거에 없음"}
return {"grade": "pass", "reason": "근거와 질문에 모두 맞음"}
# 1) 인용이 없는 답: 심판을 부르지 않아야 합니다.
print(verify("환불은 7일 이내에 신청하시면 됩니다.", False, fake_judge))
# 2) 너무 짧은 답: 역시 심판을 부르지 않아야 합니다.
print(verify("7일[1]", True, fake_judge))
# 3) 규칙은 통과하지만 환각이 섞인 답: 심판이 잡아내야 합니다.
print(verify("환불은 7일 이내입니다[1]. 수수료는 10%입니다[1].", True, fake_judge))
# 4) 정상 답: 심판이 pass 를 줍니다.
print(verify("환불은 상품 수령 후 7일 이내에 신청하실 수 있습니다[1].", True, fake_judge))
# 심판 호출은 3), 4) 두 번뿐이어야 합니다.
print("심판 호출 횟수:", len(judge_calls))
실행 결과
{'grade': 'retry'}
{'grade': 'retry'}
{'grade': 'retry', 'reason': '수수료는 근거에 없음'}
{'grade': 'pass', 'reason': '근거와 질문에 모두 맞음'}
심판 호출 횟수: 2채점 기준: 짧은 답이나 인용 실패에서 judge를 호출하면 오답이다.
관련 교안: 26차시 「3. 검증 방식 비교 — 비용과 정확도」 › 3-1) 2단 검증 — 비용을 아끼는 구조