← All posts

Memory Architectures for Long-Running Agents


Long-running agents need memory outside the context window. Design working, episodic, semantic, and procedural memory with retrieval and expiry.

An agent that remembers everything eventually remembers the wrong thing. An agent that remembers nothing repeats work, loses commitments, and asks the same question twice. The useful middle ground is not a larger context window. It is a memory architecture: separate stores for different kinds of state, explicit rules for writing and retrieving them, and an expiry policy that lets old information stop steering new work.

The practical takeaway is this: keep authoritative state in the systems that own it, keep the current task small and explicit, and retrieve only the durable facts that are relevant to the next decision. Memory is a harness concern, not a feature to bolt onto a prompt.

The context window is a cache, not a database

The model sees only the context it is given for this turn. That context may be truncated, summarized, reordered, or lost when a worker restarts. Treating it as a durable record produces familiar failures: an agent sends a message it already sent, reopens a resolved ticket, or carries an old user preference into a new request.

This distinction matters because context and memory answer different questions:

Layer Question it answers Typical lifetime
Working context What must the model consider right now? One turn or task
Operational state What is currently in progress? Until completion or reconciliation
Episodic memory What happened in a prior run? Days to months
Semantic memory What durable fact do we know? Until changed or expired
Procedural memory How should this workflow be performed? Versioned and reviewed

Putting all five layers into every prompt is context stuffing. It raises token cost and gives stale details equal weight with the current instruction. The context-engineering discipline is selection: assemble the smallest context that permits the next correct action.

Start with authoritative state

Not every fact belongs in agent memory. A customer’s current subscription belongs in the billing system. The state of a deployment belongs in the deployment service. The open status of a support ticket belongs in the ticketing system.

When a decision depends on changing external state, query the owner rather than trusting a remembered copy. This is especially important after a timeout or restart. The idempotency ledger can record the agent’s intent and the external reference, but it does not replace the billing API’s answer about whether a charge exists.

That gives a useful ordering of trust:

authoritative tool response
    > durable operation ledger
        > reviewed memory record
            > model summary in the current context

The lower layers are useful for speed and continuity. They are not permission to skip a source-of-truth check when the consequence is real.

Working memory: make the current job recoverable

Working memory should contain the task contract and no more: objective, constraints, current plan, evidence gathered, and the next safe action. It must be serializable outside the model so another worker can resume it.

{
  "run_id": "run_482",
  "objective": "Publish the approved release notes",
  "constraints": ["Do not change pricing copy", "Require preview verification"],
  "completed": ["draft_validated", "preview_verified"],
  "next_action": "request_publish_approval",
  "source_refs": ["doc:release-notes:v17", "preview:pr-614"]
}

This record is not a transcript. It is a checkpoint. A fresh agent should be able to read it, inspect the referenced systems, and continue without reconstructing the entire conversation. If the record cannot name the next action or the evidence behind it, it is too vague to be useful.

For side-effecting work, pair the checkpoint with a durable operation key. A restart should resume publish:release-notes:v17, not invent a new intent because the earlier conversation is absent.

Episodic memory: retain outcomes, not narration

Episodic memory is a compact record of prior runs: what task was attempted, what happened, which tool boundaries failed, and what recovered the run. It is where an agent can learn that a particular service returns an ambiguous timeout or that a user rejected a specific draft.

Good episode records are structured and attributable:

{
  "event": "deploy_preview_failed",
  "scope": "project:docs-site",
  "observed_at": "2026-08-31T09:42:00Z",
  "evidence": "run_482/tool/deploy/attempt_1",
  "outcome": "retry with unchanged artifact succeeded",
  "confidence": "high",
  "expires_at": "2026-09-30T00:00:00Z"
}

The evidence field is doing essential work. A memory without provenance is a model-generated assertion waiting to become policy. Link it to a run, tool result, human decision, or document revision. The observability record should contain enough structured trace data to investigate a recalled episode rather than accepting it on faith.

Avoid storing chain-of-thought, raw private tool payloads, or every conversational turn. Those are high-volume, hard to review, and often unsuitable to reuse. Store the decision-relevant outcome and a pointer to the source under the retention policy that applies to the data.

Semantic memory: facts need scope, confidence, and an expiry date

Semantic memory captures durable facts: a user prefers concise release notes, a repository uses a particular deployment command, or a service requires a region parameter. The danger is that “durable” starts to mean “permanent.” Facts change.

