지난주에 "A팀 담당자가 박지훈 님으로 바뀌었어요"라고 비서 에이전트에 알려 줬어요. 이번 주에 "A팀에 마감 공지해 줘"라고 했더니 김서연 님에게 메일이 갔어요. 반대 경우도 있어요. 사실을 깔끔하게 추출해 저장하도록 고쳤더니, 이번엔 "박지훈 님 전에는 누구였죠?"에 모른다고 답해요.
둘 다 같은 질문으로 돌아와요. AI 에이전트 메모리에 무엇을 쓰고, 무엇을 지워도 되나요.
정리해서 저장한 12개 시스템이 원문 검색 하나에 졌어요
10월에 나온 논문 두 편이 이 질문을 정면으로 건드렸어요. 하나는 제목부터 "Naive RAG Is Stronger Than We Thought"예요. 대화 원문을 256토큰 창으로 잘라 그냥 검색하고 리랭킹만 한 Raw-RAG 가, 사실 추출 · 통합 · 그래프 같은 구조를 갖춘 메모리 시스템 12개를 네 벤치마크 7개 설정 중 6개에서 이겼어요. 저자들은 이유를 "커버리지"로 설명해요. 정리본은 답을 쓰기엔 좋지만, 답에 필요한 근거를 애초에 덜 가져온다는 거예요. 같은 110문항 기준 처리 시간도 다음 시스템의 5.1배, 가장 느린 시스템의 30.4배 빨랐어요.
더 눈에 띈 숫자는 따로 있어요. 메모리 시스템이 내린 쓰기 결정 중 UPDATE 와 DELETE 는 LoCoMo 33,902건 중 4.39%, LongMemEval 428,858건 중 2.46% 뿐이었어요. 공들여 만든 "똑똑한 갱신"이 실제로 쓰이는 일은 드물다는 뜻이에요. 사흘 뒤 나온 다른 논문은 이 현상에 "Memory Tax"라는 이름을 붙였어요. 사실을 재구성하는 과정 자체가 근거를 지우거나 가린다는 거예요.
저희가 궁금했던 건 점수가 아니라, 쓰기 정책마다 구조적으로 무엇이 사라지는가였어요.
60턴 가상 대화로 다섯 가지 쓰기 정책을 돌려봤어요
가상의 업무 비서 대화 10세션 60턴을 만들었어요. 담당자 · 회의 시간 · 예산 · 마감 같은 추적 사실 9개가 있고 그중 7개는 중간에 값이 바뀌어요. 출장지 · 송장 번호 · 쿠폰 위치처럼 한 번만 지나가는 세부 9개도 섞었어요. 질문은 "지금 값"(9) · "바뀌기 전 값"(7) · "주제 밖 세부"(9)예요. LLM 은 부르지 않았고, 추출기는 정규식이에요. 재는 건 모델 품질이 아니라 검색된 컨텍스트에 답이 들어 있는가예요.
쓰기 정책은 다섯 개예요. 결정은 "사실을 어떻게 쓰느냐"뿐이고, 읽기는 전부 같은 BM25 예요.
PAT = re.compile(TOPIC + r"[는은] ([^.]+?)이에요") # 추적 주제 목록에 있는 사실만 뽑아요
for date, turns in SESSIONS:
for t in turns:
for key, val in PAT.findall(t):
# B. 덮어쓰기 — UPDATE 가 곧 DELETE 예요
facts_overwrite[key] = f"{key}: {val}"
# C. 이력 보존 — 현재값 앞에, 이전값은 날짜와 함께 뒤에
prev = facts_hist.get(key)
facts_hist[key] = f"{key}: {val} ({date}부터)" + (f" / 이전: {prev}" if prev else "")
# A. 원문 턴은 날짜를 머리말로 붙여 그대로 둬요
raw_turns = [f"[{d}] {t}" for d, ts in SESSIONS for t in ts]
이 한 줄 차이로 결과가 갈렸어요.
| 쓰기 정책 | 지금 값 | 옛값 동반 | 바뀌기 전 값 | 주제 밖 세부 | 컨텍스트 글자 |
|---|---|---|---|---|---|
| A 원문 검색 (턴 top-5) | 9/9 | 6/9 | 7/7 | 9/9 | 196 |
| B 정리본 · 덮어쓰기 | 9/9 | 0/9 | 0/7 | 0/9 | 15 |
| C 정리본 · 이력 보존 | 9/9 | 6/9 | 7/7 | 0/9 | 76 |
| D 세션 요약 (top-3) | 9/9 | 6/9 | 7/7 | 0/9 | 79 |
| E 혼합: C + 원문 top-3 | 9/9 | 6/9 | 7/7 | 9/9 | 208 |
"옛값 동반"은 최신값을 찾은 질문 중 바뀌기 전 값까지 같은 컨텍스트에 따라 들어온 수예요.
덮어쓰기는 15글자로 끝나지만, 두 가지를 영영 잃어요
B 가 제일 싸요. "A팀 담당자: 이도윤" 한 줄, 15글자로 지금 값은 전부 맞혔어요. 대신 "박지훈 님 전에는 누구였죠?"는 7문항 전부, 송장 번호 같은 주제 밖 세부도 9문항 전부 빈손이에요. 추출 주제 목록에 없던 건 애초에 기록되지 않았고, UPDATE 가 곧 DELETE 였거든요.
A 는 다 찾아요. 그런데 9문항 중 6문항에서 김서연 · 박지훈 · 이도윤이 한 컨텍스트에 같이 들어왔어요. 턴마다 날짜를 붙여 뒀으니 모델이 고를 수 있지만, 날짜가 없는 로그였다면 세 이름 중 하나를 찍는 문제가 돼요. 원문 검색의 커버리지 우위는 날짜 머리말이 있을 때 비로소 정확도로 바뀌어요.
C 는 이력 질문을 되찾았어요. 옛값 동반 6/9 는 A 와 숫자가 같지만 성격이 달라요. "이도윤 (10-27부터) / 이전: 박지훈 (09-29부터)"처럼 순서가 적혀 있어서 모델이 고를 일이 없어요. 그래도 주제 밖 세부는 0 이에요. 결국 전부 가져온 건 E 뿐이고, 비용은 208글자예요. A 보다 12글자 더 쓴 셈이에요.
첫 실행에서 작은 사고도 있었어요. 추출기가 조사 "는"만 보고 "은"을 안 봐서 "1차 마감은 …" · "보고서 형식은 …" 두 사실을 통째로 놓쳤어요. 원문 턴에는 남아 있어서 바로 복구했고요. 규칙 추출기도 이러는데 LLM 추출은 더 자주, 더 다양한 이유로 놓쳐요. 정리본은 캐시고 정본은 원문이라는 원칙이 이 사고에서 나왔어요.
그래서 저희는 쓰기와 읽기를 이렇게 나눠요
벤더들의 방향도 같아요. Google 의 Memory Bank 는 통합 단계에서 기존 메모리를 UPDATE · DELETE 하지만, 합치기 전 추출 결과를 남기는 "리비전"이 기본으로 켜져 있어요. Anthropic 의 Managed Agents 메모리 스토어는 아예 파일 디렉터리라서 에이전트가 파일 도구로 읽고 쓰고, 문서 하나 100 kB 한도 안에서 "작은 파일 여러 개"로 쪼개라고 안내해요. 11월 4일 MongoDB 가 내놓은 Google ADK 통합도 세션 이벤트를 그대로 적재해 두고 나중에 찾는 구조예요. 원문을 먼저 남기고 정리는 그 위에 얹는 거예요.
컨텍스트 창 안에서 무엇을 버릴지는 지난 글에서 다뤘어요. 이번 글은 그 창 밖, 세션을 넘어 남는 것 이야기예요. 문서 쪽에서 낡은 버전이 남는 문제는 RAG 지식베이스 최신화 글과 같은 뿌리고요.
바로 믿으면 안 되는 세 가지
- 추출기가 정규식이에요. 실제 LLM 추출은 누락도 오추출도 더 많아요. 표의 B · C 는 "추출이 완벽할 때"의 상한이에요.
- 60턴 · 10세션 규모예요. 세션 요약(D)이 잘 된 건 요약이 10개뿐이라서예요. 수백 세션이면 요약 검색부터 흔들려요.
- 컨텍스트에 답이 있는지만 쟀어요. 모델이 그걸 보고 맞게 답하는지(논문의 "utilization")는 안 쟀어요. 그건 골든셋 평가로 따로 재야 해요.
무엇을 기억할지가 아니라, 무엇을 접어 둘지예요
도입부의 두 장면은 반대처럼 보였지만 원인은 하나였어요. 정리본을 정본으로 썼다는 거예요. 원문은 날짜를 달아 추가만 하고, 정리본은 현재값 뒤에 이전값을 접어 두고, 읽을 때는 둘을 합친다. 완성된 원칙이 아니라 60턴에서 맞았던 원칙이에요. 세션이 수백 개로 늘면 어디서 먼저 무너지는지, 그게 다음 실험이에요.
자주 묻는 질문
Q. 원문을 전부 남기면 개인정보 · 보안 이슈가 커지지 않나요? A. 커져요. 그래서 "남기지 않는다"가 아니라 "원문 로그에 보존 기간과 접근 권한을 건다"가 답이에요. 정리본에서 지운다고 원문에서 사라지는 게 아니니, 삭제 요구는 원문 로그 단위로 처리해야 해요.
Q. 정리본에 이력을 계속 쌓으면 항목이 무한히 길어지지 않나요? A. 길어져요. 실험에선 "이전:" 을 세 번까지 이었어요. 운영에선 최근 N개만 정리본에 두고 그 이전은 원문 날짜로 되짚게 하면 돼요. 원문이 있으니 정리본은 잘라도 돼요.
Q. 벡터 검색이 아니라 BM25 로 잰 결과를 믿어도 되나요? A. 쓰기 정책 다섯 개를 같은 검색기로 비교한 거라, 검색기를 바꿔도 "덮어쓰기가 이력과 주제 밖 세부를 잃는다"는 구조는 그대로예요. 검색기 차이는 청킹 실험에서처럼 따로 재야 해요.
Sources
- Is Complex Agentic Memory Always Needed? Naive RAG Is Stronger Than We Thought (arXiv 2610.30755, 2026-10-22) — https://arxiv.org/abs/2610.30755
- Memory Tax: Dissecting the Net Value of Agent Memory (arXiv 2610.34073, 2026-10-25) — https://arxiv.org/abs/2610.34073
- Mem0: Building Production-Ready AI Agents with Scalable Long-Term Memory (arXiv 2504.19413, 2025-04-28) — https://arxiv.org/abs/2504.19413
- Google Cloud, Vertex AI Agent Engine Memory Bank — Memory revisions — https://docs.cloud.google.com/agent-builder/agent-engine/memory-bank/revisions
- Anthropic, Using agent memory (Managed Agents, beta) — https://platform.claude.com/docs/en/managed-agents/memory
- MongoDB, Introducing the MongoDB Google ADK Integration: Durable Memory and Agent State (2026-11-04) — https://mongodb.com/company/blog/product-release-announcements/introducing-mongodb-google-adk-integration-durable-memory-agent-state
- 실험 스크립트(가상 대화 60턴, LLM 미호출) — data/verification/ai-agent-long-term-memory-overwrite-vs-raw-history.experiment.py

