본문 바로가기
AI2026년 8월 26일21분 읽기

에이전트 메모리 완전 정복 — LLM 에이전트가 장기 기억을 갖는 법

YS
김영삼
조회 11
에이전트 메모리 완전 정복 — LLM 에이전트가 장기 기억을 갖는 법

컨텍스트 윈도우는 기억이 아니라 책상이다. 세션이 끝나면 책상은 치워지고, 에이전트는 어제 나눈 대화도, 방금 고친 실수도 전부 잊는다.

LLM 에이전트에게 “장기 기억”을 심는 일은 단순히 프롬프트를 길게 붙이는 문제가 아니다. 무엇을 저장하고, 언제 꺼내오며, 무엇을 잊을지 결정하는 하나의 정보 시스템을 설계하는 일이다. 이 글은 단기와 장기 기억의 구분부터 벡터·요약·지식그래프 저장, 회수와 망각 전략, 반영(reflection)과 자기수정, MemGPT식 계층 메모리, 그리고 2026년 현재의 실무 아키텍처와 함정까지 깊게 정리한다.

4종
핵심 메모리 유형(대화·사실·절차·에피소드)
O(1)
계층 메모리의 목표: 대화가 길어져도 프롬프트 비용 상수화
3단계
저장 → 회수 → 망각의 기억 수명주기
top-k
벡터 회수의 기본 단위 — 하지만 정답은 아니다

컨텍스트 윈도우만으로는 왜 부족한가

2026년 현재 주요 모델의 컨텍스트 윈도우는 20만 토큰을 넘고, 일부는 100만 토큰급까지 열렸다. 그러면 “그냥 다 넣으면 되지 않나”라는 반론이 자연스럽다. 그러나 컨텍스트 윈도우는 휘발성 작업 공간이지 저장소가 아니다. 세션이 끝나면 사라지고, 다음 요청은 백지에서 시작한다. 사용자가 3주 전에 “나는 유당 불내증이 있어”라고 말했다면, 그 사실은 어딘가에 지속(persist)되어 있어야 다음 대화에서 살아난다.

비용과 지연도 무시할 수 없다. 대화가 길어질수록 매 턴마다 전체 히스토리를 다시 토큰화해 보내면 비용은 대화 길이에 비례해 선형으로 늘고, 지연도 함께 커진다. 100턴짜리 상담 세션에서 첫 턴의 내용을 100번째 턴까지 매번 재전송하는 것은 낭비다.

더 근본적인 문제는 주의 희석(attention dilution)이다. 윈도우가 크다고 모델이 그 안의 모든 정보를 균일하게 활용하지는 않는다. 중간에 파묻힌 핵심 사실은 무시되기 쉽고(이른바 “lost in the middle” 현상), 관련 없는 잡음이 많을수록 추론 품질이 떨어진다. 즉 컨텍스트에 넣을 것을 고르는 일 자체가 성능 문제다. 메모리 시스템의 본질은 “지금 이 순간의 추론에 정확히 필요한 것만 골라 윈도우에 올리는 것”이다.

참고“컨텍스트가 곧 기억”이라는 오해가 실무 사고의 대부분을 만든다. 컨텍스트 윈도우는 RAM에, 메모리 시스템은 디스크+인덱스에 가깝다. RAM을 아무리 키워도 전원을 끄면(세션 종료) 내용은 사라진다. 지속성은 별도 계층에서 책임져야 한다.

단기 기억과 장기 기억 — 두 개의 층

인지과학의 은유를 빌리면 에이전트 기억은 크게 둘로 나뉜다. 단기(작업) 기억은 현재 세션에서 진행 중인 추론에 필요한 정보다. 지금 컨텍스트 윈도우에 올라와 있는 최근 대화, 방금 호출한 도구의 결과, 진행 중인 작업 계획이 여기 해당한다. 빠르고 정확하지만 용량이 제한적이고 세션과 함께 사라진다.

장기 기억은 세션을 넘어 지속되는 외부 저장소다. 사용자 선호, 과거에 배운 사실, 반복 작업의 절차, 지난 상호작용의 요약이 여기 담긴다. 장기 기억은 무한히 커질 수 있지만, 필요할 때 회수(retrieval)를 거쳐 단기 기억(컨텍스트)으로 올려야만 추론에 쓸 수 있다. 결국 실전의 핵심 질문은 하나로 수렴한다. “방대한 장기 기억 중 지금 무엇을 단기로 끌어올릴 것인가.”

