09 · Learning Loop

Teaching the system to learn from us

Every time a person approves, edits, or rejects an AI-written email, that decision is a lesson. Today we throw most of those lessons away. This page is the plan to keep them — so the writing gets better over time — explained in plain language, step by step: what we do, why it matters, and how. One rule never breaks: Memory (what the AI remembers to personalize) is never the training data (the clean, separate record we learn from).

The problem, in plain words

We grade the work, then shred it

Imagine a teacher who marks an essay “pass” or “fail”, then shreds the essay and the corrections. The student can never improve. That is roughly what happens now: the system records that a human decided, but throws away the most useful part — the original draft, what the human changed, and why.

What we lose today · 1

The original draft

Until recently, when someone edited a draft the AI’s first version was overwritten and the before vs after — the single strongest lesson (“the AI wrote this, the human fixed it to that”) — was lost. The first step of the plan now keeps it.

What we lose today · 2

The reason

Until recently, reject and escalate only saved free text and we couldn’t count why drafts got rejected (too generic? factual error? wrong tone?). The first step of the plan adds that count with reason codes.

What we lose today · 3

Which model & prompt wrote it

Until recently we didn’t record which AI model or which instructions produced a draft, so we couldn’t reproduce a result, compare versions, or know what changed when quality moves. The plan now stamps both.

What we lose today · 4

The outcome

We only know sent or failed — never whether the email was opened, replied to, or won a deal. So we can’t tell which drafts actually worked.

Good news — half the plumbing already exists

We are not building from zero. The Hub already writes an append-only audit record of every action, and the database’s change-stream (DynamoDB Streams) is already switched on — it simply has nothing connected to the other end yet. The plan mostly connects and labels what is already there, rather than rebuilding it.

What we’ll build

Four simple layers

Each layer has one job. The fast, live part stays exactly as it is; the new parts sit beside it and only ever add information.

Layer 1

The live queue — unchanged

Where a task sits while a person reviews it. It must stay fast, so we don’t touch it — we just keep the AI’s original draft alongside the edited one.

DynamoDB · the tasks table

Layer 2

The decision log — events

A permanent, append-only record of every human decision: who, what, why, when, plus links to the original and final drafts. Nothing can overwrite it. This is the source of truth for learning.

Append-only events

Layer 3

The evidence store — S3

The big stuff (full drafts, the exact context the AI saw, the diffs) kept cheaply and safely for later analysis and training. The events point to it.

S3 · encrypted, queryable

Layer 4

Memory — short notes

Small rules the AI remembers to personalize (“this client likes short emails”, “one call-to-action”). Useful at writing time — but never the training data, and never the only copy of anything.

Scoped preferences

On top of these, later

Two things sit on the four layers once they exist: dashboards (is the writing actually improving?) and training datasets (clean, privacy-scrubbed examples to teach a smaller model the house style). Both read from the decision log — they never read from the live queue or from Memory.

The plan, step by step

Built in order — small and reversible first

The early steps are tiny, safe, and don’t touch infrastructure. Nothing here changes how an email is sent. Each step says what we do, why, and how.

01
Capture the decision properly
Why: today we lose the reason and the original draft, so we can’t learn from edits or rejections. How: add a short pick-list of reason codes (Too generic, Factual error, Wrong tone, Missing call-to-action…) to rejects and escalations; keep the AI’s original draft untouched when a human edits; record exactly what changed (the diff); and make sure the saved reviewer is the real signed-in person — a small but important security fix that the first step already ships.
Phase 1 · reason codes + keep original + diff
02
Save every decision as a permanent event
Why: we need one trustworthy timeline of what happened that nothing can overwrite or fake. How: every approve / edit / reject / escalate writes an append-only event — who, what, why, when, the before/after, and a key that stops double-clicks from counting twice.
Phase 1 · append-only events
03
Connect the pipe to long-term storage
Why: the live database is for “now”; learning needs a cheap place that keeps everything and is easy to analyze. How: switch on the connection that already exists (the database change-stream) → a small function → an encrypted S3 store. While we’re there, stamp each draft with which model and which prompt produced it, so results are reproducible.
Phase 2 · Stream → S3 (Athena)
04
Remember preferences
Why: the AI should reuse what we keep correcting (tone, length, one call-to-action) without us repeating ourselves. How: a small, scoped “Memory” of short rules, approved by a person before it’s trusted, and ranked so a company-wide rule always beats one reviewer’s personal taste. Memory holds notes, never raw customer data.
Phase 3 · scoped Memory
05
See if it’s working
Why: we can’t improve what we don’t measure. How: simple dashboards over the decision log — how often drafts are approved as-is vs edited, the top reasons for rejection, how much editing each draft needs, and (once sending is wired) replies and bounces.
Phase 4 · dashboards (Athena)
06
Teach a model from it
Why: once we have clean, labeled examples (the AI’s draft → the human’s final), a model can learn the house style. How: build a clean, privacy-scrubbed, versioned dataset from the events, then train a smaller, customizable model on it. Note: our current writing model can’t be fine-tuned, so this means training a smaller model — and only after the earlier steps prove their value.
Phase 5–6 · dataset → train

