Study/AI
[LangChain] 채팅 히스토리 기억하기 (Memory, MessagesPlaceholder)
Super-Son
2025. 3. 20. 22:03
LangChain의 메모리 관리 기능을 공부했습니다. LangChain의 메모리 관리 기능을 사용하면, AI 챗봇은 이전에 사용자가 나눈 대화 내용을 기억하고 이를 바탕으로 자연스러운 대화를 이어나갈 수 있습니다. 다양한 메모리 저장 방법이 있지만 글에서는 대화 내용을 요약해서 저장하는 코드만 정리하겠습니다.
배운 내용 요약
- 저장된 메모리는 대화 흐름을 자연스럽게 유지하는 데 활용됩니다.
- 메모리를 사용하면 이전 대화의 맥락을 참고하여 사용자의 질문에 더욱 정확하고 자연스럽게 응답할 수 있습니다.
주요 코드 정리
ConversationSummaryBufferMemory
메모리는 언어 모델(llm
)을 통해 대화를 요약한 뒤, 지정된 토큰 수 내에서 기억합니다.
from langchain.memory import ConversationSummaryBufferMemory
memory = ConversationSummaryBufferMemory(
llm=llm, # 대화를 요약해 저장할 언어 모델
max_token_limit=120, # 메모리에 저장할 최대 토큰 수
return_messages=True, # 메모리 호출 시 메시지 형태로 반환
)
MessagesPlaceholder
이전의 대화 내용을 동적으로 불러와 프롬프트 내부에 배치하는 역할을 합니다. 이를 통해 챗봇은 이전의 대화 맥락을 참고할 수 있게 됩니다. MessagesPlaceholder
를 사용하면 메모리를 템플릿에 쉽게 적용할 수 있습니다.
prompt = ChatPromptTemplate.from_messages(
[
("system", "You are helpful AI assistant."),
MessagesPlaceholder(variable_name="history"), # 이전 대화 내용을 동적으로 포함할 수 있는 위치 지정
("human", "{question}"),
]
)
공부한 코드
from langchain.memory import ConversationSummaryBufferMemory
from langchain.chat_models import ChatOpenAI
from langchain.schema.runnable import RunnablePassthrough
from langchain.prompts import PromptTemplate, ChatPromptTemplate, MessagesPlaceholder, FewShotChatMessagePromptTemplate
from langchain.prompts.example_selector import LengthBasedExampleSelector
llm = ChatOpenAI(temperature=0.1)
memory = ConversationSummaryBufferMemory(
llm=llm,
max_token_limit=120,
return_messages=True,
)
# 예시 설정
examples = [
{"country": "한국", "alphabet": "KR"},
{"country": "일본", "alphabet": "JP"},
{"country": "미국", "alphabet": "US"},
{"country": "프랑스", "alphabet": "FR"},
]
example_selector = LengthBasedExampleSelector(
examples=examples,
example_prompt=PromptTemplate(
input_variables=["country", "alphabet"],
template="Human: {country}\nAI: {alphabet}"
),
max_length=50,
)
few_shot_prompt = FewShotChatMessagePromptTemplate(
example_selector=example_selector,
example_prompt=ChatPromptTemplate.from_messages(
[("human", "{country}"), ("ai", "{alphabet}")]
),
)
prompt = ChatPromptTemplate.from_messages(
[
("system", """You are an AI assistant who responds with alphabetic abbreviations from a particular country.
If you ask about the country you asked before, please answer with the country name and the abbreviation of the alphabet you expressed."""),
MessagesPlaceholder(variable_name="history"),
few_shot_prompt,
("human", "{question}"),
]
)
def load_memory(_):
return memory.load_memory_variables({})["history"]
chain = RunnablePassthrough.assign(history=load_memory) | prompt | llm
def invoke_chain(country):
result = chain.invoke({"question": country})
memory.save_context(
{"input": country},
{"output": result.content},
)
print(result.content)