이 두 층 사이의 경계를 관리하는 정책이 메모리 시스템의 알맹이다. 무엇을 장기로 승격(commit)할지, 무엇을 단기에서 버릴지(evict), 회수한 것을 얼마나 오래 컨텍스트에 유지할지 — 이 결정들의 집합이 곧 “에이전트의 성격”을 만든다.

메모리의 네 가지 유형

실무에서 기억을 설계할 때는 저장소를 하나로 뭉뚱그리지 말고 종류별로 다른 정책을 적용해야 한다. 인지심리학의 분류를 차용한 아래 네 유형이 사실상 표준이 됐다.

유형담는 것예시전형적 저장 방식
대화 기억최근 주고받은 메시지“아까 말한 그 파일”의 지시 대상버퍼 + 롤링 요약
의미(사실) 기억시간과 무관한 사실·선호“사용자는 파이썬을 선호”키-값 / 지식그래프
절차 기억“어떻게 하는가”의 방법배포 체크리스트, 도구 사용법시스템 프롬프트 / 스킬 문서
에피소드 기억특정 시점의 사건 경험“지난주 그 버그를 이렇게 고쳤다”벡터 저장소(타임스탬프 포함)

구분이 중요한 이유는 갱신 정책이 다르기 때문이다. 사실 기억은 새 정보가 들어오면 기존 값을 덮어써야 한다(“사용자가 이사했다”면 옛 주소는 폐기). 반면 에피소드 기억은 덮어쓰지 않고 누적한다 — 과거 사건은 그 자체로 기록으로서 가치가 있기 때문이다. 절차 기억은 대개 사람이 관리하는 문서나 스킬로 두고, 대화 기억은 세션 단위로 요약해 압축한다. 이 정책 차이를 무시하고 모든 것을 하나의 벡터 저장소에 밀어넣으면 뒤에서 다룰 ‘메모리 오염’이 반드시 터진다.

저장 방식 — 벡터, 요약, 지식그래프

장기 기억을 물리적으로 어디에, 어떤 형태로 담을 것인가. 세 가지 대표 접근을 비교하자.

1) 벡터 메모리. 텍스트 조각을 임베딩해 벡터 저장소에 넣고, 질의 시 의미 유사도로 top-k를 회수한다. 유연하고 “대충 비슷한” 것을 잘 찾지만, 정확한 사실 갱신이나 관계 추론에는 약하다. 유사도 상위 k개가 곧 “정답 k개”는 아니라는 점이 함정이다.

2) 요약 메모리. 오래된 대화를 LLM으로 압축해 “롤링 요약”으로 유지한다. 토큰을 극적으로 줄이지만, 요약 과정에서 세부가 소실되고 요약의 요약이 반복되면 정보가 서서히 뭉개지는 손실 압축의 성격이 있다.

3) 지식그래프. 엔티티와 관계를 노드/엣지로 구조화해 저장한다. “A는 B의 관리자, B는 프로젝트 C의 담당” 같은 관계 질의와 다단계 추론에 강하고 갱신도 명시적이다. 대신 추출·정규화 비용이 크고 구축이 까다롭다.

방식강점약점적합한 곳
벡터유연·구축 쉬움·의미 검색갱신·정확성·관계추론 약함에피소드·문서 회상
요약토큰 절감·전체 맥락 유지세부 소실·손실 누적긴 대화 압축
지식그래프관계추론·명시적 갱신·정합성추출비용·구축 복잡사실·관계 중심 도메인

실전에서는 셋 중 하나를 고르는 문제가 아니라 계층으로 조합하는 문제다. 사실은 키-값이나 그래프에, 에피소드는 벡터에, 대화 흐름은 요약에 두고 회수 단계에서 합치는 하이브리드가 2026년의 실무 표준에 가깝다.

저장, 회수, 그리고 망각

메모리의 수명주기는 세 동작으로 이뤄진다. 각각이 독립된 설계 결정을 요구한다.

저장(write). 모든 발화를 저장하면 저장소는 잡음으로 가득 찬다. “고마워” 같은 무의미한 턴까지 임베딩할 이유는 없다. 저장 시점에 추출기(extractor)를 두어 “기억할 가치가 있는 사실/선호/사건”만 골라 구조화하는 것이 좋다. 흔히 이 단계에서 LLM에게 “이 대화에서 장기 기억에 남길 것을 JSON으로 뽑아라”라고 시킨다.

회수(read). 순진한 top-k 벡터 검색은 종종 실패한다. 개선책으로 (a) 최근성 가중, (b) 중요도 점수, (c) 유사도를 결합한 복합 랭킹이 쓰인다. Generative Agents 논문이 제시한 score = 유사도 + 최근성 + 중요도의 가중합이 대표적 패턴이다.

