Workspace Memory ์›Œํฌ์ŠคํŽ˜์ด์Šค ๋ฉ”๋ชจ๋ฆฌ

Overview ๊ฐœ์š”

Workspace Memory automatically saves important workspace knowledge โ€” bug postmortems, architectural decisions, and compact notes โ€” and injects relevant memories into future agent prompts so the agent avoids rediscovering prior context. Each workspace has an isolated memory store that persists across sessions and survives context compaction.

์›Œํฌ์ŠคํŽ˜์ด์Šค ๋ฉ”๋ชจ๋ฆฌ๋Š” ์ค‘์š”ํ•œ ์›Œํฌ์ŠคํŽ˜์ด์Šค ์ง€์‹ โ€” ๋ฒ„๊ทธ ํฌ์ŠคํŠธ๋ชจํ…œ, ์•„ํ‚คํ…์ฒ˜ ๊ฒฐ์ •, ๊ฐ„๊ฒฐํ•œ ๋ฉ”๋ชจ โ€” ์„ ์ž๋™์œผ๋กœ ์ €์žฅํ•˜๊ณ , ์ด์ „ ๋ฌธ๋งฅ์„ ์žฌ๋ฐœ๊ฒฌํ•˜์ง€ ์•Š๋„๋ก ๊ด€๋ จ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ–ฅํ›„ ์—์ด์ „ํŠธ ํ”„๋กฌํ”„ํŠธ์— ์ฃผ์ž…ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ ์›Œํฌ์ŠคํŽ˜์ด์Šค์—๋Š” ์„ธ์…˜ ๊ฐ„์— ์ง€์†๋˜๊ณ  ์ปจํ…์ŠคํŠธ ์ปดํŒฉ์…˜์—์„œ๋„ ์œ ์ง€๋˜๋Š” ๊ฒฉ๋ฆฌ๋œ ๋ฉ”๋ชจ๋ฆฌ ์ €์žฅ์†Œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

Key Insight ํ•ต์‹ฌ ์ธ์‚ฌ์ดํŠธ

Memories are not instructions โ€” they are provided as read-only context wrapped in <workspace_memories> tags so the agent can reference past findings without re-executing them.

๋ฉ”๋ชจ๋ฆฌ๋Š” ์ง€์‹œ์–ด๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค โ€” <workspace_memories> ํƒœ๊ทธ๋กœ ๋ž˜ํ•‘๋œ ์ฝ๊ธฐ ์ „์šฉ ์ปจํ…์ŠคํŠธ๋กœ ์ œ๊ณต๋˜์–ด ์—์ด์ „ํŠธ๊ฐ€ ๊ณผ๊ฑฐ ๋ฐœ๊ฒฌ์„ ์žฌ์‹คํ–‰ํ•˜์ง€ ์•Š๊ณ  ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Architecture ์•„ํ‚คํ…์ฒ˜

Storage is per-workspace. The memory directory lives under the agent's data root, keyed by an encoded version of the working directory path.

์ €์žฅ์†Œ๋Š” ์›Œํฌ์ŠคํŽ˜์ด์Šค๋ณ„์ž…๋‹ˆ๋‹ค. ๋ฉ”๋ชจ๋ฆฌ ๋””๋ ‰ํ† ๋ฆฌ๋Š” ์—์ด์ „ํŠธ ๋ฐ์ดํ„ฐ ๋ฃจํŠธ ์•„๋ž˜์— ์ž‘์—… ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ์˜ ์ธ์ฝ”๋”ฉ๋œ ๋ฒ„์ „์„ ํ‚ค๋กœ ํ•˜์—ฌ ์œ„์น˜ํ•ฉ๋‹ˆ๋‹ค.

# Storage path ${getAgentDir()}/memory/${encodeCwd(cwd)}/ # encodeCwd implementation "--" + cwd.replace(/^[\\/]/, "").replace(/[\\/:]/g, "-") + "--"

Files ํŒŒ์ผ

