본 포스팅은 "Do it! LLM을 활용한 AI 에이전트 개발 입문"을 독학하며 쓴 글입니다.
내돈내산 포스팅임을 참고해주시면 감사하겠습니다.
2026년 3월 7일 기준으로 작성되었습니다.
본 포스팅에서 랭그래프에서 대화 내용을 저장하는 기능을 사용해보겠습니다
이전 포스팅에서 만든 챗봇이 이전 대화 내용을 기억하게 하려면 매번 수동으로 업데이트 해야 했다
이런 방식이 필요한 경우도 있겠지만 특수 상황이 아니라면 랭그래프에서 제공하는 메모리(Memory)를 활용해 대화 내용을 간편하게 저장할 수도 있다
랭그래프의 메모리를 다루기 전에 기본 챗봇을 만들어보자
langgraph_memory.py 파일을 만들고 아래 코드를 입력하자
이전 포스팅에서 만든 챗봇 코드를 그대로 가져왔다
from langchain_openai import ChatOpenAI
import os
from dotenv import load_dotenv
load_dotenv()
# 모델 초기화
model = ChatOpenAI(model = "gpt-4o-mini")
from typing import Annotated # annotated는 타입 힌트를 사용할 때 사용하는 함수
from typing_extensions import TypedDict # TypedDict는 딕셔너리 타입을 정의할 때 사용하는 클래스
from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import add_messages
class State(TypedDict):
"""
State 클래스는 TypedDict를 상속받습니다
속성:
messages (Annotated[list[str], add_messages]) : 메세지들은 "list" 타입을 갖비니다
'add_messages' 함수는 이 상태 키가 어떻게 업데이트 되어야 하는지를 정의합니다
(이 경우, 메세지를 덮어쓰는 대신 리스트에 추가합니다)
"""
messages: Annotated[list[str], add_messages]
# StateGraph 클래스를 사용하여 State 타입의 그래프 생성
graph_builder = StateGraph(State)
def generate(state: State):
"""
주어진 상태를 기반으로 챗봇의 응답 메세지를 생성한다
매개변수 :
state (State) : 현재 대화 상태를 나타내는 객체로, 이전 메세지들이 포함되어 있다
반환값:
dict : 모델이 생성한 응답 메세지를 포함하는 딕셔너리
형식은 {"messages" : [응답메세지]} 입니다.
"""
return {"messages" : [model.invoke(state["messages"])]}
graph_builder.add_node("generate", generate)
graph_builder.add_edge(START, "generate")
graph_builder.add_edge("generate", END)
graph = graph_builder.compile()
#--------------- 여기부터 코드 달라짐
from langchain_core.messages import HumanMessage
while True:
user_input = input("You\t:")
if user_input in ["exit", "quit", "q"]:
break
for event in graph.stream({"messages" : [HumanMessage(user_input)]}, stream_mode="values"):
event["messages"][-1].pretty_print()
print(f'\n현재 메세지 개수 : {len(event["messages"])}\n----------------\n')


이 파일을 실행시켜보면 과거 대화에 기반해서 대화를 이어나갈 수 없는 것을 볼 수 있다
이제 이 코드에서 메모리를 추가해보자
이러면 이전 대화 내용을 기억한 상태로 대화를 이어나갈 수 있도록 설정할 수 있다
graph_builder.add_node("generate", generate)
graph_builder.add_edge(START, "generate")
graph_builder.add_edge("generate", END)
# 추가된 부분
from langgraph.checkpoint.memory import MemorySaver
memory = MemorySaver()
config = {"configurable" : {"thread_id" : "abcd"}}
graph = graph_builder.compile(checkpointer = memory)
#--------------- 여기부터 코드 달라짐
from langchain_core.messages import HumanMessage
while True:
user_input = input("You\t:")
if user_input in ["exit", "quit", "q"]:
break
for event in graph.stream({"messages" : [HumanMessage(user_input)]}, config, stream_mode="values"):
event["messages"][-1].pretty_print()
print(f'\n현재 메세지 개수 : {len(event["messages"])}\n----------------\n')
- memory = MemorySaver()
랭그래프에서 제공하는 MemorySaver를 임포트하고 memory 라는 이름의 객체로 생성한다
- graph = graph_builder.complie(checkpointer = memory)
memory 객체는 graph_builder.complie(checkpointer=memory)에서 설정되고 대화 내용을 계속 쌓아 나갈 수 있도록 한다
- config = {"configurable" : {"thread_id" : "abcd"}}
config 에서 thread_id를 abcd로 설정한다 이때 thread_id는 임의로 설정해도 상관 없다
thread_id는 일종의 대화방 ID로 저장하고 싶은 대화 종류가 달라지면 변경하면 된다
이제 이 코드를 실행시켜서 이전 대화 내용을 기억하는지 확인해보자


이렇게 간단하게 랭그래프의 메모리 기능을 이용해서 멀티턴 대화가 가능한 챗봇을 만들어보았다
다행히 지금까지의 과정은 직접 리스트를 이용해서 프롬프트에 넣어서 멀티턴 대화를 구현하기도 하고
랭체인을 이용해서 구현해본적도 있는 기능이라서 간단한것 같다
다음 포스팅에서는 인터넷 검색 후 기사를 작성하는 챗봇을 만드는 실습을 진행해보자