
AI 에이전트를 위한 메모리 유형: 에이전트가 모든 것을 잊어버린다면? 해결 방법
요약
AI 에이전트가 세션 간 정보를 유지하지 못하는 '메모리 감퇴' 문제를 해결하기 위한 다양한 메모리 설계 전략을 다룹니다. 단순히 컨텍스트 윈도우를 늘리는 대신, 비용 효율적이고 정확한 정보 검색을 위한 메모리 유형과 읽기/쓰기 경로 설계의 중요성을 설명합니다.
핵심 포인트
- 컨텍스트 윈도우 확장만으로는 비용과 세션 유지 문제를 해결할 수 없음
- 메모리는 모델 내부가 아닌 외부 저장소와 하네스(harness)를 통해 구축됨
- 효율적인 메모리 관리를 위해 쓰기(Writing)와 읽기(Reading) 경로 설계가 필수적임
- 정보의 양보다 질문과 관련된 정제된 컨텍스트를 선택하는 것이 핵심
당신의 AI 에이전트는 데모에서는 완벽하게 작동합니다. 하지만 다음 날 실제 사용자가 돌아오면, 에이전트는 이전 대화의 아무것도 기억하지 못합니다. 사용자의 이름도, 선호도도, 이미 완료한 구매 내역도 기억하지 못합니다. 모든 세션이 처음부터 다시 시작됩니다.
"내 AI 에이전트는 세션 사이에 모든 것을 잊어버린다"는 에이전트에 대한 가장 흔한 불만 중 하나입니다. 연구에서는 이를 **메모리 감퇴 (memory decay)**라고 부르지만, 모델이 고장 난 것은 아닙니다. 모델은 설계상 무국적(apátridas) 상태입니다. 메모리는 모델 주변에 당신이 구축하는 하네스 (harness), 도구, 상태 및 저장소에 속합니다. 이는 실제 트레이드오프 (trade-offs)가 존재하는 설계 결정입니다.
이 포스트는 지도 역할을 할 것입니다. 가장 일반적인 메모리 유형, 각 유형의 용도, 비용, 그리고 이들 사이에서 어떻게 선택해야 하는지를 다룹니다.
왜 "더 큰 컨텍스트 윈도우 (context window)를 사용하는 것"이 효과가 없는가
유혹적인 해결책은 매 턴마다 전체 대화 기록을 다시 보내는 것입니다. 첫 일주일 동안은 작동합니다. 하지만 그 이후에는 다음과 같은 문제가 발생합니다:
- 컨텍스트 윈도우 (context window)는 비용이 많이 듭니다. 매 턴마다 동일한 토큰을 다시 처리하는 비용을 지불해야 하며, 이는 영구적입니다. 비용은 기록의 길이와 함께 증가하며, 기록의 대부분이 현재 질문과 무관하더라도 마찬가지입니다.
- 세션이 유지되지 않습니다. 사용자가 내일 돌아왔을 때, 어딘가에 저장해 두지 않았다면 다시 보낼 기록이 없습니다.
- 더 많은 컨텍스트가 더 좋은 컨텍스트는 아닙니다. 관련성 있는 정제된 컨텍스트를 검색하는 것이 전체 기록을 포함하는 것보다 정확도와 비용 측면 모두에서 우수합니다. 선택이 볼륨보다 중요합니다.
따라서 진짜 질문은 "어떻게 모든 것을 저장할 것인가?"가 아니라, "내 에이전트가 정말로 무엇을 기억해야 하며, 어디에서 어떻게 그것을 다시 찾을 것인가?"입니다.
메모리는 어떻게 모델에 전달되는가?
모델은 오직 자신의 컨텍스트 창 (Context Window)만을 봅니다. 모든 메모리는 양 끝단에서 동일한 방식으로 작동합니다:
- 쓰기 경로 (Writing Path): 대화 중 또는 대화 후에, 저장할 가치가 있는 무언가를 외부 저장소 (Store)에 저장합니다.
- 읽기 경로 (Reading Path): 응답하기 전에, 에이전트는 현재 질문과 관련된 소수의 항목을 검색하여 프롬프트 (Prompt)의 일부로 또는 도구 (Tool)의 결과로서 컨텍스트에 배치합니다.
저장소는 모델과 직접 대화하지 않습니다. 메모리 유형을 구분 짓는 것은 중간 단계, 즉 올바른 항목을 다시 가져오기 위해 어떻게 찾아내는가입니다: 키 (Key)를 통해서, 의미 (Meaning)를 통해서, 또는 관계 (Relation)를 통해서 말입니다.
AI 에이전트의 주요 메모리 유형은 무엇인가? 메모리가 주로 머무는 네 가지 장소
전체적인 구도를 관리하기 쉽게 나누려면, 메모리가 어디에 머무는가 (저장 유형)와 어떻게 관리되는가 (기능)를 구분해야 합니다. 먼저 유형부터 살펴보겠습니다.
| 유형 | 쿼리 모델 (Query Model) | 지연 시간 프로필 (Latency Profile) | 인프라 (Infrastructure) | 최적의 용도 |
|---|---|---|---|---|
| 키-값 (Key-value) | 키를 통한 정확한 검색 | 무시할 수 있는 수준 (Negligible) | 없음: 상태(State) + 세션 레이어 | 이름을 알고 있는 사실들 |
| ... |
유형을 가장 크게 가르는 차이점은 접근 방식입니다. 저장된 메모리는 동일하더라도, 그것에 접근하는 경로는 다릅니다:
1. 키-값 (Key-value) 메모리: 명명된 키 아래의 구조화된 사실들
사용자의 이름, 언어, 플랜: 에이전트의 도구들이 읽고 쓰는 키 아래에 저장된 사실들입니다. 임베딩 (Embeddings)도, 검색 인프라 (Search Infrastructure)도 필요하지 않습니다.
특징. 빠르고, 저렴하며, 키를 알고 있다면 정확합니다. 지속성 (Persistence)은 단계적입니다: 프로세스 내 상태 (State in process), 디스크의 세션 파일, 클라우드 저장소의 세션 객체 순으로 확장됩니다.
사용 시점: 기억할 가치가 있는 정보가 프로필, 선호도, 설정, 카운터와 같이 명확한 이름을 가지고 있을 때 사용하세요. 이는 사람들이 예상하는 것보다 더 많은 범위를 포괄하며, 모든 에이전트가 시작해야 할 지점입니다.
한계: 모든 읽기 작업은 누군가가 사전에 설계한 검색(search)입니다. 스토어(store)에 다음과 같은 항목이 있다고 가정해 봅시다:
dietary_notes: "vegetariana, alergia severa a los mariscos"
| 사용자의 질문 | 발생하는 현상 |
|---|---|
| "제 식단 관련 메모가 무엇인가요?" | dietary_notes에 매핑됨 → 찾음 ✅ |
| "저녁 식사 때 무엇을 피해야 하나요?" | 그것이 어떤 키(key)에 해당하나요? 매핑되는 것이 없음 → 찾지 못함 ❌ |
정답은 내내 스토어에 있었습니다. 두 번째 질문은 단순히 어떤 키도 명시하지 않았으며, 이 스토어에 진입하는 유일한 방법은 _키(key)를 통해서_이기 때문입니다. 다음에 설명할 각 유형은 새로운 진입 방식을 추가합니다.
개선 팁:
- 항목에 버전을 부여하세요. 선호도가 변경되면 이전 값 옆에 모순되는 내용을 추가하는 대신, 버전을 업데이트하고 올리세요. 이렇게 하면 변화 과정이 가시적으로 남고 스토어는 깔끔하게 유지됩니다.
- 양식(form)이 아닌 행동에서 배우세요. 사용자가 실제로 하는 행동(무엇을 구매하고, 무엇을 선택하고, 무엇을 거부하는지)은 사용자가 작성한 그 어떤 것보다 선호도를 더 신뢰할 수 있게 알려줍니다.
- 지속성(durability)의 계단을 의도적으로 높이세요: 임시 작업을 위한 프로세스 내 상태(state in process), 재방문 사용자를 위한 세션(sessions) 순으로 확장합니다.
2. 벡터 메모리 (Vector Memory): 이름이 아닌 의미로 검색하기
각 메모리를 한 번 벡터(vector)로 임베딩(embed)하고, 들어오는 질문을 임베딩한 뒤, 가장 가까운 이웃(nearest neighbors)을 검색합니다. 키-값(key-value) 방식이 답할 수 없었던 동일한 메모리와 동일한 질문을 다시 시도해 봅시다:
| 사용자의 질문 | 발생하는 현상 |
|---|---|
| "저녁 식사 때 무엇을 피해야 하나요?" | 임베딩됨 → 가장 가까운 이웃은 "vegetariana, alergia severa a los mariscos"임 → 찾음 ✅ |
질문과 메모리 사이에 공유되는 단어는 없습니다. 하지만 이들은 의미(meaning) 측면에서 가깝고, 인덱싱(indexed)된 것은 바로 그 의미입니다.
Key-value와의 경계선: 키(key)를 알고 있나요, 아니면 의도(intention)만 알고 있나요?
특징. 사람들이 혼동하는 두 가지 비용이 있습니다: 인덱스(index)를 조회하는 비용과 질문을 임베딩(embedding)하는 비용이며, 일반적으로 임베딩 호출 비용이 조회 자체보다 더 많이 듭니다. 임베딩 호출이 비용의 대부분을 차지합니다.
사용 시점: 메모리가 노트, 에피소드, 히스토리로 성장하여 질문이 예측 불가능한 각도에서 접근하게 될 때 사용하세요.
사용하지 말아야 할 때: 키 기반 검색(key-based search)으로 충분할 때(사용자의 계획을 가져오기 위해 임베딩 비용을 지불하지 마세요), 또는 질문이 _관계(relationships)_에 관한 것일 때입니다. 아래 내용을 더 참조하세요.
개선 팁:
- 작성하는 시점에 한 번만 임베딩하세요. 질문은 조회 시점에만 임베딩되어야 합니다.
- 하나의 커다란 인덱스 대신 메모리 유형(사실 vs 선호도 vs 에피소드)별로 파티셔닝(partitioning)하세요. 이렇게 하면 검색이 더 정확해지고 정리가 정교해집니다.
- 자체 지연 시간(latency)을 측정하세요. 발표된 수치는 참고용일 뿐 보증 수치가 아닙니다.
3. 그래프 메모리 (Graph Memory): 엔티티(entities)와 그들 사이의 관계
이제 키(key)도, 의미(meaning)도 답할 수 없는 질문을 던져보겠습니다. 저장소(store)에는 세 가지 분리된 사실이 있습니다: Maya는 X 회사에서 일한다 · X 회사는 Y 그룹에 속한다 · Y 그룹은 스페인에서 운영된다.
| 진입 방식 | 결과 |
|---|---|
| 키(key)를 통한 진입 | 일치하는 키 없음 → ❌ |
| ... |
정답은 어떠한 개별 메모리에도 존재하지 않습니다. 정답은 메모리들을 관통하는 경로(path)로서 존재하며, 경로를 따라갈 수 있는 진입 방식이 필요합니다.
특징. 밀리초(millisecond) 단위의 쿼리, 본질적인 내구성, 그리고 유일하게 **추적 가능(traceable)**하다는 점입니다. 즉, 답변과 함께 그 답변을 생성한 사실의 사슬(chain of facts)이 제공됩니다. 비용은 실제 운영을 위한 데이터베이스와 사고를 위한 스키마(schema)가 필요하다는 점입니다.
사용 시점: 도메인이 본질적으로 연결되어 있고(사람, 조직, 의존성 등), 사용자가 이러한 연결을 가로지르는 질문을 던질 때 사용하세요.
사용하지 말아야 할 때: 메모리가 독립적인 노트 형태일 때입니다. 서로 연결되지 않은 노드들로 구성된 그래프는 불필요한 단계를 추가한 느린 키-값 (key-value) 저장소에 불과합니다.
개선 팁:
- 벡터 인덱스 (vector index)를 그래프
_내부_에 배치하세요 (최신 그래프 저장소는 이를 지원합니다): 유사도 (similarity) 검색이 진입점을 찾고, 트래버설 (traversal)이 답변을 찾아냅니다. 이 조합이 다음에 설명할 "하이브리드 (hybrid)" 패턴입니다. - 모든 것을 모델링하는 대신, 실제 질문("~에서 내가 아는 사람은 누구인가?")을 바탕으로 관계를 설계하세요. 추가하는 각 엣지 (edge) 유형은 반드시 쿼리 (query) 효율을 높여야 합니다.
- 영향 범위 (blast radius)를 주의하세요: 연결성은 힘인 동시에 취약점이기도 합니다 (아래의 hygiene 섹션 참조).
4. 하이브리드 (Hybrid): 에이전트 내의 벡터 + 그래프
어떤 질문들은 두 가지 움직임을 동시에 필요로 합니다: "내가 좋아했던 것과
비슷한 것을 찾아줘, 하지만 내가
관계가 있는 공급업체의 것만.". 어떤 단일 진입 방식도 이 질문에 혼자 답할 수 없지만, 이들을 체인(chain)으로 연결하면 가능합니다:
유사도 검색이 후보를 찾고, 트래버설이 관계에 따라 필터링합니다.
하이브리드 방식은 두 가지 형태를 취합니다: 두 가지 움직임을 모두 지원하는 저장소(벡터 인덱스가 내장된 그래프 데이터베이스), 또는 에이전트가 질문에 따라 선택할 수 있도록 나란히 배치된 두 개의 전문화된 저장소입니다. 어떤 방식이든 에이전트는 두 가지 진입 방식을 모두 얻게 됩니다. 여기에는 관리형 버전(managed version)과 직접 구축하는 버전(build-it-yourself version)이 있으며, 이들 사이의 트레이드오프 (trade-off)가 바로 이 시리즈의 코드 포스트들이 측정하고자 하는 핵심입니다.
역량 계층 (Capabilities layer): 메모리와 어질러진 서랍을 구분하는 것
유형(types)은
어디에 저장할지를 결정합니다. 유형과 독립적인 세 가지 역량은
_무엇을, 무엇을 하지 않을지, 그리고 왜_를 결정합니다.
선택적 메모리 (Selective memory): 에이전트가 정말로 기억해야 할 것은 무엇인가?
실제 대화는 지속적인 사실, 사소한 잡담, 선호도 및 사건들이 뒤섞여 있습니다. 모든 것을 저장하면 메모리는 비용이 많이 드는 노이즈(noise)가 됩니다. 아무것도 저장하지 않으면 기억상실증에 걸린 에이전트로 돌아가게 됩니다. 누군가, 혹은 무언가가 반드시 **선택(select)**해야 합니다.
누군가는 그 결정을 내려야 하며, 선택할 수 있는 대상에는 세 가지 옵션이 있습니다:
- 에이전트 자신: 대화 중간에 호출하는 메모리 도구(memory tools)를 사용합니다. 구축 비용은 무료이지만, 선택의 품질은 대화에 집중하느라 바쁜 모델의 성능에 달려 있으며, 선택 작업이 매 턴(turn)의 지연 시간(latency)에 영향을 미칩니다.
- 자체 추출기 (Your own extractor): 대화 경로 밖에서 매 턴이 끝난 후 실행됩니다. 메모리 유형별로 특화된 프롬프트(prompts)를 사용하며, 각 프롬프트는 "저장할 가치가 없음"이라고 응답할 수 있도록 설정됩니다. 단일 목적 프롬프트는 멀티태스킹(multitasking)보다 성능이 뛰어나며, 대화 흐름을 방해하지 않습니다. 비용은 사용자가 프롬프트를 직접 관리하고 토큰(tokens) 비용을 부담해야 한다는 점입니다.
- 관리형 서비스 (Managed service): Amazon Bedrock AgentCore Memory와 같은 서비스입니다. 가공되지 않은 턴(raw turns)을 전송하면, 내장된 전략(의미적 사실, 사용자 선호도, 요약, 에피소드적 메모리)이 대신 추출해 줍니다. 쓰기 경로(write path)가 더 저렴하고 유지 관리해야 할 파이프라인(pipeline)이 없습니다. 트레이드오프(trade-off)로는 추출이 비동기식으로 이루어져(메모리가 즉시가 아닌 약간의 지연 후에 조회 가능함), 저장/폐기 기준을 사용자가 직접 조정할 수 없다는 점이 있습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기