FileํŒŒ์ผ Description์„ค๋ช…
index.json Lightweight index with id, file, template, summary, tags, createdAt, lastRecalledAt, recallCount, and score for each memory. Used for ranking without loading full content. ๊ฐ ๋ฉ”๋ชจ๋ฆฌ์˜ id, file, template, summary, tags, createdAt, lastRecalledAt, recallCount, score๊ฐ€ ํฌํ•จ๋œ ๊ฒฝ๋Ÿ‰ ์ธ๋ฑ์Šค. ์ „์ฒด ์ฝ˜ํ…์ธ  ๋กœ๋“œ ์—†์ด ๋žญํ‚น์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
mem-${timestamp}-${random}.json Individual memory file containing the full structured content, template type, and metadata. ์ „์ฒด ๊ตฌ์กฐํ™”๋œ ์ฝ˜ํ…์ธ , ํ…œํ”Œ๋ฆฟ ์œ ํ˜• ๋ฐ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๊ฐ€ ํฌํ•จ๋œ ๊ฐœ๋ณ„ ๋ฉ”๋ชจ๋ฆฌ ํŒŒ์ผ.

Recall Pipeline ๋ฆฌ์ฝœ ํŒŒ์ดํ”„๋ผ์ธ

The recall pipeline is designed for zero-token overhead during ranking:

๋ฆฌ์ฝœ ํŒŒ์ดํ”„๋ผ์ธ์€ ๋žญํ‚น ์ค‘ ํ† ํฐ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ์—†๋„๋ก ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค:

  1. Load lightweight index (summaries + tags only, no full content) ๊ฒฝ๋Ÿ‰ ์ธ๋ฑ์Šค ๋กœ๋“œ (์š”์•ฝ + ํƒœ๊ทธ๋งŒ, ์ „์ฒด ์ฝ˜ํ…์ธ  ์—†์Œ)
  2. Local keyword filter extracted from recent conversation text (zero token cost) ์ตœ๊ทผ ๋Œ€ํ™” ํ…์ŠคํŠธ์—์„œ ์ถ”์ถœํ•œ ๋กœ์ปฌ ํ‚ค์›Œ๋“œ ํ•„ํ„ฐ (ํ† ํฐ ๋น„์šฉ ์—†์Œ)
  3. Score-based ranking (local computation) ์ ์ˆ˜ ๊ธฐ๋ฐ˜ ๋žญํ‚น (๋กœ์ปฌ ๊ณ„์‚ฐ)
  4. Load full content for top-K memories only ์ƒ์œ„ K๊ฐœ ๋ฉ”๋ชจ๋ฆฌ์— ๋Œ€ํ•ด์„œ๋งŒ ์ „์ฒด ์ฝ˜ํ…์ธ  ๋กœ๋“œ

Memory Templates ๋ฉ”๋ชจ๋ฆฌ ํ…œํ”Œ๋ฆฟ

Three templates define the structure of saved memories. The template is auto-detected from the content or can be specified manually.

์„ธ ๊ฐ€์ง€ ํ…œํ”Œ๋ฆฟ์ด ์ €์žฅ๋œ ๋ฉ”๋ชจ๋ฆฌ์˜ ๊ตฌ์กฐ๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ํ…œํ”Œ๋ฆฟ์€ ์ฝ˜ํ…์ธ ์—์„œ ์ž๋™ ๊ฐ์ง€๋˜๊ฑฐ๋‚˜ ์ˆ˜๋™์œผ๋กœ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Templateํ…œํ”Œ๋ฆฟ Fieldsํ•„๋“œ Use When์‚ฌ์šฉ ์‹œ๊ธฐ
post-mortem problem, rootCause, fix, prevention After resolving a bug ๋ฒ„๊ทธ ํ•ด๊ฒฐ ํ›„
decision-record context, decision, rationale, alternativesConsidered When making an architectural choice ์•„ํ‚คํ…์ฒ˜ ๊ฒฐ์ •์„ ๋‚ด๋ฆด ๋•Œ
compact-note summary, keyPoints[] Quick knowledge capture ๋น ๋ฅธ ์ง€์‹ ์บก์ฒ˜

Saving Memories ๋ฉ”๋ชจ๋ฆฌ ์ €์žฅ

Memories are saved via the memory_save tool or the /memory save slash command. The agent also auto-detects important moments (bug fixes, decisions, discoveries) and suggests saving them.

