SK플래닛 ai활용 데이터엔지니어 과정 2기/ML & DL

LangGraph 1 - 상태 그래프 기초

dev-lee 2026. 6. 2. 12:40

1. LangGraph 개요

LLM 워크플로우를 "상태를 공유하는 노드들의 그래프"로 표현하는 프레임워크임.

LangChain이 호출을 직선으로 잇는 체인 구조라면, LangGraph는 노드를 자유롭게 연결하고 조건·순환까지 표현할 수 있는 그래프 구조다. 첫 단계에서는 가장 단순한 형태인 단방향 그래프부터 시작함.

1.1 핵심 3요소

  • State(상태) — 모든 노드가 공유하는 전역 메모리. 데이터를 담는 그릇 역할을 함.
  • Node(노드) — 작은 단위의 Task. 단순한 함수 하나로 구성됨.
  • Edge(엣지) — 노드 간 실행 순서(방향성)를 지정하는 연결선임.

노드는 "무엇을 할지", 엣지는 "어떤 순서로 흐를지"를 담당한다고 보면 된다.


2. 상태 정의

공유 메모리의 형태를 `TypedDict`로 규정함.

상태는 그래프 전체를 흐르는 데이터의 형태다. 어떤 키를 가질지 미리 정의해 두면 모든 노드가 같은 구조를 참조할 수 있음.

from langgraph.graph import StateGraph, END
from typing import TypedDict   # 공유 메모리의 형태를 규정할 때 활용

# 상태 정의: 데이터를 저장할 그릇이자 공유 메모리. 모든 노드에서 접근 가능
class CustomState(TypedDict):
    msg: str
`msg`라는 문자열 키 하나만 가진 단순한 상태이다.

3. 노드 구성

특정 목적을 가진 작은 함수가 곧 노드가 됨.

노드는 상태를 입력받아 일부를 가공해 다시 상태 형태로 반환하는 함수다. 여기서는 문자열 앞뒤에 텍스트를 덧붙이는 두 노드를 만듦.

# 노드는 단순한 함수로 구성됨
def add_prefix(state: CustomState):
    '''
    기존 상태값 앞에 특정 내용을 추가
    parameters:
        - state : 공유 메모리(전역 상태). 랭그래프가 관리하는 상태
    '''
    return {'msg': "하이 " + state['msg']}

def add_suffix(state: CustomState):
    # 기존 상태값 뒤에 특정 내용을 추가
    return {'msg': state['msg'] + " !!"}
각 노드는 변경된 부분만 dict로 반환하면, 랭그래프가 상태에 병합해 다음 노드로 넘김.

4. 그래프 연결과 컴파일

노드를 등록하고 시작점·방향·끝점을 지정한 뒤 실행 가능한 형태로 컴파일함.

노드를 추가한 직후의 그래프는 시작과 끝을 모르는 "원형(circle)" 상태다. 엣지를 걸어줘야 비로소 방향이 생김.

# 4-1. 그래프를 연결할 타겟(구조적 틀) — CustomState 기반 공유 메모리로 구성
workflow = StateGraph(CustomState)

# 4-2. 노드(task/tool/agent) 추가 — 아직 시작·끝을 모르는 상태
workflow.add_node("T1", add_prefix)
workflow.add_node("T2", add_suffix)

# 4-3. 시작점 설정 — 그래프 호출 시 이 노드가 먼저 호출됨(상태값을 전달받아)
workflow.set_entry_point("T1")

# 4-4. 작업 순서(방향성) 지정 — T1 -> T2
workflow.add_edge('T1', 'T2')

# 4-5. 끝점 설정 — T2 수행이 끝나면 종료
workflow.add_edge("T2", END)

# 4-6. 컴파일 — 실행 가능한 형태로 완성
app = workflow.compile()

이 단계의 구성 요소를 정리하면 다음과 같음.

메서드  역할
StateGraph(State) 상태 기반 그래프의 골격 생성
add_node(name, fn) 노드(함수) 등록
set_entry_point(name) 시작 노드 지정
add_edge(a, b) a → b 단방향 연결
add_edge(b, END) 종료 지점 연결
compile() 실행 가능한 앱으로 변환

5. 실행

데이터를 주입하면 그래프를 순환하며 요청을 처리함.

상태 형태에 맞춰 데이터를 넣고 invoke로 호출하면 데이터 → T1 → T2 → END 순으로 흐름.

# 데이터 주입 -> 그래프 호출 -> 데이터 -> 노드 -> 노드 -> END
res = app.invoke({"msg": "랭그래프"})
print(res)
{'msg': '하이 랭그래프 !!'}
`add_prefix`가 "하이 "를 붙이고, `add_suffix`가 " !!"를 붙인 결과가 그대로 누적됨.

아직은 흐름이 코드에 고정되어 있어 분기·반복이 없다. 다음 단계에서 LLM이 직접 경로를 판단하게 만든다.


요약

LangGraph의 최소 단위인 State·Node·Edge를 조립해 단방향 그래프를 만들고 실행했음.
개념  이번 글에서의 구현
State TypedDict로 msg 키 하나 정의
Node 접두/접미 추가 함수 2개
Edge T1 → T2 → END 고정 단방향
흐름 제어 없음(코드에 고정)

지금 그래프는 "정해진 길만 가는" 구조다. 이후 조건부 엣지·도구·기억을 더해가며 점점 자율적인 에이전트로 발전시킨다.