
AI Agent에 Memory를 붙이는 방식은 지금까지 꽤 정형화돼 있었다.
대화 발생
↓
중요한 내용 추출
↓
요약
↓
Vector DB 저장
↓
다음 질문에서 검색
↓
관련 Memory를 Context에 삽입
조금 더 발전시키면 다음과 같다.
Working Memory
Episodic Memory
Semantic Memory
User Profile
Project Memory
개발자가 미리 분류하고 저장 규칙을 만든다.
예를 들어 이런 식이다.
사용자 선호
→ 항상 저장
프로젝트 결정
→ 장기 Memory
최근 오류
→ 7일 보관
일반 대화
→ 저장하지 않음
처음에는 꽤 잘 동작한다.
그런데 실제 Agent를 오래 운영하면 문제가 생긴다.
어떤 작업에서는 사용자의 선호가 중요하고,
다른 작업에서는 정확한 날짜 하나가 중요하며,
또 다른 작업에서는 과거에 실패했던 해결책을 기억하는 것이 중요하다.
즉 모든 작업에 같은 Memory 전략이 잘 맞는 것은 아니다.
Task A
요약이 중요
Task B
정확한 원문이 중요
Task C
시간 순서가 중요
Task D
최근 정보만 중요
그런데 기존 Memory System은 대체로 개발자가 미리 만든 규칙을 계속 사용한다.
최근 공개된 SelfMem: Self-Optimizing Memory for AI Agents가 재미있는 이유가 여기에 있다.
SelfMem은 Agent에게
이 정보를 저장해라.
이 형식으로 요약해라.
최근 20개만 기억해라.
라고 고정된 전략을 주는 대신,
Agent에게 Memory를 다룰 수 있는 Tool과 Feedback을 제공한다.
그리고 Agent 자신이 결정한다.
무엇을 기억할까?
무엇은 압축할까?
무엇은 원문으로 남겨둘까?
기존 Memory를 교체할까?
두 Memory를 합칠까?
오래된 내용을 Archive할까?
정확한 값은 Memory 대신 원문에서 다시 찾을까?
즉 Memory가 단순 저장 기능에서 Agent가 최적화해야 하는 또 하나의 작업 영역으로 바뀐다.
이번 글에서는 SelfMem의 구조를 살펴보고, 이를 실제 Coding Agent에 적용한다면 어떻게 설계할 수 있는지 정리한다.
많은 Agent Memory 시스템은 다음 문제를 해결하려 한다.
Context Window 부족
그래서 Conversation 전체를 넣지 않고 Memory를 만든다.
Conversation 500K tokens
↓
요약
↓
10K Memory
↓
Model Context
하지만 진짜 어려운 문제는 따로 있다.
무엇을 10K 안에 남길 것인가?
다.
예를 들어 사용자가 몇 달 동안 개발 프로젝트를 진행했다고 하자.
Agent가 알고 있는 내용은 다음과 같다.
Architecture
Bug History
사용자 Coding Style
취소된 기능
현재 기능
지난 Test 결과
Release Rule
Temporary Debug 정보
Dependency Version
사라진 API
새로운 결정
이걸 단순히 요약하면 중요한 세부 사항이 빠질 수 있다.
반대로 전부 저장하면 Memory 자체가 새로운 Context Pollution이 된다.
예를 들어 다음처럼 구현했다고 하자.
if (importance > 0.7) {
await memory.store(item);
}
혹은
최근 Conversation 20개
↓
LLM Summary
↓
Vector Store
문제는 importance > 0.7이 모든 Task에서 좋은 기준인지 알 수 없다는 것이다.
어떤 정보는 당시에는 중요하지 않아 보인다.
사용자가 테스트 환경에서
특정 Feature Flag를 꺼두었다.
그런데 3주 뒤 발생한 Bug의 핵심 원인이 될 수 있다.
반대로 당시 중요한 정보였던
오늘 Build Server 장애 발생
은 한 달 뒤에는 아무 의미가 없을 수도 있다.
Memory에는 시간과 Task Context가 함께 들어간다.
SelfMem은 크게 다음 구조로 볼 수 있다.
Raw Transcript
↓
Memory Agent
↓
Memory Tools
↓
Memory Workspace
↓
Review / Feedback
↓
Memory 수정
↓
Future Query
여기서 매우 중요한 부분이 있다.
원본 Transcript는 그대로 보존한다.
Memory가 Source of Truth가 아니다.
Raw Transcript
Immutable Source of Truth
Memory는
빠르게 판단하기 위한
압축된 Working Representation
에 가깝다.
이 구조는 실무에서도 상당히 중요하다.
Database가 있다고 하자.
Database
Source of Truth
Redis는
Cache
다.
Cache가 틀리면 Database를 다시 확인한다.
Agent Memory도 비슷하게 볼 수 있다.
Raw Conversation
Repository
Official Config
↓
Source of Truth
Agent Memory
↓
빠른 판단을 위한 Cache
따라서 Memory와 실제 Repository가 충돌하면 Repository를 다시 읽는다.
이 원칙 하나만 있어도 오래된 Memory 때문에 Agent가 계속 잘못 판단하는 문제를 상당히 줄일 수 있다.
SelfMem 연구에서는 원본 Conversation History를 읽기 전용 저장소로 유지한다.
Agent는 원문을 마음대로 수정하지 않는다.
개념적으로 다음과 같다.
Transcript Store
turn 1
turn 2
turn 3
...
turn 25000
그리고 Agent가 필요할 때 검색한다.
Memory Agent
↓
최근 Session에서
"production signing" 관련 대화 찾아줘
↓
Transcript Search
원본과 Memory를 분리하는 것이다.
Coding Agent에서는 Source of Truth가 여러 개다.
Git Repository
Git History
Issue
PR
Build Result
Test Artifact
Architecture Docs
Conversation
따라서 실무에서는 다음처럼 볼 수 있다.
Sources of Truth
├── repository/
├── git/
├── conversations/
├── tests/
└── docs/
그리고 별도로:
.ai/memory/
를 둔다.
Agent가 직접 관리할 수 있는 작업 공간이다.
고정 Schema만 강제하지 않는다.
Agent가 Task에 따라 구조를 바꿀 수 있다.
예를 들어:
memory/
user-profile.md
project-state.md
timeline.md
decisions.md
일 수도 있고,
다른 Task에서는:
memory/
entities.json
known-issues.json
current-assumptions.md
일 수도 있다.
중요한 것은 Framework가 모든 Memory 구조를 미리 결정하지 않는다는 것이다.
Agent에게
알아서 Memory 만들어.
만 주면 Memory가 난잡해질 수 있다.
그래서 SelfMem의 아이디어는
Memory Strategy
Agent가 결정
하지만
Memory Tool
Audit
Feedback
Constraints
Framework가 제공
으로 나눈다.
좋은 Agent Runtime 설계에서도 이 경계가 필요하다.
실전에서는 다음 정도의 Tool이 있으면 된다.
inspect_memory
search_source
write_memory
replace_memory
merge_memory
archive_memory
review_memory
좀 더 구체적으로 만들면:
type MemoryOperation =
| "add"
| "replace"
| "merge"
| "refine"
| "archive"
| "delete";
그리고 모든 변경을 구조화한다.
type MemoryChange = {
operation: MemoryOperation;
target?: string;
content?: string;
reason: string;
evidence: string[];
};
Agent가 Memory를 고치는 이유까지 남긴다.
remember() 하나보다 이 구조가 낫다보통 Memory API를 처음 만들면 이렇다.
remember(text);
문제는 너무 강력하다.
Agent가 어떤 이유로 무엇을 저장했는지 알기 어렵다.
대신:
await memory.apply({
operation: "replace",
target: "architecture/auth-refresh",
content: `
Session refresh ownership belongs to SessionCoordinator.
`,
reason: "Previous TokenStore ownership is obsolete.",
evidence: [
"Sources/Auth/SessionCoordinator.swift",
"PR-842"
]
});
처럼 만든다.
Memory 변경도 하나의 Transaction으로 취급한다.
SelfMem을 가장 단순하게 표현하면 다음이다.
Inspect
↓
Write
↓
Review
↓
Revise
한 번 Summary를 만들고 끝내지 않는다.
Agent가 자신의 Memory를 다시 읽는다.
이 Memory로 다음 질문에 답할 수 있을까?
중복된 정보는 없는가?
오래된 정보는 없는가?
근거가 없는 내용은 없는가?
정확한 숫자를 너무 압축하지 않았는가?
그리고 다시 고친다.
Coding Agent 관점에서는 이해하기 쉽다.
기존:
Agent
↓
Code 생성
↓
Reviewer
↓
수정
SelfMem:
Agent
↓
Memory 생성
↓
Memory Review
↓
수정
즉 Memory도 품질 검증 대상이다.
review_memory Tool을 만들어보자예:
type MemoryReview = {
unsupportedFacts: string[];
staleFacts: string[];
contradictions: string[];
duplicates: string[];
retrievalRisks: string[];
};
Agent가 다음 Memory를 저장했다고 하자.
App은 iOS 18만 지원한다.
그런데 현재 Deployment Target이 iOS 19라면:
{
"staleFacts": [
"App은 iOS 18만 지원한다."
]
}
가 나온다.
그리고 Memory Agent가 수정한다.
모든 정보를 같은 형태로 저장하지 않는다.
예:
사용자는 답변을 간결하게 선호한다.
이런 것은 Summary Memory로 괜찮다.
하지만:
App Store Connect API Key 만료일
2026-10-14
같은 정보는 상황이 다르다.
쉽게 바뀌고 정확성이 중요하다.
SelfMem식으로 생각하면 이런 정보는 Memory에 그대로 믿고 저장하기보다 원본 Source에서 다시 확인하는 편이 낫다.
Memory
App Store Credential은
release 시점에 다시 확인해야 함
↓
Release 실행
↓
Source 조회
↓
현재 값 확인
이 기준이 상당히 중요하다.
Architecture 결정
사용자 선호
반복되는 Gotcha
Module 책임
과거 Incident의 원인
취소된 Architecture와 이유
현재 Version
현재 Branch
오늘 Test 결과
현재 가격
현재 API 상태
현재 Environment
후자는 쉽게 바뀐다.
잘못된 Agent Memory 시스템은 Snapshot을 영구 사실처럼 저장한다.
2026-03
version = 3.2.0
↓
2026-08
Agent Memory
version = 3.2.0
↓
실제로는:
4.1.0
이다.
이런 값은 애초에 Long-term Memory에 저장하지 않는 편이 좋다.
대신:
Version은 project config에서 확인한다.
라는 Retrieval Hint를 저장한다.
Memory에는 답 자체뿐 아니라
어디에서 답을 찾을 수 있는가
도 저장할 수 있다.
예:
# iOS Version
현재 버전 값은 Memory에 저장하지 않는다.
Source:
`ios/App.xcodeproj/project.pbxproj`
Release Version은 배포 전에 이 파일에서 다시 확인한다.
Agent에게 매우 유용하다.
.ai/
├── memory/
│ ├── index.md
│ ├── architecture/
│ │ ├── auth.md
│ │ ├── camera.md
│ │ └── network.md
│ │
│ ├── decisions/
│ │ ├── ADR-001.md
│ │ └── ADR-002.md
│ │
│ ├── gotchas/
│ │ ├── xcode-cloud.md
│ │ └── signing.md
│ │
│ └── strategies/
│ └── current-memory-policy.md
│
├── tasks/
│ └── current/
│ ├── goal.md
│ └── checkpoint.json
│
└── artifacts/
여기서 재미있는 부분은:
strategies/
다.
Agent가 어떤 Memory 전략이 잘 동작했는지도 기록할 수 있다.
예:
version: 3
preferences:
persist: true
architecture_decisions:
persist: true
require_evidence: true
exact_dynamic_values:
persist: false
use_retrieval_hint: true
tool_logs:
persist: false
failed_hypotheses:
persist: false
incidents:
persist:
root_cause: true
raw_log: false
이런 정책을 처음에는 사람이 만든다.
Self-Optimizing 방식에서는 Agent가 결과를 보고 변경을 제안한다.
Memory 전략:
날짜 관련 정보를 Summary에 포함
그런데 Eval에서 계속 실패한다.
잘못된 날짜
오래된 날짜
이벤트 순서 오류
Agent가 전략을 수정한다.
- 날짜는 일반 Summary에 포함
+ 날짜가 중요한 이벤트는 Timeline으로 별도 관리
+ 정확한 날짜는 원문 Evidence를 연결
Memory Strategy가 개선된 것이다.
중요한 점이 있다.
여기서 반드시 모델 Weight를 재학습하는 것은 아니다.
Model Fine-tuning
이 아니라
Memory 행동 방식
↓
Tool 사용 방식
↓
Memory 구조
↓
Revision 전략
을 개선한다.
즉 Agent Policy의 일부를 자연어·Tool 행동 수준에서 최적화하는 것에 가깝다.
Agent가 무엇이 좋은 Memory인지 알려면 Feedback이 있어야 한다.
SelfMem에서는 단순 정답 점수 하나만 주는 방식이 아니라 Memory Tool과 Runtime에서 관찰 가능한 신호를 활용한다.
실무에서는 다음을 사용할 수 있다.
Answer Correctness
Retrieval Hit
Memory Token Size
Latency
Tool Calls
Cache Hit
API Cost
Human Correction
Reopened Investigation
{
"task": "AUTH-142",
"memoryHits": 3,
"memoryMisses": 1,
"repeatedFileReads": 7,
"repeatedInvestigation": true,
"humanCorrection": false,
"tokensUsed": 42800
}
Agent가 다음과 같이 판단할 수 있다.
Session refresh 구조를
매 Task마다 다시 조사하고 있다.
↓
Architecture Memory를 추가하는 것이 좋음
Memory Hit는 많지만 Agent가 틀린다.
{
"memoryHits": 8,
"answerCorrect": false,
"staleMemoryDetected": 3
}
이 경우:
Memory가 부족한 것이 아니라
Memory를 너무 믿고 있다.
문제다.
전략을 바꾼다.
변경 가능성이 높은 사실은
현재 Source와 다시 검증
많이 기억하는 시스템을 만들기는 쉽다.
전부 저장
하면 된다.
문제는 검색 결과다.
관련 Memory 3개
+
비슷하지만 오래된 Memory 20개
가 나오면 Agent 판단이 더 어려워진다.
따라서 Memory 품질에서는
얼마나 많이 저장했는가?
보다
현재 Task에 맞는 기억을
얼마나 정확하게 꺼냈는가?
가 중요하다.
Memory도 시간이 지나면 쌓인다.
100
↓
1,000
↓
10,000
무한히 두면 검색 비용이 증가한다.
따라서 다음 Operation이 필요하다.
merge
archive
supersede
delete
예:
ADR-014
status: superseded
↓
ADR-031
기존 결정을 없애지 않고 관계를 남긴다.
forget도 중요한 Memory Tool이다AI Memory 기능을 이야기하면 늘
remember
를 먼저 생각한다.
하지만 실제 장기 Agent에서 더 어려운 것은
forget
이다.
무엇을 잊을 것인가?
일회성 Log
완료된 Temporary Debug 상태
잘못된 가설
오래된 Environment 정보
중복된 Summary
는 버려도 된다.
예를 들어 Coding Agent가 6개월 동안 Repository를 사용했다고 하자.
Memory가 50,000개 있다고 해서 좋은 것은 아니다.
다음 500개만 정확히 유지하는 편이 나을 수도 있다.
Architecture
Gotcha
Important Decisions
User Preferences
Recurring Failure Patterns
Memory의 목표는 기록 보존이 아니다.
다음 Task를 더 잘 수행하도록 돕는 것이다.
Self-Optimizing Memory가 강력해질수록 새로운 위험이 있다.
Agent가 잘못 판단한다.
Library X는 Thread-safe하다.
Memory에 저장한다.
다음 Agent가 읽는다.
Thread-safe
라고 믿는다.
다시 작업한다.
잘못된 정보가 반복되면서 더 강한 Memory가 될 수 있다.
잘못된 정보
↓
Memory
↓
다음 판단의 근거
↓
다시 Memory 강화
이게 Memory Poisoning의 대표적인 형태다.
중요 Memory에는 Source를 붙인다.
id: auth-refresh-owner
status: active
fact:
SessionCoordinator owns session refresh coordination.
evidence:
- Sources/Auth/SessionCoordinator.swift
- Tests/Auth/SessionRefreshTests.swift
last_verified:
2026-08-13
Agent가 다시 검증할 수 있다.
{
"fact": "...",
"confidence": 0.93
}
모델 Confidence 숫자가 실제 사실성을 보장하지 않는다.
그보다 중요한 것은:
Evidence
Last Verified
Source Type
Freshness
다.
Temporary Search Hint
Log Summary
Working Notes
Agent 자동 수정 가능.
Known Gotcha
Workflow
User Preference
Agent 수정 + 변경 기록.
Architecture Decision
Security Policy
Release Policy
Production Rule
Human Review 필요.
이 부분은 꼭 구분해야 한다.
Self-Optimizing
≠
Unlimited Self-Modification
좋은 Runtime에서는:
Agent
Memory 전략 제안
↓
Policy
허용 범위 확인
↓
Memory Update
구조로 간다.
특히 Security·Production Memory는 사람이 확인한다.
memory-policy-v1
↓
memory-policy-v2
↓
memory-policy-v3
예:
version: 4
created_at: 2026-08-13
changes:
- dynamic exact values are no longer persisted
- architecture memory now requires evidence
- raw test logs expire after task completion
문제가 생기면 어떤 전략에서 시작됐는지 추적할 수 있다.
Memory System도 테스트가 필요하다.
예:
Memory Test 1
3개월 전 Architecture 결정 질문
Expected:
현재 유효한 결정 반환
Memory Test 2
폐기된 API 질문
Expected:
Stale Memory 사용하지 않음
Memory Test 3
정확한 Release Version
Expected:
Memory에서 답하지 않고 현재 Config 조회
Memory Test 4
사용자 선호
Expected:
장기 Memory 사용
{
"query": "현재 iOS 최소 지원 버전이 뭐야?",
"expectedBehavior": {
"memoryOnly": false,
"mustVerifySource": true
},
"source": "project.pbxproj"
}
이 테스트는 답만 검사하지 않는다.
어떤 Memory 전략을 사용했는지도 검사한다.
Answer Accuracy
Memory Hit Rate
Stale Memory Usage
Unnecessary Source Reads
Repeated Investigation
Memory Tokens
Tool Calls
Latency
Cost
이 정도면 충분하다.
Agent가 매번 Repository Architecture를 다시 조사한다고 하자.
Task 1
40K tokens
Task 2
37K tokens
Task 3
42K tokens
대부분 같은 조사다.
잘 만든 Memory가 있으면:
Architecture Memory
↓
필요한 Source만 확인
↓
Task 실행
으로 줄일 수 있다.
가장 작은 Memory:
Auth는 SessionCoordinator가 담당.
Token은 거의 없다.
하지만 정보가 부족하다.
너무 많은 Memory:
Auth 관련 대화 전체
정확할 수 있지만 비싸다.
따라서 최적화 목표는
Minimum Token
이 아니다.
Quality
+
Cost
+
Latency
의 균형이다.
Memory를 많이 저장하면 Recall은 좋아질 수 있다.
하지만:
Context 증가
Cost 증가
Retrieval Noise 증가
가 생긴다.
강하게 압축하면:
Context 감소
Cost 감소
하지만:
세부 정보 손실
이 생긴다.
Agent가 현재 Task와 Feedback을 보고 이 사이에서 전략을 바꾼다.
SelfMem 연구에서는 BEAM 장기 대화 Benchmark의 100K, 500K, 1M Token 조건에서 RAG, Compression, MemGPT, MemoryBank, Mem0, A-Mem 등 여러 Memory 방식을 비교했다.
SelfMem은 세 Context 규모 모두에서 가장 높은 공식 Score를 기록했다.
특히 연구 결과는
Memory를 복잡하게 많이 쌓는다
=
더 좋은 결과
가 아니라는 점도 보여준다.
일부 Memory Pipeline은 더 많은 LLM 호출이나 Embedding 작업을 사용했지만 SelfMem보다 낮은 점수를 기록했다.
그렇다고 RAG가 필요 없다는 의미는 아니다.
SelfMem 연구에서도 RAG는 꽤 강한 Baseline이었다.
둘의 역할이 다르다.
RAG
질문 발생
↓
관련 Chunk 검색
SelfMem:
과거 경험
↓
Agent가 Memory Representation 생성
↓
필요하면 수정
↓
질문 시 Memory + 원문 Evidence 활용
RAG는 Retrieval이고,
SelfMem은 Memory Management Strategy까지 포함한다.
실무 구조는 오히려 다음이 자연스럽다.
Long-term Memory
↓
Self-Optimized Memory Workspace
↓
Broad Search 필요
↓
RAG
↓
Source Evidence
↓
Main Agent
둘 중 하나만 선택할 이유가 없다.
Knowledge Access Beats Model Size 연구에서는 반복적인 사용자 맞춤형 질문에서 관련 Memory에 접근할 수 있는 작은 모델이 Memory 없이 동작하는 훨씬 큰 모델보다 나은 결과를 보인 사례가 보고됐다.
이 메시지는 상당히 중요하다.
더 큰 Model
만으로 모든 Agent 문제가 해결되지 않는다.
적절한 Knowledge
+
적절한 Retrieval
+
적절한 Memory
가 모델 크기보다 중요한 Task도 있다.
예:
Task 발생
↓
충분한 Memory 있음?
YES:
작은 Model
NO:
강한 Model + Search
같은 Routing이다.
개념적으로:
if (memoryCoverage >= 0.9 && memoryFreshness >= 0.9) {
return "fast-model";
}
return "frontier-model";
단순한 구현 예지만 방향은 재미있다.
Task가 요구하는 정보:
Architecture
User Preference
Current Version
Memory에서:
Architecture
O
User Preference
O
Current Version
X
Coverage:
2 / 3
Agent는 Version만 Source에서 확인한다.
Repository 전체를 다시 조사할 필요가 없다.
Codex용으로는 다음 정도부터 시작하면 된다.
.ai/
├── memory/
│ ├── index.md
│ ├── architecture/
│ ├── decisions/
│ ├── gotchas/
│ └── strategy/
│
├── tasks/
│ └── current/
│ ├── goal.md
│ └── checkpoint.json
│
└── artifacts/
그리고 Agent에게 다음 Rule을 준다.
현재 Task가 끝났다고 모든 정보를 Memory에 저장하지 마.
다음 작업에서도 가치가 있는 내용만 후보로 선정해.
현재 Repository에서 쉽게 다시 확인할 수 있는 값은
Memory에 복사하지 말고 Retrieval Hint를 남겨.
중요 Memory에는 Evidence를 포함해.
기존 Memory와 충돌하면 자동 덮어쓰지 말고
replace / supersede 후보로 보고해.
CLAUDE.md에는 Memory 전체를 넣지 않는다.
# Project Context
Long-term project memory:
`.ai/memory/index.md`
Current task:
`.ai/tasks/current/`
Rules:
- 필요한 Memory만 읽는다.
- 현재 Repository와 Memory가 충돌하면 Repository를 우선한다.
- Dynamic value는 현재 Source에서 다시 확인한다.
CLAUDE.md가 Memory Database가 아니라 Memory Map 역할을 한다.
멀티에이전트 구조라면:
Main Agent
↓
Task 수행
완료 후:
Memory Curator
에게 넘긴다.
Memory Curator는 다음만 담당한다.
이번 Task에서
장기적으로 유용한 내용이 있는가?
기존 Memory와 중복인가?
기존 Memory를 폐기해야 하는가?
근거가 충분한가?
작업이 구조화되어 있다면:
Search
Classification
Deduplication
Metadata 작성
중심이다.
Main Coding Agent보다 가벼운 모델을 사용할 수 있다.
예:
Main
Sol / Opus
Memory Curator
Terra / Sonnet
Memory Search
Luna / Haiku
처럼 나눌 수 있다.
단, 어떤 모델 조합이 실제로 효율적인지는 Repository별 Eval로 확인해야 한다.
전체 구조는 다음과 같다.
Task
↓
Main Agent
↓
Memory Search
↓
Task 실행
↓
Result
↓
Feedback
↓
Memory Curator
↓
Memory Review
↓
Memory Update
↓
Strategy Evaluation
그리고 일정 주기로:
Memory Strategy
↓
Eval
↓
개선 제안
↓
Policy Version Update
한다.
async function completeTask(task: Task) {
const memory = await memorySearch(task);
const result = await runAgent({
task,
memory
});
const feedback = await evaluateResult(result);
const proposal = await proposeMemoryUpdate({
task,
result,
feedback
});
const review = await reviewMemoryProposal(proposal);
if (review.safeToApply) {
await applyMemoryUpdate(proposal);
}
return result;
}
이 자체가 SelfMem 구현은 아니다.
SelfMem 아이디어를 실무 Agent Runtime에 적용한 단순화된 구조다.
const metrics = {
answerQuality,
memoryTokens,
retrievalCalls,
repeatedReads,
staleMemoryHits,
latency,
cost
};
const nextStrategy =
await optimizeMemoryStrategy({
currentStrategy,
metrics,
recentFailures
});
Agent가
최근 20개의 실패 중 7개가
오래된 Dynamic Value 때문
이라고 판단한다.
그리고:
- dynamic values may be stored
+ dynamic values must be resolved from source
를 제안한다.
바로 Production에 적용하지 않는다.
Current Strategy
vs
Candidate Strategy
두 개로 Replay한다.
Memory Eval Dataset
↓
A/B
측정:
Accuracy
Cost
Latency
Stale Usage
Retrieval Calls
Candidate가 실제로 낫다면 승격한다.
예:
memory-policy PR
↓
Memory Eval
↓
Regression Test
↓
Human Review
↓
Merge
Agent의 기억법도 Code처럼 관리하는 것이다.
지금 Agent 개발자는 주로 다음을 최적화한다.
Prompt
Model
Tools
Context
앞으로는 여기에 하나가 더 들어갈 가능성이 높다.
Memory Policy
그리고 그 Memory Policy도 사람이 수동으로 만드는 것이 아니라 Agent가 Feedback을 보고 개선하는 방향이다.
SelfMem은 최근 연구 결과다.
모든 실제 기업 Agent에서 같은 성능 향상이 보장되는 것은 아니다.
연구의 실험 환경과 실제 Coding Repository는 다르다.
특히 Production에서는 다음 문제가 추가된다.
Privacy
Access Control
Memory Poisoning
Multi-user Isolation
Freshness
Deletion
Compliance
Cost
따라서 논문의 핵심 아이디어를 가져오되 자체 Eval이 필요하다.
사용자가
이 정보는 기억하지 마.
라고 할 수 있어야 한다.
그리고:
Memory 삭제
↓
Index 삭제
↓
Cache 삭제
↓
관련 Summary 수정
까지 연결돼야 한다.
Self-Optimizing이라는 이유로 Memory Retention 정책까지 Agent 마음대로 바꾸게 하면 안 된다.
User A Memory
↓
User B Agent Context
은 심각한 사고다.
Memory 저장소에는 최소:
tenant
user
project
agent
scope
같은 경계가 필요하다.
{
"id": "mem-4821",
"scope": {
"tenant": "company-a",
"project": "mobile-app"
},
"type": "architecture",
"status": "active",
"content": "SessionCoordinator owns refresh coordination.",
"evidence": [
"Sources/Auth/SessionCoordinator.swift"
],
"createdAt": "2026-08-13",
"lastVerifiedAt": "2026-08-13",
"risk": "medium"
}
Memory 하나에도 Lifecycle을 둔다.
Candidate
↓
Reviewed
↓
Active
↓
Stale
↓
Superseded
↓
Archived
무조건 create/delete 두 상태로만 관리하지 않는다.
Meta Memory는
내가 무엇을 알고 있는가?
무엇을 모르는가?
어떤 정보가 오래됐는가?
어디에서 다시 확인할 수 있는가?
를 아는 것이다.
예:
현재 Production Version
Memory 없음
하지만 release config에서 찾을 수 있음
이것이:
현재 Production Version은 4.2.0이라고 기억함
보다 안전할 수 있다.
Memory에 정보가 없으면:
모름
이라고 판단하고 Source를 찾는다.
잘못된 Agent:
Memory 없음
↓
추측
↓
Memory 저장
↓
다음부터 사실처럼 사용
이 패턴은 막아야 한다.
예:
if (
memory.risk === "high" &&
memory.evidence.length === 0
) {
throw new Error("High-risk memory requires evidence.");
}
Architecture나 Security Memory에서는 특히 중요하다.
Main Agent
│
┌───────────┼───────────┐
│ │ │
▼ ▼ ▼
Memory Search Source Tools
│ Lookup
│ │
└─────┬─────┘
│
▼
Context
│
▼
Task
│
▼
Result
│
▼
Feedback
│
▼
Memory Curator
│
┌──────┴──────┐
│ │
▼ ▼
Memory Review Strategy Review
│ │
▼ ▼
Memory Update Candidate Policy
│
▼
Eval
이 정도가 Self-Optimizing Memory를 실제 Agent Runtime으로 옮긴 모습에 가깝다.
개인 개발자라면 네 개부터 시작해도 된다.
.ai/
├── memory.md
├── decisions.md
├── checkpoint.json
└── artifacts/
그리고 다음 규칙만 둔다.
1. 반복해서 다시 조사한 정보만 Memory 후보로 본다.
2. 쉽게 다시 확인 가능한 값은 저장하지 않는다.
3. 중요한 Memory에는 Source를 남긴다.
4. 오래된 Memory는 Archive한다.
5. Task 종료 때 Memory Update 후보를 검토한다.
이것만으로도 상당한 차이가 난다.
1단계:
사람이 Memory 관리
2단계:
Agent가 Memory 후보 제안
3단계:
Agent가 Low-risk Memory 자동 관리
4단계:
Memory Eval
5단계:
Agent가 Memory Strategy 개선 제안
순서가 안전하다.
지금까지 Agent Memory의 핵심 질문은 대부분 이랬다.
어디에 저장할까?
Vector DB?
File System?
Graph DB?
Summary?
하지만 SelfMem이 던지는 질문은 조금 다르다.
왜 Memory 전략 자체는
개발자가 영원히 고정해야 하는가?
Task마다 중요한 정보가 다르고,
시간이 지나면 Memory가 오래되며,
Agent마다 사용하는 정보가 다르다면,
Memory 관리 방식도 상황에 따라 달라져야 한다.
그래서 앞으로 Agent는 다음 능력을 갖게 될 가능성이 높다.
Remember
Retrieve
Forget
Merge
Archive
Verify
Review
그리고 한 단계 더 나아가:
어떤 Memory 행동이
실제로 자신의 성능을 높였는가?
까지 평가하게 된다.
최근 SelfMem 연구는 이 방향에서 꽤 흥미로운 결과를 보여줬다.
고정된 Retrieval·Compression·Memory Pipeline을 사용하는 대신 Agent가 Memory Tool과 Feedback을 이용해 자신의 Memory Workspace를 구성하고 수정하도록 했을 때, 100K부터 1M Token 규모의 장기 Conversation Benchmark에서 강한 결과를 보였다.
여기서 중요한 메시지는 단순히 SelfMem이라는 Framework 하나가 아니다.
Memory
=
Storage Feature
에서
Memory
=
Agent가 지속적으로 최적화해야 하는 Runtime Component
로 사고방식이 이동하고 있다는 점이다.
그리고 또 다른 최근 연구들이 보여주듯 일부 반복적·개인화 Task에서는 모델을 무조건 키우는 것보다 적절한 과거 지식에 정확하게 접근하는 것이 더 큰 효과를 낼 수도 있다.
한 줄로 정리하면 이렇다.
앞으로 좋은 AI Agent는
모든 것을 기억하는 Agent가 아니라,
어떤 정보를 기억했을 때
자신이 더 잘 일했는지를 학습하고,
필요 없는 기억은 버리고,
정확한 정보는 다시 확인하며,
기억하는 방식 자체를 개선하는 Agent가 될 것이다.
Context Window가 Agent의 Working Memory라면,
File System이나 Memory Store는 Long-term Memory가 되고,
SelfMem이 보여주는 다음 단계는 그 Memory를 다루는 전략 자체도 Agent의 학습 대상이 될 수 있다는 것이다.
Yang, Wu, Wong, Wang — SelfMem: Self-Optimizing Memory for AI Agents
고정된 저장·검색·압축 전략 대신 Agent에게 Transcript 조회, Memory 작성·수정·검토 Tool과 Feedback을 제공하고 Memory Strategy 자체를 모델이 조정하도록 한 2026년 연구.
Liu et al. — Knowledge Access Beats Model Size: Memory Augmented Routing for Persistent AI Agents
반복적이고 사용자 특화된 Task에서는 더 큰 모델을 항상 사용하는 것보다 관련 Conversation Memory를 적절히 제공하는 것이 정확도와 비용 측면에서 중요할 수 있음을 분석한 연구.
BEAM — Beyond a Million Tokens
SelfMem 평가에 사용된 장기 Conversation Memory Benchmark로, 100K·500K·1M Token 규모에서 정보 추출, 시간 추론, Multi-session Reasoning 등을 평가.
SelfMem은 원본 Conversation Transcript를 수정할 수 없는 Source of Truth로 유지하고, 별도의 Memory Workspace를 Agent가 직접 구성한다. Agent는 Transcript 검색, Memory 읽기·쓰기·병합·교체·Archive, Memory Review 등의 행동을 조합하고 Feedback을 보면서 Memory를 계속 수정한다.
특히 Memory 작성은 한 번의 Summary로 끝나는 것이 아니라 inspect → write → review → revise Loop로 구성된다. 정확한 값이나 자주 바뀌는 정보는 무조건 Memory에 넣기보다 필요할 때 원본 Transcript에서 다시 확인하는 전략도 Agent가 선택할 수 있다.
SelfMem 연구는 BEAM의 100K, 500K, 1M Token 조건에서 RAG, Compression, LoCoMo, ReadAgent, MemoryBank, MemGPT, A-Mem, Mem0 등의 Baseline과 비교했으며 세 규모 모두에서 가장 높은 공식 Score를 보고했다.
중요한 점은 단순히 더 많은 Memory Infrastructure를 사용했다고 성능이 좋아진 것이 아니라는 것이다. 연구에서는 일부 복잡한 Memory Pipeline이 더 많은 LLM·Embedding 호출과 비용을 사용하면서도 SelfMem보다 낮은 결과를 보였다.
따라서 SelfMem의 핵심은 “Memory를 많이 저장한다”가 아니라 Agent가 Task와 Feedback에 따라 무엇을 저장하고, 무엇을 압축하고, 무엇을 수정하며, 무엇은 원문에서 다시 찾을지를 스스로 조정하는 것에 있다.