# 회수 랭킹: 유사도 + 최근성 + 중요도 결합
import math, time

def retrieval_score(mem, query_emb, now, w=(1.0, 0.9, 0.8)):
    sim = cosine(mem["embedding"], query_emb)          # 의미 유사도 0~1
    hours = (now - mem["last_access"]) / 3600.0
    recency = math.exp(-0.01 * hours)                   # 지수 감쇠(오래될수록 감점)
    importance = mem["importance"] / 10.0               # 저장 시 LLM이 매긴 1~10 점수
    ws, wr, wi = w
    return ws * sim + wr * recency + wi * importance

def retrieve(memories, query_emb, k=5):
    now = time.time()
    ranked = sorted(memories, key=lambda m: retrieval_score(m, query_emb, now), reverse=True)
    top = ranked[:k]
    for m in top:            # 회수된 기억은 접근 시각 갱신 → 자주 쓰는 기억이 살아남음
        m["last_access"] = now
    return top

망각(forget). 무한히 쌓기만 하면 회수 정밀도가 떨어지고 비용이 폭증한다. 인간처럼 잊는 메커니즘이 필요하다. 대표 전략은 (1) TTL/감쇠 — 오래되고 접근되지 않은 기억의 점수를 낮춰 자연 도태, (2) 병합/통합 — 유사한 여러 기억을 하나의 일반화된 기억으로 압축, (3) 모순 해소 — 새 사실이 옛 사실과 충돌하면 옛것을 무효화(soft delete)하는 것이다. 특히 사실 기억에서는 “덮어쓰기”가 곧 “망각”이다.

주의망각을 “하드 삭제”로 구현하면 감사(audit)와 롤백이 불가능해진다. 실무에서는 valid_from/valid_to 같은 시점 필드로 양방향 시간(bitemporal)을 남기는 소프트 무효화가 안전하다. “지금 유효한 사실”과 “과거에 유효했던 사실”을 모두 질의할 수 있어야 한다.

반영(reflection)과 자기수정

고급 메모리 시스템은 원시 로그를 쌓는 데 그치지 않고, 주기적으로 스스로 되돌아본다. 이를 반영(reflection)이라 한다. 예컨대 일정량의 새 관찰이 누적되면 에이전트가 “최근 관찰들로부터 내가 새로 알게 된 상위 수준의 결론은 무엇인가?”를 스스로 질문하고, 그 답을 다시 상위 기억으로 저장한다. 개별 사건(“사용자가 A를 물었다”)에서 일반 원리(“사용자는 성능 최적화에 관심이 많다”)를 증류하는 과정이다.

자기수정은 여기서 한 걸음 더 나간다. 에이전트가 과거의 실수를 에피소드로 저장해두고, 유사 상황에서 그 실패 기억을 회수해 같은 실수를 피한다. “지난번 이 API를 이렇게 호출했다가 실패했다”는 기록은 다음 시도의 프롬프트에 자동으로 끼어들어 행동을 교정한다. 이는 파라미터를 바꾸지 않고도(가중치 재학습 없이) 경험으로 행동을 개선하는, 일종의 비모수적 학습이다.

다만 반영은 공짜가 아니다. 반영 자체가 LLM 호출이라 비용이 들고, 잘못된 일반화(성급한 결론)를 기억으로 굳히면 오히려 해롭다. 반영 결과에도 신뢰도와 출처를 붙여, 나중에 반증되면 철회할 수 있게 설계해야 한다.

MemGPT식 계층 메모리 — 운영체제 은유

메모리 설계에 큰 영향을 준 발상이 MemGPT다. 핵심 은유는 가상 메모리(virtual memory)다. 운영체제가 물리 RAM보다 큰 주소 공간을 다루기 위해 RAM과 디스크 사이에서 페이지를 스왑하듯, LLM도 제한된 컨텍스트 윈도우(=RAM)와 무한한 외부 저장소(=디스크) 사이에서 정보를 페이징한다.

여기서 결정적인 전환은, 에이전트가 자기 메모리를 스스로 관리하는 도구를 호출한다는 점이다. 컨텍스트가 꽉 차면 모델이 직접 “오래된 대화를 저장소로 내려라(memory_write)”, “관련 기억을 불러와라(memory_search)” 같은 함수를 호출한다. 메모리 관리 정책 일부를 사람이 하드코딩하는 대신 LLM 자신에게 위임하는 것이다.

