02-types-memory
Dec 7, 2025
MemoryNode
📁 관련 코드:
lib/types/nodes/memory.ts
시스템의 핵심 단위입니다. 이메일에서 추출된 의미 있는 정보를 저장합니다.
핵심 개념: 이메일 ≠ 메모리
왜 분리하는가?
접근 방식 | 장점 | 단점 |
|---|---|---|
이메일 = 메모리 | 단순함 | 검색 시 불필요한 정보 포함 |
이메일 → 여러 메모리 | 정밀한 검색, 관계 추적 가능 | 추출 로직 필요 |
선택 이유: 사용자가 "내일 미팅 몇 시야?"라고 물으면, 미팅 정보만 정확히 반환해야 합니다. 이메일 전체를 반환하면 LLM이 불필요한 정보까지 처리해야 합니다.
MemoryCategory
분류 기준
카테고리 | 키워드/패턴 | 예시 |
|---|---|---|
MEETING | 미팅, 회의, 일정, 시간, 장소 | "내일 2시 회의실에서 만나요" |
DECISION | 결정, 확정, 합의, 승인 | "Q1 예산 500만원으로 확정" |
PROJECT | 진행, 완료, 마일스톤, 릴리즈 | "v2.0 다음 주 월요일 배포" |
TASK | 해주세요, 부탁, 요청, 까지 | "금요일까지 보고서 보내주세요" |
ADS | 할인, 프로모션, 구독 해지 | "50% 할인 이벤트!" |
MISC | 위 어디에도 해당 안 됨 | "잘 지내시죠?" |
분류 우선순위
하나의 이메일이 여러 카테고리에 해당할 수 있습니다:
예: "미팅에서 결정된 사항을 정리해서 보내주세요" → TASK (요청이 있으므로)
ImportanceFactor
왜 점수 산정 근거를 저장하는가?
문제: 사용자가 "왜 이게 중요하다고 판단했어?"라고 물으면?
해결: importanceFactors 배열에 근거 저장
주요 Factor 목록
Factor | Weight | 설명 |
|---|---|---|
| +0.3 | 금액 언급 |
| +0.2 | 마감일 언급 |
| +0.1 | 여러 사람 참여 |
| +0.15 | 액션 아이템 포함 |
| +0.05 | 답장 체인의 일부 |
| +0.2 | 중요 인물로부터 |
시간 필드 구분
각 필드의 의미
왜 occurredAt이 중요한가?
시나리오: "지난 주에 무슨 일이 있었어?"
Embedding 필드
왜 optional인가?
Lazy Computation: 모든 메모리에 즉시 임베딩 생성하면 비용 큼
Batch Processing: 나중에 일괄 생성 가능
Model Update: 임베딩 모델 변경 시 재생성 필요
사용 시점
Version Control
왜 버전 관리가 필요한가?
시나리오: 미팅 시간이 변경됨
버전 관리 없이:
두 개의 별개 메모리 → "미팅이 2시야 3시야?" 혼란
버전 관리 있으면:
버전 업데이트 로직
Factory Helper
왜 Factory 함수를 제공하는가?
기본값 자동 설정:
createdAt,updatedAt,version타입 안전성:
nodeType: NodeType.MEMORY자동 설정일관성 보장: 모든 메모리가 같은 방식으로 생성
다음 문서
→ PersonNode: 사람 정보 스키마
→ base.md: BaseNode, ImportanceTier 상세