ChatMessageHistory

정의

LangChain의 ChatMessageHistory 클래스는 사용자와 AI 간의 대화 메시지를 구조화하여 저장하고 관리하는 메모리 저장소. 메시지를 HumanMessageAIMessage로 분리하여 저장하고, 대화 히스토리를 프롬프트에 전달할 때 사용한다.

핵심 메서드

메서드설명예시
add_user_message(content)사용자 메시지 추가history.add_user_message("안녕하세요")
add_ai_message(content)AI 메시지 추가history.add_ai_message("안녕하세요!")
messages모든 메시지 조회all_msgs = history.messages
clear()히스토리 비우기history.clear()

구조

from langchain.memory import ChatMessageHistory
 
history = ChatMessageHistory()
 
# 메시지 추가
history.add_user_message("일본어로 '잘 먹겠습니다' 말해줄래?")
history.add_ai_message("いただきます (이타다키마스)")
history.add_user_message("내가 방금 뭐라고 했지?")
 
# 모든 메시지 조회
print(history.messages)
# Output:
# [
#   HumanMessage(content="일본어로 '잘 먹겠습니다' 말해줄래?"),
#   AIMessage(content="いただきます (이타다키마스)"),
#   HumanMessage(content="내가 방금 뭐라고 했지?")
# ]

사용 패턴

기본 사용 (Method 2)

from langchain.memory import ChatMessageHistory
from langchain.prompts import ChatPromptTemplate
from langchain.chat_models import ChatOpenAI
 
# 1. 히스토리 저장소 생성
history = ChatMessageHistory()
 
# 2. 프롬프트 구성
prompt = ChatPromptTemplate.from_messages([
    ("system", "당신은 도움을 주는 어시스턴트입니다."),
    ("placeholder", "{chat_history}"),
    ("human", "{input}")
])
 
# 3. 체인 구성
model = ChatOpenAI(model="gpt-4o")
chain = prompt | model
 
# 4. 멀티턴 대화 루프
user_input = input("사용자: ")
history.add_user_message(user_input)
 
response = chain.invoke({
    "chat_history": history.messages,
    "input": user_input
})
 
history.add_ai_message(response.content)

ChatMessageHistory vs. 수동 리스트

특성수동 리스트ChatMessageHistory
메시지 타입dict/strHumanMessage/AIMessage 객체
가독성낮음 (수동 작성)높음 (명확한 메서드)
역할 구분문자열 (“user”, “ai”)클래스로 구분
확장성제한적좋음
수동 호출필수 (chain.invoke 마다)필수 (chain.invoke 마다)

장단점

✅ 장점

  • 메시지 저장/로드의 구조화
  • add_user_message(), add_ai_message() 메서드로 명확한 의도 표현
  • 메시지 객체의 타입 정보 (HumanMessage, AIMessage) 활용 가능
  • 대화 로직을 인간이 읽기 쉽게 작성

❌ 단점

  • 여전히 수동 호출 필요 (invoke 시점에 add_ai_message 호출 필수)
  • RunnableWithMessageHistory로 이동 시 자동화 부족
  • 멀티 유저/세션 관리 시 별도 저장소 구현 필요

RunnableWithMessageHistory와의 차이

구분ChatMessageHistoryRunnableWithMessageHistory
자동화❌ 수동 호출✅ 자동 저장/로드
세션 관리❌ 없음✅ session_id 지원
메모리 저장invoke마다 수동invoke 자동 처리
사용 복잡도낮음중간

실제 예제: 음악 추천 챗봇

from langchain.memory import ChatMessageHistory
from langchain.prompts import ChatPromptTemplate
from langchain.chat_models import ChatOpenAI
 
history = ChatMessageHistory()
model = ChatOpenAI(model="gpt-4o")
prompt = ChatPromptTemplate.from_messages([
    ("system", "당신은 음악 추천 어시스턴트입니다."),
    ("placeholder", "{chat_history}"),
    ("human", "{input}")
])
chain = prompt | model
 
# 대화 1
history.add_user_message("안녕")
response = chain.invoke({"chat_history": history.messages, "input": "안녕"})
history.add_ai_message(response.content)
# AI: "안녕하세요! 어떤 음악을 좋아하세요?"
 
# 대화 2
history.add_user_message("나는 말차를 좋아해")
response = chain.invoke({"chat_history": history.messages, "input": "나는 말차를 좋아해"})
history.add_ai_message(response.content)
# AI: "좋아요, 말차 관련 음악이라면..."
 
# 대화 3 — 이전 컨텍스트 활용
history.add_user_message("디저트 추천해줘")
response = chain.invoke({"chat_history": history.messages, "input": "디저트 추천해줘"})
history.add_ai_message(response.content)
# AI: "당신이 말차를 좋아하신다니, 말차 라떼 같은 곡을 추천합니다."

통합 개념


관련 소스: word-chain-chatbot (Method 2 예제)