Do this before recording send outcomes

More than one worker can pick up approved emails to send — the AWS Lambda dispatcher (the live Unified Sender) and an older n8n worker. Before we start recording outcomes (replied / bounced), retire the old worker so there is one sender. Otherwise outcomes get double-counted and the learning signal is poisoned — and it also removes the risk of a double send to the client. See Risks.

Decisions we need

Five questions to unblock the work

These are the only real blockers. Each has a plain reason and a recommended answer — say “go with the recommendations” and step 1 can start (it’s reversible and doesn’t touch infrastructure).

Decision 1

A stable customer ID

Why: to group lessons “per client” we need one reliable ID. Names and emails change.

Recommended HubSpot company id

Decision 2

How we version the prompt

Why: to compare “did this week’s instructions write better than last week’s” we need a version label. The prompt is assembled live, so there’s no natural number.

Recommended a tag + a fingerprint of the live prompt

Decision 3

Where the draft-writer lives

Why: to stamp model & prompt on each draft we must edit the part that writes them.

Recommended confirm: the task_consumer Lambda, CD ships it

Decision 4

One sender, not two

Why: two senders double-count outcomes and risk a double send. This must be settled before we record outcomes.

Recommended retire the old n8n worker first

Decision 5

Where Memory lives

Why: build it ourselves, or buy the managed AWS “AgentCore Memory”? It’s a build-vs-buy + dependency call.

Recommended start in our own database; buy later only if we need smart search
Your question

Will we use AWS’s “AgentCore Memory”?

Short answer: not at the start — and yes, later, only when it pays off. We begin with our own simple memory (a few notes in the database we already run). We switch to AWS’s managed memory once we actually need the two clever things it does. This is exactly Decision 5 above.

What is AgentCore Memory, in one line?

It’s a ready-made AWS service that gives an AI a memory: it automatically reads past reviews, pulls out durable notes (facts, short summaries, preferences), keeps them organized per client and per rep, and lets the AI find the most relevant note by meaning while it writes — all without us building the memory machinery ourselves.

Now — our own notes

Simple, hand-curated

A person approves short rules (“this client likes short emails”) and they live in the database we already use. Why start here: it’s cheap, instant, fully ours (no lock-in), and at small volume that’s all we need.

Later — AgentCore Memory

AWS writes & searches them

AWS auto-creates the notes from the history of reviews and lets the AI search them by meaning across sessions — so no one curates by hand. Trade-off: pay-per-use, a short delay before a new lesson shows up, and it’s an AWS-locked service.

What the change actually does — in plain words

Today a person writes the AI’s memory notes. With AgentCore Memory, AWS writes and organizes those notes for us automatically, and the AI pulls the most relevant ones “by meaning” while drafting — so it remembers what we keep correcting, across days and across clients, without anyone maintaining a list by hand. Nothing else in the plan changes — the live queue, the decision log and the S3 store stay exactly the same.

When we’d switch

We turn it on the moment either is true: (1) we have enough notes that the AI needs smart search to pick the right one, or (2) we want the notes created automatically instead of by a person. It’s already generally available in our AWS region, so switching later is low-friction — we just keep our code able to plug into it from day one.

The rule still holds — even with AgentCore Memory

Memory is never the training data. Its notes are a derived convenience built from the events, and they can expire — so it never holds the only copy of anything, and we never train a model from it. The permanent, complete record always stays in the decision log + S3.

Build vs buy

Build the backbone, buy only the training

We checked our plan against AWS’s own building blocks (and three AWS guides Daniel shared). The guides all cover the approval step — they stop exactly where learning begins — which confirms the learning loop is ours to build.

Build ourselves

The data backbone

The live queue, the decision log (events), the S3 evidence store, and the small Memory store. They are cheap, fully ours (no lock-in), and have to exist regardless. Our review screen (the Hub) is already richer than AWS’s off-the-shelf human-review product, so we keep it.

Buy (managed AWS)

Only the training + an optional check

Use a managed AWS service for the actual model training (Phase 6) and, optionally, a quality gate before each training run. Caveat: our current writing model can’t be fine-tuned, so training targets a smaller, customizable model in a different AWS region. Everything we capture is model-agnostic, so this changes only the last step.

Skip (avoid over-engineering)

We’re not adopting the heavier AWS human-review products (Amazon A2I) or the real-time, in-chat approval patterns (Strands interrupts / MCP elicitation): those assume a live, synchronous conversation, while our review is asynchronous — drafts are written first and reviewed minutes-to-hours later. Our Hub already fits our way of working better.

Two rules we never break

The guardrails

Rule 1 — Memory is not the training data

Memory is short notes for personalization; it can expire and is a convenience. The training data is the clean, complete, versioned record kept separately in events + S3. We never train from Memory, and we never let Memory hold the only copy of anything important.

Rule 2 — the recorded reviewer must be the real one

If who-approved-what can be faked, every lesson is suspect and the dataset is poisoned. So the reviewer on every event comes from the verified sign-in, never from anything a client could set. This is the small security fix in step 1.