ChatMessageHistory
정의
LangChain의 ChatMessageHistory 클래스는 사용자와 AI 간의 대화 메시지를 구조화하여 저장하고 관리하는 메모리 저장소. 메시지를 HumanMessage와 AIMessage로 분리하여 저장하고, 대화 히스토리를 프롬프트에 전달할 때 사용한다.
핵심 메서드
| 메서드 | 설명 | 예시 |
|---|
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/str | HumanMessage/AIMessage 객체 |
| 가독성 | 낮음 (수동 작성) | 높음 (명확한 메서드) |
| 역할 구분 | 문자열 (“user”, “ai”) | 클래스로 구분 |
| 확장성 | 제한적 | 좋음 |
| 수동 호출 | 필수 (chain.invoke 마다) | 필수 (chain.invoke 마다) |
장단점
✅ 장점
- 메시지 저장/로드의 구조화
add_user_message(), add_ai_message() 메서드로 명확한 의도 표현
- 메시지 객체의 타입 정보 (
HumanMessage, AIMessage) 활용 가능
- 대화 로직을 인간이 읽기 쉽게 작성
❌ 단점
| 구분 | ChatMessageHistory | RunnableWithMessageHistory |
|---|
| 자동화 | ❌ 수동 호출 | ✅ 자동 저장/로드 |
| 세션 관리 | ❌ 없음 | ✅ 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 예제)