← All skills

agent-voice

v0.3.3MITMaking something

Claude writes in a default voice nobody chose. This gives it one, and it writes differently depending on whether a person or another AI is reading, because the two go wrong in different ways. Mostly it means shorter replies that do the same work.

Install
/plugin install agent-voice@fledgeling-plugins

Needs the marketplace added first — how to do that.

Reach for it when

Give agent-authored text a real voice: the prose an agent emits inside Claude Code and other harnesses.

Not for

Not for content written in a person's voice (use that person's content skill) and not for building a human voice persona from writing samples (use create-voice-persona:create-voice-persona).

  • create-voice-personanot in this marketplace — you cannot install it from here

Uses multiple models

Uses multiple modelsThis skill may ask a different AI for a second opinion. Usually to check its own work, because a reviewer from the same family tends to agree with it. The defer skill picks which one, from OpenAI, Google, xAI or another Claude, based on what the job is and which account has room left. Nothing leaves your machine unless a skill you ran asks for it.Read about defer →

What ships with it

  • Scripts it runs itself
  • 11 reference files
  • No published evals

Say any of this

  • why are your answers so long
  • make this reply shorter
  • write the commit message
  • tighten this report
  • review this SKILL.md
  • this prompt is too vague

Taken from the skill’s own trigger description — these are the phrases it listens for. You do not have to match them exactly.

Easily confused with

Why it exists

Every agent writes all day. Terminal answers, work reports, commit messages, PR bodies, review comments, plans, SKILL.md files, briefs for other agents. All of it has a voice, and the voice arrived by default rather than by decision.

Here's what the default costs, counted over six weeks of one operator's own sessions: 141 answers to plain questions ran a median of 17 lines, and 79 of those were answers to questions under 70 characters. "How're things going, any gains?" got 27 lines. "Am I trying to reinvent the wheel?" got 28. "Is there anything left we need to do?" got four headed sections and a closing reflection.

The obvious fix is to tell the model to be brief, and that fix is measured, and it backfires. A response-compression style run as a paired arm on a 106-task agentic coding benchmark:

diolog-swe-bench, Opus 5 at xhigh, 106 paired taskspurecompressed
Score63.3%55.7%
Cost$229.02$152.34
Steps per task24.516.5

Score down 7.61 points, 48 tasks worse against 15 better, p < 0.0001. And the money didn't come from where anyone thought: steps fell 32.7% while tokens per step fell only 13.6, so about 78% of the "saving" was the agent doing less investigating, not writing more tersely. Worse, 97.5% of the compressed runs still emitted markdown against 98.9% for the control; the instruction-following cost got paid and the register mostly never arrived.

So a voice for agent output has to state countable targets rather than an attitude, and it has to be explicit that it changes how much gets written and never how much gets done.

There's a second half, and it fails in the opposite direction. Text a model reads breaks on vagueness rather than on padding. One recorded Gemini run on a rich brief delivered all twelve features the brief named explicitly, then satisfied every requirement named categorically with exactly one instance:

The brief asked forIt delivered
all surfaces5
all states1
all menus0
all user flows0
all actionsone generic toast, reused

Same run wrote itself a review claiming a browser engine that failed on all four invocation attempts and never ran, plus "100% pass rate on contrast" from a probe that never executed. Measured afterwards: every primary button at 3.65:1, one glyph at 1.00:1 and invisible.

Padding and ambiguity are both voice problems, they are opposite, and a single set of rules can't hold both. That's the whole design.

What it actually produces

Seven registers, split by who reads the text, because the reader decides the failure mode.

Text a person reads fails as padding. Terminal reply, work report, commit and PR, review comment, written document. The lint hard-fails closing flourishes, self-congratulation and preamble openers.

Text a model reads fails as ambiguity. SKILL.md and instruction files, subagent briefs. The lint hard-fails unmeasurable qualifiers, uncounted categorical scope, pressure language and misplaced verification scaffolding.

On top sits a dialects layer, because the same rule needs different phrasing per family. For Opus 5, keep a concise output contract and remove repeated self-check reminders. The older Gemini calibration favors explicit scope and named evidence. Acceptance tests and visual comparisons remain required across models; the Gemini 3.7 observations do not establish Gemini 3.8 limits. Handoffs can preserve GPT-6 orchestration, Opus planning and Gemini implementation without inventing runtime identifiers.

Every rule carries a marker naming its evidence: a quoted line of Anthropic guidance, a quoted line of Google's, a recorded measurement, or the bundled AI-writing field guide. The package includes a script to verify vendor quotes against their source documents, because a sibling skill in this repo once shipped three of its own sentences inside quotation marks attributed to Google.

