직선 흐름만으로는 에이전트를 만들 수 없다. 조건부 엣지는 노드 실행 후 라우팅 함수를 호출해, 그 반환값(다음 노드 이름)에 따라 경로를 분기한다. 같은 노드로 되돌아가는 엣지를 만들면 순환(loop)이 되어, "판단 → 행동 → 재판단"을 반복하는 에이전트의 뼈대가 완성된다.
이 강의 목표는 add_conditional_edges로 분기와 루프를 만드는 것이다.
1. 라우팅 함수
라우팅 함수는 State를 보고 다음 노드의 이름(문자열)을 반환한다. 반환값이 곧 목적지다.
from typing import Literal
from langgraph.graph import END
def route(state) -> Literal["tools", "__end__"]:
last = state["messages"][-1]
if getattr(last, "tool_calls", None): # 도구 호출이 있으면
return "tools"
return END # 없으면 종료
2. 조건부 엣지 연결
g.add_conditional_edges("chat", route) # chat 이후 route 로 분기
g.add_edge("tools", "chat") # 도구 후 다시 chat → 순환(loop)
chat 노드가 끝나면 route가 실행돼 tools로 갈지 END로 갈지 정한다. tools → chat 엣지가 루프를 만든다.
3. 매핑으로 이름 바꾸기
라우팅 함수 반환값과 실제 노드 이름을 다르게 쓰려면 매핑 dict를 준다.
g.add_conditional_edges("chat", route,
{"tools": "run_tools", END: END})
핵심 명령·용어
| 이름 | 뜻 |
|---|---|
add_conditional_edges |
조건부 분기 엣지 |
| 라우팅 함수 | State→다음 노드 이름 |
Literal[...] |
반환 가능한 목적지 힌트 |
| 순환(loop) | 노드로 되돌아가는 엣지 |
예제
# 재시도 루프: 검증 실패 시 다시 생성
def check(state) -> Literal["generate", "__end__"]:
return "generate" if not state["ok"] else END
g.add_node("generate", generate)
g.add_node("validate", validate)
g.add_edge("generate", "validate")
g.add_conditional_edges("validate", check) # 실패 → generate 로 루프
해설) 조건부 엣지 하나로 재시도·라우팅·종료를 모두 표현한다. 단, 무한 루프를 막으려면 app.invoke(inp, {"recursion_limit": 25})처럼 한계를 둔다.
댓글 0
댓글은 운영자만 작성할 수 있어요.