
LangGraph란? (간단 개념)
LangGraph는 복잡한 AI 에이전트를 만들 때 유용한 도구입니다. 기존의 LangChain이 A→B→C처럼 한 방향으로 흐르는 파이프라인에 강점이 있었다면, LangGraph는 상황에 따라 B에서 다시 A로 돌아가거나, C 대신 D로 가는 등의 순환과 분기가 가능한, 더 유연한 '그래프' 형태의 워크플로우를 만들 수 있게 해줍니다.
쉽게 말해, '상태'를 가진 에이전트를 만들 때 사용합니다. 에이전트가 어떤 행동을 하고(Node), 그 결과에 따라 다음 행동을 결정하는(Edge) 과정을 시각적으로 구성할 수 있습니다.
LangGraph 사용법: 설치부터 실행까지
1단계: 설치하기
가장 먼저 필요한 패키지들을 설치해야 합니다. LangGraph는 LangChain 생태계의 일부이므로 langchain과 함께 설치하며, 보통 OpenAI의 모델을 많이 사용하므로 langchain-openai도 같이 설치하는 것이 일반적입니다.
터미널에 다음 명령어를 입력하여 설치합니다.
pip install langgraph langchain langchain-openai
2단계: 핵심 개념 이해하기 (상태, 노드, 엣지)
LangGraph를 사용하려면 세 가지 핵심 요소를 이해해야 합니다.
- 상태 (State): 그래프의 모든 단계(노드)가 공유하는 '메모리' 또는 데이터 저장소입니다. 각 노드는 이 상태를 읽고, 자신의 작업을 수행한 뒤, 상태를 업데이트하여 다음 노드로 전달합니다. 보통 파이썬의 TypedDict를 사용하여 구조를 정의합니다.
- 노드 (Node): 그래프에서 실제 작업을 수행하는 단위입니다. LLM을 호출하거나, 특정 도구를 사용하거나, 데이터를 처리하는 하나의 '함수'라고 생각하면 쉽습니다. 각 노드는 현재 '상태'를 입력받아 작업을 처리하고, 변경된 '상태' 정보를 반환합니다.
- 엣지 (Edge): 노드와 노드를 연결하는 **'경로'**입니다. 이 엣지가 워크플로우의 흐름을 결정합니다.
- 일반 엣지: A 노드가 끝나면 항상 B 노드로 이동합니다.
- 조건부 엣지: A 노드의 결과에 따라 B로 갈지, C로 갈지를 결정합니다. 이것이 LangGraph의 핵심 기능입니다.
3단계: 간단한 AI 에이전트 만들어보기
이제 간단한 'AI 연구 비서' 에이전트를 만들어 보겠습니다. 이 에이전트는 사용자의 질문에 대해 웹 검색이 필요한지 스스로 판단하고, 필요하면 검색을 수행한 후 답변을 생성합니다.
1. 상태(State) 정의하기
먼저, 에이전트가 작업하는 동안 유지해야 할 정보들을 '상태'로 정의합니다. 여기서는 사용자의 질문과 생성된 답변들을 리스트로 관리하겠습니다.
from typing import List, TypedDict
from langchain_core.messages import BaseMessage
class AgentState(TypedDict):
# BaseMessage는 LangChain에서 사용하는 메시지 형식 (HumanMessage, AIMessage 등)
messages: List[BaseMessage]
2. 노드(Node) 정의하기
이제 에이전트가 수행할 작업들을 함수(노드)로 만듭니다.
- call_model: LLM을 호출하여 사용자의 질문에 답변하거나, 다음 할 일을 결정하는 핵심 노드입니다.
- call_tool: call_model이 웹 검색이 필요하다고 판단했을 때, 실제 검색을 수행하는 노드입니다.
import os
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage, AIMessage
from langchain_community.tools.tavily_search import TavilySearchResults
# .env 파일 등에 OPENAI_API_KEY, TAVILY_API_KEY를 설정해야 합니다.
# os.environ["OPENAI_API_KEY"] = "sk-..."
# os.environ["TAVILY_API_KEY"] = "tvly-..."
# 도구 정의: 웹 검색 도구
tool = TavilySearchResults(max_results=2)
tools = [tool]
# 모델 정의
model = ChatOpenAI(temperature=0).bind_tools(tools)
# 1) 모델 호출 노드
def call_model(state: AgentState):
messages = state['messages']
response = model.invoke(messages)
# AIMessage 형태로 응답을 messages 리스트에 추가
return {"messages": [response]}
# 2) 도구 호출 노드
def call_tool(state: AgentState):
last_message = state['messages'][-1] # 모델이 생성한 메시지
# tool_calls에서 도구 이름과 인자를 추출하여 실행
tool_call = last_message.tool_calls[0]
result = tool.invoke(tool_call['args'])
# 도구 실행 결과를 ToolMessage 형태로 messages 리스트에 추가
return {"messages": [AIMessage(content=str(result), tool_call_id=tool_call['id'])]}
3. 엣지(Edge)와 그래프 연결하기
이제 정의한 상태와 노드들을 그래프로 엮어줍니다. 여기서 조건부 엣지가 사용됩니다.
- 모델을 호출(call_model)한 뒤, 그 결과에 tool_calls가 있으면 웹 검색(call_tool) 노드로 이동합니다.
- tool_calls가 없으면(단순 답변이면) 워크플로우를 종료(END)합니다.
- 웹 검색(call_tool)이 끝나면, 검색 결과를 가지고 다시 모델을 호출(call_model)하여 최종 답변을 생성합니다.
from langgraph.graph import StateGraph, END
# 조건부 엣지를 위한 라우팅 함수
def should_continue(state: AgentState):
last_message = state['messages'][-1]
if last_message.tool_calls:
return "call_tool" # tool_calls가 있으면 call_tool 노드로
else:
return END # 없으면 종료
# 그래프 생성
graph = StateGraph(AgentState)
# 노드 추가
graph.add_node("call_model", call_model)
graph.add_node("call_tool", call_tool)
# 진입점(Entry Point) 설정
graph.set_entry_point("call_model")
# 조건부 엣지 추가
graph.add_conditional_edges(
"call_model", # call_model 노드 실행 후
should_continue, # should_continue 함수 결과에 따라
{
"call_tool": "call_tool", # "call_tool"이 반환되면 call_tool 노드로
END: END # END가 반환되면 종료
}
)
# 일반 엣지 추가 (도구 사용 후 다시 모델 호출)
graph.add_edge("call_tool", "call_model")
# 그래프 컴파일
app = graph.compile()
4. 실행하기
컴파일된 app을 invoke 메소드로 실행하면 됩니다. 첫 질문을 messages에 담아 전달합니다.
inputs = {"messages": [HumanMessage(content="What is the weather in Seoul?")]}
result = app.invoke(inputs)
# 최종 결과 출력
print(result['messages'][-1].content)
위 코드를 실행하면, 에이전트는 다음과 같은 순서로 동작합니다.
- "서울 날씨가 어때?"라는 질문을 받고 call_model 노드가 실행됩니다.
- 모델은 이 질문에 답하려면 웹 검색이 필요하다고 판단하고, tool_calls가 포함된 응답을 생성합니다.
- should_continue 함수가 tool_calls를 감지하고, 워크플로우를 call_tool 노드로 보냅니다.
- call_tool 노드가 실제 웹 검색을 수행하고, 그 결과를 상태에 추가합니다.
- call_tool 노드에서 call_model 노드로 엣지가 연결되어 있으므로, 검색 결과를 가지고 다시 call_model이 실행됩니다.
- 모델은 검색 결과를 바탕으로 "서울의 현재 날씨는..."과 같은 최종 답변을 생성합니다.
- 이 최종 답변에는 tool_calls가 없으므로, should_continue 함수가 END를 반환하고 워크플로우가 종료됩니다.
요약
LangGraph 사용법을 정리하면 다음과 같습니다.
- 설치: pip install langgraph langchain langchain-openai
- 상태 정의: 에이전트의 메모리 역할을 할 TypedDict를 만든다.
- 노드 정의: 실제 작업을 수행할 함수들을 만든다. (LLM 호출, 도구 사용 등)
- 그래프 구성: StateGraph를 만들고, 노드와 엣지(특히 조건부 엣지)를 추가하여 워크플로우를 설계한다.
- 컴파일 및 실행: 그래프를 compile()하고, invoke()로 실행한다.
처음에는 조금 복잡해 보일 수 있지만, 이 구조 덕분에 여러 단계를 거치며 스스로 판단하고 행동하는 복잡한 AI 에이전트를 훨씬 체계적으로 만들 수 있습니다.
'최신 AI' 카테고리의 다른 글
| 가장 쉽게 이해할 수 있는 LangChain 설명 (0) | 2026.02.20 |
|---|---|
| LangGraph로 AI 에이전트 구축하기 (0) | 2026.02.10 |
| 로컬 에이전트 기반의 개인용 AI 비서 플랫폼: Moltbot(구 Clawdbot) (0) | 2026.02.03 |
| MCP, LangGraph 및 FastAPI로 스마트 웹 AI 에이전트 구축하기 (0) | 2026.01.23 |
| 디자이너를 위한 MCP: 실제 기능과 한계 (What It Actually Does and Doesn't) (0) | 2025.12.05 |