coredot.today
LangGraph 완전 가이드: AI 에이전트를 위한 그래프 기반 오케스트레이션의 모든 것
블로그로 돌아가기
LangGraphAI 에이전트LangChain상태 머신워크플로

LangGraph 완전 가이드: AI 에이전트를 위한 그래프 기반 오케스트레이션의 모든 것

LLM 에이전트는 직선 파이프라인이 아니라 '생각하고, 행동하고, 관찰하고, 다시 생각하는' 루프다. LangGraph는 이 루프를 그래프 기반 상태 머신으로 구현한다. 핵심 개념부터 실전 패턴, Klarna·Uber의 프로덕션 사례, 커뮤니티 베스트 프랙티스까지 총정리한다.

코어닷투데이2026-03-1134

들어가며: 에이전트는 직선이 아니라 루프다

LangChain의 Chain은 직선 파이프라인이다. 프롬프트 → LLM → 출력 파서. A → B → C. 단순하고 예측 가능하다.

하지만 AI 에이전트는 이렇게 작동하지 않는다.

에이전트에게 "내일 서울 날씨를 확인하고, 비가 온다면 실내 데이트 코스를 추천해줘"라고 하면:

  1. 생각: "먼저 날씨를 확인해야 해" → 날씨 API 호출
  2. 관찰: "비가 온다" → 조건 분기
  3. 생각: "실내 장소를 검색해야 해" → 검색 도구 호출
  4. 관찰: "검색 결과가 부족하다" → 다시 검색 (루프!)
  5. 생각: "충분한 정보를 모았다" → 최종 답변 생성

분기, 루프, 조건부 실행 — Chain의 직선 구조로는 표현할 수 없다. 이것이 2024년 1월, LangChain 팀이 LangGraph를 만든 이유다.


1. LangGraph란 무엇인가

한 줄 정의

LangGraph는 장기 실행(long-running), 상태 유지(stateful) AI 에이전트를 위한 그래프 기반 오케스트레이션 프레임워크다.

핵심 차이를 비유로 표현하면:

  • LangChain Chain = 조립 라인. 부품이 한 방향으로 흘러간다.
  • LangGraph = 순서도(flowchart). 분기점에서 다른 경로로 가고, 필요하면 이전 단계로 돌아간다.
Chain : A B C
LangGraph : A 판단? B or C 다시?

왜 만들어졌는가

LangGraph를 설계한 팀은 LLM 에이전트의 세 가지 근본적 특성을 파악했다:

특성의미필요한 것
느리다LLM 호출에 수 초 소요병렬화, 스트리밍
불안정하다장시간 에이전트는 중간에 실패체크포인팅, 재시도
비결정적이다같은 입력에 다른 출력사람 개입, 추적

기존 도구로는 이 세 가지를 동시에 해결할 수 없었다. DAG 기반 워크플로(Apache Airflow)는 루프를 지원하지 않고, 내구성 실행 엔진(Temporal)은 스트리밍을 지원하지 않았다. LangGraph는 루프 + 체크포인팅 + 스트리밍을 모두 지원하는 에이전트 런타임으로 설계되었다.

내부적으로는 Bulk Synchronous Parallel(BSP)/Pregel 알고리즘 위에 구축되어, 결정론적 동시성과 완전한 루프 지원을 보장한다.

현재 상태 (2026년 3월)

  • 버전: v1.1.3 (2026.3.18)
  • v1.0 GA: 2025년 10월 (LangChain 1.0과 동시)
  • 월간 다운로드: LangChain 합산 9,000만+
  • 프로덕션 사용: Klarna, Uber, LinkedIn, J.P. Morgan, BlackRock, Elastic, Replit
  • 라이선스: MIT

2. 핵심 개념 5가지

① State (상태): 그래프를 관통하는 데이터

State는 그래프의 모든 노드가 공유하는 데이터 구조다. 질문, 중간 결과, 에러 카운트, 대화 기록 등이 담긴다.

hljs language-python
from typing import Annotated, TypedDict
from langgraph.graph.message import add_messages

class AgentState(TypedDict):
    messages: Annotated[list, add_messages]  # 대화 기록
    search_results: list[str]                # 검색 결과
    retry_count: int                         # 재시도 횟수

