기본 개념: 상태 기반 흐름 설계
LangGraph는 대규모 언어 모델(LLM)과 사용자 정의 함수, 비즈니스 로직을 통합하여 순차적 처리 흐름을 관리하는 프레임워크입니다. 핵심은 StateGraph를 통해 정의된 그래프 구조이며, 이는 복잡한 인공지능 애플리케이션의 흐름을 명확하게 시각화하고 제어할 수 있게 합니다.
흐름의 세 가지 요소: 상태, 노드, 엣지
- 상태 (State): 데이터의 현재 전달 단계를 나타냅니다. 예를 들어, 채팅 세션에서는 메시지 목록이 상태에 포함되며, 이는 흐름 중에 유지되는 정보의 집합입니다.
- 노드 (Node): 각 작업 단위로, 하나의 함수 또는 로직 블록입니다. 채팅 응답 생성과 같은 특정 작업을 수행합니다.
- 엣지 (Edge): 노드 간의 흐름 경로를 정의하며, 다음 실행 대상 노드를 결정합니다.
상태 정의: 데이터 구조의 표준화
from typing import Annotated
from typing_extensions import TypedDict
class SessionState(TypedDict):
messages: Annotated[list, add_messages]
이 정의는 모든 흐름에서 사용되는 데이터 형식을 강제하며, 메시지 리스트가 상태 내부에 안전하게 저장되고 누적될 수 있도록 보장합니다.
노드 구현: 동작의 단위화
def generate_response(state: SessionState):
response = llm.invoke(state["messages"])
return {"messages": [response]}
이 함수는 입력된 메시지 기반으로 모델을 호출하고, 결과를 새로운 상태로 반환합니다. 이는 하나의 작업 단위로서 독립적으로 재사용 가능합니다.
그래프 구성: 흐름의 연결
builder = StateGraph(SessionState)
builder.add_node("response_generator", generate_response)
builder.add_edge(START, "response_generator")
graph = builder.compile()
여기서 START는 흐름의 시작 지점이며, 첫 번째 노드인 response_generator로 바로 연결됩니다. 이는 단일 단계의 처리 흐름을 의미합니다.
실행 및 반복 처리
while True:
user_input = input("User: ")
if user_input.lower() in ("quit", "exit", "q"):
print("Goodbye!")
break
for event in graph.stream({"messages": [("user", user_input)]}):
if "response_generator" in event:
print("AI:", event["response_generator"]["messages"][-1].content)
사용자 입력을 기반으로 스트림 방식으로 그래프를 실행하며, 각 단계의 결과를 실시간으로 출력합니다.
핵심 가치: 확장성과 명확성
이러한 구조는 단순한 조건문이나 복잡한 중첩 함수보다 훨씬 더 명확하고 확장 가능한 설계를 제공합니다. 나중에 추가적인 노드(예: 검증, 저장, 분석 등)와 엣지를 쉽게 삽입할 수 있으며, 전체 흐름은 그림처럼 직관적으로 이해할 수 있습니다.