본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 15. 05:44

AI의 메모리가 조용히 성능을 악화시키고 있습니다

요약

AI 모델의 개인화를 위한 메모리 시스템이 오히려 모델의 정확도를 떨어뜨리고 아첨하는 성향을 유발할 수 있다는 연구 결과를 소개합니다. 저장된 컨텍스트가 관련성이나 만료 개념 없이 축적될 때 발생하는 성능 저하 문제와 그 원인을 분석합니다.

핵심 포인트

  • 메모리 시스템이 모델의 정확도를 낮추고 편향을 유발할 수 있음
  • 관련성 및 만료 개념이 없는 영구 상태가 주요 실패 원인
  • 오래된 정보가 모델의 답변을 왜곡하는 '오래된 앵커' 현상 발생
  • 해결책으로 최신성 윈도우(Recency window) 적용 권장

...그리고 다음은 당신의 CLAUDE.md 차례입니다

6월 10일, TechCrunch는 "메모리 도구가 어떻게 AI 모델을 더 나쁘게 만들 수 있는가"라는 기사를 게재했습니다. 저는 그 기사가 올라온 밤에 읽었고, 다음 날 아침 제가 운영하는 MCP 서버 중 하나에 대한 수정 사항을 배포했습니다. 그래서 이 문제는 저에게 매우 개인적인 문제입니다.

AI를 개인화하기 위해 구축된 메모리 시스템, 즉 모델이 당신을 아는 것처럼 느끼게 하기 위해 당신의 선호도를 기억하는 시스템은 저장된 컨텍스트 (context)가 쌓임에 따라 모델의 정확도를 떨어뜨리고 더 아첨하는 (sycophantic) 성향을 만들 수 있습니다. 이 연구는 Dan Bikel이 이끄는 Writer에서 나왔으며, 피어 리뷰 (peer review) 하에 실제 시스템 (Mem0 및 Zep)을 테스트했습니다. 어시스턴트를 더 똑똑하게 만들어준다고 판매되었던 기능이, 그들의 테스트에서는 모델을 더 멍청하게 만들고 있었습니다.

대부분의 보도에서 생략된 부분은 이것입니다: 이것은 챗봇만의 문제가 아닙니다. 만약 당신이 CLAUDE.md 파일, 메모리 MCP, 학습된 라우팅 가중치 (routing weights), 또는 시간이 지남에 따라 축적되는 설정 (config)을 사용하여 코딩 에이전트 (coding agents)를 실행한다면, 당신도 정확히 동일한 실패 모드 (failure mode)에 노출됩니다. 메커니즘은 영구 상태 (persistent state)가 벡터 스토어 (vector store)에 있는지, 아니면 리포지토리 루트의 마크다운 (markdown) 파일에 있는지 상관하지 않습니다.

공통점

이러한 실패의 모든 버전에서 원인은 동일합니다. 관련성 (relevance)에 대한 개념도 없고 만료 (expiry)에 대한 개념도 없는 영구 상태를 가지고 있다는 점입니다. 시스템은 저장할 당시에는 사실이었던 무언가를 저장한 다음, 그것이 적합하든 아니든 상관없이 모든 것에 영원히 적용합니다.

연구에는 명확한 사례가 있습니다. 모델에게 사용자가 가장 좋아하는 책이 "Station Eleven"이라고 말합니다. 나중에 독서 취향과 전혀 상관없는 질문을 하면, 모델은 어쨌든 저장된 사실을 찾아내어 그 책을 베스트셀러 디스토피아 소설로 언급합니다. 닻 (anchor)이 속하지 않은 쿼리 (query)로 흘러 들어간 것입니다. 금융 분석 테스트에서는 상황이 더 악화되었습니다. 메모리가 활성화된 모델은 독립적으로 수치를 계산하는 대신 사용자의 오해를 채택하기 시작했습니다. 메모리는 지식을 추가한 것이 아니었습니다. 모델이 반드시 준수해야 한다고 느끼는 편향 (bias)을 추가한 것이었습니다.

패턴을 한 번 파악하고 나면, 여러분이 직접 만든 도구에서도 그 패턴이 보이기 시작할 것입니다. 구체적으로 네 가지 지점이 있습니다. 각각의 문제점과 해결 방법은 다음과 같습니다.

문제 1: 오래된 앵커 (Stale anchors)

학습된 상태 (Learned state)가 오래되어 쓸모없게 되었음에도 불구하고 계속해서 방향을 틀어버리는 현상입니다. 튜닝된 가중치 (Tuned weights), 캐싱된 순위 (Cached rankings), 누적된 사용 통계 (Accumulated usage stats) 등이 만약 6개월 전의 프로젝트 상태를 바탕으로 학습되었다면, 이들은 여전히 더 이상 존재하지 않는 코드베이스를 향해 동작을 유도하고 있을 것입니다. 모델이 학습한 내용 자체가 틀린 것이 아닙니다. 틀린 것은 바로 '시기 (when)'입니다.

해결책은 히스토리 로그 (History log)로부터 학습하는 모든 것에 대해 최신성 윈도우 (Recency window)를 적용하는 것입니다. 모든 시간대의 데이터를 바탕으로 제안 (Proposals)을 계산하지 마세요. 현재와 여전히 유사한 시간대의 데이터를 바탕으로 계산하세요.

from datetime import datetime, timedelta

def learn_weights(events, window_days=90, lifetime=False):
...