Annotated[list, add_messages]가 핵심이다. add_messages리듀서(reducer) — 노드가 반환한 부분 업데이트를 기존 상태에 어떻게 병합할지 정의한다. add_messages는 새 메시지를 기존 목록에 추가하고, 같은 ID의 메시지는 덮어쓴다.

핵심 원칙: 노드는 전체 상태가 아니라 변경할 부분만 반환한다. LangGraph가 리듀서를 통해 자동으로 병합한다.

② Node (노드): 실제 작업을 수행하는 함수

Node는 현재 상태를 받아 작업을 수행하고, 상태 업데이트를 반환하는 Python 함수다.

hljs language-python
def search_node(state: AgentState):
    """관련 문서를 검색하는 노드"""
    query = state["messages"][-1].content
    results = search_engine.search(query)
    return {"search_results": results}

def generate_node(state: AgentState):
    """검색 결과를 바탕으로 답변을 생성하는 노드"""
    context = "\n".join(state["search_results"])
    response = llm.invoke(
        f"컨텍스트: {context}\n질문: {state['messages'][-1].content}"
    )
    return {"messages": [response]}

③ Edge (엣지): 노드 간 이동 경로

일반 엣지는 무조건적 이동, 조건부 엣지는 상태에 따라 다음 노드를 결정한다.

hljs language-python
from langgraph.graph import StateGraph, START, END

builder = StateGraph(AgentState)
builder.add_node("search", search_node)
builder.add_node("generate", generate_node)
builder.add_node("evaluate", evaluate_node)

# 일반 엣지: 항상 이 경로로
builder.add_edge(START, "search")
builder.add_edge("search", "generate")

# 조건부 엣지: 상태에 따라 분기
builder.add_conditional_edges(
    "evaluate",
    lambda state: "retry" if state["retry_count"] < 3
                  else "end",
    {"retry": "search", "end": END}
)

④ Checkpointing (체크포인팅): 매 단계 저장

LangGraph는 매 노드 실행 후 자동으로 상태를 저장한다. 에이전트가 3번째 단계에서 실패해도, 1번부터 다시 시작할 필요 없이 3번째부터 재개할 수 있다.

hljs language-python
from langgraph.checkpoint.memory import MemorySaver

# 개발용: 메모리 체크포인터
graph = builder.compile(checkpointer=MemorySaver())

# 프로덕션: PostgreSQL 체크포인터
from langgraph.checkpoint.postgres import PostgresSaver
graph = builder.compile(checkpointer=PostgresSaver(conn))

체크포인팅은 대화 메모리도 자연스럽게 해결한다. thread_id로 대화를 식별하면, 같은 스레드에서의 이전 상태가 자동으로 복원된다.

⑤ Human-in-the-Loop (사람 개입): 중요한 순간에 멈추기

에이전트가 이메일을 보내거나, 주문을 실행하거나, 코드를 배포하기 전에 사람의 승인을 받아야 하는 경우가 많다.

hljs language-python
from langgraph.types import interrupt, Command

def send_email_node(state: AgentState):
    # 여기서 실행이 멈추고 사람에게 확인 요청
    approval = interrupt({
        "message": "이 이메일을 보내도 될까요?",
        "draft": state["email_draft"]
    })

    if approval == "승인":
        send_email(state["email_draft"])
        return {"status": "sent"}
    else:
        return {"status": "cancelled"}

interrupt()에서 그래프 실행이 일시 정지된다. 사람이 승인/거절을 보내면 Command(resume="승인")으로 재개된다. 이 사이에 체크포인팅이 상태를 보존하므로, 아무것도 잃어버리지 않는다.


3. 실전 패턴 6가지

패턴 1: ReAct 에이전트 — 가장 기본적인 도구 사용 루프

REACT AGENT LOOP무한 루프
THINKLLM이 메시지를 분석하고 다음 행동을 결정
ACT도구 호출이 필요하면 tool_calls 생성 → ToolNode가 실행
OBSERVE도구 결과를 ToolMessage로 받아 다시 LLM에 전달
DECIDEtool_calls가 없으면 → 최종 답변 출력. 있으면 → ACT로 돌아감
hljs language-python
from langchain.agents import create_agent
from langchain.tools import tool

@tool
def get_weather(city: str) -> str:
    """도시의 현재 날씨를 가져옵니다."""
    return f"{city}: 흐림, 18°C, 강수확률 80%"

