Intuition What this page is
On the parent note you met the three memory layers (working, episodic, semantic), the four operations (write/read/update/forget), and the retrieval-as-ranking idea. Here we stop explaining and start doing the arithmetic — one worked example for every "corner case" a memory system can hit. If your production agent ever behaves strangely, it is almost certainly sitting in one of the cells below.
Before any formula appears, one reminder of the two numbers everything depends on.
Definition Token, and cosine similarity — the two rulers we measure with
A token is a chunk of text the language model counts (roughly ¾ of an English word). Every memory cost is measured in tokens because that is what the model's context window is made of.
Cosine similarity between two vectors a and b is
cos ( a , b ) = ∥ a ∥ ∥ b ∥ a ⋅ b .
Read it as "how aligned are these two arrows?" — 1 = identical direction, 0 = perpendicular (unrelated), − 1 = opposite. The dot product a ⋅ b = ∑ i a i b i multiplies matching coordinates and adds them; dividing by the two lengths ∥ a ∥ = ∑ i a i 2 throws away "how long" and keeps only "which way". We use cosine and not raw distance because in a vector database the direction of an embedding carries the meaning, not its magnitude.
Every question a memory system throws at you falls into one of these cells. The worked examples below are labelled with the cell they cover.
#
Cell (case class)
What breaks / what to watch
Example
A
Fits in window (working memory, normal)
budget arithmetic, positive slack
Ex 1
B
Overflow (working memory, degenerate)
slack goes negative — must evict
Ex 2
C
Boundary (slack = exactly 0)
zero-slack: keep or drop the last turn?
Ex 3
D
High similarity retrieval (cosine near 1)
correct recall of a past episode
Ex 4
E
Orthogonal / zero similarity
unrelated query, cosine = 0, must NOT recall
Ex 5
F
Redundancy limit (cosine > 0.95)
near-duplicate → merge/delete
Ex 6
G
Forgetting: recency vs importance
two policies disagree on same episode
Ex 7
H
Word problem (support agent over days)
end-to-end episodic pickup
Ex 8
I
Exam twist (units / limiting value)
tokens-per-turn → how many turns survive; T window → ∞
Ex 9
We use one formula from the parent for all three:
slack = W ctx − P sys − B out − H hist
where W ctx is the context-window size, P sys the system prompt, B out the reserved output buffer, and H hist the history we want to carry. Slack is what is left for the new user turn. Its sign is the whole story.
Worked example Ex 1 — Cell A: everything fits (positive slack)
Model window W ctx = 8000 . System prompt P sys = 1000 , output buffer B out = 500 , history H hist = 4200 . A new user turn is 600 tokens. Does it fit?
Forecast: guess — plenty of room, or squeezed?
Compute slack = 8000 − 1000 − 500 − 4200 = 2300 .
Why this step? Slack is the free space the new turn must live in.
Compare to the turn size: 2300 ≥ 600 ? Yes.
Why this step? The turn fits iff it is no bigger than the slack.
Leftover after inserting the turn: 2300 − 600 = 1700 .
Why this step? Positive leftover means we can still add tool outputs.
Verify: total used = 1000 + 500 + 4200 + 600 = 6300 ≤ 8000 . ✓ Green zone in the figure.
Worked example Ex 2 — Cell B: overflow (negative slack)
Same model, but a long transcript: P sys = 1000 , B out = 500 , H hist = 7000 , new turn 600 .
Forecast: will the raw slack be positive or negative?
Slack = 8000 − 1000 − 500 − 7000 = − 500 .
Why this step? A negative slack means the history alone already overflows the window.
We are 500 + 600 = 1100 tokens over once the new turn arrives.
Why this step? The turn cannot even start; we must evict before writing.
Evict oldest exchanges until slack ≥ 600 . Need to free 1100 tokens: drop history down from 7000 to 7000 − 1100 = 5900 .
Why this step? Sliding-window eviction removes the least recent turns first (they are least likely relevant — see the forgetting rule).
Verify: new slack = 8000 − 1000 − 500 − 5900 = 600 , exactly enough for the 600 -token turn. Total = 8000 ≤ 8000 . ✓ This is the red zone in the figure.
Worked example Ex 3 — Cell C: the boundary (slack exactly 0)
W ctx = 8000 , P sys = 1000 , B out = 500 , H hist = 6500 . New turn = 0 tokens (a "continue" ping with no new text).
Forecast: slack is zero — do we still have a working memory?
Slack = 8000 − 1000 − 500 − 6500 = 0 .
Why this step? This is the exact edge: the parent note's 6500 -token example lands here.
A 0 -token turn needs 0 ≤ 0 slack → it fits (degenerate but valid).
Why this step? Zero is the limiting input; the inequality is non-strict (≤ ), so equality passes.
Any turn > 0 tokens would fail — the system is full , not broken.
Why this step? Boundary behaviour: at slack = 0 you are one token away from Cell B.
Verify: used = 1000 + 500 + 6500 + 0 = 8000 = W ctx . Exactly full, no overflow. ✓
For episodic retrieval we embed the query and each stored episode, then rank by cosine. We use tiny 3-dimensional vectors so the arithmetic is visible.
Worked example Ex 4 — Cell D: strong match (cosine near 1)
Query embedding q = ( 3 , 4 , 0 ) . Stored "refund episode" e = ( 6 , 8 , 0 ) . Should the agent recall it?
Forecast: the vectors point the same way but e is twice as long — does cosine care?
Dot product: q ⋅ e = 3 ⋅ 6 + 4 ⋅ 8 + 0 = 18 + 32 = 50 .
Why this step? The numerator measures raw alignment.
Lengths: ∥ q ∥ = 9 + 16 = 5 , ∥ e ∥ = 36 + 64 = 10 .
Why this step? Dividing by lengths strips out "twice as long" so only direction survives.
cos = 5 ⋅ 10 50 = 50 50 = 1.0 .
Why this step? Cosine = 1 ⇒ identical direction ⇒ same topic. Recall it.
Verify: e = 2 q , so they are literally the same arrow scaled. Cosine of a vector with its own multiple is 1 . ✓
Worked example Ex 5 — Cell E: orthogonal / no match (cosine = 0)
Query q = ( 1 , 0 , 0 ) ("weather today?"). Stored episode e = ( 0 , 5 , 0 ) ("billing refund").
Forecast: unrelated topics — what cosine do you expect?
Dot product = 1 ⋅ 0 + 0 ⋅ 5 + 0 = 0 .
Why this step? Zero numerator is the fingerprint of unrelatedness.
cos = 1 ⋅ 5 0 = 0 .
Why this step? Perpendicular arrows share no direction ⇒ do NOT load this episode into working memory.
Degenerate guard: if a stored vector were the zero vector ( 0 , 0 , 0 ) , ∥ e ∥ = 0 and cosine is undefined (division by zero) — such empty embeddings must be filtered before ranking.
Why this step? Zero-length input is the true degenerate case; the code must skip it, never divide by it.
Verify: perpendicular vectors have dot product 0 by definition. ✓
Worked example Ex 6 — Cell F: redundancy threshold (cosine > 0.95)
New episode v new = ( 1 , 1 , 0 ) , existing v old = ( 1 , 0.9 , 0 ) . Rule: cosine > 0.95 ⇒ merge/delete the old one.
Forecast: almost-parallel — will it cross the 0.95 line?
Dot = 1 ⋅ 1 + 1 ⋅ 0.9 + 0 = 1.9 .
Why this step? Numerator for near-duplicate check.
Lengths: ∥ v new ∥ = 2 ≈ 1.4142 , ∥ v old ∥ = 1 + 0.81 = 1.81 ≈ 1.3454 .
cos = 1.4142 ⋅ 1.3454 1.9 ≈ 1.9026 1.9 ≈ 0.9986 .
Why this step? 0.9986 > 0.95 , so these are effectively the same fact → keep one, delete the other, saving retrieval noise.
Verify: 0.9986 > 0.95 ⇒ triggers the merge rule. ✓ This is why the parent's semantic-redundancy pruning fires.
Worked example Ex 7 — Cell G: recency vs importance disagree
Two policies from the parent, applied to one episode e : it is old (age 45 days, window T window = 30 ) but frequently used and user-starred .
Importance = w 1 ⋅ AccessCount + w 2 ⋅ Recency + w 3 ⋅ Feedback , with w 1 = 0.5 , w 2 = 0.2 , w 3 = 0.3 , and AccessCount = 20 (normalised to 1.0 as the top item), Recency = 0.1 (old), Feedback = 1.0 (starred).
Forecast: recency says delete; will importance override?
Recency policy: Keep = 1 iff t now − t e < T window . Here 45 < 30 is false ⇒ Keep = 0 (delete) .
Why this step? The sliding window sees only age; it does not know the episode is valuable.
Importance policy: score = 0.5 ⋅ 1.0 + 0.2 ⋅ 0.1 + 0.3 ⋅ 1.0 = 0.5 + 0.02 + 0.3 = 0.82 .
Why this step? A weighted vote lets access and feedback outweigh staleness.
With a keep-threshold of 0.5 , 0.82 ≥ 0.5 ⇒ Keep . The two policies disagree; a production system runs importance after recency so valuable-but-old items survive.
Why this step? This is the classic corner case where a naive recency prune throws away your best memory.
Verify: 0.5 + 0.02 + 0.3 = 0.82 , and 0.82 ≥ 0.5 . Recency alone would have deleted it. ✓
Worked example Ex 8 — Cell H: support agent picks up across days (see
Vector Databases )
Day 1 the user reports a double charge; an episode is stored with embedding e 1 = ( 0 , 3 , 4 ) . Day 5 the user asks "is my refund processed?" with query embedding q = ( 0 , 6 , 8 ) . Also stored: a chit-chat episode e 2 = ( 5 , 0 , 0 ) . Which episode is retrieved?
Forecast: guess which of e 1 , e 2 wins the ranking.
Cosine to e 1 : dot = 0 ⋅ 0 + 6 ⋅ 3 + 8 ⋅ 4 = 18 + 32 = 50 ; lengths ∥ q ∥ = 36 + 64 = 10 , ∥ e 1 ∥ = 9 + 16 = 5 ; cos = 50/50 = 1.0 .
Why this step? Refund query is the same direction as the billing episode.
Cosine to e 2 : dot = 0 ⋅ 5 + 6 ⋅ 0 + 8 ⋅ 0 = 0 ⇒ cos = 0 .
Why this step? Chit-chat is orthogonal; it must not surface.
Rank: 1.0 > 0 ⇒ load e 1 into working memory. Agent responds without asking the user to re-explain.
Why this step? This is the whole payoff of episodic memory — continuity across sessions.
Verify: cos ( q , e 1 ) = 1.0 , cos ( q , e 2 ) = 0.0 , so e 1 ranks first. ✓
Worked example Ex 9 — Cell I: how many turns survive, and the
T window → ∞ limit
Part (a) — units. Working memory has 6500 tokens of slack. Each conversation turn averages 325 tokens. How many recent turns fit?
Forecast: integer answer — round up or down?
325 tokens/turn 6500 tokens = 20 turns .
Why this step? Tokens cancel tokens, leaving pure turns — a units check.
Since a partial turn is unusable, we floor : ⌊ 20 ⌋ = 20 turns exactly.
Why this step? You cannot keep half a message; capacity is a whole-turn count.
Part (b) — limiting behaviour. In the recency policy Keep = 1 iff age < T window . What happens as T window → ∞ ?
As T window → ∞ , the condition age < T window is true for every episode ⇒ nothing is ever forgotten ⇒ memory grows unboundedly and cost explodes.
Why this step? This is exactly the failure the parent warned about — the reason importance/redundancy pruning exists.
Verify: (a) 325 × 20 = 6500 tokens, exact fit. (b) limit of the keep-set is "all episodes". ✓
Mnemonic The sign of slack tells you everything
Positive slack → write freely (Cell A). Zero slack → full, ping-only (Cell C). Negative slack → evict first (Cell B). Same three signs you tracked for quadrants in trig — here they gate memory, not angles.
Recall Self-check
A history uses 7100 tokens in an 8000 window with 1000 system + 500 buffer. Fits? ::: Slack = 8000 − 1000 − 500 − 7100 = − 600 < 0 → overflow, must evict 600+ tokens.
Two embeddings have dot product 0. Recall or skip? ::: Cosine = 0 , orthogonal → skip, unrelated.
Cosine of new vs old episode is 0.97. Action? ::: > 0.95 → merge/delete the duplicate.
Recency deletes an old but starred, heavily-used episode. Right call? ::: No — run importance policy; its weighted score keeps it.
Connections: Memory systems for agents · Vector Databases · LM Context Window Management · Knowledge Graphs · Prompt Engineering · Agent Planning and Reasoning · Multi-Agent Systems