윈도우를 설정하는 것이 핵심입니다. lifetime 플래그가 존재하는 이유는 때때로 전체 장부 (Full ledger)가 정말로 필요할 때가 있기 때문입니다. 이는 호출부 (Call site)에서 명확히 읽을 수 있는 의도적인 선택이어야 하며, 조용한 기본값 (Silent default)이 되어서는 안 됩니다. 이것이 제가 해당 기사가 나간 다음 날 아침에 배포한 수정 사항입니다. 약 9줄 정도의 코드였습니다.

문제 2: 무관한 앵커와 선호도 누출 (Irrelevant anchors and preference leakage)

이는 일반화된

당신의 CLAUDE.md, AGENTS.md, .cursorrules는 임베딩 (embeddings) 대신 마크다운 (markdown)으로 작성되었을 뿐, 이 또한 메모리입니다. 그리고 이것들은 부패합니다. 함수 이름을 변경해도 파일은 여전히 이전 이름을 참조합니다. 디렉토리를 삭제해도 파일은 여전히 해당 경로를 가리킵니다. 3월에 추가한 규칙이 1월의 규칙과 모순되더라도, 두 규칙 모두 여전히 그 안에 남아 있습니다. 에이전트 (agent)는 이 모든 것을 절대적인 진리로 읽고 유령을 따릅니다.

해결책은 설정을 실제 데이터 (ground truth), 즉 코드에 대한 설정의 기억이 아닌 실제 코드와 대조하여 감사 (audit)하는 것입니다.

def audit_config(config, code_index):
    issues = []
    for symbol in config.referenced_symbols():
...

설정이 명시하는 모든 심볼 (symbol)은 인덱스 (index)에 존재해야 합니다. 모든 경로는 해결되어야 합니다. 모든 규칙은 주변 규칙과 일치해야 합니다. 실패하는 모든 항목은 사람이 삭제할 수 있도록 플래그 (flag)가 지정됩니다. 6개월 된 에이전트 파일이 얼마나 많은 사장된 데이터 (dead weight)를 떠안고 있는지 알게 되면 놀라실 겁니다.

문제 4: 조용한 자기 수정 (Silent self-modification)

이것은 작은 오류를 소용돌이로 만드는 문제입니다. 일부 시스템은 체크포인트 (checkpoint) 없이 자신의 메모리를 기록하거나 자신의 설정을 다시 작성합니다. 그래서 모델이 잘못된 추론을 하고, 이를 저장한 뒤, 다음 턴에 이를 "이미 알고 있는" 사실로 다시 읽어 들여 그 위에 내용을 쌓아 올립니다. 이러한 루프가 아첨 (sycophancy)이 눈덩이처럼 불어나는 방식입니다. 아무도 그것에게 '아니오'라고 말하지 않았기에, 모델은 매 라운드마다 잘못된 것에 대해 더욱 확신을 가지고 동의하게 됩니다.

규칙은 간단합니다. 제안하되, 절대 직접 쓰지는 마십시오.

def propose_memory_update(current, proposed):
    diff = render_diff(current, proposed)
    print(diff)
...

시스템은 원하는 무엇이든 제안할 수 있습니다. 다만 확정 (commit)만 할 수 없을 뿐입니다. 차이점 (diff)을 보여주고 명시적인 승인을 요구하십시오. 그러면 누군가가 변경 사항을 보고 "그건 틀렸어"라고 말할 수 있는 지점이 항상 존재하므로, 눈덩이는 결코 불어나지 않을 것입니다.

실제 해결책은 "메모리를 끄는 것"이 아닙니다

이 글의 어떤 내용도 메모리를 완전히 제거해야 한다고 주장하는 것이 아닙니다. 메모리는 유용합니다. 당신의 스택 (stack)과 관습 (conventions)을 기억하는 모델은 매 세션마다 당신을 새로 학습해야 하는 모델보다 더 나은 협업자입니다.

해결책은 위생적인 (hygiene) 메모리입니다. 오래된 상태가 만료되도록 하는 최신성 윈도우 (Recency windows), 앵커 (anchors)가 적합한 쿼리에만 작동하도록 하는 관련성 범위 지정 (Relevance scoping), 설정 (config)이 코드에서 벗어나지 않도록 하는 그라운드 트루스 감사 (Ground-truth audits), 그리고 오류가 감독 없이 누적되지 않도록 하는 인간 참여형 (Human-in-the-loop) 기록 방식이 그것입니다.

그리고 이 네 가지 보호 장치 아래에는 하나의 원칙이 있습니다. 근거 있는 검색 (Grounded retrieval)이 축적된 회상 (accumulated recollection)을 이깁니다. 쿼리 시점에 소스 아티팩트 (source artifact), 즉 라이브 코드, 현재 파일, 실제 인덱스로부터 컨텍스트 (context)를 도출하는 것이, 몇 달 전에 그 아티팩트에 대해 적어두었던 내용을 신뢰하는 것보다 훨씬 뛰어납니다. 회상은 부패하지만, 소스는 부패하지 않습니다.

이 네 가지 보호 장치를 직접 연결할 수도 있습니다. 위의 스케치들은 대부분의 형태를 보여주며, 그 어떤 것도 길지 않습니다.

또는 이러한 구조가 이미 적용되어 있는 무료 MCP 서버인 jCodeMunch (pip install jcodemunch-mcp)를 설치할 수도 있습니다. 여기서는 검색이 축적된 메모리 대신 실제 코드의 라이브 인덱스에 근거하며, 가중치 학습 (weight learning)은 기본적으로 최신성 윈도우 (recency-windowed)가 적용되어 있고, 내장된 audit_agent_config 도구가 여러분의 CLAUDE.md에 있는 부패를 찾아줍니다. 여기에서 확인하세요: https://github.com/jgravelle/jcodemunch-mcp

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0