Skip to content
AI360XpertBeta

Memory Systems

Short-term memory is what sits in the context window right now. Long-term memory is facts you saved on purpose and pull back only when the current task needs them.

Short-term memory is the live context window while a durable store holds twelve facts and retrieval pulls only the top match back in
Short-term memory is the live context window while a durable store holds twelve facts and retrieval pulls only the top match back in

Why Does This Exist?

Say you use a coding assistant for weeks. In week one you tell it you test with pytest and you want type hints everywhere. In week eleven you expect type hinted code and pytest fixtures without repeating yourself. That only happens if something from week one survived after its window closed.

A model call is stateless. It reads exactly the tokens in its context window and keeps none of them afterward. Context engineering decides what fits inside that window right now. Memory systems decide what stays true next time, without pasting every old chat into every new prompt.

This page covers that system: what counts as short term, what earns a durable write, and how retrieval pulls facts back. The split inside durable storage lives in episodic and semantic memory. The loop that spends memory on real tasks lives in AI agent architecture.

Think of It Like This

A whiteboard versus a filing cabinet

You work in a room with a whiteboard and a filing cabinet down the hall.

The whiteboard is the context window. Anything written on it sits right in front of you and costs nothing to read. When the meeting ends and someone wipes it for the next team, everything on it is gone.

The cabinet is durable storage. Filing takes a real decision. You do not file every napkin sketch, only the note worth keeping, like the client's test runner. A filed note does nothing for today's meeting until someone walks down the hall, pulls that one folder, and copies it back onto the board.

Where it stops: paper never argues with itself, but stored facts do. You change your mind, two folders disagree, and the cabinet will not settle it for you. And a cabinet never charges rent per page, while every retrieved line costs window space, so pulling the whole drawer each morning would bury the board you meant to help.

How It Actually Works

Model calls forget by design, so an agent needs two kinds of memory. Short-term memory is whatever sits in the window right now. Long-term memory is facts written somewhere durable on purpose, plus the two decisions that make them useful: what earns a write, and what gets retrieved.

Short-term ends when the window closes

Call WW the window: the most tokens one request may hold, input plus output. Call the live contents SS: system instructions, recent turns, and whatever retrieval just added. SS is free because it is already there, and temporary because the next session starts with an empty SS. Nothing is saved by staying in SS.

If the frame itself is fuzzy, start with context windows and the token math in context budgeting.

Long-term needs a write and a retrieve

Call the durable pile MM: one row per saved fact, each with its source. A write moves a fact from SS into MM. A retrieve moves a few rows from MM back into SS for one request. Saved and used are two steps, and skipping the second is how teams end up with a store nobody reads.

The write is a durability judgment. A one off instruction, like renaming one variable today, belongs in SS and dies there. A repeated preference, like pytest over unittest stated twice and confirmed by your edits, earns a row in MM. When in doubt, do not write. Every extra row taxes every future search.

Retrieval is usually similarity search over embeddings. Call the current task qq: the query vector for what you need right now. Call each stored fact mim_i: fact number ii written as a vector. Call sis_i its score against qq: how closely fact ii matches this task. Call kk how many you pull back: usually one or two. You rank by sis_i and copy only the top kk rows into SS. The rest stay filed.

Worked example: three facts ranked, one pulled back

Take three stored facts, each as a two dimensional vector so you can check the math. Real stores use hundreds of dimensions. The arithmetic is the same.

Here q=[3,1]q = [3, 1] stands in for writing a pytest fixture, m1=[3,1]m_1 = [3, 1] is prefers pytest, m2=[2,2]m_2 = [2, 2] is deploys on Fridays, and m3=[0,3]m_3 = [0, 3] is likes demo GIFs.

Score with cosine similarity, which is alignment divided by lengths. The length of a vector [a,b][a, b] is a2+b2\sqrt{a^2 + b^2}, the straight line distance from the origin.

Lengths first: ∥q∥=32+12=10≈3.1623\lVert q \rVert = \sqrt{3^2 + 1^2} = \sqrt{10} \approx 3.1623, and the same for m1m_1. ∥m2∥=22+22=8≈2.8284\lVert m_2 \rVert = \sqrt{2^2 + 2^2} = \sqrt{8} \approx 2.8284. ∥m3∥=02+32=3\lVert m_3 \rVert = \sqrt{0^2 + 3^2} = 3.