Each stored fact needs at least five fields:

Field Example Why it matters
Subject and scope repo:docs-site Prevents a fact from leaking into another project
Claim deploys through Pages Gives retrieval a concise target
Source config commit abc123 Allows verification
Confidence high Distinguishes a confirmed fact from an inference
Freshness rule recheck after 30 days Prevents stale recall from becoming truth

Retrieval should filter before ranking. First constrain by tenant, project, and permission scope. Then constrain by memory type and freshness. Only then rank candidates for relevance to the current decision. Similar wording is not enough: a remembered instruction for staging is a poor match for a production change, even if the embedding score is excellent.

When a high-impact decision uses a recalled fact, verify it. A fact can shape a search query or a draft safely; it should not silently authorize a payment, deletion, or production deploy. This is the same principle behind matching verifier strength to consequence.

Procedural memory: version workflows like code

Procedural memory is the set of approved ways of doing work: escalation rules, checklists, tool sequences, and response templates. It should not be an accumulation of “tips” extracted from past chats. A procedure changes agent behavior repeatedly, so it needs ownership, versioning, and review.

For example, a deploy procedure might be represented as:

procedure: deploy-static-site
version: 3
preconditions:
  - build_passed
  - preview_verified
steps:
  - deploy_artifact
  - verify_homepage_200
  - verify_changed_route_200
escalate_if:
  - production_response_not_200
  - artifact_digest_differs_from_preview

This is preferable to a sentence in a memory store saying, “Last time, deploy after the build.” The structured version exposes preconditions and failure paths. It can be tested in an eval, reviewed in a change, and rolled back if it causes a regression. Treat it like the prompt versioning layer: an editable operational artifact, not folklore.

Retrieval is a decision, not a reflex

The common failure mode in long-running agents is automatic retrieval: every message triggers a broad semantic search, and the top few snippets enter the prompt. This produces plausible but irrelevant context, increases cost, and makes the agent vulnerable to stale or poisoned entries.

Use a retrieval gate instead:

  1. Classify the next decision: planning, factual lookup, side effect, or recovery.
  2. Specify the missing information and the allowed memory scopes.
  3. Retrieve a small set of candidates with source and timestamp metadata.
  4. Verify externally if the decision is high impact or the record is stale.
  5. Record whether the memory was useful, contradicted, or superseded.

That last step closes the loop. If a recalled preference is repeatedly contradicted by current user instructions, mark it superseded rather than allowing it to keep resurfacing. If a tool workaround stops working, expire the episode and open a failure record. Memory quality improves when writes are governed as carefully as reads.

A practical write policy

Before writing a memory, ask four questions:

  • Is this information useful beyond the current task?
  • Does it have a source the harness may retain and later inspect?
  • Can it be scoped to a person, project, or workflow without leaking elsewhere?
  • What event should update, invalidate, or delete it?

If the answer to the first question is no, keep it in the task checkpoint. If the answer to the second is no, label it as an unverified hypothesis or do not save it. If the scope is unclear, do not store it globally. If there is no expiry rule, create one; absence of an expiry is a policy decision, not a neutral default.

Also separate write authority from model fluency. An agent may propose a memory after a run, but the harness should enforce schema, provenance, sensitivity classification, and deduplication. For user preferences and operational rules, a human confirmation or an observed repeated pattern may be the right threshold. The model’s confidence is not evidence.

Test memory as part of the harness

Memory failures are testable. Add cases that make stale, conflicting, and out-of-scope records available, then assert that the agent retrieves the correct fact or asks for verification. Include recovery tests where the context window is empty but the checkpoint and operation ledger remain.

Useful checks include:

  • A stale deployment instruction must trigger an authoritative lookup.
  • A preference for one user must not appear in another user’s context.
  • A superseded fact must rank below its replacement.
  • A restart must preserve the same idempotency key for a pending operation.
  • A procedural update must pass its workflow eval before becoming active.

These are harness regression tests, not vague hopes that “the memory system seems smart.” The agent evals should include them whenever memory changes the agent’s tool choice or permission boundary.

Takeaway

Long-running agents need more than long context. Give them a small recoverable working state, an evidence-backed history of outcomes, scoped facts with freshness rules, and versioned procedures. Retrieve memory only when it resolves a defined uncertainty, and query the owner when the world may have changed. The result is not an agent that remembers everything. It is one that can reliably remember what matters — and know when not to trust it.