@tool
def search_places(query: str) -> str:
    """장소를 검색합니다."""
    return f"'{query}' 검색 결과: 카페A, 영화관B, 미술관C"

agent = create_agent(
    model="openai:gpt-4o",
    tools=[get_weather, search_places],
    prompt="날씨와 장소 추천을 도와주는 어시스턴트입니다.",
)

result = agent.invoke({
    "messages": [{"role": "user",
     "content": "내일 서울 날씨 보고 실내 데이트 추천해줘"}]
})

패턴 2: 자기 수정 RAG — 검색 품질을 스스로 평가하고 재시도

이전 글에서 다룬 Corrective RAG를 LangGraph로 구현하는 패턴이다.

SELF-CORRECTING RAG품질 루프
RETRIEVE벡터 DB에서 관련 문서 검색
EVALUATELLM이 검색 결과의 관련성을 평가 ("이 문서가 질문에 답할 수 있는가?")
BRANCH관련 있음 → 답변 생성 | 관련 없음 → 쿼리 재작성 후 웹 검색 보완
GENERATE답변 생성 후 환각 여부 검사. 환각 발견 시 → 다시 RETRIEVE

이 패턴이 강력한 이유: 검색이 실패해도 포기하지 않고 다른 전략을 시도한다. 쿼리를 재작성하거나, 웹 검색으로 전환하거나, 여러 번 반복하여 답변 품질을 끌어올린다.

패턴 3: 멀티 에이전트 — 감독자(Supervisor) 패턴

복잡한 작업을 전문화된 하위 에이전트에게 분배하는 패턴이다.

Supervisor 멀티 에이전트 패턴
감독자 에이전트 질문을 분석하고 적절한 전문 에이전트에게 작업 할당
리서치 에이전트 웹 검색, 문서 분석
코드 에이전트 코드 작성, 실행
분석 에이전트 데이터 분석, 차트

Swarm 패턴도 있다 — 감독자 없이 에이전트들이 직접 작업을 넘기는 분산형 구조. 벤치마크에서 Supervisor 대비 응답 시간 40% 단축을 보였다.

패턴 4: 스트리밍 — 토큰 단위 실시간 출력

hljs language-python
# 5가지 스트리밍 모드 중 선택
async for event in graph.astream(
    input, config, stream_mode="messages"
):
    # 토큰이 생성될 때마다 실시간으로 받음
    print(event.content, end="", flush=True)
모드용도
values각 노드 후 전체 상태
updates상태 변경분만 (대역폭 효율적)
messages토큰 단위 LLM 출력 (챗봇 UX)
custom앱 전용 이벤트
debug전체 실행 추적

패턴 5: 에러 핸들링 — 다층적 안전장치

hljs language-python
from langgraph.prebuilt import ToolNode
from langgraph.types import RetryPolicy

# 레벨 1: 도구 에러를 LLM에 전달하여 자체 수정
tool_node = ToolNode(
    tools,
    handle_tool_errors=True  # 에러를 ToolMessage로 변환
)

# 레벨 2: 노드 수준 자동 재시도
builder.add_node(
    "api_call", call_external_api,
    retry=RetryPolicy(
        max_attempts=3,
        initial_interval=1.0,
        backoff_factor=2.0
    )
)

# 레벨 3: 그래프 수준 루프 제한
def should_continue(state):
    if state.get("retry_count", 0) >= 5:
        return "fallback"  # 안전한 대체 경로
    return "retry"

패턴 6: 서브그래프 — 그래프 안의 그래프

복잡한 워크플로를 모듈화하기 위해 그래프 안에 그래프를 중첩한다.

hljs language-python
# RAG 서브그래프
rag_subgraph = create_rag_graph()

# 메인 그래프에 서브그래프를 노드로 추가
main_builder = StateGraph(MainState)
main_builder.add_node("rag", rag_subgraph)
main_builder.add_node("code_gen", code_gen_graph)

체크포인터는 부모에서 자식 서브그래프로 자동으로 전파된다.


4. 프로덕션 사례

Klarna — 8,500만 사용자의 AI 고객 지원

스웨덴 핀테크 기업 Klarna는 LangGraph로 AI 고객 지원 어시스턴트를 구축했다.

지표개선
해결 시간11분 → 2분 이내 (80% 감소)
반복 문의율25% 감소
자동화 비율반복 업무의 70% 자동화
인력 효과700명 FTE 상당

