요즘 LangChain을 써서 LLM(Language Model) 기반 애플리케이션을 개발하는 분들이 많습니다.
LLM을 여러 차례 호출하면서, “이전 대화 내용이나 문맥을 모델이 기억하고 있다면 좋을 텐데…”라고 생각해 보신 적 있으실 거예요.
LangChain은 이러한 “메모리(Memory)” 개념을 도입해, 대화형 AI나 컨텍스트가 중요한 작업에서 훨씬 더 자연스러운 흐름을 구현할 수 있도록 도와줍니다.
오늘은 LangChain의 메모리 개념과, 가장 기본적이면서도 자주 쓰이는 ConversationBufferMemory에 대해 자세히 살펴보겠습니다.
1. LangChain의 메모리(Memory)란 무엇인가?
1) 메모리가 필요한 이유
일반적으로 LLM은 하나의 요청(prompt) 을 받으면, 그에 대한 단발성 응답을 생성합니다.
그런데 실생활에서 챗봇(혹은 대화형 AI)을 활용할 때, 우리는 “이전 대화에서 했던 질문”이나 “방금 전 내가 말한 내용”을 바탕으로
맥락(Context)을 이어가는 답변을 원하죠.
예시를 들어볼까요?
유저: 오늘 저녁으로 뭐 먹으면 좋을까?
AI: 파스타 어떠세요?
유저: 아, 그러면 재료는 뭐가 필요해?
이때, AI가 갑자기 “어떤 요리를 원하냐”고 되묻거나, 문맥을 몰라서 전혀 다른 답을 준다면 이상하겠죠.
따라서 이전 대화 기록을 적절히 프롬프트에 포함시켜야 하고, 이 과정을 자동화해 주는 기능이 바로 LangChain의 Memory입니다.
2) Memory의 역할
- 이전 대화나 작업 결과를 저장하고,
- 새로운 프롬프트를 보낼 때, 과거 기록을 추출해서 LLM에 다시 전달해 주는 것.
즉, 메모리는 “ChatGPT처럼 대화를 잊지 않고 이어가는” 기능을 LangChain에서 좀 더 편리하게 구현하도록 도와줍니다.
2. Memory의 작동 방식 한눈에 살펴보기
아주 단순화해서 표현하면, LangChain에서 Memory는 다음과 같은 단계를 거칩니다.
- 유저 입력: 사용자가 LLM에게 질문 또는 명령을 보냅니다.
- 메모리 저장: 현재 대화 내용을 메모리에 추가합니다.
- 기존 대화 이력 추출: 메모리에 저장된 “이전 대화 내용” 중, 중요하거나 전부를 꺼냅니다.
- 프롬프트 생성: 현재 질문과 함께 과거 대화 이력을 하나의 프롬프트로 합쳐 LLM에 전달합니다.
- LLM 응답: 모델이 문맥을 인식해 적절한 답변을 돌려줍니다.
- 응답 결과 메모리 저장: 모델이 준 응답도 다시 메모리에 저장해, 다음 대화에 연결할 수 있습니다.
결과적으로, 유저가 연속적인 대화를 할 때마다 LangChain의 메모리는 “이전 대화 요약” 혹은 “원문”을 모델에 건네주어, 끊기지 않고 자연스러운 대화 경험을 제공합니다.
3. ConversationBufferMemory란?
1) 정의
ConversationBufferMemory는 LangChain에서 가장 단순하고 직관적인 형태의 메모리입니다.
- “Buffer” 라는 말 그대로, 대화 내용을 순차적으로 누적하여 저장하는 방식이에요.
예를 들어, 유저가 대화를 여러 번 주고받으면:
유저: 질문 1
AI: 대답 1
유저: 질문 2
AI: 대답 2
… (계속)
이 모든 것을 원문 그대로 메모리에 차곡차곡 쌓아두는 개념입니다.
2) 특징
- 간단: 과거 대화 기록을 요약(summary)하지 않고, 텍스트 전체를 저장합니다.
- 메모리 용량: 대화가 길어질수록 메모리에 저장되는 내용(즉, 프롬프트 길이)도 길어집니다.
- 따라서 긴 대화를 자주 하거나, 토큰 제한에 신경을 써야 하는 상황이라면 주의해야 합니다.
- 처리 과정 명료: 말 그대로 최근 대화까지 그대로 불러오기 때문에, AI가 이전 메시지를 모두 참조하게 됩니다.
3) 간단 예시 코드
from langchain.chat_models import ChatOpenAI
from langchain.memory import ConversationBufferMemory
from langchain.chains import ConversationChain
# 1. 메모리 객체 생성
memory = ConversationBufferMemory()
# 2. 대화 모델(ChatOpenAI 예시)
llm = ChatOpenAI(temperature=0.7)
# 3. ConversationChain 생성
conversation = ConversationChain(
llm=llm,
memory=memory,
verbose=True # 어떤 프롬프트가 전달되는지 확인하고 싶다면 True
)
# 4. 대화 시나리오 예시
print(conversation.run("안녕하세요! 오늘 기분이 어때요?"))
print(conversation.run("저녁 메뉴 추천 좀 해주세요."))
print(conversation.run("그 추천 이유가 궁금한데요?"))
코드 흐름 설명
- ConversationBufferMemory() : 대화 내용을 순차적으로 쌓아 두는 가장 기본적인 메모리.
- ConversationChain : 유저 입력을 받고, 메모리 정보를 추가해, LLM에 전달한 후 답변을 되돌려주는 역할.
- 각 conversation.run(...) 호출 마다
- LangChain이 이전 대화(memory에 저장된 내용) + 새 질문을 합쳐서 LLM에 보냅니다.
- LLM이 이전 맥락을 반영해서 응답을 주고, 다시 그 응답을 메모리에 저장합니다.
4. ConversationBufferMemory에서 주의할 점
- 토큰 사용량 증가
- 대화가 오래 이어지면, 모든 과거 대화를 프롬프트에 합쳐 전달하므로, 토큰 소비가 많아질 수 있습니다.
- 이는 곧 OpenAI API 비용이나 응답 지연으로 이어질 수 있으니, 꼭 사용량을 모니터링해야 해요.
- 민감 정보 누출
- 메모리에 이전 대화 내용이 계속 쌓이는 구조이므로, 민감한 정보를 중간에 삭제하거나,
요약해서 저장하는 등의 관리가 필요할 수 있습니다.
- 메모리에 이전 대화 내용이 계속 쌓이는 구조이므로, 민감한 정보를 중간에 삭제하거나,
- 대화 요약 필요성
- 대화가 너무 길어질 경우, 요약을 활용하는 ConversationBufferWindowMemory 혹은 ConversationSummaryMemory 와 같은 다른 메모리 방식을 고려해 볼 수 있습니다.
- 긴 대화를 매번 통째로 불러오는 대신, 핵심 내용만 유지함으로써 비용과 맥락 처리를 효율화할 수 있습니다.
5. LangChain Memory의 다른 유형들
- ConversationBufferWindowMemory: 말 그대로 “윈도우”처럼, 최근 몇 개의 대화만 기록을 유지합니다.
- ConversationSummaryMemory: 이전 대화를 요약해서 저장하고, 전체 프롬프트 길이를 줄입니다.
- VectorStore-Backed Memory: 대화 내용이나 특정 문맥을 벡터 DB에 저장한 뒤, 유사도 검색으로 필요한 부분만 불러오는 고급 방식입니다.
이 외에도 다양한 메모리 방식이 존재하며, 프로젝트 규모와 요구 사항에 따라 선택하면 됩니다.
6. 마무리: 어떻게 활용하면 좋을까?
- 간단한 챗봇: “이전 대화 문맥을 포함해 답해줘!” 정도의 기능이면, ConversationBufferMemory만으로도 충분합니다.
- 장기 대화: 사용자와 긴 시간 대화를 이어가야 하거나, 토큰 비용이 부담된다면, 대화 내용을 일부만 유지하거나 요약하는 메모리 방식을 고려해야 합니다.
- 핵심 정보 추출: 특정 프로젝트에서 “사용자의 요구사항”이나 “주요 사실”만 계속 이어가야 한다면, 대화를 가공해 저장해 줄 고급 메모리가 유용합니다.
무엇보다, Memory는 단순히 “대화를 기억한다”에서 그치지 않고,
어떻게 대화를 요약/생성/검색할지를 커스터마이징할 수 있다는 점이 LangChain의 강점이에요.
초반에는 ConversationBufferMemory처럼 직관적인 방식부터 익힌 뒤,
점차 복잡한 시나리오로 확장해 보시는 것을 추천드립니다.
요약
- Memory 개념: LLM에게 과거 대화를 기억시키고,
- ConversationBufferMemory: 가장 기본적인 “버퍼” 형태 메모리로, 모든 대화 내용을 순서대로 저장하며,
- 장단점: 간단하고 직관적이지만, 대화가 길어지면 토큰 비용이 커지는 문제점이 있음.
LangChain 메모리를 잘 이해하고 프로젝트에 맞게 활용하면,
챗봇이나 컨텍스트가 중요한 AI 서비스에서 훨씬 자연스러운 사용자 경험을 제공할 수 있습니다.
초보자 분들은 우선 ConversationBufferMemory부터 경험해 보고, 필요에 따라 다른 메모리 구현을 시도해 보세요!
'Data Analysis > AI' 카테고리의 다른 글
ConversationSummaryBufferMemory: 요약과 버퍼의 절묘한 조합 (0) | 2025.01.31 |
---|---|
ConversationBufferWindowMemory: 핵심만 기억하는 효율적인 대화 메모리 (0) | 2025.01.29 |
OpenAI 사용량 추적의 비밀병기: get_openai_callback (0) | 2025.01.28 |
LLM 활용도를 높이는 꿀팁: set_llm_cache, set_debug, 그리고 InMemoryCache (0) | 2025.01.28 |
LLM을 제대로 활용하는 꿀팁: FewShotPromptTemplate & StreamingStdOutCallbackHandler (0) | 2025.01.28 |
댓글