에이전트 메모리를 구축하는 것을 멈추세요. 당신의 에이전트에는 필요하지 않습니다.
요약
에이전트 개발 시 불필요하게 구축되는 5가지 메모리 유형을 분석하고, 실제 운영 환경에서 단기 대화 기록만이 유효하게 사용됨을 경험적으로 증명합니다. 복잡한 메모리 시스템 구축 대신 실질적인 필요성에 집중할 것을 권고합니다.
핵심 포인트
- 에이전트 메모리 중 단기 대화 기록만이 실제 활용도가 높음
- 장기 에피소드, 절차적, 의미론적, 감정 메모리는 과잉 엔지니어링일 가능성 존재
- 벡터 데이터베이스 기반의 검색이 실제로는 거의 사용되지 않을 수 있음
- 에이전트 설계 시 복잡한 메모리 구조보다 실질적인 컨텍스트 유지에 집중 필요
에이전트 메모리를 구축하는 것을 멈추세요. 당신의 에이전트에는 필요하지 않습니다.
지난주에 제 Redis 대시보드를 살펴보다가 한 가지 사실을 깨달았습니다. 에이전트 메모리 데이터베이스 5개 중 4개는 7일 동안 쿼리(Query)가 단 한 건도 없었습니다. 저는 그것들을 구축하는 데 3주를 보냈습니다. 그것들은 사용하지 않는 헬스장 회원권처럼 먼지만 쌓인 채 방치되어 있었습니다.
에이전트는 정확히 한 가지 유형의 메모리만 사용합니다. 나머지 네 가지는요? 한 번도 쿼리되지 않았습니다. 읽히지도 않았고, 쓰이지도 않았습니다.
이 글은 에이전트 메모리를 어떻게 구축하는지에 대한 글이 아닙니다. 왜 제가 잘못된 것을 만들었는지, 그리고 그 모든 것을 걷어냈을 때 무엇을 배웠는지에 대한 글입니다. 이전에 저는 제 AI 에이전트가 계속 고장 났던 이유와 제가 변경한 점에 대해 썼는데, 이 메모리 실험은 그 여정의 일부였습니다.
제가 구축했던 다섯 가지 메모리 유형
제가 찾을 수 있는 모든 에이전트 메모리 논문과 블로그 포스트를 기반으로 구현한 내용은 다음과 같습니다:
1. 단기 대화 기록 (Short-term conversation history). 컨텍스트(Context)에 저장된 대화의 마지막 N개 턴(Turn)입니다. 이는 에이전트가 세 번의 대화마다 "방금 내가 뭐라고 했지?"라고 묻지 않고 대화를 이어가는 데 사용하는 메모리입니다.
2. 장기 에피소드 메모리 (Long-term episodic memory). 의미론적 유사성(Semantic similarity)에 따라 인덱싱된 과거 대화의 벡터 데이터베이스(Vector database)입니다. 사용자가 "지난주에 우리가 이야기했던 그것"이라고 언급하면, 에이전트는 이를 검색(Retrieve)합니다.
3. 절차적 메모리 (Procedural memory). 학습된 워크플로(Workflow)와 도구 사용(Tool-use) 패턴입니다. 만약 사용자가 빌드 실패 후 항상 배포 로그를 요청한다면, 에이전트는 이를 선제적으로 가져오는 법을 학습합니다.
4. 의미론적 지식 베이스 (Semantic knowledge base). 사용자의 프로젝트, 팀, 선호도에 관한 사실들입니다. "스테이징 서버의 이름은 staging-01이다.", "팀은 이메일보다 Slack을 선호한다.", "API 키는 ~/.config/app/credentials에 저장되어 있다."와 같은 정보입니다.
5. 감정 메모리 (Emotional memory). 사용자 피드백 및 감정 추적입니다. 사용자가 응답에 대해 좌절감을 표현하면, 에이전트는 이를 기억하고 향후 응답을 조정합니다.
저는 이 다섯 가지를 모두 구현했습니다. 각 유형에 대한 검색 함수(Retrieval functions)를 작성했습니다. 메모리를 통합하기 위한 크론 잡(Cron jobs)을 설정했습니다. 검색 정확도를 추적하기 위한 메트릭(Metrics)도 추가했습니다.
그 후 저는 일주일 동안 제 에이전트가 작동하는 것을 지켜보았습니다.
실제로 사용된 것
에이전트는 단기 대화 기록(short-term conversation history)만을 사용했습니다. 오로지 그것뿐이었습니다.
제가 서비스를 배포하라고 요청했을 때, 에이전트는 세 차례 전의 대화에서 언급된 서비스 이름을 기억했습니다. 로그를 확인하라고 요청했을 때, 에이전트는 제가 어떤 배포에 대해 말하고 있는지 알고 있었습니다. 롤백(rollback)을 요청했을 때, 에이전트는 이전 버전을 기억했습니다.
하지만 에이전트는 에피소드 메모리(episodic memory)를 단 한 번도 조회하지 않았습니다. 단 한 번도 말이죠. 벡터 데이터베이스(vector database)에는 847개의 대화가 인덱싱되어 있었지만, 검색(retrieval)된 것은 0건이었습니다.
절차적 메모리(procedural memory)도 전혀 사용하지 않았습니다. 저는 제 워크플로(workflows)를 학습하도록 설계된 시스템을 구축했습니다. 하지만 에이전트는 아무것도 배우지 않았습니다. 모든 배포는 매번 새로운 대화로 시작되었습니다.
시맨틱 지식 베이스(semantic knowledge base)를 읽지도 않았습니다. 저는 서버 이름, API 엔드포인트(endpoints), 팀 선호도 등을 저장해 두었습니다. 하지만 에이전트는 매번 저에게 그것들을 다시 물어보았습니다.
감정 메모리(emotional memory)는 어땠을까요? 에이전트는 제가 좌절하고 있는지조차 확인하지 않았습니다. 에이전트는 사과를 한 뒤, 똑같은 실수를 다시 반복했습니다.
나머지 네 가지가 실패한 이유
저는 이를 디버깅(debugging)하는 데 일주일을 보냈습니다. 왜 에이전트는 제가 구축한 다섯 가지 메모리 시스템 중 네 가지를 무시하는 것일까요?
답은 불편하게도 이렇습니다: 저는 제 에이전트에게 존재하지도 않는 문제들을 해결하기 위해 메모리를 구축했습니다.
에피소드 메모리가 실패한 이유는 제 대화가 짧기 때문입니다. 저는 에이전트와 한 시간 동안 대화를 나누지 않습니다. 저는 5회 정도의 짧은 대화를 나눕니다. "서비스 X를 배포해줘." "완료했습니다." "로그를 확인해줘." "여기 있습니다." "롤백해줘." "완료했습니다." 지난주의 대화는 이번 주의 작업과 무관하기 때문에, 지난주로부터 검색해 올 내용이 전혀 없습니다.
절차적 메모리가 실패한 이유는 제 워크플로가 명시적(explicit)이기 때문입니다. 저는 에이전트가 제가 다음에 무엇을 원하는지 추측하기를 원하지 않습니다. 저는 직접 말해주고 싶습니다. 제가 로그를 볼 준비가 되면, 제가 로그를 요청할 것입니다. 에이전트가 선제적으로 로그를 가져오는 것은 도움이 되는 것이 아니라 주제넘은 행동입니다. 만약 에이전트가 잘못 추측한다면, 저는 그것을 바로잡아야 하며, 이는 그냥 요청하는 것보다 더 많은 시간이 걸립니다.
환경이 변하기 때문에 의미론적 메모리 (Semantic memory)는 실패했습니다. 지난달 스테이징 서버는 staging-01이었습니다. 이제는 staging-02입니다. API 엔드포인트(API endpoint)는 v1에서 v2로 이동했습니다. 자격 증명(Credentials)은 교체되었습니다. 지식 베이스(Knowledge base)는 제가 업데이트할 수 있는 속도보다 더 빠르게 노후화되었습니다. 에이전트는 잘못된 사실을 학습했고, 그것을 자신 있게 반복했습니다.
제가 에이전트가 저의 감정을 모델링하기를 원하지 않기 때문에 정서적 메모리 (Emotional memory)는 실패했습니다. 저는 에이전트가 작업을 수행하기를 원합니다. 제가 좌절한다면, 그것은 작업이 실패했기 때문입니다. 해결책은 사과하는 것이 아니라 작업을 수정하는 것입니다. 저의 감정(Sentiment)을 추적하는 것은 에이전트가 업무를 수행하는 데 도움이 되지 않습니다.
제가 남긴 것
저는 다섯 가지 메모리 시스템 중 네 가지를 삭제했습니다. 제가 남긴 것은 다음과 같습니다:
약간의 변형을 가한 단기 대화 기록 (Short-term conversation history). 에이전트는 마지막 10번의 턴(turns)을 컨텍스트(context)에 유지합니다. 하지만 저는 한 가지 규칙을 추가했습니다. 만약 대화가 10턴을 초과하면, 에이전트는 반드시 처음 5턴을 요약하고 이를 삭제해야 합니다. 이렇게 하면 필수적인 정보를 보존하면서도 컨텍스트 윈도우 (Context window)를 관리 가능한 수준으로 유지할 수 있습니다.
이 요약본은 데이터베이스에 저장되지 않습니다. 인덱싱(Indexed)되지도 않습니다. 나중에 검색할 수도 없습니다. 오직 대화가 진행되는 동안에만 존재합니다. 대화가 끝나면 메모리는 사라집니다.
그리고 그것으로 충분합니다.
교훈
제가 배운 교훈은 이것입니다: 에이전트 메모리는 모든 것을 저장하는 것이 아닙니다. 당면한 작업에 중요한 것을 저장하는 것입니다. 이는 제가 홈랩 AI 에이전트 비용을 60% 절감했을 때 발견한 것과 일맥상통합니다. 최선의 최적화는 종종 필요 없는 것을 제거하는 것입니다.
저는 사용자들과 긴 대화를 나누고, 시간이 지나면서 사용자의 선호도를 학습하며, 관계를 구축하는 범용 어시스턴트를 위해 설계된 메모리 시스템을 만들었습니다. 하지만 제 에이전트가 하는 일은 그것이 아닙니다. 제 에이전트는 도구입니다. 작업을 수행합니다. 제 생일을 기억할 필요는 없습니다.
제가 읽은 에이전트 메모리 (agent memory)에 관한 논문들은 챗봇 (chatbots)이나 동반자 (companions)를 만드는 사람들이 작성한 것입니다. 그들에게는 에피소드 메모리 (episodic memory)가 필요합니다. 왜냐하면 그들의 가치 제안 (value proposition)은 연속성 (continuity)이기 때문입니다. 제 에이전트의 가치 제안은 실행 (execution)입니다. 연속성은 기능 (feature)이 아니라 버그 (bug)입니다.
만약 제가 매일 동일한 코드베이스 (codebase)에서 작업하는 코딩 에이전트 (coding agent)를 구축하고 있다면, 코드베이스 구조를 위한 의미론적 메모리 (semantic memory)를 구현할 것입니다. 만약 제가 고객 지원 에이전트 (customer support agent)를 구축하고 있다면, 고객 이력을 위한 에피소드 메모리 (episodic memory)를 구현할 것입니다. 만약 제가 개인 비서 (personal assistant)를 구축하고 있다면, 사용자 습관을 위한 절차적 메모리 (procedural memory)를 구현할 것입니다.
하지만 저는 배포 에이전트 (deployment agent)를 구축하고 있습니다. 그것은 서비스를 배포합니다. 로그 (logs)를 확인합니다. 실패 시 롤백 (rollbacks)을 수행합니다. 지난 화요일에 우리가 무슨 대화를 나누었는지 기억할 필요가 없습니다.
제가 다르게 했을 방식
만약 제가 되돌아갈 수 있다면, 다섯 가지 메모리 유형으로 시작하지 않을 것입니다. 저는 0개에서 시작할 것입니다. 일주일 동안 제 에이전트가 작동하는 것을 지켜볼 것입니다. 에이전트가 기억했어야 할 정보를 요청할 때마다 기록할 것입니다. 에이전트가 무언가를 잊어버려서 실수를 할 때마다 기록할 것입니다.
그러고 나서 정확히 그 문제를 해결하기 위해 정확히 하나의 메모리 시스템 (memory system)만을 구축할 것입니다.
그 메모리 시스템은 대화 요약 (conversation summarization)일 수도 있습니다. 최근 배포 내역의 캐시 (cache)일 수도 있습니다. 혹은 아예 아무것도 아닐 수도 있습니다.
핵심은 이것입니다: 저는 가상의 필요를 예상하여 메모리를 구축하는 것이 아니라, 특정 실패에 대응하여 메모리를 구축할 것입니다.
직관에 반하는 부분
저를 놀라게 했던 부분은 이것입니다: 다섯 가지 메모리 시스템 중 네 가지를 삭제한 후, 제 에이전트가 더 빨라졌습니다.
메모리 쿼리 (memory queries)가 느려서가 아닙니다. 그렇지 않았습니다. 저는 그것들을 50ms 미만으로 최적화했습니다. 에이전트가 더 빨라진 이유는 유용한 정보를 전혀 반환하지 않는 메모리 검색 (memory retrievals)을 기다리는 것을 멈췄기 때문입니다.
에이전트는 에피소드 메모리 (episodic memory) 데이터베이스에 쿼리를 보냅니다. 데이터베이스는 지난달의 의미론적으로 유사한 대화 세 건을 반환합니다. 에이전트는 그것들을 읽습니다. 그중 어느 것도 관련이 없습니다. 에이전트는 그것들을 버리고 계속 진행합니다.
그것은 50ms의 낭비입니다. 모든 턴(turn)에 곱해지고, 모든 대화에 곱해집니다.
메모리 쿼리(memory queries)를 제거했을 때, 에이전트는 그냥... 작동했습니다. 제가 시키는 대로 했습니다. 관련 없는 컨텍스트(context)를 검색하기 위해 멈추지 않았습니다. 오래된 지식에 기반해 스스로를 의심하지도 않았습니다. 그대로 실행했습니다.
현재 제가 사용하는 방식
제 에이전트 메모리 아키텍처(architecture)는 이제 20줄의 코드 안에 들어갑니다:
class AgentMemory:
def __init__(self, max_turns=10):
self.conversation = []
...
그게 전부입니다. 벡터 데이터베이스 (vector database)도 없습니다. Redis도 없습니다. 크론 잡 (cron jobs)도 없습니다. 검색 전략 (retrieval strategies)도 없습니다.
에이전트는 현재 대화를 위해 기억해야 할 것들만 기억합니다. 대화가 끝나면 메모리는 사라집니다. 그리고 그것이 정확히 제가 원하는 것입니다.
진짜 질문
진짜 질문은 "내 에이전트가 어떤 유형의 메모리를 가져야 하는가?"가 아닙니다. 진짜 질문은 "내 에이전트가 완수하려는 작업은 무엇이며, 그 작업을 완수하기 위해 무엇을 기억해야 하는가?"입니다.
배포 에이전트 (deployment agent)의 경우: 현재 서비스 이름, 현재 버전, 마지막 에러 메시지. 그게 전부입니다.
코드 리뷰 에이전트 (code review agent)의 경우: 현재 PR, 코딩 표준 (coding standards), 이전 코멘트들. 그게 전부입니다.
고객 지원 에이전트 (customer support agent)의 경우: 고객의 티켓 이력, 제품 문서, 에스컬레이션 규칙 (escalation rules). 그게 전부입니다.
메모리 아키텍처는 작업(task)으로부터 도출됩니다. 그 반대가 아닙니다.
제가 배운 것
저는 정교함이 더 나음을 의미하지 않는다는 것을 배웠습니다. 학술 논문은 이상적인 시스템을 설명할 뿐, 실용적인 시스템을 설명하는 것이 아니라는 것을 배웠습니다. 최고의 메모리 시스템은 에이전트가 실제로 사용하는 시스템이라는 것을 배웠습니다.
그리고 때로는 정답이 "메모리를 더 추가하는 것"이 아닐 수도 있다는 것을 배웠습니다. 정답은 "대부분을 삭제하는 것"입니다.
제 에이전트는 이제 한 가지 유형의 메모리만 가집니다. 그것을 매번 사용합니다. 잘 작동합니다.
당신의 에이전트에게도 아마 나머지 네 가지는 필요 없을 것입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기