목차
반응형

langgraph 버전: 0.6.4
내용 출처 : LangGrapn Docs
LangGraph
LangGraph Trusted by companies shaping the future of agents – including Klarna, Replit, Elastic, and more – LangGraph is a low-level orchestration framework for building, managing, and deploying long-running, stateful agents. Get started Install LangGr
langchain-ai.github.io
1. State 개념
- 그래프의 전체 상태를 나타내는 데이터 구조
- 그래프를 만들 때 가장 먼저 정의
- 그래프에서 사용될 데이터 구조(schema) + state를 업데이트할 때 적용할 방식(reducer 함수) 를 포함함
- 모든 노드(Node)와 엣지(Edge)는 State를 기반으로 데이터를 읽고 씀
2. State 만들기
- State의 Schema란 state가 어떤 필드를 포함하고 어떤 타입을 가지는지 정의한 것
- 아래 두가지 방식으로 생성 가능
- TypedDict (권장, 문서에서도 주로 사용)
- Pydantic BaseModel
- 또한 다중 스키마(Multiple Schmas) 형식으로 구성 가능
2.1. TypedDict 으로 만들기
- LangGraph 문서에서 주로 사용하는 방식
- 클래스 정의 시 TypeDict를 상속받음
- 콜론(:)을 이용해 타입 정의
- 그래프 안에서 오가는 값, 노드 간 합치는 값은 가볍게 하기 위해 TypeDict가 적합함
from typing import TypedDict
# 상태 스키마 정의
class MyState(TypedDict):
name: str
greeting: str
2.2. Pydantic BaseModel 으로 만들기
- 기본값 설정, 유효성 검사, nested 구조 지원 등 풍부한 기능 제공
- API 입출력, 외부 리소스 I/O, 노드의 입력/출력 계약은 Pydantic으로 감싸서 검증.
from pydantic import BaseModel
# 상태 스키마 정의
class MyState(BaseModel):
name: str
greeting: str = "Hello!" # 기본값 설정
2.3. Multiple Schemas
기본적으로 LangGraph는 하나의 State Schema를 모든 노드가 공유
하지만 아래와 같은 경우가 있을 수 있다.
- 입력은 단순한데, 내부 처리에는 다양한 키가 필요할 때
- 출력에는 특정 결과만 포함하고 나머지는 숨기고 싶을 때
- 노드 간 비공개 데이터를 주고받고 싶을 때 (예: 캐시, 중간 계산 값)
Input Schema / Output Schema / Internal Schema / Private Schema 등 으로 나눠서 사용
| Schema 타입 | 설명 |
| InputState | 그래프에 입력으로 들어올 데이터 구조 |
| OutputState | 최종 결과로 반환될 데이터 구조 |
| OverallState | 그래프 전체에서 사용하는 모든 키를 포함하는 내부 스키마 |
| PrivateState | 노드 간 내부 통신에만 사용되는 숨겨진 스키마 (사용자에겐 보이지 않음) |
예시 코드
# 📌 입력 스키마
class InputState(TypedDict):
user_input: str
# 📌 출력 스키마
class OutputState(TypedDict):
graph_output: str
# 📌 전체 스키마 (입력 + 중간 값 + 출력 포함)
class OverallState(TypedDict):
foo: str
user_input: str
graph_output: str
# 📌 내부 전용 스키마
class PrivateState(TypedDict):
bar: str
3. Reducer
개념
- 각 state의 key마다 따로 정의되는 함수
- 해당 key가 어떻게 업데이트될지를 정함
예시 1
- Reducer가 지정되지 않은 예시
- 값을 덮어쓰기로 동작함
from typing_extensions import TypedDict
class State(TypedDict):
foo: int
bar: list[str]
예시 2
- bar 속성에 add reducer가 사용됨
- Annotated[] 함수의 두번째 인자는 업데이트할 함수가 들어옴
- 초기: {"foo": 1, "bar": ["hi"]}
- 노드1: {"foo": 2} → 결과: {"foo": 2, "bar": ["hi"]} # foo에는 reducer가 없으므로 덮어쓰기
- 노드2: {"bar": ["bye"]} → 결과: {"foo": 2, "bar": ["hi", "bye"]} # bar는 add 연산이 들어감
from typing import Annotated
from typing_extensions import TypedDict
from operator import add
class State(TypedDict):
foo: int
bar: Annotated[list[str], add]
4. Message in Graph State
- 대부분의 LLM은 “메시지 목록” (list of messages) 형식으로 입력을 받음
- 예: LangChain의 ChatModel은 HumanMessage, AIMessage 같은 메시지 객체 리스트를 받음
- 그래프에서도 이런 메시지들을 state에 저장해두면 유용
- state에 messages라는 key를 추가하고, 여기에 Message 객체 리스트를 저장
- 이 리스트는 대화 히스토리처럼 누적돼야 하니까, reducer가 필요
- 사람이 직접 message를 업데이트하거나 고칠 때 (human-in-the-loop 상황)는 add_messages라는 LangGraph 제공 함수 사용
add_messages를 reducer로 설정하면 다음 두 가지 입력 형태를 자동 인식
# this is supported
{"messages": [HumanMessage(content="message")]}
# and this is also supported
{"messages": [{"type": "human", "content": "message"}]}
구현 예시
from langchain_core.messages import AnyMessage
from langgraph.graph.message import add_messages
from typing import Annotated
from typing_extensions import TypedDict
class GraphState(TypedDict):
messages: Annotated[list[AnyMessage], add_messages]
LangGraph에서는 위 내용을 이미 구현해 놓음
즉, 아래와 같이 사용하면 됨
- messages는 MessagesState에서 자동 제공
- documents는 내가 추가한 새로운 필드
from langgraph.graph import MessagesState
class State(MessagesState):
documents: list[str]반응형
'자연어처리 > LangGraph' 카테고리의 다른 글
| [LangGraph] 워크플로우(workflow) (2) | 2025.08.10 |
|---|---|
| [LangGraph] 노드(node)와 엣지(edge) (4) | 2025.08.09 |
| [LangGraph] 스트림(Stream) 호출(invoke) (4) | 2025.08.09 |
| [LangGraph] Graph 기본 개념 (0) | 2025.04.23 |
| [LangGraph] Prebuilt ReAct Agent 사용법 (1) | 2025.04.16 |