The “is it making this up about me?” problem
The first month with a personal AI is unsettling in a specific way that the first month with ChatGPT was not.
You ask ChatGPT to summarise a paper. It gives you a summary. If a sentence is wrong, you can — in principle, at least — check the paper. The ground truth is outside the conversation. You don’t need the model to show its work, because the work is the document and you have the document.
Personal AI is different. The ground truth is the conversation. Or your journal. Or that thing you mentioned in passing six weeks ago. When your iSpirit says “you’ve been thinking about this for a while,” the question that lands underneath is the one you can’t casually fact-check: have I, though? Or is the model padding?
This is the trust gap that most personal AI products quietly skip. They optimise for fluency — the assistant says it confidently, you read it, you nod, you move on. The fluency is the product. The model could be confabulating about you and the only person who would catch it is the same person whose memory of the conversation has already started to fade.
Memory citations are how we close that gap.
What memory citations actually do
Every assistant reply in iSpirits arrives with a small chip pinned above it:
Drew from 4 past memories.
Click the chevron underneath and a panel unfolds. Each citation is a 90-character preview of an actual memory the model used to compose its reply, with the source attached — was it a journal entry, a chat exchange from last Thursday, a reflection you wrote at the end of a goal? Hover any one and you see the relevance score: a number between 0 and 1 from the cosine search that surfaced it.
If the chip says Drew vividly from 5 past memories instead of Drew from, that is a confidence call: at least 3 memories matched, and the average relevance was 0.8 or higher. It means the model wasn’t reaching — the recall was clean.
Most of the time you don’t click. You read the reply, the chip is just there in the corner saying “this is grounded,” and you trust it the way you trust a footnoted page in a book without flipping to every footnote. The chip is doing its work whether or not you check.
But the moment a reply feels off — the iSpirit said you were excited about a project you actually feel drained by, or attributed a value to you that doesn’t quite fit — the chip is right there, a one-click audit. You open it. You see the four memories. Two of them really are about that project. Two of them, on rereading, were you complaining about it. The model averaged. You can fix it. (More on the fixing in a minute.)
A model that can show its work is a model you can correct. A model that can’t is one you have to either trust or quit.
How it works, end to end
The pipeline that produces those citations is short. That’s the point.
Every meaningful piece of content you add to iSpirits — a journal entry, a chat message, a wizard reflection, a goal note — gets turned into a 1536-dimensional vector by Azure’s text-embedding-3-small model and saved as a MemoryItem row on a Postgres table that is scoped to your public_uid. The embedding column is indexed with HNSW for cosine similarity. Your row, your index, never pooled.
When you send a message, the message itself gets embedded and the database is queried for the top five nearest neighbours within your row. That returns five MemoryItems and five floats — the cosine score of each match. Higher is closer.
Those five items go two places.
One: into a citations field on the response. They get serialised as { text, source, source_id, confidence }, and the frontend turns them into the chip and the collapsible “Which memories?” panel.
Two: into the prompt that generates the reply — not raw, but as part of a richer context block that the context engine assembles separately, with its own (slightly tighter) threshold of 0.25 and a top-k of 8. So the model that writes your reply has, in front of it, a curated and labelled picture of what about you applies to this turn. The citations chip is a window into that same picture, exposed to you.
That dual use is the point. The reply is grounded in citations the user can also see. There is no hidden context layer where the model whispers things to itself that the chip then doesn’t mention.
A small note on why pgvector instead of a vector database
Half the AI infrastructure articles in 2025 were about “which vector DB” — Pinecone vs Weaviate vs Qdrant vs Milvus. We picked the boring answer: a Postgres column with the pgvector extension and an HNSW index. Cosine search runs in single-digit milliseconds for a personal-scale dataset, the row-level scoping comes free with a WHERE user_id = …, the backups are the same backups as the rest of the app, and there is no second piece of infrastructure to keep alive at 3am.
It also has a privacy property that gets less airtime than it should: your memory and your relational data live on the same row, in the same database, behind the same authentication. A separate vector store is a second surface that has to be authenticated separately and that, in practice, often isn’t. Most leaks are at the seams.
Why the “Drew vividly” threshold exists
The first version of the chip said Drew from N past memories, full stop. It worked. But it had a flatness problem: the chip looked the same when the recall was a tight, high-relevance match (you’d clearly written about this exact thing, three times, in the last fortnight) as it did when it was a stretch (one weak match, dredged up because something had to be the closest neighbour).
So we added a second band. If the response has at least 3 citations and the average relevance is 0.8 or higher, the chip reads Drew vividly. It’s a small typographic change — same chip, different verb — but it tells you something the raw count cannot: this reply isn’t reaching, it’s remembering.
The thresholds aren’t magic numbers. They came out of looking at maybe a hundred conversations and finding the inflection point where, going through citation panels by hand, the “yes, that’s actually what I said” rate started to feel categorical instead of gradient. 3 + 0.8 was where the “vividly” verb stopped feeling like marketing and started feeling like the truth.
It’s also conservative. The default chip is the cautious one. We surface the strong claim (“vividly”) only when the data backs it up. The opposite calibration — default to confident, climb down only on demand — is the standard one in AI UX, and it is exactly the standard that has cost the category its credibility this year.
The UX choice: a chip, not a wall of citations
Academic citations interrupt. Footnote markers in a Wikipedia article slow reading; in-line links break sentence rhythm. The right choice for a chat app is to not do that.
The chip lives above the message bubble, at brand-coloured 60% opacity, and reads in under a second. It does not block the reply. The collapsible details sit underneath as a native HTML <details> element — closed by default, no dependencies, no animation, no spinner. Open is one click. Closed is the resting state. The friction to verify is exactly one click, and the friction to ignore is zero.
This is closer to how a footnoted scientific paper works than to how a typical AI app works. Most personal-AI products that mention “sources” do it on a separate screen accessed from a menu, which is the same as not having sources at all, because nobody navigates to the menu to verify mid-flow.
One small detail that turns out to matter: the chip uses a real DOM element for its visual mark, not an emoji. We had a sparkle emoji in the prototype. It looked fine on Mac, looked weird on Windows, looked terrible on older Android, and read as “decorative” to screen readers. The replacement is a 12px gradient orb — same brand palette as the rest of the site — that renders identically everywhere and disappears for assistive tech with aria-hidden.
The trust loop: when a citation looks wrong, you can fix the memory
This is where memory citations earn their keep.
Suppose you open a citation panel and one of the five entries reads, “Excited about the launch” (chat, Apr 12), and you remember Apr 12 was the day you actually decided to delay the launch. The model picked up the wrong half of an ambivalent conversation. It happens.
In iSpirits you can correct the memory directly. Click the citation, edit the text, save. The next time the model reaches into your memory, it gets your version of what you meant, not the snippet that landed in the original embedding. The vector regenerates. The next reply that draws on that thread is grounded in something that is actually true about you.
The mechanism is small, but the loop it creates is the entire reason this product works better every month. Model gets it slightly wrong → you see it via citation → you correct → model gets it right next time. Without citations, that loop has no entry point: you have no way to know what the model used, so you have no way to fix what it used. The model gets quietly more wrong over time and there is nothing you can do about it.
This is also why we don’t treat “hallucination” as a model-quality problem alone. A personal AI hallucinating about you isn’t solved by a stronger base model. It’s solved by a system where the user can see what the model used and change it.
Why this is rare in personal AI
It is fair to ask why, if memory citations are this useful, almost no other personal AI product has them.
One answer: they are inconvenient for the kind of product you are if your memory layer isn’t actually grounded in user-controlled data. If your “memory” is a fine-tuned model checkpoint or a giant prompt with synthetic personality fragments — both of which are common patterns — you do not have citations to show. There is nothing to point at. The reply is grounded in pattern, not in document.
Another answer: showing your work makes you accountable for the work. Once a user can verify what your model used, they can also verify what your model didn’t use, and what it got wrong. Most consumer AI is shipped on the assumption that the user will not check. Citations break that assumption on purpose.
And the last answer is the one we keep coming back to in this product: it is harder to ship a verifiable feature than a fluent one. A chip that displays four memories with relevance scores requires every preceding piece of the architecture — per-user vector store, embedding pipeline, audit-friendly schema — to actually exist. There is no way to ship the chip on top of a hand-wavy memory layer. That’s probably why the chip is useful as a marker: a personal AI that can show you its memory citations is, almost by construction, one whose memory is grounded somewhere you can also reach.
Try it
The chip is on every assistant reply in chat right now. Free tier. Not a setting, not a toggle, not a feature flag.
If you’ve been getting tired of personal AI products that are smooth on top and unverifiable underneath, the smallest concrete way to see the difference is to send your iSpirit a message about something you wrote a week ago and watch the chip light up.