28차시. Conditional Edge 이해
2. 분기 함수의 4가지 규칙
출처: 원본 PDF 28차시_ConditionalEdge이해.pdf 5~7쪽 · 쪽 그림 5쪽 6쪽 7쪽
이 규칙을 지키면 라우팅 버그가 거의 사라집니다.
2-1) 규칙 ① — State만 보고 판단한다
❌ 외부 상태나 랜덤에 의존
──────────────────────────────────────
import random
def bad_route(state):
if random.random() > 0.5: # 재현 불가!
return "a"
return "b"
def bad_route2(state):
if datetime.now().hour > 18: # 시간에 따라 달라짐
return "night"
return "day"✅ State만 사용
──────────────────────────────────────
def good_route(state) -> str:
return "ok" if state.get("retrieval_ok") else "empty"
→ 같은 State면 항상 같은 경로
→ 테스트와 재현이 가능합니다💡 시간이나 랜덤이 필요하다면?
노드에서 값을 계산해 State에 넣고,
분기 함수는 그 값을 읽기만 합니다.
노드: {"is_night": datetime.now().hour > 18}
분기: return "night" if state["is_night"] else "day"
이러면 테스트할 때 is_night를 직접 넣어 검증할 수 있습니다.
2-2) 규칙 ② — 부수 효과 금지
❌ State를 수정
──────────────────────────────────────
def bad_route(state):
state["retries"] += 1 # 금지!
return "retry"
→ LangGraph가 이 변경을 인식하지 못합니다
→ 병렬 실행 시 충돌합니다
→ 언제 몇 번 호출됐는지 보장되지 않습니다✅ 판단만 하고, 변경은 노드가
──────────────────────────────────────
def good_route(state) -> str:
return "retry" # 판단만
def bump_node(state): # 변경은 노드가
return {"retries": state.get("retries", 0) + 1}2-3) 규칙 ③ — 모든 경우를 처리한다
출처: 원본 PDF 7쪽
❌ 빠져나갈 구멍이 없음
──────────────────────────────────────
def bad_route(state):
if state["grade"] == "pass":
return "done"
if state["grade"] == "retry":
return "again"
# grade가 "research"면? → None 반환 → 에러!✅ 마지막은 조건 없이
──────────────────────────────────────
def good_route(state) -> str:
grade = state.get("grade", "retry") # 기본값
if grade == "pass":
return "done"
if grade == "giveup":
return "giveup"
return "regenerate" # 그 외 전부2-4) 규칙 ④ — 반환값 = 경로맵의 키
출처: 원본 PDF 7쪽
def route(state) -> str:
return "ok" # ← 이 문자열이
g.add_conditional_edges("retrieve", route, {
"ok": "generate", # ← 여기 키와 정확히 같아야 함
"empty": "fallback",
})⚠️ 가장 흔한 에러
분기 함수는 "OK"를 반환하는데
경로맵의 키는 "ok"인 경우.
대소문자 하나에 런타임 에러가 납니다.
예방법 — 경로 이름을 상수로 정의하세요.
OK, EMPTY = "ok", "empty"
def route(state): return OK if ... else EMPTY
g.add_conditional_edges(..., {OK: "generate", EMPTY: "fallback"})