Objective
Ask a RAG pipeline "which plan is this customer on?" and it searches for notes that sound like the question. It finds the signup note, the upgrade note and an agent's guess from last week, and the model picks one. Similarity tells you what's relevant. It doesn't tell you what's still true.
In this recipe you load nine months of account notes for one customer, watch plain RAG and RAG-with-recency answer from them, then store the same notes in a SynapCores memory object and ask again. The memory object knows the current value of each fact, which note it came from, which value it replaced, and what was true on any past date. Everything is SQL, in one database, on the free Community Edition.
Every query and number below ran on SynapCores 2.4.3 with the default models (
all-minilmembeddings,qwen2.5:7bforGENERATE). Generation usestemperature 0and a fixedseed, so you get the same answers.
Step 1: Load the account notes
Fourteen notes about Harborline Logistics, the way a support and success team writes them:
a kickoff call, tickets, two billing events, a contact who left, a cloud migration, an agent's guess,
and one call note typed in four months late. noted_at is when it happened; filed_at is when it was typed in.
CREATE TABLE IF NOT EXISTS account_notes (
note_id INTEGER PRIMARY KEY,
account_id TEXT,
noted_at TIMESTAMP,
filed_at TIMESTAMP,
source TEXT,
body TEXT,
embedding VECTOR(384)
);
INSERT INTO account_notes (note_id, account_id, noted_at, filed_at, source, body) VALUES
(1, 'harborline', '2026-02-11 15:00:00', '2026-02-11 16:00:00', 'kickoff call', 'Kickoff call. Harborline runs its whole platform on Azure: AKS clusters and Azure SQL in West Europe.'),
(2, 'harborline', '2026-02-11 15:05:00', '2026-02-11 16:05:00', 'kickoff call', 'Main contact at Harborline is Dana Okafor, VP of Platform. Dana prefers email.'),
(3, 'harborline', '2026-03-04 09:00:00', '2026-03-04 09:00:00', 'billing system','Harborline signed the Pro plan, billed annually.'),
(4, 'harborline', '2026-04-18 11:20:00', '2026-04-18 12:00:00', 'support ticket','Ticket 3981: Azure SQL connection pool exhausted on the Harborline Azure deployment. Fixed by raising the pool limit.'),
(5, 'harborline', '2026-05-22 14:00:00', '2026-05-22 17:00:00', 'QBR', 'Quarterly review. Harborline''s Azure spend keeps growing; they asked about Azure reserved instances.'),
(6, 'harborline', '2026-06-30 08:40:00', '2026-06-30 09:00:00', 'support ticket','Ticket 4412: checkout API latency spike for Harborline, p99 above 2 seconds for 40 minutes.'),
(7, 'harborline', '2026-07-08 16:00:00', '2026-07-08 16:30:00', 'CSM call', 'Dana Okafor says Harborline is evaluating AWS because they want Bedrock.'),
(8, 'harborline', '2026-08-01 00:00:00', '2026-08-01 00:00:00', 'billing system','Harborline upgraded from Pro to the Enterprise plan.'),
(9, 'harborline', '2026-08-19 10:00:00', '2026-08-19 10:30:00', 'CSM call', 'Dana Okafor has left Harborline. The new main contact is Priya Raman, Head of Infrastructure.'),
(10, 'harborline', '2026-09-02 13:00:00', '2026-09-02 13:10:00', 'CSM call', 'Priya Raman prefers Slack Connect over email for anything urgent.'),
(11, 'harborline', '2026-09-15 18:00:00', '2026-09-15 18:30:00', 'CSM call', 'Harborline completed its move from Azure to AWS eu-west-1. The old Azure subscriptions are being shut down.'),
(12, 'harborline', '2026-10-06 09:30:00', '2026-10-06 10:00:00', 'support ticket','Ticket 5127: IAM role misconfiguration on the new Harborline account blocked a deploy. Resolved.'),
(13, 'harborline', '2026-10-20 07:00:00', '2026-10-20 07:00:00', 'agent note', 'Usage looks lower this month. Harborline may have downgraded to the Team plan.'),
(14, 'harborline', '2026-06-12 15:00:00', '2026-10-28 17:45:00', 'CSM call', 'Call notes from June 12, filed late: Harborline is all-in on Azure and happy with AKS.');
UPDATE account_notes SET embedding = EMBED(body);
Step 2: Ask the way plain RAG does
Embed the question, take the three most similar notes, and hand them to the model.
SELECT note_id, noted_at, body,
COSINE_SIMILARITY(embedding, EMBED('Which plan is Harborline on right now?')) AS relevance
FROM account_notes
WHERE account_id = 'harborline'
ORDER BY relevance DESC
LIMIT 3;
The top three are the upgrade note (#8, 0.637), the signup note (#3, 0.627) and the agent's guess (#13, 0.614). All three are about plans, and nothing in a similarity score says which one is still true. Freeze them into a context and ask the model:
CREATE TABLE IF NOT EXISTS rag_top (note_id INTEGER PRIMARY KEY, noted_at TIMESTAMP, body TEXT, score DOUBLE);
DELETE FROM rag_top;
INSERT INTO rag_top (note_id, noted_at, body, score)
SELECT note_id, noted_at, body,
COSINE_SIMILARITY(embedding, EMBED('Which plan is Harborline on right now?')) AS score
FROM account_notes
WHERE account_id = 'harborline'
ORDER BY score DESC
LIMIT 3;
CREATE TABLE IF NOT EXISTS rag_ctx (id INTEGER PRIMARY KEY, notes TEXT);
DELETE FROM rag_ctx;
INSERT INTO rag_ctx (id, notes)
SELECT 1, GROUP_CONCAT('[note ' || note_id || ', ' || noted_at || '] ' || body, ' ') FROM rag_top;
SELECT GENERATE(
'Answer the question in one short sentence using ONLY these account notes. Cite the note number. Notes: ' ||
notes || ' Question: Which plan is Harborline on right now?',
json_object('temperature', 0, 'seed', 7, 'max_tokens', 80)) AS rag_answer
FROM rag_ctx;
The answer is "Harborline is on the Team plan. [note 13]". It's wrong: the billing system says Enterprise. The model trusted the newest note, and the newest note was a guess.
Step 3: Try the usual fix, a recency boost
Blend similarity (70%) with freshness (30%), so newer notes rank higher. "Today" is fixed at 2026-11-01 so the scores are reproducible.
SELECT note_id, noted_at, body,
COSINE_SIMILARITY(embedding, EMBED('Which plan is Harborline on right now?')) * 0.7
+ (1.0 / (1.0 + DATEDIFF('2026-11-01', noted_at) / 30.0)) * 0.3 AS score
FROM account_notes
WHERE account_id = 'harborline'
ORDER BY score DESC
LIMIT 3;
Now the guess ranks first (#13, 0.644), ahead of the upgrade (#8, 0.520). Feed these three to the same prompt and the answer is "Harborline may have downgraded to the Team plan. [note 13]". Recency measures how new a note is. It can't tell a billing record from a hunch.
Step 4: Create a memory object for accounts
One statement creates the object and five ordinary tables: episodes, facts, current state,
provenance and relationships. IDENTITY scopes every read and write to one account.
CREATE MEMORY account_memory IDENTITY account_id;
Step 5: Remember the same notes, with time and authority
One REMEMBER per note, as it arrives. Three options carry what similarity can't:
event_time: when it happened, so a late-filed note lands in the right place on the timeline.source_type: how much to trust it. The billing system issystem_of_record; the agent's guess isagent_inference.attributeandvalue: the fact the note changes. Notes that only record an event (a ticket, a review, "we're evaluating AWS") useextract = falseand stay events.
REMEMBER account_memory FOR account_id = 'harborline'
'Kickoff call. Harborline runs its whole platform on Azure: AKS clusters and Azure SQL in West Europe.'
WITH (attribute = 'cloud_provider', value = 'Azure', event_time = '2026-02-11T15:00:00Z');
REMEMBER account_memory FOR account_id = 'harborline'
'Main contact at Harborline is Dana Okafor, VP of Platform. Dana prefers email.'
WITH (attribute = 'primary_contact', value = 'Dana Okafor', event_time = '2026-02-11T15:05:00Z');
REMEMBER account_memory FOR account_id = 'harborline'
'Harborline signed the Pro plan, billed annually.'
WITH (attribute = 'subscription_plan', value = 'Pro', source_type = 'system_of_record', event_time = '2026-03-04T09:00:00Z');
REMEMBER account_memory FOR account_id = 'harborline'
'Ticket 3981: Azure SQL connection pool exhausted on the Harborline Azure deployment. Fixed by raising the pool limit.'
WITH (source_type = 'tool_result', event_time = '2026-04-18T11:20:00Z', extract = false);
REMEMBER account_memory FOR account_id = 'harborline'
'Quarterly review. Harborline''s Azure spend keeps growing; they asked about Azure reserved instances.'
WITH (event_time = '2026-05-22T14:00:00Z', extract = false);
REMEMBER account_memory FOR account_id = 'harborline'
'Ticket 4412: checkout API latency spike for Harborline, p99 above 2 seconds for 40 minutes.'
WITH (source_type = 'tool_result', event_time = '2026-06-30T08:40:00Z', extract = false);
REMEMBER account_memory FOR account_id = 'harborline'
'Dana Okafor says Harborline is evaluating AWS because they want Bedrock.'
WITH (event_time = '2026-07-08T16:00:00Z', extract = false);
REMEMBER account_memory FOR account_id = 'harborline'
'Harborline upgraded from Pro to the Enterprise plan.'
WITH (attribute = 'subscription_plan', value = 'Enterprise', source_type = 'system_of_record', event_time = '2026-08-01T00:00:00Z');
REMEMBER account_memory FOR account_id = 'harborline'
'Dana Okafor has left Harborline. The new main contact is Priya Raman, Head of Infrastructure.'
WITH (attribute = 'primary_contact', value = 'Priya Raman', event_time = '2026-08-19T10:00:00Z');
REMEMBER account_memory FOR account_id = 'harborline'
'Priya Raman prefers Slack Connect over email for anything urgent.'
WITH (attribute = 'contact_channel', value = 'Slack Connect', event_time = '2026-09-02T13:00:00Z');
REMEMBER account_memory FOR account_id = 'harborline'
'Harborline completed its move from Azure to AWS eu-west-1. The old Azure subscriptions are being shut down.'
WITH (attribute = 'cloud_provider', value = 'AWS', event_time = '2026-09-15T18:00:00Z');
REMEMBER account_memory FOR account_id = 'harborline'
'Ticket 5127: IAM role misconfiguration on the new Harborline account blocked a deploy. Resolved.'
WITH (source_type = 'tool_result', event_time = '2026-10-06T09:30:00Z', extract = false);
REMEMBER account_memory FOR account_id = 'harborline'
'Usage looks lower this month. Harborline may have downgraded to the Team plan.'
WITH (attribute = 'subscription_plan', value = 'Team', source_type = 'agent_inference', event_time = '2026-10-20T07:00:00Z');
REMEMBER account_memory FOR account_id = 'harborline'
'Call notes from June 12, filed late: Harborline is all-in on Azure and happy with AKS.'
WITH (attribute = 'cloud_provider', value = 'Azure', event_time = '2026-06-12T15:00:00Z');
Every note is stored, including the guess and the late note. Two of them come back with a message explaining why they didn't change the current value:
- The guess: "'subscription_plan' = 'Team' was not accepted as current: lower source authority than the accepted value".
- The late note: "'cloud_provider' = 'Azure' was not accepted as current: equal authority, older validity".