모든 세션에서 자동으로 메모리를 추출하고, 잠자는 동안 통합하는 방법.
자동 메모리 시스템은 두 가지 핵심 프로세스로 구성됩니다: 대화 중 실시간으로 메모리를 추출하는 턴별 추출과, 축적된 메모리를 주기적으로 통합하는 교차 세션 통합(드림)입니다.
memory/extraction.ts → memory/consolidation.ts → memory/recall.ts → memory/dream.ts → memory/teamSync.ts
두 가지 핵심 프로세스:
턴별 추출은 대화의 각 턴이 완료될 때마다 백그라운드에서 실행됩니다. 메인 에이전트의 응답 지연에 영향을 주지 않도록 설계되어 있습니다.
추출 에이전트는 마지막으로 처리한 대화 위치를 커서로 추적합니다. 새 턴이 추가되면 커서 이후의 내용만 처리하여 중복 추출을 방지합니다.
추출 에이전트는 한 번에 하나만 실행됩니다. 이전 추출이 아직 진행 중이면 새 추출은 대기하거나 건너뜁니다.
추출 에이전트는 메인 에이전트와 동일한 도구 목록을 사용하는 포크 에이전트 패턴을 따릅니다. 이를 통해 API 프롬프트 캐시를 공유합니다.
// 포크 에이전트 패턴 — 캐시 공유 핵심
// 메인 에이전트와 동일한 도구 목록을 전달하되
// canUseTool()로 런타임에서 실제 사용을 제한
const extractionAgent = {
tools: mainAgent.tools, // 동일 목록 → 캐시 공유
canUseTool: (tool) => {
return memoryWriteTools.includes(tool.name)
},
}
메인 에이전트가 현재 턴 범위에서 메모리 경로에 직접 쓴 경우, 추출 에이전트는 해당 턴을 건너뛰고 커서를 전진시킵니다. 이는 메인 에이전트의 명시적 메모리 쓰기와 자동 추출이 충돌하는 것을 방지합니다. 메인 에이전트가 "이것을 기억해"라는 사용자 요청에 응답하여 직접 메모리를 작성했다면, 추출 에이전트가 같은 내용을 중복 추출할 필요가 없습니다.
드림은 여러 세션에서 축적된 메모리를 통합하고 정리하는 프로세스입니다. 메모리 파일이 많아지면 중복, 충돌, 낡은 정보가 발생할 수 있으므로 주기적인 통합이 필요합니다.
드림은 다음 세 가지 게이트를 모두 통과해야 실행됩니다:
.consolidate-lock 파일로 동시 실행을 방지.consolidate-lock과 타임스탬프마지막 통합 타임스탬프는 .consolidate-lock 파일의 mtime(파일 수정 시간)에 저장됩니다. 파일 내용이나 별도의 JSON 필드가 아니라 파일시스템의 mtime을 활용하여 원자적 타임스탬프 기록을 달성합니다.
// .consolidate-lock — mtime 기반 타임스탬프
async function shouldRunConsolidation(): Promise<boolean> {
const lockPath = join(memoryDir, '.consolidate-lock')
const stat = await fsStat(lockPath)
// mtime = 마지막 통합 시간
const lastConsolidation = stat.mtime
const elapsed = Date.now() - lastConsolidation.getTime()
return elapsed > MIN_CONSOLIDATION_INTERVAL
}
드림이 실행되면 DreamTask가 4단계로 메모리를 통합합니다:
리콜은 새 세션 시작 시 저장된 메모리에서 현재 작업에 관련된 것들을 선택하는 프로세스입니다.
findRelevantMemories와 Sonnet 사이드쿼리리콜은 Sonnet 모델에 사이드쿼리를 보내 관련성을 평가합니다. 이 쿼리는 메인 대화와 병렬로 실행되어 응답 지연에 영향을 주지 않습니다.
리콜 시스템은 현재 활성 사용 중인 도구의 참조 문서를 선택에서 억제합니다. 이유는 해당 도구가 이미 대화에서 사용되고 있으므로, 작동 예시가 대화 자체에 존재하기 때문입니다. 참조 문서를 중복으로 주입하면 컨텍스트 윈도우만 낭비됩니다.
사용자가 Edit 도구를 활발히 사용하는 세션에서 "Edit 도구 사용법" 참조 메모리를 주입하면, 이미 대화에 실제 사용 예시가 존재하므로 중복입니다. 리콜 시스템은 현재 활성 도구 목록을 확인하고, 해당 도구에 대한 참조 문서를 필터링하여 컨텍스트 효율을 높입니다.
팀 환경에서는 여러 팀메이트가 독립적으로 메모리를 추출합니다. 팀 메모리 통합 모드는 이 분산된 메모리를 일관되게 병합하고 동기화합니다.
통합 시 SHA-256 해시를 사용하여 변경을 감지하고, 비밀 스캐닝으로 민감한 정보가 팀 전체에 전파되지 않도록 합니다. 동일한 드림 3개 게이트(시간/세션/잠금)를 통과해야 팀 통합이 실행됩니다.
canUseTool로 런타임에서 사용을 제한합니다.consolidate-lock의 마지막 통합 타임스탬프는 파일의 mtime에 저장됩니다 — 파일 내용이 아닌 파일시스템 메타데이터를 활용Q1. 포크 에이전트가 부모의 프롬프트 캐시를 공유하는 기법은?
canUseTool 함수로 런타임에서 제한합니다.Q2. .consolidate-lock의 마지막 통합 타임스탬프가 저장되는 위치는?
.consolidate-lock 파일의 mtime(파일 수정 시간)이 마지막 통합 시점을 나타냅니다. 파일 내용이나 별도 필드가 아닌 파일시스템 메타데이터를 활용하여 원자적 타임스탬프 기록을 달성합니다.Q3. 코드 패턴/아키텍처/git 히스토리를 메모리에서 제외하는 이유는?
Q4. 턴별 추출이 건너뛰고 커서를 전진시키는 경우는?
Q5. 리콜 시스템이 선택에서 억제하는 것과 그 이유는?