AI & Data14 October 20267 min read

Build Your Way into AI Engineering — Part 4 of 8

Add memory only when the stateless design fails

The first thing a conversational assistant gets wrong is forgetting what the customer said one message ago. The tempting fix is to send the whole conversation every turn. Part 4 adds the smallest state that solves Umgeni Fibre's problem, then a preference memory with provenance, correction and expiry, and the tests that prove both.

#AI Engineering#AI Agents#POPIA#Production Readiness

Stage 1 of the Umgeni build classifies tickets. It never talks to anyone. Stage 2 does: a support assistant on WhatsApp and web chat that answers the questions customers ask most, starting with "what is happening with my ticket?"

The first version is stateless. Each message is handled on its own, which keeps it simple, cheap and private. It also fails within two messages. A customer gives their account number, asks a question, then writes "any update?" and the assistant asks for the account number again. Nothing is more irritating in a support conversation, and nothing makes an AI assistant feel less intelligent.

This is the moment memory earns its place. Not before. And the question is not "which memory framework should we use?" It is "what is the smallest thing we must keep, for how long, to stop this failure?"

The failure, stated precisely

Umgeni Fibre is fictional, and its systems and figures are illustrative. In the first week of testing the stateless assistant with support staff playing customers, the team logged every conversation. Of 140 test conversations that went past one turn, 97 included the assistant asking again for something the customer had already given: the account number, the suburb, or which of two problems they meant.

That is the failure to fix. Writing it as a number gives the stage a finishing line: repeated questions in multi-turn tests should drop to near zero without the cost or privacy profile of the assistant getting meaningfully worse.

The tempting fix, and why Umgeni rejected it

The easiest way to give an assistant memory is to send the whole conversation back to the model on every turn. Many tutorials do exactly this, and for a five-turn chat it is fine.

For a support desk it has three problems. Cost grows with every turn, because the model reads the entire history again each time; a long conversation about a recurring fault can become several times more expensive per message than a short one. Context gets diluted: the account number given in message two competes for attention with everything said since. And everything the customer typed, including details they should not have shared, is resent to the provider on every turn.

Conversation history is not a memory strategy in the Memory series explains the trade-offs in depth. For Umgeni, the conclusion was simple: keep a small, structured state record and send that, plus the last couple of messages, instead of the whole transcript.

Stage 2a: a state record, not a transcript

Stateless and stateful, side by sideWITHOUT STATEWITH A STATE RECORDTurn 1: "My line is down,account 40217"Nothing kept between turnsTurn 2: "Any update?""What is your account number?"Turn 1: "My line is down,account 40217"State saved: ticket T-88213,account verified, step 2Turn 2: "Any update?""T-88213 is with the fieldteam, booked for 14:00"
Without state, the assistant forgets the account number between turns and asks again. A small state record, not the whole transcript, is enough to carry the ticket, the verification result and the current step into the next turn.

The state record holds only what the current task needs:

{
  "conversation_id": "wa-55120",
  "ticket_id": "T-88213",
  "account_ref": "acct_tok_7f3c",
  "verified": { "method": "otp_sms", "at": "2026-10-14T09:12:00+02:00" },
  "step": "awaiting_technician",
  "open_question": null,
  "expires": "24h after ticket closes"
}

Four details matter.

It stores a reference, not the account number. account_ref is a token that only Umgeni's own systems can resolve. The model never needs the real number to answer "your ticket is with the field team".

Verification is part of the state. The assistant must not reveal ticket details until the customer has proved who they are. Recording how and when they were verified means the next turn does not have to ask again, and an auditor can see the basis on which information was shared.

It is keyed to the verified identity, not just the phone number. In many South African households one phone is shared between family members, and a business WhatsApp line may be answered by several staff. A new conversation on the same number does not inherit someone else's verified state.

It expires. Working state belongs to one ticket. Umgeni deletes it 24 hours after the ticket closes. If the customer comes back next month, they start a new conversation and verify again. That is a small inconvenience and a large reduction in what the system holds.

With the state record in place, repeated questions in the multi-turn tests dropped from 97 of 140 conversations to 4, and the cost per message stayed close to the stateless version because the model reads a short record rather than a growing transcript (illustrative).

Stage 2b: a preference, with provenance

