Building a Personality Model That Writes About Itself
February 24, 2026
There’s a particular kind of recursive absurdity that appeals to me—the book about writing the book, the AI system that models a person well enough to write about the system that models them. That’s what the Gamma Corpus project became, and I think it’s worth walking through how it got there, because the path was more interesting than the destination I originally had in mind.
The Email Problem
The project started with a practical question: I have roughly 20 years of email sitting in Google Takeout archives, and that email contains a pretty detailed record of how I think, argue, write, and make decisions. Could I extract that into something structured enough to build a personality model from it?
The term “gamma-level” comes from Alastair Reynolds’ Revelation Space—a behavioral sketch that captures communication patterns and reasoning style without approaching anything like real consciousness. The aspiration was to get from gamma (sounds right) toward beta (reasons right), using enough data and careful architecture.
Phase 1 was straightforward engineering: parse MBOX files into SQLite, reconstruct email threads, build a contact registry, run enrichment passes for noise detection and basic classification. The personal Gmail archive alone was a 14.9 GB MBOX file—about 540,000 messages spanning October 2005 through February 2026. Combined with the business Gmail and an older Thunderbird archive, the email database ended up at around 618,000 messages across 297,000 threads before non-email sources were added. The vast majority of those turned out to be noise—automated notifications, mailing list traffic, political campaign emails, pharma spam—and identifying and filtering out the 92% noise to isolate the ~48,000 genuine messages underneath required about ten iterative filtering passes, each one targeting a different pattern.
The Curation App
You can’t curate half a million messages from a SQLite prompt. I built a local web application (FastAPI backend, React frontend) that turned out to be the workhorse of the whole project—a split-panel message browser with full-text search, keyboard shortcuts for rapid triage, batch operations with undo, and a tag management system that tracks the lifecycle from model-suggested through human-confirmed.
The keyboard shortcuts matter more than they sound. When you’re classifying thousands of messages, the difference between clicking a button and pressing h for “high quality” or n for “noise” adds up fast. I ended up doing most of the noise triage in long sessions where I’d filter by sender pattern, scan a few examples, and batch-mark entire categories—WordPress notifications (8,812 messages), Twitter (2,222), GitHub notifications (753), and so on down the long tail.
The Generation Agent
With the corpus structured and tagged, the next step was building something that could actually write in my voice. The first version was a single-pass RAG pipeline: embed the corpus into ChromaDB using a local embedding model, retrieve stylistically similar examples for a given task, assemble them into a prompt with a personality system prompt, and call Claude.
The system prompt itself went through three major versions. v1 was a rough sketch from the initial blind analysis. v2 added quantified linguistic markers—things like “uncertainty hedges appear at 4-6 per thousand words” and “confidence markers at 2.3-2.6 per thousand words”—derived from statistical analysis of 14,405 messages spanning 1998 through 2026. v3 added anti-fabrication guardrails after a sobering discovery I’ll get to in a moment.
The A/B testing was revealing. With corpus examples and the personality prompt, the output read like an engineer talking to peers—parenthetical asides, hedged estimates, dry humor, no bullet-point takeaway sections. Without them, the same model produced conventional blog structure with bolded lessons and motivational closers. The voice delta was clear and consistent.
The Hallucination Problem
Voice authenticity and content accuracy turned out to be orthogonal problems. The voice was perfect; the facts were wrong.
The v2 prompt produced text that was stylistically indistinguishable from my actual writing—which made the fabricated content more dangerous, not less. In one A/B test, the model invented an elaborate 4-stage RAG pipeline (embedding retrieval → BM25 keyword filtering → LLM re-ranking → answer generation) that doesn’t exist. It fabricated performance statistics, cost figures, and pipeline architecture with complete confidence, all wrapped in my characteristic hedging and conditional reasoning.
A reader familiar with my style would have had no stylistic cues to flag the content as fabricated.
The fix was a three-stage pipeline: generate a draft, then run an adversarial fact-checker (a separate model call with no personality prompt and no corpus access—intentionally different from the generator to avoid rationalizing the same fabrications), then conditionally revise based on the fact-check results. I added a parallel copy editor that evaluates narrative structure and pacing as a cold reader. Both reports feed into the revision stage, where fact-check issues are mandatory fixes and copy-edit issues are judgment calls.
v3 of the system prompt added explicit anti-fabrication instructions—“never invent technical details, performance statistics, architecture descriptions, or implementation specifics not present in the source material”—and the combination of prompt constraints plus adversarial fact-checking eliminated the wholesale fabrication problem. Opus with v3 produced the cleanest output: no invented architecture, no fabricated statistics, accurate pricing numbers, and appropriate “I don’t know” hedges.
Beyond Email
The corpus grew beyond email fairly quickly. I imported 425 Slashdot comments (2003–2011), 258 Borland C++ Builder newsgroup posts (1998–2000), 3,049 Reddit comments across two accounts (2009–2026), 2,620 Claude.ai conversation messages, and 2,387 Claude Code CLI session logs. Each source required its own import script and platform-specific body cleaning—Slashdot comments needed quote re-extraction from saved HTML because the original scraper had flattened the distinction between quoted parent text and my actual replies.
The non-email sources turned out to be disproportionately valuable for personality modeling. Reddit and Slashdot comments are where opinions live—industry commentary, political positions, humor that doesn’t appear in professional email. Claude conversations capture how I frame problems and reason through architecture decisions in real time. The Borland posts from 1998 suggest the voice was already largely formed at that point—the same conditional reasoning, the same parenthetical qualifications, the same dry humor. If that’s true, it means the personality model is capturing something genuinely stable rather than just fitting to recent patterns, which has interesting implications for how far this kind of modeling can go.
The Worldview Pipeline
Tone mimicry was effectively solved by the v3 system prompt. But the system prompt is a cognitive style sheet—it describes how I communicate without encoding what conclusions that reasoning has reached. Moving toward beta-level modeling required capturing attitudes, beliefs, and opinions.
I built a three-phase extraction pipeline: Haiku filters messages for belief-bearing content, Sonnet extracts structured belief records (domain, topic, position, confidence level), and Opus synthesizes per-domain summaries into a 9,742-word worldview document covering everything from institutional skepticism to pragmatic idealism to positions on AI and credentialism. The extraction produced 4,530 beliefs across 9 domains; 4,511 of those matched existing messages and went into a stances table in the database and a dedicated section of the vector store, giving the agent semantic search across my actual positions on things.
What surprised me was how the worldview document changed the output. A/B testing confirmed it produces meaningfully different editorial choices—not just style variation, but different decisions about what to emphasize and what to leave out. The version with the worldview was shorter, more direct, and more opinionated. It trusted the reader more.
Retrieval Quality
The most impactful late-stage improvement was cross-encoder re-ranking. The initial retrieval used embedding distance from ChromaDB, which gets you in the right neighborhood but doesn’t discriminate well between “topically adjacent” and “actually relevant.” Inserting a cross-encoder (ms-marco-MiniLM-L-6-v2) between the vector search and the existing style/recency/diversity re-ranking added roughly 50 milliseconds of latency and meaningfully improved which examples the model actually saw.
I also ran a tag quality audit—having Sonnet blindly re-tag a stratified sample without seeing Haiku’s assignments. The key finding was that Haiku was under-tagging rather than over-tagging, which is the less dangerous direction. Adding platform-specific guidance to the taxonomy prompt improved coverage for the non-email sources, particularly for persona classification where agreement had been weakest.
The Book
The system wrote a book.
The gamma agent—the tool-using version with dual-channel RAG, citation tracking, and iterative retrieval—generated all 15 sections of a book about building a SaaS platform in 16 days. 42,066 words, 524 citations back to source material. The cost accounting depends on how you measure it—the Claude Console reported about $72 for the generation runs, though the full pipeline including retries and re-runs was higher. I submitted it to KDP in both paperback and Kindle editions.
It’s not a great book. But the facts check out and it sounds like me, which was the point. It’s an interesting proof of concept for what a personality model can produce when you give it good source material and a reliable fact-checking pipeline.
The Recursive Part
The thing I keep coming back to is the recursion. The system that models my personality was used to write about the system that models my personality. The agent that retrieves my beliefs was asked to prioritize its own backlog—and it picked pragmatic improvements (better retrieval, daily practical use, don’t crash) that are consistent with the values the worldview pipeline extracted from my writing. The tag audit used a stronger model to check a weaker model’s work on data that both models would eventually use to generate content in my voice.
The voice is solved. The facts require ongoing vigilance. The beliefs are captured but static—they’ll drift as mine do, and there’s no mechanism yet for the model to update its own worldview. That seems like the next interesting problem.
Total project cost through the end of February 2026: somewhere around $400 in API calls, plus a lot of evenings. The corpus contains 626,000 messages, 4,511 extracted beliefs, and a system prompt that knows I use double spaces after periods and will never write the word “amazing.”