Why your assistant redoes last week's work, and where the memory actually needs to live

You open a new chat, paste roughly the same prompt you used last time, and the assistant repeats something it already handled. It re-drafts a note you already sent, or asks a question you answered a few sessions ago.

Why rewording won't fix this

A chat model only knows what is inside the current conversation. Close the tab or start a new chat and that context is gone, no matter how detailed last week's prompt was. Some products keep a per-account memory feature, but it stores whatever the product decided was worth keeping, on its own schedule, and you cannot point it at one specific field in one specific record. Wording the prompt more carefully cannot open a channel that was never built.

What 'remembering' has to mean here

Before building anything, write down exactly what needs to carry over. Usually it is a handful of fields: the last date you touched a given record, the last status you set on it, an id for whatever you produced last time, and nothing else. It is rarely 'everything that happened', and treating it that way is what makes this feel harder than it is.

Once you can name the few fields that matter, the fix is small. State lives in a sheet or a table, and gets injected into the prompt as plain text. The model never remembers; your record does, and you hand it over each run.

Read the state in, write the state back

The shape is the same no matter what you are tracking: read the stored state, build a prompt that includes it, run the model, then update the stored state with whatever changed. The model's job gets narrower this way too. It is reasoning about a fact you handed it, not trying to reconstruct history from nothing.

Skeleton. State lives outside the model and travels with the record.

function run(recordId) {
  const state = readState(recordId);     // { lastHandled: "2026-09-02", lastStatus: "pending" }
  const facts = gatherFacts(recordId);   // current data, not from the model

  const prompt = buildPrompt(facts, state); // state is handed over as plain text
  const result = callModel(prompt);

  writeState(recordId, {
    lastHandled: today(),
    lastStatus: result.status,
  });
}

See also: Recurring report that must land in the right folder

Don't paste the whole history back in

It is tempting to solve this by keeping a growing log and pasting all of it into every prompt. That works for a while and then quietly stops working. The prompt gets longer and costs more every run, and the one fact that matters ends up buried under months of ones that don't.

A compact state record beats a full transcript, because the model should see what is relevant now, not everything that was ever relevant.

What stays manual

  • Deciding which fields are actually worth tracking. That is judgement, not code.
  • Cleaning up state for records that no longer need tracking.
  • Resolving conflicts if two runs touch the same record before either finishes.