๋ฉ”๋ชจ๋ฆฌ๋Š” memory_save ๋„๊ตฌ ๋˜๋Š” /memory save ์Šฌ๋ž˜์‹œ ๋ช…๋ น์„ ํ†ตํ•ด ์ €์žฅ๋ฉ๋‹ˆ๋‹ค. ์—์ด์ „ํŠธ๋Š” ์ค‘์š”ํ•œ ์ˆœ๊ฐ„(๋ฒ„๊ทธ ์ˆ˜์ •, ๊ฒฐ์ •, ๋ฐœ๊ฒฌ)์„ ์ž๋™์œผ๋กœ ๊ฐ์ง€ํ•˜์—ฌ ์ €์žฅ์„ ์ œ์•ˆํ•˜๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.

Tool Parameters ๋„๊ตฌ ํŒŒ๋ผ๋ฏธํ„ฐ

ParameterํŒŒ๋ผ๋ฏธํ„ฐ Typeํƒ€์ž… Description์„ค๋ช…
content string (required)(ํ•„์ˆ˜) Structured memory content ๊ตฌ์กฐํ™”๋œ ๋ฉ”๋ชจ๋ฆฌ ์ฝ˜ํ…์ธ 
template string (optional)(์„ ํƒ) Auto-detected if omitted ์ƒ๋žต ์‹œ ์ž๋™ ๊ฐ์ง€
tags string[] (optional)(์„ ํƒ) Tags for relevance matching ๊ด€๋ จ์„ฑ ๋งค์นญ์„ ์œ„ํ•œ ํƒœ๊ทธ

Recalling Memories ๋ฉ”๋ชจ๋ฆฌ ๋ฆฌ์ฝœ

Before each agent turn, the recall pipeline extracts keywords from recent conversation text, ranks memories by relevance, and injects the top results into the system prompt.

๊ฐ ์—์ด์ „ํŠธ ํ„ด ์ „์— ๋ฆฌ์ฝœ ํŒŒ์ดํ”„๋ผ์ธ์ด ์ตœ๊ทผ ๋Œ€ํ™” ํ…์ŠคํŠธ์—์„œ ํ‚ค์›Œ๋“œ๋ฅผ ์ถ”์ถœํ•˜๊ณ , ๊ด€๋ จ์„ฑ๋ณ„๋กœ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋žญํ‚นํ•˜์—ฌ ์ƒ์œ„ ๊ฒฐ๊ณผ๋ฅผ ์‹œ์Šคํ…œ ํ”„๋กฌํ”„ํŠธ์— ์ฃผ์ž…ํ•ฉ๋‹ˆ๋‹ค.

Limits ์ œํ•œ

ParameterํŒŒ๋ผ๋ฏธํ„ฐ Value๊ฐ’ Description์„ค๋ช…
MAX_MEMORIES 200 Per-workspace limit ์›Œํฌ์ŠคํŽ˜์ด์Šค๋‹น ์ตœ๋Œ€ ๋ฉ”๋ชจ๋ฆฌ ์ˆ˜
RECENCY_HALFLIFE_DAYS 30 Score decay half-life ์ ์ˆ˜ ๊ฐ์‡  ๋ฐ˜๊ฐ๊ธฐ
MAX_RECALL_MEMORIES 5 Injected per prompt ํ”„๋กฌํ”„ํŠธ๋‹น ์ฃผ์ž… ์ˆ˜
MAX_RECALL_CONTEXT_CHARS 8000 Total recalled text budget ์ „์ฒด ๋ฆฌ์ฝœ ํ…์ŠคํŠธ ์˜ˆ์‚ฐ
MAX_RECALL_MEMORY_CHARS 2000 Single memory text limit ๋‹จ์ผ ๋ฉ”๋ชจ๋ฆฌ ํ…์ŠคํŠธ ์ œํ•œ

Scoring Formula ์ ์ˆ˜ ๊ณต์‹

score = recallCount ร— exp(-daysSinceLastRecall / 30)

Relevance Matching ๊ด€๋ จ์„ฑ ๋งค์นญ

Match Type๋งค์นญ ์œ ํ˜• Score์ ์ˆ˜
Exact tag match์ •ํ™•ํ•œ ํƒœ๊ทธ ๋งค์นญ +10
Partial tag match๋ถ€๋ถ„ ํƒœ๊ทธ ๋งค์นญ +5
Summary keyword match์š”์•ฝ ํ‚ค์›Œ๋“œ ๋งค์นญ +3
Learned score boostํ•™์Šต๋œ ์ ์ˆ˜ ๋ถ€์ŠคํŠธ score ร— 0.5

