반응형
LangChain에서 메모리(Memory)는 과거 대화를 저장·활용해, LLM(대규모 언어 모델)이 맥락을 유지하고 일관성 있는 답변을 생성하도록 돕는 핵심 요소입니다.
이때, 단순히 대화 기록을 통째로 저장하는 방식(예: ConversationBufferMemory)은 대화가 길어지면 토큰 사용량이 폭발할 수 있고,
요약만 하는 방식(예: ConversationSummaryMemory)은 최근 대화의 정교한 정보를 잃을 위험이 있죠.
ConversationSummaryBufferMemory는 이러한 문제점을 절충한 메모리 방식으로,
“최근 대화”는 버퍼(Buffer) 형태로 원문을 유지하고,
그 이전 대화는 요약(Summary) 해서 간결하게 저장함으로써
“중요한 최신 대화”와 “과거 맥락”을 모두 놓치지 않게 도와줍니다.
1. ConversationSummaryBufferMemory란?
- “최근 N개의 대화” 정도는 그대로 저장(버퍼)
- 오래된 대화는 요약본으로 관리
- 따라서 LLM에 프롬프트를 보낼 때,
- 가장 최근 대화 부분(버퍼)은 원문 그대로 전달
- 오래된 부분은 요약된 텍스트만 전달
- 이 방식으로 필요한 세부 정보는 놓치지 않고, 토큰 사용량은 일정 수준으로 제어할 수 있습니다.
2. 작동 원리와 흐름
- 대화가 시작되면, 초기에는 버퍼에 대화가 그대로 쌓입니다.
- 버퍼가 설정한 임계(토큰 한도 또는 메시지 개수)를 초과하면, 가장 오래된 대화를 요약해 요약본(Summary)에 합칩니다.
- 이후에는
- 최신 대화(k개/토큰 제한 이하)는 버퍼에 남기고,
- 나머지(오래된) 메시지는 이미 업데이트된 요약본에 추가·통합함으로써
- 요약 + 버퍼를 동시에 관리하게 됩니다.
- 결국 LLM에 프롬프트를 보낼 때,
- 요약본(과거 맥락) + 버퍼(최근 대화) + 새로운 메시지
이 합쳐져서 맥락으로 제공되므로, 장기 맥락과 최근 디테일을 모두 챙길 수 있습니다.
- 요약본(과거 맥락) + 버퍼(최근 대화) + 새로운 메시지
3. 기본 코드 예시
from langchain.memory import ConversationSummaryBufferMemory
from langchain.chat_models import ChatOpenAI
from langchain.chains import ConversationChain
# 1) LLM 세팅
llm = ChatOpenAI(temperature=0.7)
# 2) ConversationSummaryBufferMemory 설정
memory = ConversationSummaryBufferMemory(
llm=llm, # 요약에 사용될 LLM
return_messages=True, # 메시지 객체 형태로 반환
max_token_limit=1000 # 최대 토큰 제한 (대략적으로 조정 가능)
)
# 3) ConversationChain 구성
conversation = ConversationChain(
llm=llm,
memory=memory,
verbose=True
)
# 4) 대화 시뮬레이션
print(conversation.run("안녕하세요? 최근 날씨가 너무 덥네요."))
print(conversation.run("이번 여름휴가 추천지를 알려줄 수 있나요?"))
print(conversation.run("오, 거기 날씨나 볼거리도 궁금해요."))
# ...
코드 주요 포인트
- ConversationSummaryBufferMemory
- 버퍼와 요약을 함께 관리하는 고급 메모리 클래스입니다.
- llm 인자로 요약을 수행할 LLM을 지정해 주어야 해요. (보통 대화용 LLM과 같은 모델 쓰는 경우가 많습니다.)
- max_token_limit
- 버퍼가 무한정 커지지 않도록,
- 프롬프트에 포함될 토큰이 일정 한도를 넘으면, 오래된 대화를 요약본으로 이전합니다.
- 이 값은 실제 토큰 사용량과 일정 오차가 있을 수 있으므로, 적절히 조금 여유롭게 잡는 것이 좋습니다.
- verbose=True
- 대화 시 어떤 프롬프트가 실제로 모델에게 전달되는지 콘솔 로그로 확인할 수 있습니다.
- 디버깅이나 테스트 시 매우 유용합니다.
4. 언제 쓰면 좋을까?
- 장기간 이어지는 대화
- 유저가 여러 번 질문하고, 답변이 길어지는 상황에서 모든 대화를 통째로 기억하려면 토큰이 폭증할 수 있습니다.
- 요약+버퍼 전략을 쓰면 부담이 훨씬 줄어듭니다.
- 가장 최신 내용이 특히 중요한 시나리오
- 최근에 나온 명령이나 정보는 정확히 유지해야 하지만,
- 오래된 기록은 전체 흐름만 알면 충분한 경우.
- 예: 채팅봇이 “직전 몇 번의 메시지”를 디테일하게 파악해야 하면서, “그 이전 맥락”은 놓치면 안 되지만 자세히 필요하지는 않을 때.
- 트랜잭션성 대화
- 예: 어느 정도 시간이 지난 정보는 요약 수준으로만 갖고 있어도 되는 온라인 주문 상담,
- “최근 2~3번의 변경 사항”이 중요하고, 나머지는 흐름 파악만 필요한 경우.
5. 장단점
장점
- 효율성: 모든 대화를 전부 유지하는 방법보다, 토큰 사용량을 크게 줄일 수 있음.
- 정확도: 가장 최신 대화는 원문 형태로 전달되므로, 중요한 디테일이 손실되지 않음.
- 맥락 보존: 오래된 내용은 요약으로 전환하되, 대화의 핵심 흐름을 유지할 수 있음.
단점
- 요약 품질 의존: 요약 자체가 잘못되면, 오류가 누적될 가능성이 있음.
- 설정 난이도: 적절한 버퍼 크기나 토큰 제한을 잡는 것이 중요하고, 상황에 따라 미세 튜닝이 필요.
- 추가 비용: 요약을 할 때마다 LLM 호출이 추가로 일어날 수 있으므로,
전체적인 API 호출 수가 늘어날 수도 있습니다(다만, 긴 프롬프트 비용을 줄이는 것과 어느 쪽이 더 비싼지는 케이스 바이 케이스).
6. 다른 Memory와 비교
- ConversationBufferMemory
- 모든 대화를 쌓아두고 계속 전달
- 대화가 길어지면 토큰 폭발 위험이 큼
- ConversationSummaryMemory
- 전부 요약해서 기억
- 가장 최신 디테일도 요약되므로, 세부 정보가 사라질 수 있음
- ConversationBufferWindowMemory
- 최근 N개 대화만 저장(버퍼)
- 오래된 대화는 아예 사라져서, 중요한 과거 정보가 유실될 수 있음
- ConversationSummaryBufferMemory
- Buffer(최근 N개) + Summary(오래된 대화)
- 최신 상세 정보 & 오래된 맥락을 둘 다 챙길 수 있음
- 구현이 조금 복잡하지만, 다양한 시나리오에서 실용적
7. 마무리
ConversationSummaryBufferMemory는 긴 대화를 다루면서도,
가장 최근 대화의 정밀한 맥락과 과거 대화의 요약된 흐름을 동시에 유지해야 할 때 최고의 선택지입니다.
- 최적의 토큰 절감과
- 최대한의 맥락 보존 사이에서 고민 중이라면,
꼭 한번 시도해 보시길 추천드립니다.
이 글이 도움이 되셨다면, 댓글과 공유 부탁드립니다!
궁금한 점이나 추가로 다루었으면 하는 주제가 있다면, 댓글로 자유롭게 남겨주세요. 감사합니다.
반응형
'Data Analysis > AI' 카테고리의 다른 글
Chat Based Memory: 대화형 AI의 기억 관리 이해하기 (0) | 2025.02.01 |
---|---|
LLMChain: 간단하면서 강력한 LangChain의 핵심 구성요소 (0) | 2025.02.01 |
ConversationBufferWindowMemory: 핵심만 기억하는 효율적인 대화 메모리 (0) | 2025.01.29 |
LangChain의 메모리 개념과 ConversationBufferMemory 완벽 이해하기 (0) | 2025.01.29 |
OpenAI 사용량 추적의 비밀병기: get_openai_callback (0) | 2025.01.28 |
댓글