XPoster Start free →
← Blog

We tested whether an AI can copy your writing voice. It failed.

August 8, 2026 · 6 min read

The entire premise of XPoster is that it writes like you rather than like an AI. That is a testable claim, so we tested it, and the first result was bad enough that we spent the next week rebuilding how voice reaches the model.

The test

We picked five X accounts with unmistakably different writing: levelsio, naval, paulg, patio11 and cobie. Each was run through our profile scan, which reads their public posts and builds a voice profile.

Then we generated one post per account with everything else held constant: same topic, same mode, same niche, same model, same tone. The only variable in the whole experiment was the voice profile.

The bar we set beforehand: show the five outputs to someone and have them match at least four back to the right account. If a voice profile does anything, matching should be easy.

The result

We never got to the matching step.

Two of the five outputs, levelsio and patio11, opened with the same sentence, word for word. A third, cobie, differed by one word. All five then walked to the same argument. There was nothing to match, because there was nothing different.

This is the least comfortable kind of test result and also the most useful one. A partial failure invites you to tune. A total failure tells you the mechanism is not connected.

What was actually wrong

Our first instinct was that the scan was bad. That we were reading the accounts wrong. That turned out to be false. The profiles were specific and accurate; read on their own, you could tell which writer each described. The failure was downstream, in how a profile reached the model.

Two things were wrong, and the second one is the interesting one.

A profile is a biography, not a style specification

The profiles described who someone is: what they write about, what they care about, roughly how they sound. What they did not contain was a single measurable fact about the writing. Not the typical length of a post. Not whether the person capitalises sentences. Not how they use line breaks, or whether they end on a question, or how long their sentences run.

"Writes with conviction about indie hacking" is a description a model can nod along to without changing a single output token. "Median post is 180 characters, no capital letters, never ends on a question" is a constraint it has to satisfy.

The voice was outvoted roughly eight to one

This is the part we did not expect, and it is worth understanding if you build anything on top of a language model.

We counted the characters going into the prompt. The voice profile was about 800 characters of descriptive text. Against it sat the niche instructions (~3,600 characters), plus the tone block, plus the mode rules, plus our anti-AI-tell block (~2,800 characters), over 7,000 characters of imperative, structural rules.

A model given seven thousand characters of "do this, never do that" and eight hundred characters of "this person is thoughtful and direct" will follow the rules and treat the description as flavour. It was not ignoring the voice. It was obeying everything else.

The voice profile was not competing with nothing. It was competing with our own product, and losing.

The bug that had been running since launch

While we were in there, we found something worse.

Our scan reads public posts through nitter mirrors. Those mirrors mark a retweet in the item title, RT by @handle:, while the description carries the retweeted text with no marker at all. Our parser read the description and checked whether it started with RT .

It never did. The filter had never fired once since the feature shipped.

Every profile scan we had ever run was feeding other people's writing into the user's voice profile as if they had written it. On one of our test accounts, four of the first six items were retweets. We were building a picture of someone's voice partly out of quotes from strangers.

Fixing it changed the profiles immediately and visibly. One account's profile went from a vague and partly invented history to correctly describing the writer as terse and aphoristic. Another's typical post length dropped from 589 characters to 202, because the long retweeted posts had been inflating it the whole time.

The lesson we took: when a filter has never rejected anything, that is not evidence the input is clean.

What we changed

Four changes, in the order they mattered.

  1. Measure the style instead of describing it. The scan now counts things: median and 75th-percentile post length, average words per sentence, how often the writer uses line breaks, lowercase openings, questions, numbers and emoji, and which words they reach for. If there are fewer than four samples we measure nothing rather than guess. A made-up metric is worse than an absent one.
  2. Put the voice where it cannot be outvoted. The profile now opens the prompt, in imperative form, above the niche and tone blocks, and is restated at the end. If there is no profile, the prompt is byte-for-byte what it was before.
  3. Stop the house voice from overwriting a real one. Each of our 48 niche engines carries its own voice section and a worked example of correct output. Good defaults when we know nothing about you; noise when we do. When a profile is present, those sections are now removed, along with a rule present in all 48 niches, NEVER start with "I", which directly contradicted every writer who narrates in first person. Domain knowledge stays. The prompt got about a third smaller.
  4. Give it the raw posts. A profile is a recipe. It shapes how something is said, but it does not decide what gets said. The scan was already fetching roughly fifteen real posts and then throwing them away. Now it hands them back and they go into the writing examples the model sees.

Where it actually got to

We are not going to claim we solved this.

After the first three changes, distinguishability went from unmatchable to two out of five, then to three out of five. Real progress, still short of the four-out-of-five bar we set.

The fourth change, raw posts in the prompt, produced the first divergence at the level of content rather than style. One output went fully lowercase and dropped question marks entirely. Another started using the writer's own products by name. Another built a completely different argument from the other four. Another reached for vocabulary that appeared nowhere in our prompts.

We also learned where it works less well, which matters more than where it works. The effect scales with how much concrete material an account has posted. An account writing 2.2k characters of abstract aphorism gives the model far less to hold onto than one writing 7.9k characters of specifics, projects, numbers, things that happened. If you write in aphorisms, the signal is genuinely weaker, and we would rather say that than pretend otherwise.

One convergence force survived everything: the model still likes to open by restating the topic. We removed the worked examples and it kept doing it. That is a habit of the underlying model, not of our prompt, and it is next on the list.

Why we are publishing a failed test

Because "sounds like you" is the claim the whole product rests on, and for a while the code was not delivering it. We would rather show the measurement than the marketing.

If you want to see where it currently lands on your own writing: scan your profile, or paste a handful of posts you have already written, and compare the output to something you wrote yourself. That comparison is the only benchmark that matters.

Try it on your own writing →

30 credits free, up to 100. No card.

Read next

What actually makes writing read like AI

It is rarely the vocabulary. Readers spot AI writing from structure, rhythm and a specific kind of empty confidence. Here are the tells we score every draft against, and how to remove them from your own writing.

Why your AI writing tool sounds the same in every niche

One prompt behind every topic is why a post about fundraising reads exactly like a post about marathon training. What we found when we split ours into 48 separate engines, including the mistake that made every user in a niche sound identical.