Eviction ์ถ•์ถœ

When the memory count exceeds MAX_MEMORIES (200), the system evicts the lowest-scoring memories. All scores are recalculated, memories are sorted by score ascending (tie-break: createdAt ascending โ€” oldest first), and the overflow is removed.

๋ฉ”๋ชจ๋ฆฌ ์ˆ˜๊ฐ€ MAX_MEMORIES(200)์„ ์ดˆ๊ณผํ•˜๋ฉด ์‹œ์Šคํ…œ์€ ์ ์ˆ˜๊ฐ€ ๊ฐ€์žฅ ๋‚ฎ์€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ถ•์ถœํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ์ ์ˆ˜๊ฐ€ ์žฌ๊ณ„์‚ฐ๋˜๊ณ , ์ ์ˆ˜ ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌ๋˜๋ฉฐ(๋™์  ์‹œ createdAt ์˜ค๋ฆ„์ฐจ์ˆœ โ€” ๊ฐ€์žฅ ์˜ค๋ž˜๋œ ๊ฒƒ ์šฐ์„ ), ์ดˆ๊ณผ๋ถ„์ด ์ œ๊ฑฐ๋ฉ๋‹ˆ๋‹ค.

# Eviction algorithm 1. recalculateAllScores() 2. sort by score ASC, createdAt ASC 3. splice top N over MAX_MEMORIES 4. re-sort remaining by createdAt DESC

Slash Commands ์Šฌ๋ž˜์‹œ ๋ช…๋ น์–ด

Command๋ช…๋ น์–ด Description์„ค๋ช…
/memory list List all memories with id, template, summary, recall count, and score id, ํ…œํ”Œ๋ฆฟ, ์š”์•ฝ, ๋ฆฌ์ฝœ ์ˆ˜, ์ ์ˆ˜์™€ ํ•จ๊ป˜ ๋ชจ๋“  ๋ฉ”๋ชจ๋ฆฌ ๋‚˜์—ด
/memory show <id> Display a specific memory's full content ํŠน์ • ๋ฉ”๋ชจ๋ฆฌ์˜ ์ „์ฒด ๋‚ด์šฉ ํ‘œ์‹œ
/memory save <text> Save a manual note (auto-detects template) ์ˆ˜๋™ ๋ฉ”๋ชจ ์ €์žฅ (ํ…œํ”Œ๋ฆฟ ์ž๋™ ๊ฐ์ง€)
/memory delete <id> Remove a memory by id id๋กœ ๋ฉ”๋ชจ๋ฆฌ ์‚ญ์ œ
/memory search <query> Search memories by keyword ํ‚ค์›Œ๋“œ๋กœ ๋ฉ”๋ชจ๋ฆฌ ๊ฒ€์ƒ‰
/memory stats Show memory statistics (total, by template, total recalls, top recalled) ๋ฉ”๋ชจ๋ฆฌ ํ†ต๊ณ„ ํ‘œ์‹œ (์ด๊ณ„, ํ…œํ”Œ๋ฆฟ๋ณ„, ์ด ๋ฆฌ์ฝœ ์ˆ˜, ์ตœ๋‹ค ๋ฆฌ์ฝœ)

Configuration ๊ตฌ์„ฑ

No environment variables or configuration files are required. Workspace Memory operates automatically with per-workspace isolation โ€” each working directory gets its own independent memory store under the agent's data directory.

ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋‚˜ ๊ตฌ์„ฑ ํŒŒ์ผ์ด ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์›Œํฌ์ŠคํŽ˜์ด์Šค ๋ฉ”๋ชจ๋ฆฌ๋Š” ์ž๋™์œผ๋กœ ์ž‘๋™ํ•˜๋ฉฐ ์›Œํฌ์ŠคํŽ˜์ด์Šค๋ณ„ ๊ฒฉ๋ฆฌ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค โ€” ๊ฐ ์ž‘์—… ๋””๋ ‰ํ† ๋ฆฌ๋Š” ์—์ด์ „ํŠธ ๋ฐ์ดํ„ฐ ๋””๋ ‰ํ† ๋ฆฌ ์•„๋ž˜์— ์ž์ฒด ๋…๋ฆฝ์ ์ธ ๋ฉ”๋ชจ๋ฆฌ ์ €์žฅ์†Œ๋ฅผ ๊ฐ–์Šต๋‹ˆ๋‹ค.

