Distill a writing voice into a reusable agent skill — a system prompt that makes an LLM write like a specific author or persona on any topic. No fine-tuning, no gradients, no model of its own. Just measurement and a prompt.
Point your agent at ~2–8k words of someone's writing. It fingerprints the voice, writes the skill, checks its own work against the corpus, and — if you want — installs the skill into your agent for future sessions. It asks first.
A voice is not a word list. It's a distribution over structure: how long sentences run, how often they repeat, which function words and punctuation recur, and — the part most imitations miss — the rhetorical moves the writer keeps performing. Authorship attribution identifies writers almost entirely from these structural statistics, not from topic words. So if you can measure them and write explicit instructions to reproduce them, a prompt can carry a voice.
Mimic fingerprints in two layers:
- L1 — the distribution the writer can't help. Function-word rates, punctuation, sentence
rhythm, lexical richness. Measured by
stylometry.py. This gets you the rightshape . - L2 — the moves the writer performs. The agent reads the corpus closely and extractsperformable rhetorical moves — "a move is something the writerdoes , not a word they reach for": digress-and-snap-back, embedded mini-anecdote, vague-authority sourcing, the escalation ladder, ring composition. These are written into the skill as "deploy this" actions, and the model is told to perform 2–3 per passage. This is what separates voice from caricature.
Everything is driven by the skill. There's no distillation script — the agent does the
work by following skills/author-voice/SKILL.md:
- Corpus. Collect ~2–8k words of the author's own writing →
corpus.txt. - Measure (L1).
python3 skills/author-voice/scripts/stylometry.py corpus.txt— read off rhythm, richness, function words. - Analyze (L2). The agent reads 15–25 passages closely and extracts the moves, with real examples quoted from the corpus.
- Write the skill. Grounded in the numbers and the moves, following the template.
- Validate. Generate a few neutral prompts with the draft as system prompt, save to
SAMPLE.txt, and re-runstylometry.py corpus.txt SAMPLE.txt— it prints exactly what to push. Iterate two or three times. - Offer to install — asking first. On an explicit yes, the skill is copied to
~/.claude/skills/<author>-voice/SKILL.md. Never silently.
If you're using Claude Code, just drop this repo in and say "use the author-voice skill to mimic from this corpus."
From the worked Trump example — a fresh model, skill as system prompt vs. baseline:
| baseline | with skill | real corpus | |
|---|---|---|---|
| mean sentence length | 19 | 8 | ~11 |
| lexical richness (TTR) | 0.65 | 0.51 | 0.10 |
| cosine distance to the author | 1.11 | 0.85 | — |
It moves from orthogonal to clearly in-voice — capturing the short-punchy-repetitive structure a vocabulary list alone never would.
On the de-contaminated benchmark (6 authors × 4 tasks, scorer blind to which output is which), two measurements disagree in a telling way:
- Surface stylometry (
score.py: function words + rhythm + char-grams)cannot reliably tell the skill from plain "write as X" — both land far closer to the real voice than no-style, but neck-and-neck with each other (Elo ≈ skill 1047, plain 1066, no-style 887). A function-word metric is blind to the rhetoricalmoves the skill adds. - A blind LLM judge that actually reads the text — and so can see the moves — preferred the skill's output on24 of 24 items (24–0 over plain; no-style last every time).
That disagreement is the argument for L2: the moves are real, but only a measurement deep
enough to read them rewards them. Both results reproduce from the shipped data — see
bench/.
skills/author-voice/ the meta-skill — the agent reads this to distill a voice
SKILL.md the full method (measure → analyze → write → validate → install)
scripts/stylometry.py the L1 measurement instrument the skill invokes (stdlib only)
examples/ real distilled voice skills + the benchmark dataset
trump.md hemingway.md poe.md austen.md shakespeare.md obama.md paulgraham.md
bench/ verify a skill actually matches the voice (de-contaminated)
score.py model-free stylometric Elo
build_judge.py blind X/Y/Z set for an LLM judge
stylo.py measurement library (Delta, rhythm, function words)
Mimic is for style, not deception. Imitate public figures, authors, your own writing, or a persona you have permission to use. Don't impersonate a private individual, and don't use a voice skill to pass off generated text as genuinely theirs. The install step always asks before touching your agent's skills directory.
No dependencies — Python 3 stdlib only. MIT licensed.