Most AI applications built today suffer from machine amnesia.
You can have a brilliant conversation with an LLM, but the second the session ends, the model forgets everything. If you are building a simple chat wrapper, a standard context window is fine. But if you want to build an autonomous agent or a system that actually manages business logic, relying on temporary memory will fail.
I encountered this exact problem while building Sutton, an AI bookkeeper prototype for informal market traders in Africa.
The goal was simple. A trader should be able to tell the AI: "Customer Chika owes ₦45,000 for 3 bags. Payment is expected next Friday." The system needed to remember this forever, not just until the browser refreshed.
Here is how I moved away from transient context windows and built a persistent extraction layer using Next.js, Groq, and Walrus Memory.
The Context Window Illusion
Many developers try to solve memory by just stuffing previous messages into the system prompt. This creates major problems.
First, it gets expensive. You are paying to process the same historical data on every single request. Second, models lose focus. The larger the context window gets, the worse the model becomes at retrieving specific facts.
To build a reliable system, you have to separate working memory from long-term storage.
Extracting State from Chaos
Instead of passing the entire chat history back and forth, the better approach is to intercept the user's message, extract the core business data, and save it as a structured object.
For Sutton, I used the Vercel AI SDK alongside Groq to handle this extraction. Because Groq is incredibly fast, running an extraction step before responding to the user adds almost no latency.
Here is the Next.js API route logic to force the LLM to return structured state:
import { generateObject } from 'ai';
import { groq } from '@ai-sdk/groq';
import { z } from 'zod';
export async function POST(req: Request) {
const { userMessage } = await req.json();
// force Groq to extract the state into a strict JSON schema
const { object } = await generateObject({
model: groq('llama-3.3-70b-versatile'),
schema: z.object({
customerName: z.string(),
amountOwed: z.number(),
items: z.string(),
dueDate: z.string().optional(),
}),
prompt: Extract the business transaction details from this message. ,
Message: "${userMessage}"
});
// example extracted object:
// { customerName: "Chika", amountOwed: 45000, items: "3 bags", dueDate: "next Friday" }
await saveToPersistentMemory(object);
return Response.json({ success: true, savedState: object });
}
Locking It in the Vault
Once the state is extracted into a clean JSON object, it needs a permanent home.
For a traditional app, you might save this to a PostgreSQL database like Supabase. For the Sutton prototype, I experimented with decentralized storage using Walrus Memory on the Sui ecosystem. I used the @mysten-incubation/memwal package to store these extracted JSON objects as permanent blobs.
When the user returns the next day and asks, "Who owes me money?", the system does not need to read through 50 pages of chat history. It simply queries the permanent storage, retrieves the exact figures, and feeds that clean data back to the LLM.
The Key Takeaway is that if you want to build AI products that people actually rely on, stop relying entirely on context windows. Treat your LLM as a processing engine, not a database. Extract the state, save it securely, and give your AI the persistent memory it needs to be useful.
Top comments (0)