# MemGPT식 자기관리 메모리: 모델이 호출하는 도구로 노출
tools = [
  {"name": "core_memory_append",
   "description": "항상 컨텍스트에 유지되는 핵심 메모리(예: 사용자 프로필)에 추가",
   "parameters": {"section": "str", "content": "str"}},
  {"name": "recall_search",
   "description": "대화 기록 저장소에서 과거 대화를 의미 검색",
   "parameters": {"query": "str", "top_k": "int"}},
  {"name": "archival_insert",
   "description": "무제한 장기 저장소에 사실/문서를 보관",
   "parameters": {"text": "str"}},
]

# 컨텍스트 압박 시 모델 스스로 결정하도록 유도하는 시스템 지침
SYSTEM = """당신의 컨텍스트는 유한하다. 중요한 사실은 core_memory_append로 고정하고,
오래된 세부는 archival_insert로 내려보낸 뒤, 필요할 때 recall_search로 다시 가져와라.
컨텍스트에 없는 것을 안다고 가정하지 말고, 모르면 먼저 검색하라."""

이 구조의 장점은 대화가 아무리 길어져도 프롬프트 크기가 대략 상수로 유지된다는 점이다. 단점은 모델이 메모리 관리 판단을 틀리면(중요한 걸 안 저장하거나, 엉뚱한 걸 회수) 성능이 흔들린다는 것. 그래서 실무에서는 완전 자율보다 사람이 정한 규칙 + 모델 판단의 하이브리드를 쓴다.

실무 아키텍처와 함정

지금까지의 조각을 모으면 전형적인 2026년 에이전트 메모리 파이프라인은 이렇게 그려진다.

  • 계층: 항상 붙는 코어 메모리(사용자 프로필·현재 목표) + 세션 요약 + 외부 장기 저장소(벡터+그래프 하이브리드).
  • 쓰기 경로: 대화 종료/일정 주기마다 추출기가 사실·에피소드·선호를 뽑아 유형별 저장소에 커밋(사실은 덮어쓰기, 에피소드는 누적).
  • 읽기 경로: 새 질의가 오면 복합 랭킹으로 소수의 관련 기억만 회수해 컨텍스트에 주입.
  • 유지보수: 백그라운드 반영·병합·망각 잡이 저장소를 정리.

그러나 이 그림에는 세 가지 큰 함정이 숨어 있다.

오염(poisoning). 잘못된 사실이 한번 장기 기억에 들어가면 이후 모든 대화를 오염시킨다. 사용자의 농담이나 일시적 발언을 “영구 선호”로 저장하거나, 모델의 환각을 사실로 굳히는 경우다. 방어책은 저장 전 검증, 출처·신뢰도 태깅, 그리고 모순 발생 시 최신·고신뢰 소스를 우선하는 정책이다. 특히 외부 입력(웹·문서)에서 유래한 기억은 프롬프트 인젝션의 통로가 되므로 사용자 확정 사실과 분리해 다뤄야 한다.

프라이버시. 장기 기억은 본질적으로 개인정보의 축적이다. 무엇을 저장할지에 대한 동의, 사용자별 격리(멀티테넌시에서 기억이 새어 다른 사용자에게 회수되면 심각한 사고), 삭제 요청권(“잊혀질 권리”)에 대응하는 타깃 삭제 기능이 필수다. 민감정보는 저장 시점에 마스킹하거나 아예 배제하는 정책이 안전하다.

비용과 지연. 메모리는 공짜 성능이 아니다. 매 턴 추가되는 추출·임베딩·검색 호출, 반영 잡, 저장소 운영비가 모두 든다. 회수한 기억이 오히려 잡음이 되어 품질을 떨어뜨리는 역효과도 흔하다. “메모리를 켰더니 느려지고 더 틀린다”는 결과가 실제로 자주 나온다. 메모리 없는 베이스라인과 항상 비교하고, 회수 개수와 주입량을 보수적으로 잡는 것이 정석이다.

참고메모리 시스템의 성능은 “얼마나 많이 기억하느냐”가 아니라 “지금 필요한 것을 얼마나 정확히 꺼내느냐”로 평가해야 한다. 회수 정밀도(precision)와 재현율(recall), 그리고 잘못된 기억의 주입률을 별도 지표로 측정하라. 저장량은 자랑거리가 아니라 관리 대상이다.

2026년의 동향

몇 가지 흐름이 뚜렷하다. 첫째, 메모리가 플랫폼 기본 기능으로 흡수되고 있다. 과거엔 각자 프레임워크로 붙이던 것을, 이제는 에이전트 런타임과 API가 세션 간 지속 메모리를 1급 기능으로 제공하는 방향으로 간다. 둘째, 하이브리드(벡터+그래프+구조화)가 표준이 되며 단일 벡터 저장소 접근은 한계가 분명해졌다. 셋째, 시간 인식(temporal) 메모리 — 사실의 유효 기간을 추적해 “언제부터 언제까지 참이었는가”를 다루는 것 — 가 진지하게 다뤄진다.