Dots next: q⋅m1=3×3+1×1=10q \cdot m_1 = 3 \times 3 + 1 \times 1 = 10. q⋅m2=3×2+1×2=8q \cdot m_2 = 3 \times 2 + 1 \times 2 = 8. q⋅m3=3×0+1×3=3q \cdot m_3 = 3 \times 0 + 1 \times 3 = 3.

Divide: s1=10/(3.1623×3.1623)=10/10=1.0s_1 = 10 / (3.1623 \times 3.1623) = 10 / 10 = 1.0. s2=8/(3.1623×2.8284)=8/8.9443≈0.8944s_2 = 8 / (3.1623 \times 2.8284) = 8 / 8.9443 \approx 0.8944. s3=3/(3.1623×3)=3/9.4868≈0.3162s_3 = 3 / (3.1623 \times 3) = 3 / 9.4868 \approx 0.3162. Ranked, 1.01.0 beats 0.89440.8944 beats 0.31620.3162. With k=1k = 1 you pull back m1m_1 only. The diagram shows these three scores and the one returning arrow.

Now the token reason this matters. Name W=4000W = 4000 for the fixture window. System needs 400400 tokens and today's task needs 800800. Pasting six old sessions at 500500 tokens each costs 6×500=30006 \times 500 = 3000, so the request wants 400+800+3000=4200400 + 800 + 3000 = 4200. Overflow is 4200−4000=2004200 - 4000 = 200. Something must give.

The store holds twelve facts at 1515 tokens each: 12×15=18012 \times 15 = 180 tokens total, which is 180/4000=4.5%180 / 4000 = 4.5\% of the window. Pulling the winner costs 1515. The request becomes 400+800+15=1215400 + 800 + 15 = 1215, leaving 4000−1215=27854000 - 1215 = 2785 spare. Same history, two shapes: one never fits, one barely registers.

That is the trade. Persistence costs judgment at write time and a search at read time, and it buys recall across sessions for a fraction of the window. Skip it for single session tools like a summarizer, where yesterday says nothing about today and the machinery never pays off. It assumes past choices predict future ones. When you switch runners or tastes, old rows lie until a new episode overwrites them, which is why the overwrite rule in episodic and semantic memory is load bearing.

Code

The snippet reruns the ranking and the token fit, so you can check both numbers yourself.

import math

def norm(v: list[float]) -> float:    """Straight-line length from the origin."""    return math.sqrt(sum(x * x for x in v))

def cosine(u: list[float], v: list[float]) -> float:    """Alignment divided by lengths, between -1 and 1."""    return sum(x * y for x, y in zip(u, v)) / (norm(u) * norm(v))

query: list[float] = [3.0, 1.0]memories: list[list[float]] = [[3.0, 1.0], [2.0, 2.0], [0.0, 3.0]]
scores: list[float] = [round(cosine(query, m), 4) for m in memories]print(scores)  # -> [1.0, 0.8944, 0.3162]print(scores.index(max(scores)))  # -> 0
store_total: int = 12 * 15paste_cost: int = 6 * 500request_paste: int = 400 + 800 + paste_costrequest_memory: int = 400 + 800 + 15print(store_total)  # -> 180print(request_paste - 4000)  # -> 200print(request_memory)  # -> 1215

Watch Out For

Filing every turn as a permanent fact

Symptom: the store grows by hundreds of rows a week and retrieval starts returning one off details with the same confidence as real preferences. A query about tests pulls back a renamed variable from March alongside the pytest preference, and the model treats both as instructions.

Fix: write distilled facts, not transcript lines. Require a second confirmation before a write, keep the source episode on every row, and overwrite rivals instead of appending beside them.

Pulling the whole store into every prompt

Symptom: session twelve opens with all forty stored facts pasted in just to be safe. The prompt costs more, answers slower, and the one fact today needed now competes with thirty nine it did not.

Fix: retrieve top kk only, usually one or two, ranked against today's task. Leave the rest filed and unread until some query actually calls for them.

The Quick Version

  • Short-term memory is the live context window. It costs nothing to read and it vanishes when the session ends.
  • Long-term memory is facts saved on purpose in durable storage. Saved facts do nothing until retrieval copies them back into the window.
  • Writes should record repeated preferences, not one off task details. A fact confirmed twice earns storage.
  • Retrieval ranks stored facts against the current task and pulls back the top one or two, leaving the rest filed.
  • Three facts scoring 1.0, 0.8944, and 0.3162 retrieve the 1.0 match, turning a 3000-token paste into a 15-token pull.
  • Twelve 15-token facts cost 180 tokens total, about 4.5 percent of a 4000-token window.