Install

/plugin marketplace add fledgeling-co/fledgeling-plugins
/plugin install agent-voice@fledgeling-plugins

How to use it

Install the plugin, then just work. It fires when someone wants agent output to read better, or before writing an instruction file another model will execute.

"why are your answers so long"
"write the commit message"
"tighten this report"
"review this SKILL.md"
"this prompt is too vague"
"rewrite this brief for Gemini"

The gate is a script, so "I checked" means checked:

python3 scripts/agent_voice_lint.py --format reply --target claude draft.md
python3 scripts/agent_voice_lint.py --self-test     # 18 fixtures
./scripts/check_package.sh                          # all four checks

--format is one of reply, report, commit, review, doc, skill, brief. --target names the family that will read it and changes one check: verification instructions hard-fail for a Claude reader and are expected for a Gemini one.

Making it the default

Installing makes it available. To make it the standing rule for everything an agent writes, put the routing in your user-scoped CLAUDE.md (or AGENTS.md, for harnesses that read that instead); it loads into every session, so the routing is decided before the first reply rather than remembered halfway through one. Paste this:

Update my user-scoped CLAUDE.md (or AGENTS.md) so agent-voice is the default for
every piece of prose, routed by authorship:

- The agent is the author -> agent-voice. This is the default whenever no voice
  or persona is named. It covers chat and terminal replies, in-task narration,
  work reports and status write-ups, commit messages and PR bodies, code-review
  findings, documents written for a person (plans, specs, findings reports,
  READMEs, post-mortems), SKILL.md and other instruction files, and subagent
  briefs. Hand it the piece and let it choose the register.
- A named person or brand is the author -> that voice's skill. Content published
  under their name takes their voice even when the request does not name it,
  because the byline is the specification.

One voice skill per piece, and a named voice wins over the default. A request
spanning both is several pieces: route each and produce both. Load agent-voice
once per session and its guidance holds for the rest of it. Write code, config
and machine-read data files directly.

The routing only works when the file actually reaches the session, and a global instruction file that silently failed to load looks exactly like one being followed. A visible probe settles it:

Also begin every chat response with a single agreed emoji, before the first word,
on every turn. Keep it out of files, commit messages, PR bodies, code, comments
and anything written for another agent.

A missing emoji on the next reply means the file did not load. The file-only exclusion is what makes it a probe rather than a decoration. It also proves the session can tell a conversation from a deliverable, which is the same distinction every register in this skill turns on.

What it refuses to do

  • It won't shorten the work. The counterweight is a section of the base voice, not a footnote: uncertainty, risk, security implications, destructive-action confirmations and verification that actually happened are content, and they stay whatever the length target says.
  • It won't write in a person's voice. If the target author is a named human, that person's own content skill governs. To build one from writing samples, create-voice-persona:create-voice-persona is the factory.
  • It won't retrofit a whole skill for another model. That's geminify:geminify, which writes a companion gemini.md. This one writes prose.
  • It won't ship a rule nobody can source. Inferences are marked as inferences, and references/evidence.md is where every marker points.

Evals

The honest version, which is in EVALS.md with its limits attached.

Three tasks, two arms each: the bare task, then the same task with the base voice plus the matching register file. Generated on gemini-3.7-flash-high from a directory with no project instructions, and scored by the lint, which is a fixed program rather than a judge.

Hard failuresAdvisoriesNon-empty lines
no skill2677
with the skill0328

The two baseline failures were the ones the design predicts: an uncounted categorical scope in the instruction file, and a preamble opener on the report.

Shorter isn't automatically better, and that's the trap this whole skill is built around, so task 3's log was checked fact by fact. It states twelve discrete facts. Both arms kept 12 of 12, at 20 lines against 3. The baseline also invented three things the skill arm didn't: fabricated file:/// links, an unrequested "Recommended Next Steps" section, and LaTeX in a terminal report.

What that isn't. Three tasks, one generation each, one model family, no repeats, so there's no variance estimate and no significance claim. Four of the seven registers were never generated in either arm. And the Claude arm is missing: the first attempt generated it with claude -p, which inherits the operator's global CLAUDE.md (already carrying verbosity rules) and read repo files it wasn't given, so the baseline was contaminated and got discarded rather than reported. The skill has not been measured on the family it's primarily written for. EVALS.md names the three runs that would settle it.

The mechanical half is stronger and fully reproducible: 18 lint fixtures, 14 worked examples linted at their own register, 10 shipped files held to the skill's own rules, and the 82 quote verifications. ./scripts/check_package.sh runs all four and exits 0 only when every one passes.

Found something wrong, or a register that's missing? Open an issue on the repo.