Once state worked, the support lead asked for one more thing. Customers who said "please WhatsApp me, not email" were being emailed anyway when their next ticket was opened, because the preference lived only in one closed conversation.

That is a different kind of memory. Working state lives for one ticket. A preference outlives it. So it needs more care: where it came from, whether it is still true, who can change it and when it goes away.

{
  "subject": "acct_tok_7f3c",
  "key": "contact_preference",
  "value": { "channel": "whatsapp", "language": "isiZulu" },
  "kind": "stated",
  "source": { "channel": "web_chat", "conversation_id": "wc-30117", "on": "2026-02-03" },
  "corrected": [{ "on": "2026-06-09", "by": "customer", "was": "email, English" }],
  "expires": "12 months after last confirmation"
}

kind separates what the customer said from what the system guessed. A customer writing once in isiZulu is an observation, not a stated preference. Umgeni only stores preferences the customer actually expressed. If the team ever wants to store inferences, they will be labelled as such and never presented back to the customer as something they said.

source records provenance. Anyone reviewing the record can see which conversation it came from and when. If the customer disputes it, there is something to check.

Correction is a first-class operation. When this customer said in June that WhatsApp in isiZulu now suited them better than email in English, the record was updated and the correction was logged, rather than a second, conflicting preference being added beside the first.

It expires unless confirmed. People change numbers, move house and change their minds. Twelve months after the last confirmation, the preference is deleted.

Two kinds of memory, two clocksWORKING STATEPREFERENCET-88213: account,verification, stepDeleted 24 hoursafter close"Email, English"stated 3 Feb, chatCorrected to WhatsApp,isiZulu, 9 JuneExpires 12 monthsafter confirmation
Working state belongs to one ticket and is deleted a day after the ticket closes. A preference outlives the ticket, so it carries where it came from, can be corrected by the customer, and expires unless it is confirmed again.

The four kinds of agent memory and why write policies matter more than the database go much further on these decisions. For a learning project, the lesson is that each retained item needs an answer to four questions before it is stored: what is it for, where did it come from, who can change it and when does it end.

Tests that prove memory behaves

Memory is easy to demonstrate and hard to prove. Umgeni added five automated tests to the suite:

  • Follow-up: after verification, "any update?" returns the ticket status without asking for the account again.
  • Isolation: a second identity on the same phone number cannot see the first identity's ticket.
  • Expiry: with the test clock moved 25 hours past ticket closure, the state record is gone and the assistant asks the customer to verify.
  • Correction: after "email me instead", the preference changes, the change is logged and only one preference exists.
  • No invented memory: asked "what did I tell you last time?" with no stored preference, the assistant says it has nothing on record rather than guessing.

The expiry test is the one most teams skip, because it needs a controllable clock. It is also the one that proves the system forgets, which is the property a privacy reviewer will ask about first. Retention and deletion are design questions with legal dimensions: the plain-language view in AI and POPIA helps frame them, and your privacy and legal people make the call. This is general information, not legal advice.

What the stage makes worse

Umgeni now holds data it did not hold before: short-lived working state and longer-lived preferences. Both need an owner, a deletion job that is monitored and a way for a customer to see and correct what is held. The team also notices that the assistant still cannot answer "is there an outage in Umbilo?" because it has no current knowledge at all. That is the next stage's reason.

Key points

Name the failure first. Umgeni measured repeated questions before adding any memory.

State, not transcripts. A short structured record beats resending the whole conversation on cost, focus and privacy.

Store references and verification, not raw identifiers. The model rarely needs the real account number.

Preferences need provenance, correction and expiry. And a clear line between what was said and what was inferred.

Prove forgetting. An expiry test with a controllable clock is the memory test that matters most.

Next: Part 5, Add retrieval only when knowledge must change independently. All parts are on the series page.

How CloudNala can help

We help teams decide what an assistant should remember, and design it so that working state expires, preferences carry their provenance, customers can correct what is held and tests prove all of it. The aim is an assistant that stops asking the same question without quietly becoming an unmanaged store of personal information.


Work with CloudNala

CloudNala helps organisations move from technology ambition to practical execution across cloud, AI, data, platform engineering and digital services.

Whether you are exploring AI, modernising your cloud environment, building a public-sector digital service, or turning an idea into a working MVP, we can help you shape the roadmap and deliver the next step.

Plan an AI MVP Build Sprint or write to us at consult@cloudnala.co.za