Skip to main content

LangGraph 기초

LangGraph는 그래프 기반으로 Agent와 Workflow를 구축하는 프레임워크입니다. 상태(State)를 중심으로 노드(Node)와 엣지(Edge)를 연결하여 복잡한 AI 시스템을 구성합니다.

설치

pip install langgraph

StateGraph 구조

기본 구조

from typing import TypedDict, Annotated, Sequence
from langchain_core.messages import BaseMessage, HumanMessage
from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import add_messages

# 1. 상태 정의
class State(TypedDict):
    messages: Annotated[Sequence[BaseMessage], add_messages]

# 2. 노드 함수 정의
def chatbot(state: State) -> State:
    # state에서 메시지를 읽고 처리
    return {"messages": [("assistant", "안녕하세요!")]}

# 3. 그래프 구성
graph = StateGraph(State)
graph.add_node("chatbot", chatbot)
graph.add_edge(START, "chatbot")
graph.add_edge("chatbot", END)

# 4. 컴파일 및 실행
app = graph.compile()
result = app.invoke({"messages": [HumanMessage(content="안녕")]})
print(result["messages"][-1].content)

add_messages 리듀서

add_messages는 메시지 리스트를 추가(append) 방식으로 업데이트합니다.
from langgraph.graph.message import add_messages

# 기존 메시지에 새 메시지가 추가됨
# state["messages"] = [기존 메시지들] + [새 메시지들]
리듀서동작사용
add_messages메시지 리스트에 추가대화 이력 관리
operator.add리스트 합산일반 리스트
없음 (기본)덮어쓰기단일 값

조건부 엣지

from langchain.chat_models import init_chat_model

llm = init_chat_model("gpt-4o-mini", temperature=0)

def router(state: State) -> str:
    """마지막 메시지를 분석하여 다음 노드를 결정"""
    last_message = state["messages"][-1]
    if "검색" in last_message.content:
        return "search"
    return "respond"

graph = StateGraph(State)
graph.add_node("analyze", analyze_node)
graph.add_node("search", search_node)
graph.add_node("respond", respond_node)

graph.add_edge(START, "analyze")
graph.add_conditional_edges("analyze", router, {
    "search": "search",
    "respond": "respond",
})
graph.add_edge("search", "respond")
graph.add_edge("respond", END)

app = graph.compile()

init_chat_model 패턴

LangGraph에서는 init_chat_model()을 사용하여 다양한 LLM 프로바이더를 통일된 인터페이스로 사용합니다.
from langchain.chat_models import init_chat_model

# OpenAI
llm = init_chat_model("gpt-4o", model_provider="openai")

# Anthropic
llm = init_chat_model("claude-sonnet-4-20250514", model_provider="anthropic")

# Ollama (로컬)
llm = init_chat_model("llama3.1", model_provider="ollama")
파라미터설명예시
model모델 이름"gpt-4o", "claude-sonnet-4-20250514"
model_provider프로바이더"openai", "anthropic", "ollama"
temperature생성 온도0 (결정적), 0.7 (창의적)

Quickstart: 챗봇 예제

LLM을 사용하는 가장 기본적인 챗봇입니다.
from typing import TypedDict, Annotated, Sequence
from langchain.chat_models import init_chat_model
from langchain_core.messages import BaseMessage, HumanMessage, SystemMessage
from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import add_messages

# 상태 정의
class State(TypedDict):
    messages: Annotated[Sequence[BaseMessage], add_messages]

# LLM 초기화
llm = init_chat_model("gpt-4o-mini", temperature=0)

SYSTEM_PROMPT = "당신은 친절한 AI 어시스턴트입니다."

# 챗봇 노드
def chatbot(state: State) -> State:
    messages = [SystemMessage(content=SYSTEM_PROMPT)] + state["messages"]
    response = llm.invoke(messages)
    return {"messages": [response]}

# 그래프 구성
graph = StateGraph(State)
graph.add_node("chatbot", chatbot)
graph.add_edge(START, "chatbot")
graph.add_edge("chatbot", END)

app = graph.compile()

# 실행
result = app.invoke({
    "messages": [HumanMessage(content="LangGraph가 뭐야?")]
})
print(result["messages"][-1].content)

Graph API vs Functional API

LangGraph는 두 가지 API 스타일을 제공합니다.
노드와 엣지를 명시적으로 정의하는 방식입니다. 복잡한 워크플로우에 적합합니다.
from langgraph.graph import StateGraph, START, END

graph = StateGraph(State)
graph.add_node("step1", step1_fn)
graph.add_node("step2", step2_fn)
graph.add_edge(START, "step1")
graph.add_edge("step1", "step2")
graph.add_edge("step2", END)
app = graph.compile()
항목Graph APIFunctional API
스타일선언적 (노드/엣지)함수형 (데코레이터)
복잡한 흐름우수제한적
시각화자동 그래프 시각화제한적
학습 곡선보통낮음
적합한 경우Agent, 복잡한 워크플로우단순 파이프라인
시작 추천: Graph API로 시작하세요. LangGraph의 핵심 개념(State, Node, Edge)을 이해하면 복잡한 Agent도 쉽게 구축할 수 있습니다.