22 KiB
Warning
🚧 대규모 개편 진행 중 — memU는 대규모 리워크 중이며 API, CLI 명령어, 문서가 예고 없이 변경될 수 있습니다. 2026년 7월 15일경 안정화될 예정입니다.
memU는 대화, 문서, 코드, 이미지, 오디오, 비디오, URL, 도구 트레이스를 사람이 읽을 수 있는 Markdown 파일(INDEX.md, MEMORY.md, SKILL.md)로 컴파일합니다. 에이전트는 파일 트리를 탐색하며 그 순간 필요한 기억만 불러옵니다 — 매번 전체를 스캔하거나 긴 기록을 프롬프트에 넣을 필요가 없습니다:
INDEX.md— 전체 지도: 카테고리, 파일, 요약. 에이전트가 먼저 어디를 봐야 하는지 알려줍니다MEMORY.md— 프로필, 선호, 목표, 사실, 그리고 소스 데이터에서 추출한 주요 사건SKILL.md— 도구 트레이스에서 자동 추출되고 매memorize()마다 정제되는 재사용 가능한 도구 패턴과 워크플로
workspace/
├── INDEX.md ← 전체 지도: 카테고리, 파일, 요약
├── MEMORY.md ← 프로필, 선호, 목표, 주요 사건
└── skill/
├── {skill_name}/
│ └── SKILL.md ← 학습한 스킬 또는 도구 패턴
└── {another_skill}/
└── SKILL.md
모든 것을 프롬프트에 넣는 방식과 달리 memU는 세 가지 핵심 이점이 있습니다:
- 빠른 검색 — 매번 전체를 스캔하는 대신 관련 폴더로 이동하고 파일을 순위화합니다.
- 높은 정확도 — 사용자, 작업, 세션별로 범위를 좁히고 각 항목을 원본 소스까지 추적합니다.
- 낮은 비용 — 긴 기록을 매번 주입하는 대신 압축된 범위 지정 컨텍스트만 검색합니다.
- 감사 가능 — 사람이 읽을 수 있는 파일 트리를 검토·편집하고, 자체 스토리지와 LLM 제공자로 라우팅할 수 있습니다.
🔄 작동 방식
두 가지 파일 시스템 작업으로 생각하세요: 원본 소스를 정리된 메모리에 쓰기, 그리고 알맞은 파일을 에이전트로 다시 읽기.
WRITE — memorize() READ — retrieve()
────────────────────────────────────────────── ──────────────────────────────────────────────
raw files → extract → files + folders query → walk folders → ranked files
───────────── ───────── ────────────── ───── ──────────── ─────────────
chat logs → parse → profile / event items user / task query
documents / URLs → facts → knowledge / skill items │
images / video → caption → resources + summaries ├─ route + scope → relevant folders (categories)
audio → transcribe→ event / knowledge items ├─ rank by relevance → matching files (items)
tool logs → mine → tool / skill items └─ trace to source → original resources
파일 시스템에 쓰기(memorize)
- 수집(Ingest) — 각 소스를 모달리티와 소스 위치와 함께
Resource(원본 파일)로 저장합니다 - 전처리(Preprocess) — 텍스트를 파싱하고, 이미지/비디오에 캡션을 달고, 오디오를 전사하고, 입력을 정규화합니다
- 추출(Extract) — 원본 콘텐츠를 타입이 지정된
RecallEntry레코드(파일)로 변환합니다: profile, event, knowledge, behavior, skill, tool 메모리 - 조직화(Organize) — 아이템을
RecallFile폴더(메모리 카테고리 또는 스킬)로 분류하고, 상호 링크하고, 임베딩하고, 탐색 가능한 트리로 요약합니다 - 영속화(Persist) — 설정된 백엔드를 통해 레코드, 관계, 임베딩, 폴더 요약을 기록합니다
파일 시스템에서 읽기(retrieve)
- 검색(Retrieve) — 폴더를 탐색하여 현재 사용자, 에이전트, 세션 또는 태스크에 관련된 파일만 반환합니다
🗂️ 메모리 파일 시스템
memU의 주요 산출물은 탐색 가능한 메모리 트리입니다 — 폴더, 파일, 그리고 그 뒤에 있는 소스 산출물 — 리포지토리 계약을 통해 영속화되며 memorize()와 retrieve()에서 딕셔너리로 반환됩니다.
RecallFile ← 폴더: 진화하는 요약을 가진 주제
├── name, track (memory | skill), description, content
├── embedding
└── RecallEntry[] ← 파일: 타입이 지정된 원자적 메모리
├── memory_type: profile | event | knowledge | behavior | skill | tool
├── summary, extra, happened_at, embedding
└── Resource ← 소스: 이 메모리가 비롯된 원본 파일
└── url, modality, local_path, caption, embedding
| 레코드 | 파일 시스템 역할 | 사용 목적 |
|---|---|---|
RecallFile |
폴더 — 관련 메모리를 묶고(또는 스킬을 담고) 주제 수준 요약을 유지; track 필드가 memory 또는 skill을 표시 |
폭넓은 질의를 위해 간결한 컨텍스트를 로드 |
RecallEntry |
파일 — 요약과 선택적 메타데이터를 가진 타입 지정 원자 메모리 | 정확한 사실, 선호, 사건, 스킬, 도구 패턴을 주입 |
Resource |
소스 산출물 — 메모리 뒤의 원본 파일(캡션/텍스트 포함) | 컨텍스트를 그 출처까지 추적 |
RecallFileEntry |
링크 — 아이템을 폴더 아래에 분류하는 엣지 | 소스를 재처리하지 않고 관련 메모리를 탐색 |
이를 통해 에이전트는 안정적인 메모리 파일 시스템을 얻습니다: 원본 소스는 한 번만 수집하면 되고, 이후에는 모든 소스 산출물을 다시 읽는 대신 범위가 지정되고 순위가 매겨진 파일을 요청할 수 있습니다.
🧩 memU가 구축하는 것
파일 시스템의 각 계층은 구조화 레코드로 저장됩니다:
| 계층 | 무엇을 나타내는가 | 에이전트가 사용하는 이유 |
|---|---|---|
| RecallFile | 자동 생성 폴더: 진화하는 요약을 가진 주제(또는 스킬) | 세부로 파고들기 전에 상위 수준 컨텍스트를 로드 |
| RecallEntry | 파일: 타입과 요약을 가진 원자적 구조화 메모리 | 정확한 사실, 선호, 사건, 스킬, 도구 패턴을 주입 |
| Resource | 파일 뒤의 소스 산출물: 대화, 문서, 이미지, 비디오, 오디오, URL, 파일 | 메모리를 그 출처까지 추적 |
| RecallFileEntry | 아이템을 폴더 아래에 분류하는 링크 | 소스를 재처리하지 않고 관련 메모리를 탐색 |
| Embedding | 폴더, 파일, 소스를 아우르는 벡터 인덱스 | 낮은 지연으로 관련 컨텍스트를 검색 |
memorize() 출력 예시:
{
"resource": {
"id": "res_01",
"url": "files/launch-meeting.mp4",
"modality": "video",
"caption": "A product planning discussion about onboarding and launch risks."
},
"items": [
{
"id": "mem_01",
"memory_type": "event",
"summary": "The team decided to simplify onboarding before the next launch review."
},
{
"id": "mem_02",
"memory_type": "profile",
"summary": "The user prefers concise implementation plans with explicit verification steps."
},
{
"id": "mem_03",
"memory_type": "tool",
"summary": "Use repository-wide search before editing configuration files to avoid missing duplicated settings."
}
],
"categories": [
{
"id": "cat_01",
"name": "product_goals",
"summary": "Current launch priorities, onboarding decisions, and unresolved risks."
}
],
"relations": [
{ "item_id": "mem_01", "category_id": "cat_01" }
]
}
그런 다음 에이전트는 retrieve()를 호출하여 범위가 지정되고 순위가 매겨진 컨텍스트 페이로드를 얻을 수 있습니다:
context = await service.retrieve(
queries=[{"role": "user", "content": {"text": "What context matters for this launch task?"}}],
where={"user_id": "123"},
)
⭐️ 저장소에 스타 누르기
memU가 유용하거나 흥미롭다고 느끼셨다면, GitHub 스타 ⭐️ 를 눌러 주시면 정말 감사하겠습니다.
✨ 핵심 기능
| 기능 | 설명 |
|---|---|
| 🗂️ 멀티모달 수집 | 대화, 문서, 이미지, 비디오, 오디오, URL, 로그, 로컬 파일을 메모리에 기록 |
| 📁 메모리 파일 시스템 | 폴더(카테고리), 파일(아이템), 소스 산출물, 링크, 요약, 임베딩을 영속화 |
| 🧠 타입 지정 메모리 추출 | 원본 소스에서 profile, event, knowledge, behavior, skill, tool 메모리를 추출 |
| 🧭 자기 조직화 폴더 | 수동 태깅 없이 카테고리, 링크, 요약, 임베딩을 자동 구축 |
| 🤖 에이전트 친화적 검색 | 어떤 에이전트 워크플로에도 주입할 수 있는, 범위 지정되고 순위가 매겨진 컨텍스트를 읽기 |
| 🧱 플러그형 스토리지 | 동일한 리포지토리 계약으로 in-memory, SQLite, Postgres 백엔드 사용 |
| 🔀 프로파일 기반 LLM 라우팅 | 설정 가능한 LLM 프로파일로 채팅, 임베딩, 비전, 전사 작업을 라우팅 |
🎯 활용 사례
1. 대화 메모리
채팅 로그를 사용자 선호, 목표, 사건, 관계 컨텍스트로 전환.
await service.memorize(
resource_url="examples/resources/conversations/conv1.json",
modality="conversation",
user={"user_id": "123"},
)
context = await service.retrieve(
queries=[{"role": "user", "content": {"text": "What should I remember about this user?"}}],
where={"user_id": "123"},
)
2. 코딩 에이전트를 위한 워크스페이스 컨텍스트
문서, PR 메모, 로그, 설계 결정을 재사용 가능한 프로젝트 메모리로 전환.
await service.memorize(resource_url="docs/architecture.md", modality="document")
await service.memorize(resource_url="examples/resources/logs/log1.txt", modality="document")
context = await service.retrieve(
queries=[{"role": "user", "content": {"text": "How should I structure this module?"}}],
)
3. 멀티모달 지식 계층
문서, 스크린샷, 이미지, 비디오, 음성 메모에서 검색 가능한 사실을 추출.
await service.memorize(resource_url="examples/resources/docs/doc1.txt", modality="document")
await service.memorize(resource_url="examples/resources/images/image1.png", modality="image")
# Audio is supported for your own .mp3/.wav/.m4a files.
await service.memorize(resource_url="meeting-audio.mp3", modality="audio")
context = await service.retrieve(
queries=[{"role": "user", "content": {"text": "What matters for the next research plan?"}}],
)
4. 도구와 에이전트 학습
실행 트레이스를 도구 메모리로 전환하여, 미래의 에이전트에게 언제 도구를 써야 하고 어떤 실수를 피해야 하는지 알려줍니다.
await service.memorize(resource_url="examples/resources/logs/log1.txt", modality="document")
context = await service.retrieve(
queries=[{"role": "user", "content": {"text": "Which tools worked for config editing?"}}],
)
🗂️ 아키텍처
메모리 파일 시스템은 탐색할 만큼 계층적이면서 직접 검색할 만큼 구조화되어 있습니다:
| 계층 | 주요 역할 | 검색 역할 |
|---|---|---|
| Category(폴더) | 주제 수준 요약을 유지 | 폭넓은 질의를 위해 간결한 컨텍스트를 조립 |
| Item(파일) | 타입 지정 원자 메모리를 저장 | 정확한 사실, 사건, 선호, 스킬, 도구 패턴을 로드 |
| Resource(소스) | 소스 산출물과 캡션을 보존 | 아이템/카테고리 요약으로 부족할 때 원본 컨텍스트를 회수 |
MemoryService, 워크플로 파이프라인, 스토리지 백엔드, LLM 라우팅의 런타임 관점은 docs/architecture.md를 참고하세요.
🚀 빠른 시작
옵션 1: 클라우드 버전
👉 memu.so — 관리형 수집, 구조화 메모리, 검색을 제공하는 호스팅 API
엔터프라이즈 배포: info@nevamind.ai
Cloud API (v3)
| Base URL | https://api.memu.so |
|---|---|
| Auth | Authorization: Bearer <token> |
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/v3/memory/memorize |
원본 데이터를 수집하고 구조화 메모리를 구축 |
GET |
/api/v3/memory/memorize/status/{task_id} |
처리 상태 확인 |
POST |
/api/v3/memory/categories |
자동 생성된 카테고리 나열 |
POST |
/api/v3/memory/retrieve |
에이전트 컨텍스트를 위해 메모리 질의 |
옵션 2: 셀프 호스팅
설치
이 저장소의 클론에서:
uv sync
# 또는, 전체 개발 환경 설정:
make install
게시된 패키지를 설치하려면:
pip install memu-py
요구 사항: Python 3.13+. 기본 예제는 OpenAI를 사용하므로
OPENAI_API_KEY를 설정하거나llm_profiles로 다른 제공자를 전달하세요.
인메모리 스모크 스크립트 실행:
export OPENAI_API_KEY=your_key
cd tests
uv run python test_inmemory.py
PostgreSQL + pgvector로 실행:
uv sync --extra postgres
docker run -d --name memu-postgres \
-e POSTGRES_USER=postgres \
-e POSTGRES_PASSWORD=postgres \
-e POSTGRES_DB=memu \
-p 5432:5432 \
pgvector/pgvector:pg16
export OPENAI_API_KEY=your_key
export POSTGRES_DSN=postgresql+psycopg://postgres:postgres@127.0.0.1:5432/memu
cd tests
uv run python test_postgres.py
사용자 지정 LLM 및 임베딩 제공자
from memu import MemUService
service = MemUService(
llm_profiles={
"default": {
"base_url": "https://dashscope.aliyuncs.com/compatible-mode/v1",
"api_key": "your_key",
"chat_model": "qwen3-max",
"client_backend": "sdk"
},
"embedding": {
"base_url": "https://api.voyageai.com/v1",
"api_key": "your_key",
"embed_model": "voyage-3.5-lite"
}
},
)
OpenRouter 연동
from memu import MemoryService
service = MemoryService(
llm_profiles={
"default": {
"provider": "openrouter",
"client_backend": "httpx",
"base_url": "https://openrouter.ai",
"api_key": "your_key",
"chat_model": "anthropic/claude-3.5-sonnet",
"embed_model": "openai/text-embedding-3-small",
},
},
database_config={"metadata_store": {"provider": "inmemory"}},
)
📖 핵심 API
memorize() — 원본 데이터 구조화
result = await service.memorize(
resource_url="path/to/file.json", # 로컬 파일 경로 또는 HTTP URL
modality="conversation", # conversation | document | image | video | audio
user={"user_id": "123"}, # 선택: 사용자 또는 에이전트로 범위 한정
)
# 처리 완료 후 반환:
# { "resource": {...}, "items": [...], "categories": [...], "relations": [...] }
- 원본 입력을 타입 지정 메모리 아이템으로 변환
- 수동 태깅 없이 아이템을 분류하고 임베딩
- 소스 리소스와 아이템–카테고리 관계를 보존
retrieve() — 에이전트 컨텍스트 로드
# 검색 전략은 retrieve_config로 서비스에 한 번만 설정합니다:
# MemoryService(retrieve_config={"method": "rag"}) # 벡터 우선 회수
# MemoryService(retrieve_config={"method": "llm"}) # LLM 순위 회수
result = await service.retrieve(
queries=[{"role": "user", "content": {"text": "What are their preferences?"}}],
where={"user_id": "123"}, # 범위 필터
)
# 반환:
# {
# "needs_retrieval": true,
# "original_query": "...",
# "rewritten_query": "...",
# "next_step_query": "...",
# "categories": [...],
# "items": [...],
# "resources": [...]
# }
retrieve_config.method |
동작 | 비용 | 적합한 용도 |
|---|---|---|---|
rag |
벡터 우선의 카테고리/아이템/리소스 회수. 선택적 LLM 라우팅과 충분성 검사가 기본 활성화 | route_intention과 sufficiency_check를 비활성화하지 않는 한, 임베딩에 더해 LLM 호출 |
추론을 제어 가능한 빠른 범위 회수 |
llm |
LLM이 순위를 매기는 카테고리/아이템/리소스 회수 | 각 계층에서 LLM 순위 매김 | 더 깊은 의미적 순위 매김 |
💡 예시 워크플로
항상 학습하는 어시스턴트
export OPENAI_API_KEY=your_key
uv run python examples/example_1_conversation_memory.py
선호를 자동으로 추출하고, 관계 모델을 구축하며, 이후 대화에서 관련 컨텍스트를 떠올립니다.
자기 개선하는 에이전트
uv run python examples/example_2_skill_extraction.py
에이전트의 행동을 모니터링하고, 성공과 실패의 패턴을 식별하며, 경험으로부터 스킬 가이드를 자동 생성합니다.
멀티모달 컨텍스트 빌더
uv run python examples/example_3_multimodal_memory.py
텍스트, 이미지, 문서를 자동으로 상호 참조하여 통합된 메모리 계층으로 묶습니다.
📊 성능
memU는 Locomo 벤치마크의 모든 추론 작업에서 평균 92.09% 정확도를 달성합니다.
자세한 결과 보기: memU-experiment
🧩 에코시스템
| 저장소 | 설명 |
|---|---|
| memU | 핵심 메모리 파일 시스템 — 수집, 추출, 검색 |
| memU-server | 실시간 동기화와 webhook 트리거를 갖춘 백엔드 |
| memU-ui | 메모리를 탐색하고 모니터링하는 비주얼 대시보드 |
빠른 링크:
🤝 파트너
🤝 기여하기
# 포크하고 클론
git clone https://github.com/YOUR_USERNAME/memU.git
cd memU
# 개발 의존성 설치
make install
# 제출 전 품질 검사 실행
make check
자세한 가이드라인은 CONTRIBUTING.md를 참고하세요.
필수 조건: Python 3.13+, uv, Git
📄 라이선스
🌍 커뮤니티
- GitHub Issues: 버그 신고 및 기능 요청
- Discord: 커뮤니티 참여
- X (Twitter): @memU_ai 팔로우
- 연락처: info@nevamind.ai
⭐ GitHub에서 스타를 눌러 새 릴리스 알림을 받으세요!
