31차시. 예외 처리 설계
3. Fallback 계층화
출처: 원본 PDF 31차시_방어적코딩실습.pdf 7쪽 · 쪽 그림 7쪽
지금까지 fallback은 하나였습니다. 상황별로 나눕니다.
3-1) 상황별 안내 문구
📝 src/nodes/fallback.py
import config
MESSAGES = {
# 검색은 됐지만 관련 자료가 없음
"no_match": (
"'{q}'에 대한 내용을 제공된 자료에서 찾지 못했습니다.\n"
"· 질문을 조금 다르게 표현해보시거나\n"
"· 문서에 포함된 주제인지 확인해주세요."
),
# 재작성까지 했는데도 못 찾음
"exhausted": (
"'{q}'에 대해 여러 방식으로 검색했지만 "
"관련 자료를 찾지 못했습니다.\n"
"해당 내용이 문서에 없을 가능성이 높습니다.\n"
"담당 부서에 직접 문의해주세요."
),
# 시스템 오류
"system_error": (
"일시적인 시스템 오류가 발생했습니다.\n"
"잠시 후 다시 시도해주세요.\n"
"문제가 계속되면 관리자에게 문의해주세요."
),
# API 한도 초과
"rate_limit": (
"현재 요청이 많아 처리가 지연되고 있습니다.\n"
"잠시 후 다시 시도해주세요."
),
# 검증 실패했지만 답변은 있음
"unverified": None, # 답변을 그대로 쓰고 경고만 붙임
}
def _pick_reason(state) -> str:
if state.get("gen_error") or state.get("fail_reason") == "search_error":
return "system_error"
if state.get("rewrites", 0) >= getattr(config, "MAX_REWRITE", 2):
return "exhausted"
if state.get("answer") and state.get("grade") != "pass":
return "unverified"
return "no_match"
def fallback_node(state) -> dict:
kind = _pick_reason(state)
q = state.get("question", "")
# 검증만 실패한 경우 - 기존 답변을 살린다
if kind == "unverified":
return {
"answer": state["answer"],
"verified": False,
"grade": "unverified",
"log": ["fallback: 미검증 답변 제공"],
}
return {
"answer": MESSAGES[kind].format(q=q[:40]),
"verified": False,
"grade": "giveup",
"fallback_kind": kind,
"log": [f"fallback: {kind}"],
}