Edge Cases ์—ฃ์ง€ ์ผ€์ด์Šค

  • Large memories: Individual memories are truncated at MAX_RECALL_MEMORY_CHARS (2000 chars). Total recalled context is bounded by MAX_RECALL_CONTEXT_CHARS (8000 chars). Truncated memories include a [Memory truncated to fit prompt budget] marker.

    ํฐ ๋ฉ”๋ชจ๋ฆฌ: ๊ฐœ๋ณ„ ๋ฉ”๋ชจ๋ฆฌ๋Š” MAX_RECALL_MEMORY_CHARS(2000์ž)์—์„œ ์ž˜๋ฆฝ๋‹ˆ๋‹ค. ์ „์ฒด ๋ฆฌ์ฝœ ์ปจํ…์ŠคํŠธ๋Š” MAX_RECALL_CONTEXT_CHARS(8000์ž)๋กœ ์ œํ•œ๋ฉ๋‹ˆ๋‹ค. ์ž˜๋ฆฐ ๋ฉ”๋ชจ๋ฆฌ์—๋Š” [Memory truncated to fit prompt budget] ๋งˆ์ปค๊ฐ€ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.

  • Cross-workspace isolation: Each workspace is isolated by its encoded cwd path. Memories saved in one project are never visible in another.

    ์›Œํฌ์ŠคํŽ˜์ด์Šค ๊ฐ„ ๊ฒฉ๋ฆฌ: ๊ฐ ์›Œํฌ์ŠคํŽ˜์ด์Šค๋Š” ์ธ์ฝ”๋”ฉ๋œ cwd ๊ฒฝ๋กœ๋กœ ๊ฒฉ๋ฆฌ๋ฉ๋‹ˆ๋‹ค. ํ•œ ํ”„๋กœ์ ํŠธ์— ์ €์žฅ๋œ ๋ฉ”๋ชจ๋ฆฌ๋Š” ๋‹ค๋ฅธ ํ”„๋กœ์ ํŠธ์— ํ‘œ์‹œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

  • Compaction survival: Memories persist across context compaction. They are stored on disk as separate JSON files, independent of the conversation context window.

    ์ปดํŒฉ์…˜ ์ƒ์กด: ๋ฉ”๋ชจ๋ฆฌ๋Š” ์ปจํ…์ŠคํŠธ ์ปดํŒฉ์…˜ ์ „๋ฐ˜์— ๊ฑธ์ณ ์ง€์†๋ฉ๋‹ˆ๋‹ค. ๋Œ€ํ™” ์ปจํ…์ŠคํŠธ ์œˆ๋„์šฐ์™€ ๋…๋ฆฝ์ ์œผ๋กœ ๋ณ„๋„์˜ JSON ํŒŒ์ผ๋กœ ๋””์Šคํฌ์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.

  • Orphan cleanup: If a memory file is missing or corrupted, the recall pipeline automatically removes the orphaned index entry.

    ๊ณ ์•„ ์ •๋ฆฌ: ๋ฉ”๋ชจ๋ฆฌ ํŒŒ์ผ์ด ๋ˆ„๋ฝ๋˜๊ฑฐ๋‚˜ ์†์ƒ๋œ ๊ฒฝ์šฐ, ๋ฆฌ์ฝœ ํŒŒ์ดํ”„๋ผ์ธ์ด ์ž๋™์œผ๋กœ ๊ณ ์•„ ์ธ๋ฑ์Šค ํ•ญ๋ชฉ์„ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.

  • Index caching: The index is cached in memory per session. File changes from external processes are not reflected until cache invalidation (session restart).

    ์ธ๋ฑ์Šค ์บ์‹ฑ: ์ธ๋ฑ์Šค๋Š” ์„ธ์…˜๋‹น ๋ฉ”๋ชจ๋ฆฌ์— ์บ์‹œ๋ฉ๋‹ˆ๋‹ค. ์™ธ๋ถ€ ํ”„๋กœ์„ธ์Šค์˜ ํŒŒ์ผ ๋ณ€๊ฒฝ์€ ์บ์‹œ ๋ฌดํšจํ™”(์„ธ์…˜ ์žฌ์‹œ์ž‘)๊นŒ์ง€ ๋ฐ˜์˜๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.