앞 편에서 LangGraph가 워크플로를 그래프(Node·Edge·State)로 표현한다는 것을 봤다. 이번엔 실제 코드로 아주 작은 워크플로를 직접 만든다. 예제는 간단한 카운터다. n을 1부터 시작해 1씩 늘리면서 매번 랜덤 소문자 하나를 만들고 값을 출력하다가, n이 13이 되면 멈춘다. 이 과정에서 상태(State), 노드(Node), 엣지(Edge), 그리고 조건부 엣지(conditional edge)로 만드는 루프를 익힌다.
1. State — 그래프가 공유하는 메모리
State는 그래프의 모든 입력·중간값·출력을 담는 공유 데이터 구조다. 보통 TypedDict로 타입을 명시해 정의한다. 여기서는 정수 n과 문자열 letter 두 변수를 둔다.

2. Node — 상태를 처리하는 함수
Node는 현재 상태를 받아 처리하는 함수다. 어떤 노드는 상태를 수정하고, 어떤 노드는 출력 같은 부수 효과(side effect)만 낸다. add 노드는 n을 1 늘리고 새 랜덤 문자를 넣은 상태를 돌려준다. 반환할 때 **state로 기존 값을 펼친 뒤 바뀐 키만 덮어쓴다.

노드가 상태 전체를 다시 반환해야 하는지, 바뀐 키만 반환하면 자동으로 병합되는지는 그래프 타입마다 규칙이 다르므로 문서를 확인하는 게 좋다.
3. 그래프 조립 — Node와 Edge 연결
먼저 StateGraph 객체를 만들고 노드를 추가한다. Edge는 노드 사이의 전이를 정의한다. add_edge("add", "print_out")는 "add가 끝나면 갱신된 상태가 print_out으로 넘어간다"는 뜻이다. set_entry_point로 시작 노드를 지정한다. (노드 이름은 함수 이름과 달라도 된다 — 이름은 식별자일 뿐이다.)

4. 조건부 엣지 — 상태를 보고 분기·루프
일반 엣지가 고정된 경로라면, 조건부 엣지(conditional edge)는 현재 상태를 평가하는 함수로 다음 노드를 동적으로 결정한다. 여기서 stop_condition은 n >= 13인지 보고 결과 문자열을 돌려준다. add_conditional_edges는 그 반환값을 목적지 노드에 매핑한다. "continue"면 add로 돌아가 루프를 돌고, "end"면 END로 가서 워크플로가 끝난다.

이 매핑 딕셔너리 대신, 조건 함수가 다음 노드 이름을 직접 반환하도록 설계할 수도 있다. 둘은 서로 바꿔 쓸 수 있다.

5. 컴파일과 실행
모든 노드를 연결했으면 compile()로 실행 가능한 앱을 만든다. invoke에 초기 상태를 넘기면 워크플로가 돈다. 상태는 add → print_out → stop_condition 순서로 그래프를 따라 흐르고, 조건이 참이 될 때까지 add로 되돌아가는 루프를 반복한다. 완료되면 최종 상태가 result에 담긴다.

실행 흐름을 정리하면 이렇다. 초기 상태가 add로 들어가 n이 증가하고 문자가 생성된다. 갱신된 상태가 print_out으로 넘어가 값이 출력된다. 이어 stop_condition이 n >= 13인지 확인한다. 거짓이면 다시 add로, 참이면 END로 간다. 그래프를 시각화하면 이 실행 경로와 상태 진행을 한눈에 이해할 수 있다.

다음 글에서는 여기서 만든 그래프에 추론과 행동을 결합한다. LLM이 생각하고(Reason) 도구를 쓰고(Act) 결과를 관찰하며 루프를 도는 ReAct 패턴을 다룬다.
'AI > Agent' 카테고리의 다른 글
| Reflexion: 도구와 인용으로 스스로 검증하는 에이전트 (0) | 2026.07.01 |
|---|---|
| Reflection: 스스로 비평하고 고치는 에이전트 (0) | 2026.07.01 |
| ReAct: 추론과 행동을 결합한 에이전트 (0) | 2026.07.01 |
| LangChain, LangGraph (0) | 2026.07.01 |
| Generative AI vs Agentic AI (0) | 2026.07.01 |