에이전트 메모리 관리 (Agent Memory Management)
개요
AI 에이전트에서 메모리(Memory)는 과거의 상호작용, 사용자 정보, 환경의 상태 등을 저장하고 활용하여 문맥을 유지하고 보다 지능적인 판단을 내릴 수 있도록 돕는 핵심 시스템입니다. 한정된 컨텍스트 윈도우(Context Window)를 효율적으로 사용하고 필요한 지식을 장기적으로 보존하는 것이 메모리 시스템 설계의 핵심입니다.
일반적으로 에이전트의 메모리는 인간의 인지 과학에서 영감을 받아 크게 단기 기억(Short-term Memory)과 장기 기억(Long-term Memory)으로 나뉩니다.
1. 단기 기억 (Short-term / Working Memory)
진행 중인 대화나 현재 당면한 작업에 대한 정보를 임시로 유지하는 기억입니다. 모델의 컨텍스트 윈도우 크기에 의해 직접적인 제한을 받습니다.
역할 및 특징
- 현재의 대화 상태, 사용자 의도, 최근 수행한 액션의 결과 기록.
- 에이전트가 추론 과정을 진행할 때 사용하는 ‘스크래치패드(Scratchpad)’ 역할.
- 세션이 종료되면 지워지는 휘발성 데이터 영역에 주로 저장됨.
주요 관리 전략
- Sliding Window: 가장 최근의 N개의 메시지만 남기고 이전 대화 내용은 컨텍스트에서 제외.
- Token Limiting: 최대 허용 토큰 수를 설정하여 오래된 상호작용을 순차적으로 삭제.
- Summary Buffer: 과거의 대화 기록 전체를 보존하는 대신, 일정 시점마다 주요 내용을 요약(Summarization)하여 하나의 압축된 컨텍스트로 유지.
2. 장기 기억 (Long-term Memory)
과거의 경험, 학습된 지식, 사용자의 선호도 등을 세션과 무관하게 영구적으로 저장하고 필요할 때 검색해 오는 기억 장치입니다. 주로 Vector DB, 관계형 DB, 혹은 Knowledge Graph 등의 외부 저장소에 의존합니다.
장기 기억은 역할에 따라 다시 세 가지 주요 유형으로 나눌 수 있습니다.
2.1. 일화적 기억 (Episodic Memory)
사용자와 언제, 어떤 구체적 대화를 나누었고, 어떤 조치를 취했는지에 대한 ‘경험(Experience)’의 기록입니다.
- 특징: 시간 정보(Timestamp, Session ID)와 맥락(Context)을 함께 저장.
- 활용: 과거의 성공 또는 실패 사례를 기억하여 유사한 상황에서 더 나은 결정을 내리거나 동일한 오류를 범하지 않도록 자가 수정(Self-Correction)에 활용됨.
2.2. 의미적 기억 (Semantic Memory)
사실, 개념, 외부 지식, 사용자 정보 등 문맥과 독립적인 일반적 정보의 저장소입니다.
- 특징: RAG(Retrieval-Augmented Generation) 시스템을 통해 외부 문서, 정책 자료, 위키 등을 검색해 답변의 근거로 사용.
- 활용: 할루시네이션(Hallucination)을 줄이고 최신의 정보나 사내 도메인 특화 지식을 활용할 수 있도록 지원.
2.3. 절차적 기억 (Procedural Memory)
특정 작업을 ‘어떻게’ 수행해야 하는지에 대한 규칙(Rules)이나 지침(Instructions)입니다.
- 특징: 도구(Tool) 및 스킬(Skill)의 사용법, 규정 프롬프트(System Prompt), 워크플로우를 포함.
- 활용: 장기 기억 저장소 뿐 아니라 에이전트 시스템 코드 자체의 로직이나 LLM의 가중치 내에 종속되기도 하며, 특정 상황에서 동적으로 주입될 수도 있음.
3. 메모리 통합 및 저장 아키텍처
최신 에이전트 프레임워크(LangChain, LangGraph, AutoGen 등)는 장·단기 메모리를 유기적으로 통합하여 운영합니다. 메모리의 저장 및 주입 아키텍처는 크게 에이전트가 통제권을 가지는 ‘명시적 호출 방식’과 시스템이 제어하는 ‘Hook 기반 방식’으로 나뉩니다.
3.1. 명시적 도구 호출 방식 (Memory as Tools)
에이전트에게 save_to_memory, search_memory, delete_memory 와 같은 별도의 도구(Tool/Function Calling)를 부여하는 아키텍처입니다.
- 작동 원리: 에이전트가 현재 대화의 문맥을 판단하다가 저장이 필요한 특별한 순간을 스스로 인지하여 도구를 명시적으로 호출합니다.
- 장점: 정보 저장 및 검색의 주도권을 에이전트가 가지므로 고도의 자율성과 유연성을 발휘합니다.
- 단점: 시스템 프롬프트 작성 난이도가 높아지며, 도구 호출에 수반되는 추가적인 LLM 토큰 소모 및 모델의 라우팅으로 인한 지연 시간(Latency)이 깁니다.
3.2. 생명주기 Hook 기반 관리 (Interceptor / Middleware)
현재 프로덕션 레벨에서 주로 권장되는 패턴으로, 모델의 추론 로직(Thinking)과 데이터베이스 접근 로직(I/O, Memory)을 분리하기 위해 생명주기(Lifecycle) 훅을 사용합니다. 시스템의 미들웨어 계층이 백그라운드에서 동작하므로, 에이전트는 본연의 Task 해결에만 집중하여 성능 손실과 지연 발생을 최소화합니다.
- Pre-model Hook (호출 전 인터셉트 & 주입): 사용자의 입력이 LLM으로 전달되기 직전에만 작동합니다.
- 과거 대화를 슬라이딩 윈도우 등의 단기 기억 관리법으로 정리합니다.
- 사용자의 현재 입력과 연관성이 높은 장기 기억 정보(사용자 선호도 등)를 Vector DB에서 검색(RAG)해 온 뒤, LLM이 문맥을 충분히 알 수 있도록 프롬프트에 백그라운드로 자동 삽입(Inject)합니다.
- Post-model Hook (호출 후 비동기 저장): LLM이 사용자에게 텍스트를 생성하여 반환을 끝마친 직후 작동합니다.
- 사용자와의 실시간 채팅 응답성에 악영향을 주지 않기 위해 주로 비동기(Async) 방식으로 백그라운드 환경에서 동작합니다.
- 방금 발생한 대화 턴(Turn)을 분석하여 영구적으로 기억해야 할 중요한 사실들을 별도로 추출하는 소위 선택적 저장 패턴(Selective Addition)을 수행합니다. (이 과정에서 더 작고 빠르며 저렴한 특수 LLM을 백그라운드에서 활용하기도 합니다)
3.3. 주요 프레임워크별 메모리 구현 시퀀스
앞서 설명한 Hook 및 Middleware 기반의 메모리 아키텍처가 실제 주요 에이전트 프레임워크에서 어떻게 구현되어 있는지 시퀀스 다이어그램으로 살펴봅니다. 대부분의 프레임워크는 에이전트의 ‘추론(Reasoning)’ 로직 내부에 메모리 저장 코드를 하드코딩하지 않고, 외부 래퍼(Wrapper)나 콜백(Callback)을 통해 투명하게 처리하는 패턴을 취합니다.
1) LangGraph (Checkpointer 기반 Middleware 패턴)
LangGraph는 상태(State) 기반의 그래프 엔진으로, 메모리(단기/장기) 저장을 Checkpointer(Saver)라는 미들웨어 계층으로 완전 분리합니다. 노드(에이전트 로직)는 상태 변화만 반환하며, 프레임워크가 백그라운드에서 DB 접근을 전담합니다.
sequenceDiagram
autonumber
actor User
participant Graph as LangGraph (Pregel)
participant CP as Checkpointer (Middleware)
participant Node as Graph Nodes (LLM/Tools)
User->>Graph: invoke(input, config={thread_id})
activate Graph
%% Pre-hook 개념
Graph->>CP: get_tuple(config)
CP-->>Graph: Return CheckpointTuple (이전 State 복원)
Graph->>Graph: User Input을 현재 State에 병합
loop Superstep Execution
%% 메인 로직
Graph->>Node: 현재 State를 주입하여 Node 실행
Node-->>Graph: Return state updates (상태 변경점)
Graph->>Graph: State 업데이트 로직 적용
%% Post-hook 개념
Graph->>CP: put(config, state, channel_values)
Note right of CP: 백그라운드에서 SQLite/Postgres 등에 비동기 저장
end
Graph-->>User: Return final State
deactivate Graph
2) LangChain (Runnable Decorator 패턴)
LCEL(LangChain Expression Language) 체계에서는 RunnableWithMessageHistory라는 래퍼(Wrapper)가 미들웨어 역할을 수행하여 대화 기록 입출력을 가로챕니다.
sequenceDiagram
autonumber
actor User
participant Wrapper as RunnableWithMessageHistory<br>(Middleware)
participant History as BaseChatMessageHistory (DB)
participant Agent as Inner Runnable (Agent/LLM)
User->>Wrapper: invoke(input, config={session_id})
activate Wrapper
%% Pre-hook 개념
Wrapper->>History: get_messages(session_id)
History-->>Wrapper: Return 과거 메시지 리스트
Wrapper->>Wrapper: 입력 프롬프트(Context)에 히스토리 주입
%% 메인 로직
Wrapper->>Agent: invoke(augmented_input)
activate Agent
Agent-->>Wrapper: Return output (AI 응답)
deactivate Agent
%% Post-hook 개념
Wrapper->>History: add_messages([User_msg, AI_msg])
Note right of History: AI 추론 완료 후 세션 기록에 쌍으로 비동기 저장
Wrapper-->>User: Return output
deactivate Wrapper
3) LlamaIndex (AgentRunner & MemoryModule 패턴)
LlamaIndex는 에이전트의 컨트롤러(Runner)와 사고 주체(Worker)를 분리합니다. AgentRunner가 제어의 흐름을 쥐고 MemoryModule을 호출하는 방식입니다.
sequenceDiagram
autonumber
actor User
participant Runner as AgentRunner
participant Memory as BaseMemory (Memory Module)
participant Worker as AgentWorker (LLM / Tool Router)
User->>Runner: chat(message)
activate Runner
%% Pre-hook 개념
Runner->>Memory: put(ChatMessage(role='user', content=message))
Note right of Memory: 유저 입력 사전 저장
Runner->>Memory: get() OR get_all()
Memory-->>Runner: Return context windows
%% 메인 추론 루프
Runner->>Worker: run_step(input, chat_history)
activate Worker
Worker-->>Runner: TaskStepOutput (AI 완료 응답)
deactivate Worker
%% Post-hook 개념
Runner->>Memory: put(ChatMessage(role='assistant', content=response))
Note right of Memory: AI 응답 사후 저장
Runner-->>User: Return AgentChatResponse
deactivate Runner
4) AutoGen (Event Hook 패턴)
AutoGen은 에이전트 객체 간의 메시지 송수신 이벤트 기반으로 동작합니다. 메시지가 수신되면 기본 리스트에 추가되고, 응답을 생성하는 과정에서 등록된 register_reply 콜백 훅(Hooks)들이 장기 기억 주입 등의 작업을 처리합니다.
sequenceDiagram
autonumber
actor User / Agent A
participant AgentB as ConversableAgent B
participant Memory as self._oai_messages
participant Hooks as Registered Reply Functions(Callbacks)
participant LLM as OpenAI Wrapper
User / Agent A->>AgentB: send(message)
activate AgentB
AgentB->>AgentB: receive(message)
%% 단기 메모리 업데이트
AgentB->>Memory: append(message)
Note right of Memory: Main 로직 전 단기 기억 풀에 즉시 저장
AgentB->>AgentB: generate_reply()
activate AgentB
%% Hook 체인 점화
loop Over registered_reply_funcs
AgentB->>Hooks: _invoke_reply_hook()
Note over Hooks: 메모리 플러그인(Mem0 등)이 여기서 과거 문맥 검색/주입
Hooks-->>AgentB: Return (is_final, reply, context)
opt If needs LLM generation
AgentB->>LLM: _generate_oai_reply(context)
LLM-->>AgentB: Generated Text
end
end
%% 응답 저장
AgentB->>Memory: append(generated_reply)
AgentB-->>User / Agent A: Return reply
deactivate AgentB
deactivate AgentB
4. 확장된 메모리 관리 아키텍처
최신 에이전트 시스템에서는 단순한 벡터 데이터베이스(Vector DB)를 넘어, 환경(Workspace) 자체를 메모리로 사용하거나 기존 기업 시스템을 메모리로 편입하는 방식이 적극적으로 도입되고 있습니다.
4.1. 파일 시스템 기반 메모리 (Memory Bank / Workspace)
코딩 에이전트(예: Cline, AutoGPT, OpenDevin)들이 주로 채택하는 방식으로, 에이전트가 실행되는 샌드박스의 로컬 파일 시스템을 영구적인 기억 장치로 사용하는 기법입니다.
- 작동 원리: 에이전트에게 파일 시스템 제어 스킬(
read_file,write_file,ls)을 부여하고, 프로젝트 루트 하위 특정 폴더(예:.memory-bank/)에 마크다운(Markdown) 포맷으로 현재 작업의 문맥, 규칙, 발전 상황을 자율적으로 기록하고 읽어옵니다. - 장점: 개발자(사람)가 메모리 파일을 직접 텍스트 에디터로 열람하고 언제든 손쉽게 수정(Human-in-the-loop, Editable)할 수 있어 투명성이 뛰어납니다. 별도의 복잡한 DB 설정 없이 파일 볼륨 마운트만으로 상태 영속성을 보장할 수 있습니다.
4.2. 기존 시스템 연동 기반 메모리 (NL2SQL / RDBMS)
기업 환경(Enterprise)에서 완벽하게 “접지가 가능한(Grounding)” 에이전트를 구축하기 위해, 수십 년간 축적된 RDBMS, ERP의 정형 데이터를 에이전트의 거대한 ‘의미적 확정 기억(Semantic Fact Memory)’으로 편입하는 기법입니다.
- 작동 원리: 에이전트는 Text-to-SQL(NL2SQL) 도구를 통해 복잡한 비즈니스 질문을 SQL 쿼리로 변환하고, 기존 운영 데이터베이스에서 정확한 수치나 고객 상태를 실시간으로 인출해 자신의 단기 컨텍스트로 끌어옵니다.
- 특징: 단순 비정형 벡터 검색(RAG)이 갖는 환각(Hallucination) 한계를 극복합니다. 다만 안전성을 위해 에이전트와 DB 사이에 의미론적 계층(Semantic Layer)을 두어 비즈니스 로직을 매핑하고, 인프라 차원의 철저한 읽기 전용(Read-only) 권한 통제가 수반되어야 합니다. 관련 인프라 구조는 AX Infra: 메모리 및 데이터 인프라에서 자세히 다룹니다.
4.3. 메모리 임베딩 (Memory Embeddings)
마크다운 기반의 투명한 저장소와 로컬 벡터 인덱싱을 결합한 하이브리드 메모리 관리 기법입니다. 별도의 무거운 벡터 DB 서버 없이도 개인용 기기(로컬)에서 의미 기반의 검색과 장기 기억 유지를 가능하게 합니다.
- 핵심 특징: 텍스트 본문은 사람이 읽을 수 있는 마크다운 파일로 보관하고, 검색을 위한 벡터 데이터만 로컬 인덱스로 따로 관리합니다.
- 상세 내용: 메모리 임베딩 상세 가이드에서 아키텍처와 OpenClaw 적용 사례를 확인하세요.
4.4. 다층적 영속 메모리: Hermes Agent의 4계층 아키텍처
Hermes Agent는 벡터 DB에 의존하지 않으면서도 교차 세션(Cross-session) 간의 컨텍스트 영속성을 확보하는 독자적인 4계층 메모리 아키텍처를 채택했습니다. 이는 정보의 성격에 따라 저장 및 검색 계층을 정밀하게 분리한 사례입니다.
| 계층 | 명칭 | 메모리 유형 매핑 |
|---|---|---|
| 1 | 프롬프트 파일 (Prompt Files) | 절차적 기억 — 에이전트의 정적 규칙 및 제약 |
| 2 | SQLite 아카이브 (FTS5 + LLM 요약) | 일화적 기억 — 교차 세션 대화 내역 및 메타데이터 |
| 3 | 동적 스킬 (SKILL.md) | 절차적 기억 — 에이전트가 자가 생성한 재사용 가능 절차 |
| 4 | 사용자 모델링 (Honcho) | 의미적 기억 — 사용자 선호도 및 커뮤니케이션 스타일 |
- SQLite FTS5: 전문 검색(Full-Text Search)과 LLM 기반 요약을 결합하여, 대용량 벡터 DB 없이도 과거 세션의 특정 사실이나 작업 결과를 정확하고 빠르게 검색합니다.
- 변증법적 사용자 모델링: Honcho 기술을 채택하여, 사용자의 반복적 지시 패턴·선호도·커뮤니케이션 스타일을 백그라운드에서 추론하고 심층 모델을 자율적으로 구축합니다.