KSCOLD LogoKSCOLD
Blog
Feed
Product
Admin Night
Vault
Guestbook
Info

Vault 목록

LangGraph

연결된 노트와 함께 읽기

LangGraph

2026년 7월 16일
  • LangGraph는 에이전트를 노드(Node) + 엣지(Edge) 의 상태 그래프(StateGraph) 로 모델링하는 프레임워크다. LangChain 팀이 만들었지만 독립 사용 가능.
  • 핵심 아이디어: 에이전트의 흐름을 명시적인 그래프로 표현하면 분기·반복·병렬·휴먼 인 더 루프 같은 복잡한 시나리오를 안정적으로 다룰 수 있다.

핵심 개념

용어의미
State그래프 전체에서 공유되는 상태(TypedDict, Pydantic). 자세히는 LangGraph State
Node상태를 입력받아 부분 상태를 반환하는 함수. 자세히는 LangGraph Node
Edge노드 → 노드 연결. 무조건/조건부. 자세히는 LangGraph Edge
Conditional Edge함수가 다음 노드를 결정 (LLM 라우팅 등)
Checkpoint상태 저장 장치 — 재시작·HITL 가능

개념 노트

  • LangGraph 개념 MOC
  • LangGraph 문법 치트시트
  • LangGraph StateGraph
  • LangGraph State
  • LangGraph Node
  • LangGraph Edge
  • LangGraph 워크플로우 아키텍처
  • Workflow Node vs Tool
  • LangGraph ToolNode
  • Retrieve-Generate 패턴
  • Human-in-the-loop
  • LangGraph Checkpointer
  • LangGraph thread_id

가장 단순한 ReAct 에이전트

Python

State Reducer 패턴

Python
  • 노드가 부분 상태를 반환하면, reducer가 기존 값과 어떻게 합칠지 결정한다.

조건부 라우팅 (Supervisor 패턴)

Python
  • 이걸로 Supervisor 패턴 · Hierarchical Agent 다 구현 가능.

Checkpointing — 휴먼 인 더 루프

Python
  • 이 구조에서 MemorySaver는 실습용 메모리 기반 checkpointer로 이해하면 된다. 관련 개념은 LangGraph InMemorySaver 참고.
  • thread_id는 같은 실행 흐름을 다시 찾기 위한 세션 키다. 자세히는 LangGraph thread_id 참고.
  • 중간 상태에서 사람이 승인해야 하는 흐름은 LangGraph interrupt와 Human-in-the-loop 개념으로 이어진다.
  • DB 기반 LangGraph SqliteSaver나 LangGraph PostgresSaver로 바꾸면 영속화된다. 장기 실행·복구·다중 세션이 자연스러워진다.

LangGraph가 빛나는 시나리오

  • 반복(loop) 이 있는 에이전트 — ReAct, Reflection, 재시도.
  • 여러 에이전트가 협업 — Supervisor, Swarm.
  • 휴먼 승인 단계 가 필요한 워크플로우.
  • 같은 작업을 여러 번 재현하거나 시각화해 디버깅해야 할 때 (LangGraph Studio).

한계

  • 학습 곡선이 LangChain보다 가파름.
  • 단순 1-shot 호출엔 오버엔지니어링.

관련

  • LangChain — 컴포넌트 계층.
  • Supervisor 패턴 · Swarm 패턴 · Hierarchical Agent — LangGraph로 구현 가능한 멀티 에이전트 토폴로지.
  • LangGraph StateGraph
  • Workflow Node vs Tool
  • Human-in-the-loop
  • LangGraph Checkpointer
  • LangGraph interrupt
  • LangGraph thread_id

Synapse Map Insight

from typing import Annotated, TypedDict from langgraph.graph import StateGraph, START, END from langgraph.graph.message import add_messages from langchain_openai import ChatOpenAI from langchain_core.messages import HumanMessage class State(TypedDict): messages: Annotated[list, add_messages] # 메시지 누적 reducer llm = ChatOpenAI(model="gpt-4o-mini").bind_tools([search_tool]) def call_llm(state: State): return {"messages": [llm.invoke(state["messages"])]} def call_tool(state: State): last = state["messages"][-1] results = [search_tool.invoke(tc) for tc in last.tool_calls] return {"messages": results} def should_continue(state: State): return "tool" if state["messages"][-1].tool_calls else END graph = ( StateGraph(State) .add_node("llm", call_llm) .add_node("tool", call_tool) .add_edge(START, "llm") .add_conditional_edges("llm", should_continue, {"tool": "tool", END: END}) .add_edge("tool", "llm") # 도구 결과를 받아 다시 LLM으로 .compile() ) graph.invoke({"messages": [HumanMessage("서울 날씨?")]})
class State(TypedDict): messages: Annotated[list, add_messages] # 누적 (default는 덮어쓰기) counter: Annotated[int, lambda old, new: old + new]
def route(state): last_msg = state["messages"][-1].content if "결제" in last_msg: return "payment_agent" if "환불" in last_msg: return "refund_agent" return "fallback" graph.add_conditional_edges("supervisor", route)
from langgraph.checkpoint.memory import MemorySaver graph = builder.compile(checkpointer=MemorySaver()) config = {"configurable": {"thread_id": "user-42"}} graph.invoke(input, config=config) # 중간 상태에서 사용자 승인 → 같은 thread_id로 재개 graph.invoke(None, config=config)