넷째, 초장문 컨텍스트(수백만 토큰)와 메모리 시스템은 경쟁이 아니라 보완 관계로 자리 잡았다. 큰 윈도우가 있어도 지속성·비용·주의 희석 문제는 그대로이기 때문이다. 다섯째, 평가와 벤치마크가 성숙하며, “메모리를 붙였다”가 아니라 “장기 일관성과 개인화가 실제로 개선됐는가”를 측정하려는 시도가 늘고 있다. 요약하면, 에이전트 메모리는 실험적 애드온에서 프로덕션 인프라로 넘어가는 단계에 있다.

자주 묻는 질문

컨텍스트 윈도우가 100만 토큰이면 메모리 시스템이 필요 없지 않나요?

아닙니다. 큰 윈도우는 “한 세션 안에서” 더 많은 정보를 다룰 뿐, 세션이 끝나면 내용이 사라집니다. 지속성(다음 날 대화에서 어제 사실을 기억), 비용(매 턴 전체 재전송의 비효율), 주의 희석(관련 없는 정보가 많을수록 품질 저하)은 윈도우를 키워도 남습니다. 메모리 시스템은 “세션을 넘는 지속”과 “필요한 것만 선별 주입”을 담당하므로 오히려 큰 윈도우와 보완적입니다.

RAG와 에이전트 메모리는 같은 것인가요?

겹치지만 다릅니다. RAG는 보통 고정된 외부 지식(문서, 위키)을 질의 시 검색해 넣는 읽기 중심의 정적 지식 보강입니다. 에이전트 메모리는 상호작용에서 스스로 쓰고, 갱신하고, 잊는 동적 개인 기억입니다. 즉 메모리는 “쓰기 경로와 망각”이 핵심이고, 사용자별로 시간에 따라 변합니다. 구현 기술(임베딩·벡터 검색)은 공유하지만 목적과 수명주기가 다릅니다.

모든 대화를 다 저장하면 안 되나요?

권장하지 않습니다. 무차별 저장은 저장소를 잡음으로 채워 회수 정밀도를 떨어뜨리고, 비용과 프라이버시 위험을 키웁니다. 저장 시점에 “기억할 가치가 있는가”를 판단하는 추출 단계를 두고, 사실·선호·중요 사건만 구조화해 남기는 편이 성능과 안전 모두에 유리합니다. 원시 로그가 필요하면 별도 아카이브에 두되 능동 메모리와 분리하세요.

메모리 오염을 어떻게 막나요?

세 가지를 병행합니다. (1) 저장 전 검증 — 환각이나 일시적 발언을 영구 사실로 굳히지 않도록 확정된 정보만 커밋. (2) 출처·신뢰도 태깅 — 각 기억에 근거와 확신도를 붙여 모순 시 고신뢰·최신 소스를 우선. (3) 격리 — 외부 웹·문서에서 온 내용은 프롬프트 인젝션 통로가 될 수 있으므로 사용자 확정 사실과 분리해 다룹니다. 그리고 잘못 저장된 기억을 사후에 무효화(soft delete)할 수 있는 경로를 반드시 마련하세요.

작은 프로젝트에서 지식그래프까지 도입해야 하나요?

대개는 과합니다. 초기에는 사용자별 키-값 사실 저장 + 세션 요약만으로도 개인화의 80%를 얻습니다. 관계 기반 다단계 추론(“A의 상사의 프로젝트” 같은)이 반복적으로 필요해질 때 비로소 그래프를 도입하세요. 벡터 저장소도 “과거 대화 회상”이 실제로 필요할 때 추가하는 것이 좋습니다. 메모리는 필요가 증명된 계층부터 점진적으로 쌓는 것이 정석입니다.

메모리를 붙였는데 오히려 답변이 나빠졌어요. 왜죠?

흔한 일입니다. 회수한 기억이 현재 질문과 무관하면 잡음이 되어 추론을 방해합니다(관련 없는 top-k 주입, 오래된 사실의 갱신 실패, 과도한 주입량 등이 원인). 해결책은 회수 개수를 줄이고, 최근성·중요도를 결합한 랭킹으로 정밀도를 높이며, 모순된 옛 사실을 확실히 무효화하는 것입니다. 무엇보다 메모리 없는 베이스라인과 항상 비교해 실제 개선이 있을 때만 켜야 합니다.

댓글 0

아직 댓글이 없습니다.
Ctrl+Enter로 등록