Uber — 대규모 코드 마이그레이션

Uber는 LangGraph로 코드 마이그레이션 오케스트레이션 시스템을 구축했다. 전문화된 에이전트 네트워크가 유닛 테스트를 자동 생성하며, 대규모 코드베이스의 마이그레이션을 체계적으로 수행한다.

Elastic — 실시간 위협 탐지

보안 기업 Elastic은 LangGraph로 AI 에이전트 네트워크를 오케스트레이션하여 실시간 보안 위협을 탐지한다. 여러 에이전트가 각각 다른 보안 데이터 소스를 모니터링하고, 이상 징후를 감지하면 조율된 대응을 실행한다.

AppFolio — 부동산 관리 코파일럿

부동산 관리 소프트웨어 기업 AppFolio는 LangGraph로 부동산 매니저용 코파일럿을 구축했다. 주당 10시간 이상 절약, 의사결정 정확도 2배 향상을 보고했다.


5. 베스트 프랙티스와 실전 팁

상태 관리

최소화하라. 상태에는 정말 필요한 것만 넣는다. "혹시 나중에 쓸지 모르니"라며 모든 것을 상태에 넣으면 체크포인팅 비용이 늘고, 디버깅이 어려워진다.

타입을 명시하라. TypedDict나 Pydantic으로 상태를 정의하면 런타임 에러를 예방하고, IDE 자동완성도 지원된다.

리듀서를 이해하라. add_messages를 쓰면 메시지가 누적되고, 리듀서 없이 쓰면 덮어쓴다. 이 차이를 모르면 대화 기록이 사라지는 버그가 발생한다.

그래프 설계

단순하게 시작하라. 처음부터 복잡한 멀티 에이전트를 만들지 말고, 가장 간단한 직선 그래프에서 시작해 필요할 때만 분기를 추가한다.

루프에 반드시 탈출 조건을 넣어라. 가장 흔한 실수 — 무한 루프. max_steps 카운터를 상태에 넣고, 제한에 도달하면 강제 종료한다.

hljs language-python
def should_retry(state):
    if state["retry_count"] >= 3:
        return "give_up"  # 반드시 탈출 경로
    return "retry"

조건부 엣지 디버깅: 라우팅 함수가 반환하는 문자열이 매핑 딕셔너리의 키와 정확히 일치해야 한다. 오타 하나로 전체 그래프가 멈출 수 있다.

성능 최적화

독립적인 작업은 병렬화하라. Send API로 여러 노드를 동시에 실행할 수 있다.

스트리밍 모드를 적절히 선택하라. 챗봇이라면 messages (토큰 단위), 백엔드 모니터링이라면 updates (변경분만), 디버깅이라면 debug.

비핵심 단계에는 저렴한 모델을 쓰라. 라우팅이나 평가 단계에 GPT-4o가 필요한가? 대부분 GPT-4o-mini로 충분하다.

대화 기록이 너무 길어지면 요약하라. 토큰이 계속 누적되면 비용이 급증한다. 일정 길이를 넘으면 과거 대화를 요약하는 노드를 추가한다.

테스트

그래프 수준 테스트를 작성하라. 개별 노드 단위 테스트뿐 아니라, 전체 그래프의 상태 흐름과 엣지 선택을 테스트하는 통합 테스트가 필수다.

LLM과 도구를 Mock하라. 결정론적 테스트를 위해 LLM 호출과 외부 도구를 모킹한다.

언제 LangGraph를 쓰지 말아야 하는가

상황더 나은 대안
단순 RAG 파이프라인직접 코딩 또는 LangChain LCEL
직선형 워크플로LangChain Chain
빠른 프로토타입CrewAI (역할 기반 팀 구성)
분기·루프·재시도가 필요한 복잡한 에이전트LangGraph

6. LangGraph Studio: 에이전트를 눈으로 보다

LangGraph Studio는 에이전트 워크플로를 시각적으로 디버깅하는 도구다.

주요 기능:

  • 실시간 그래프 시각화: 노드와 엣지가 시각적으로 표시되고, 실행 중인 노드가 하이라이트
  • 상태 검사: 각 단계에서의 전체 상태를 확인
  • 되감기(Rewind): 실패 지점으로 되돌아가 다시 실행 — 처음부터 재시작할 필요 없음
  • 분기 테스트: "이 분기점에서 다른 경로로 갔다면?"을 시뮬레이션

