LangGraph 대화 기록 관리

twonezero·2026년 2월 17일

1. 메시지 대화 수집하기 (add_messages reducer)

LangGraph에서는 add_messages reducer를 사용해 메시지 목록을 효율적으로 관리할 수 있습니다.

from langgraph.graph.message import add_messages
from langchain_core.messages import AIMessage, HumanMessage

# 빈 메시지 리스트 생성
msgs = []

# 메시지 생성 (ID 없음)
human = HumanMessage(content="Hi", type="human", name="Alex")
ai = AIMessage(content="Hi. How can I help you?", name="MyBot")

# 리스트와 단일 메시지 병합 → reducer가 자동으로 고유 ID 추가
msgs = add_messages(msgs, human)

# 두 메시지 리스트 병합
msgs = add_messages(msgs, [ai])

msgs

결과 예시:

[
    HumanMessage(
        content='Hi',
        additional_kwargs={},
        response_metadata={},
        name='Alex',
        id='0434f672-f473-46a1-8ea2-dd3e89def10d'
    ),
    AIMessage(
        content='Hi. How can I help you?',
        additional_kwargs={},
        response_metadata={},
        id='def7339f-294b-4954-be75-aefea1878c85',
        name='MyBot',
        tool_calls=[],
        invalid_tool_calls=[]
    )
]

메시지 ID가 필요한 이유

  • 메시지 수정 가능: ID를 통해 특정 메시지를 식별하고 수정
  • 중복 방지: 동일한 ID의 메시지가 여러 번 추가되는 것을 방지
  • 메시지 삭제: ID를 기반으로 특정 메시지 삭제

2. 왜 대화 기록 관리가 필수인가?

긴 대화에서 "모든 것을 영원히 저장"하는 것은 부작용이 따릅니다.

대화 기록 관리가 필요한 이유

문제설명
컨텍스트 제한 & 비용토큰은 한정적입니다. 기록이 길어질수록 지연 시간과 비용이 증가합니다.
품질 저하LLM은 "중간 망각" 현상을 겪습니다. 긴 대화 기록을 그대로 넣으면 중요한 정보의 리콜률이 오히려 떨어질 수 있습니다.
보안 & 프라이버시민감한 정보를 영원히 저장하면 안 됩니다. 삭제/TTL 설정으로 노출을 줄여야 합니다.
드리프트필터링되지 않은 과거 응답이 미래 답변에 편향을 주거나 환각을 전파할 수 있습니다.
툴 노이즈원시 툴 호출 페이로드(JSON, 로그)가 프롬프트를 불필요하게 부풀립니다.

3. 대화 기록 관리 핵심 전략

단순한 전략부터 복잡한 전략까지 순서대로 소개합니다.

1) 슬라이딩 윈도우 (잘라내기)

마지막 K개 메시지 또는 T토큰만 유지합니다.

  • 장점: 구현이 쉽고 비용이 저렴
  • 단점: 초기에 나왔지만 중요한 사실이 컨텍스트에서 제외될 수 있음

2) 롤링 요약 (대화 개요)

"지금까지 중요한 것"에 대한 짧고 지속적으로 업데이트되는 요약을 유지하고, 원시 메시지는 최근 일부만 보관합니다.

  • 장점: 오래된 사실을 압축된 형태로 유지, 토큰 크기 예측 가능
  • 단점: 요약이 뉘앙스를 놓칠 수 있음, 추가 LLM 호출 필요

3) 계층적/에피소드 요약

주제/세그먼트별로 요약하고, 세그먼트가 끝나면 요약들을 다시 요약("챕터" 방식)합니다.

  • 장점: 매우 긴 세션으로 확장 가능, 주제 전환 지원
  • 단점: 관리할 부분이 많음

4) 엔티티/슬롯 메모리

안정적인 사실(이름, 선호도, 제약사항)을 구조화된 키→값 또는 작은 지식 그래프로 추출/저장하고, 시스템 또는 컨텍스트 메시지로 재주입합니다.

  • 장점: 지속 가능하고 매우 작은 용량
  • 단점: 추출 및 충돌 해결 필요 (예: "저는 바보입니다." → 나중에 "저는 천재입니다.")

5) 검색 메모리 (벡터 저장소)

대화 기록(또는 증류된 핵심)을 인덱싱합니다. 각 턴마다 가장 관련성 높은 k개 조각을 검색해 주입합니다.

  • 장점: 관련 있는 것만 가져옴, 확장성 우수
  • 단점: 인프라 추가(인덱스), 청킹 및 중복 제거 필요

6) 툴 트레이스 압축

툴 입출력을 제거하거나 요약하고 결과 또는 간결한 근거만 유지합니다.

  • 장점: 큰 JSON을 반환하는 툴에서 큰 절감 효과

7) 프롬프트 위생 & 고정

핵심 규칙을 재설명하는 안정적인 시스템 메시지를 유지하고, 스크롤되어 사라지지 않게 합니다.

  • 장점: 추가 토큰 없이 드리프트 감소 (시스템 메시지는 어차피 각 호출의 일부)

8) TTL, 편집, 사용자 컨트롤

메시지의 수명(TTL), PII 편집, "잊어" 명령, 스레드별 삭제를 제공합니다.

  • 장점: 모델 성능을 저하시키지 않으면서 프라이버시 및 규정 준수

4. 실용적인 구성

  • 작은 슬라이딩 윈도우 유지 (예: 마지막 6-12턴)
  • 지속적인 사실과 결정을 캡처하는 롤링 요약 유지
  • 벡터 저장소에 핵심 저장; 각 턴마다 3-5개 관련 항목 검색

→ 훌륭한 품질/비용 균형을 제공하고 확장 가능합니다.


5. 상황별 전략 선택 가이드

전략사용 상황참고사항
슬라이딩 윈도우가장 저렴하고 단순한 해결책 원할 때메시지 개수 기반이 아닌 토큰 인식 방식으로 만들기
롤링 요약대화가 수십 턴을 넘고 초기에 중요한 사실이 나올 때요약을 짧게 유지
검색 메모리매우 긴 세션 또는 여러 주제에서 선택적 리콜이 필요할 때원시 덤프가 아니라 증류된 핵심을 저장
엔티티 메모리안정적인 사용자 프로필/선호도가 중요할 때충돌 병합 필요
툴 압축큰 JSON 페이로드를 반환하는 툴을 호출할 때미래 추론에 영향을 주는 필드만 유지
profile
I Enjoy Learn-and-Run Vibe😊

0개의 댓글