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=[]
)
]
긴 대화에서 "모든 것을 영원히 저장"하는 것은 부작용이 따릅니다.
| 문제 | 설명 |
|---|---|
| 컨텍스트 제한 & 비용 | 토큰은 한정적입니다. 기록이 길어질수록 지연 시간과 비용이 증가합니다. |
| 품질 저하 | LLM은 "중간 망각" 현상을 겪습니다. 긴 대화 기록을 그대로 넣으면 중요한 정보의 리콜률이 오히려 떨어질 수 있습니다. |
| 보안 & 프라이버시 | 민감한 정보를 영원히 저장하면 안 됩니다. 삭제/TTL 설정으로 노출을 줄여야 합니다. |
| 드리프트 | 필터링되지 않은 과거 응답이 미래 답변에 편향을 주거나 환각을 전파할 수 있습니다. |
| 툴 노이즈 | 원시 툴 호출 페이로드(JSON, 로그)가 프롬프트를 불필요하게 부풀립니다. |
단순한 전략부터 복잡한 전략까지 순서대로 소개합니다.
마지막 K개 메시지 또는 T토큰만 유지합니다.
"지금까지 중요한 것"에 대한 짧고 지속적으로 업데이트되는 요약을 유지하고, 원시 메시지는 최근 일부만 보관합니다.
주제/세그먼트별로 요약하고, 세그먼트가 끝나면 요약들을 다시 요약("챕터" 방식)합니다.
안정적인 사실(이름, 선호도, 제약사항)을 구조화된 키→값 또는 작은 지식 그래프로 추출/저장하고, 시스템 또는 컨텍스트 메시지로 재주입합니다.
대화 기록(또는 증류된 핵심)을 인덱싱합니다. 각 턴마다 가장 관련성 높은 k개 조각을 검색해 주입합니다.
툴 입출력을 제거하거나 요약하고 결과 또는 간결한 근거만 유지합니다.
핵심 규칙을 재설명하는 안정적인 시스템 메시지를 유지하고, 스크롤되어 사라지지 않게 합니다.
메시지의 수명(TTL), PII 편집, "잊어" 명령, 스레드별 삭제를 제공합니다.
→ 훌륭한 품질/비용 균형을 제공하고 확장 가능합니다.
| 전략 | 사용 상황 | 참고사항 |
|---|---|---|
| 슬라이딩 윈도우 | 가장 저렴하고 단순한 해결책 원할 때 | 메시지 개수 기반이 아닌 토큰 인식 방식으로 만들기 |
| 롤링 요약 | 대화가 수십 턴을 넘고 초기에 중요한 사실이 나올 때 | 요약을 짧게 유지 |
| 검색 메모리 | 매우 긴 세션 또는 여러 주제에서 선택적 리콜이 필요할 때 | 원시 덤프가 아니라 증류된 핵심을 저장 |
| 엔티티 메모리 | 안정적인 사용자 프로필/선호도가 중요할 때 | 충돌 병합 필요 |
| 툴 압축 | 큰 JSON 페이로드를 반환하는 툴을 호출할 때 | 미래 추론에 영향을 주는 필드만 유지 |