2025년 10월부터 LangSmith Deployment로 리브랜딩되었으며, 클라우드(SaaS), 하이브리드, 완전 셀프호스팅 옵션을 지원한다. 약 400개 기업이 이 플랫폼으로 에이전트를 배포 중이다.


7. 프레임워크 비교: 언제 무엇을 쓸까

프레임워크별 제어 수준 (높을수록 세밀한 제어)
CrewAI
중간
AutoGen
중간
LangGraph
매우 높음
직접 코딩
완전
기준LangGraphCrewAIAutoGen
아키텍처그래프 (순환 가능)역할 기반 팀대화 기반
학습 곡선가파름 (1~2주)완만 (수 시간)중간
디버깅Studio + LangSmith도전적중간
최적 사용복잡한 상태 관리, 규제 산업빠른 프로토타입, 역할 분담코드 생성, 연구
커뮤니티38M+ 다운로드44K+ 스타Microsoft 후원

8. 최근 업데이트 (2025~2026)

LangGraph 1.0 (2025년 10월)

  • 에이전트 프레임워크 최초의 안정적 1.0 릴리스
  • v2.0까지 호환성 보장, breaking change 없음
  • langgraph.prebuiltlangchain.agents로 이전

Functional API (2025년 후반)

그래프를 명시적으로 정의하지 않고, 일반 Python 함수처럼 에이전트를 작성하는 새로운 방식:

hljs language-python
from langgraph.func import entrypoint, task
from langgraph.checkpoint.memory import MemorySaver

@task
def research(topic: str) -> str:
    return llm.invoke(f"Research: {topic}")

@task
def write(research: str) -> str:
    return llm.invoke(f"Write article: {research}")

@entrypoint(checkpointer=MemorySaver())
def workflow(topic: str) -> str:
    data = research(topic).result()
    return write(data).result()

@entrypoint@task 데코레이터만으로 체크포인팅, 재시도, 사람 개입이 모두 작동한다. 내부적으로는 같은 LangGraph 런타임 위에서 동작한다.

Deep Agents (2026년 3월)

LangGraph 위에 구축된 장기 실행 에이전트 하니스:

  • 내장 계획 수립 (write_todos 도구)
  • 파일시스템 도구 (ls, read_file, write_file, edit_file)
  • 서브에이전트 생성 (task 도구)
  • 장기 메모리 (LangGraph Memory Store)
  • 샌드박스 지원 (Modal, Daytona, Deno)

9. 학습 로드맵

LangGraph를 시작하려면:

1단계 — 공식 무료 강의 (추천)

2단계 — 실전 튜토리얼

3단계 — 고급 주제

참고 자료


마치며: "에이전트의 복잡성을 관리하는 기술"

LangGraph의 핵심 가치는 한 문장으로 요약된다:

LLM 에이전트의 내재적 복잡성(분기, 루프, 실패, 비결정성)을 체계적으로 관리할 수 있게 해준다.

단순한 RAG 파이프라인이나 직선형 워크플로에는 필요 없다. 하지만 에이전트가 "생각하고, 행동하고, 관찰하고, 다시 생각하는" 루프를 돌기 시작하면 — 그 루프에서 실패가 발생하고, 사람의 승인이 필요하고, 여러 에이전트가 협업해야 하면 — LangGraph는 현재 가장 성숙한 선택이다.

Klarna의 700 FTE 상당 자동화, Uber의 대규모 코드 마이그레이션, Elastic의 실시간 위협 탐지 — 이 프로덕션 사례들이 증명하듯, LangGraph는 이미 "실험"이 아니라 "인프라"의 영역에 들어와 있다.


참고 자료

  • LangGraph Official Documentation. docs.langchain.com/oss/python/langgraph/overview
  • LangChain Blog. (2025). "Building LangGraph: Designing an Agent Runtime from First Principles."
  • LangChain Blog. (2025). "LangChain and LangGraph 1.0."
  • LangChain Blog. (2025). "Is LangGraph Used in Production?"
  • LangChain Blog. (2025). "Introducing the LangGraph Functional API."
  • LangChain Blog. (2025). "Benchmarking Multi-Agent Architectures."
  • LangGraph GitHub. github.com/langchain-ai/langgraph
  • LangChain Academy. academy.langchain.com