--- id: five-layer-memory-system title: "5계층 메모리 시스템" category: "AI_and_ML" status: "draft" verification_status: "applied" canonical_id: "" aliases: ["cognitive memory", "메모리 시스템", "short-term", "long-term", "episodic", "procedural", "distillation", "memory layers"] duplicate_of: "" source_trust_level: "A" confidence_score: 0.93 created_at: 2026-06-13 updated_at: 2026-06-13 review_reason: "" merge_history: [] tags: ["memory", "ai", "agent", "cognitive-architecture", "astraai"] raw_sources: ["AstraAI/src/memory/index.ts", "AstraAI/src/memory/types.ts", "AstraAI/src/retrieval/index.ts"] applied_in: ["AstraAI"] github_commit: "" --- # [[5계층 메모리 시스템]] ## 🎯 한 줄 통찰 (One-line insight) LLM 에이전트의 "기억"은 인간 인지처럼 **시간 범위·용도가 다른 5개 계층(단기·장기·프로젝트·절차·일화)** 으로 나누고, 각 계층이 질의에 대해 관련도 점수를 매겨 컨텍스트에 합치는 것이 AstraAI 의 설계다 [S1][S2]. ## 🧠 핵심 개념 (Core concepts) 1. **① 단기(Short-Term):** 현재 대화 흐름. 최근 N개 메시지를 FIFO 로 유지(`shortTermLimit: 8`) [S1]. 2. **② 장기(Long-Term):** 사용자 취향·규칙·결정·목표. category(`preference`/`rule`/`decision`/`goal`/`episode-digest`)와 confidence, 참조 횟수, 만료시각(`expiresAt`)을 가진 엔트리 [S2]. 3. **③ 프로젝트(Project):** 워크스페이스별 지식 — 아키텍처 결정(ADR), 버그 기록, 요구사항, 기술스택, 코드 컨벤션. workspace 경로 hash 로 식별 [S2]. 4. **④ 절차(Procedural):** 반복 작업의 절차서(skill.md). triggerPatterns 로 매칭(`["wiki화","위키","wikify"]`)해 steps 를 제공 [S2]. 5. **⑤ 일화(Episodic):** 과거 세션의 요약·주요 결정·토픽. 시간이 지나면 distillation 으로 장기 digest 로 승급 [S2]. ## 🧩 추출된 패턴 (Extracted patterns) - **통합 매니저 + 계층 위임:** `MemoryManager` 가 5개 계층 객체를 보유하고 `buildContext()` 에서 각 계층의 `buildContext(query)` 를 호출해 결과를 모은다 — 계층은 독립, 매니저는 조립 [S1]. - **관련도 점수 + 정렬:** 각 계층이 `MemoryContextResult { layer, label, content, relevance }` 를 반환, 매니저가 `relevance` 내림차순 정렬 후 합침 [S1]. - **lazy 프로젝트 메모리:** `projectMemories: Map` 로 워크스페이스별 지연 생성·캐시 [S1]. - **temporal marker 로 자동 만료:** `expiresAt < now` 인 엔트리는 검색·컨텍스트 구성에서 자동 제외 — "Q3 계획은 9/30까지만 유효" 같은 시한부 지식 [S2]. - **증류(Distillation) 폐루프:** 세션 종료 시 stale 일화를 장기 digest 로 승급하고 `promoted=true` 로 표시해 이후 검색에서 제외(중복 방지) [S1]. ## 📖 세부 내용 (Details) ### 컨텍스트 조립 (핵심 API) `buildContext(currentPrompt, visibleHistory, summarize, workspacePath)` 가 5계층에서 관련 컨텍스트를 모아 하나의 `[MEMORY CONTEXT]` 블록으로 만든다. 각 계층은 자기 데이터를 query 와 비교해 relevance 를 매기고, 빈 결과면 제외된다. 마지막에 "관련될 때만 사용하고, 충돌 시 현재 요청을 우선하라"는 지침을 덧붙인다 [S1]. ### 세션 종료 시 추출·영속화 `onSessionEnd(sessionId, messages, workspacePath, distillationOpts)`: 1. `MemoryExtractor` 가 대화에서 장기/일화/프로젝트 메모리를 추출 (실패해도 본 흐름 안 깨짐 — 빈 catch). 2. 장기 메모리 `save()`. 3. distillation 이 enabled 이고 interval 충족 시 stale 일화를 장기 digest 로 승급 [S1]. ### RAG 와의 결합 검색 오케스트레이터는 메모리 계층을 RAG 소스 중 하나로 끌어온다 — 장기/프로젝트/절차/일화 각각을 `RetrievalChunk` 로 변환하고, source 별 가중치(procedural 0.95, project 0.85, episodic 0.7)로 정규화한다 [S3]. → [[RAG 검색 파이프라인]]. ### 설정 가능성 `MemoryConfig` 로 계층별 on/off 와 한도(`longTermMaxEntries: 100`, `episodicMaxEpisodes: 50`)를 조절. 생성자에서 `{ ...defaults, ...config }` 로 부분 오버라이드 [S1]. ## ⚖️ 모순 및 업데이트 (Contradictions & updates) - **계층 경계의 모호성:** "프로젝트 결정"이 장기 메모리(decision)인지 프로젝트 메모리(ADR)인지 겹칠 수 있다. AstraAI 는 워크스페이스 종속성 유무로 가른다(프로젝트 종속이면 ③, 사용자 보편이면 ②). - **만료 vs 보존:** `expiresAt` 로 시한부 지식을 자동 제외하지만, 만료된 지식이 "역사적 맥락"으로 필요할 때도 있다 — 검색은 제외하되 distillation 이 digest 로 보존하는 식으로 절충. ## 🛠️ 적용 사례 (Applied in summary) - `AstraAI/src/memory/index.ts` — MemoryManager 의 buildContext/onSessionEnd 전체 흐름 [S1]. - `AstraAI/src/memory/types.ts` — 5계층 데이터 형태, temporal marker, distillation 승급 필드 [S2]. - `AstraAI/src/retrieval/index.ts` — `searchMemoryLayers` 가 계층을 RAG 청크로 변환 [S3]. ## 💻 코드 패턴 (Code patterns) ```typescript // 1) 통합 매니저가 계층에 위임 + 관련도 정렬 (src/memory/index.ts) public buildContext(prompt, history, summarize, workspacePath?): string { const layers: MemoryContextResult[] = []; const stm = this.shortTerm.buildContext(history, this.config.shortTermLimit, summarize); if (stm) layers.push(stm); const ltm = this.longTerm.buildContext(prompt); if (ltm) layers.push(ltm); // ... project / procedural / episodic 동일 패턴 if (!layers.length) return ''; layers.sort((a, b) => b.relevance - a.relevance); // 관련도 내림차순 return ['', '[MEMORY CONTEXT]', /* 지침 */, layers.map(l => `### ${l.label}\n${l.content}`).join('\n\n')].join('\n'); } // 2) lazy 프로젝트 메모리 (src/memory/index.ts) public getProjectMemory(workspacePath: string): ProjectMemory { if (!this.projectMemories.has(workspacePath)) this.projectMemories.set(workspacePath, new ProjectMemory(workspacePath)); return this.projectMemories.get(workspacePath)!; } // 3) 부가 작업은 본 흐름을 깨지 않음 (src/memory/index.ts) try { this.extractor.extractFromSession(...); } catch { /* never break main flow */ } ``` ## ✅ 검증 상태 및 신뢰도 - **상태:** draft - **검증 단계:** applied - **출처 신뢰도:** A - **신뢰 점수:** 0.93 - **중복 검사 결과:** 신규 생성 (New discovery) ## 🔗 지식 그래프 (Knowledge Graph) - **상위/루트:** [[AstraAI 아키텍처 개요]] - **관련 개념:** [[RAG 검색 파이프라인]], [[이벤트 소싱 스토어 패턴]], [[Agent 오케스트레이터 분해]] - **참조 맥락:** 로컬 LLM 이 에이전트의 기억/컨텍스트 시스템을 설계하거나 메모리 계층 코드를 다룰 때 참조. ## 📚 출처 (Sources) - [S1] AstraAI/src/memory/index.ts — MemoryManager, buildContext, onSessionEnd, distillation 호출 - [S2] AstraAI/src/memory/types.ts — 5계층 타입, temporal marker, 승급 필드 - [S3] AstraAI/src/retrieval/index.ts — searchMemoryLayers(메모리→RAG 청크) ## 📝 변경 이력 (Change history) - 2026-06-13: AstraAI 코드 분석 기반 초안 생성.