Opus 5: How to Fix Verbose Output
You might have noticed that Opus 5 is extremely eager to talk. It is like the uncle at the family party who always has an overly long, boring story about literally anything, and no request is too small to set one off. Ask said uncle for a one-line change and you'll get the long history of why the code needed changing, why he never spotted it sooner, how it was not his change in the first place, and how this whole thing reminds him of a story... which was the right call, mind you, and here is how you might approach the problem next time. Your CLAUDE.md has said Be concise. No preamble. near the top for a year. On 4.x it mostly listened. On 5 the line is still sitting there, in the same file, in the same position, and the model reads straight past it. I gave someone four paths for this in a Reddit thread. Here they are again, weakest lever first. CLAUDE.md instructions Write the rule down first. It is the obvious move and the weakest one. Be concise on its own barely registers, because it names nothing the model can act on. A rule that names the shape you want does better. Here is the one I use for reply verbosity, paste-ready for your own CLAUDE.md: ## Reply shape - Lead with the answer in the first sentence, before any table, list, or caveat. - Carry status, comparisons, and any multi-item result in a `table` or `bullet` list, never a prose paragraph. - Cap unbroken prose at two paragraphs; if a third starts, convert the run to a `bullet` list or `table`. - Give each item its own `bullet` row, not a clause buried across sentences. - Compose in this shape from the start; do not draft prose and reshape it afterward. One caveat to keep in mind: a short confirmation is already the answer. Done. or Yes, that works. should not get tabulated into a wall. The rule is about shape when there is something to shape. Even written this tightly, a CLAUDE.md line is advice, and it competes against everything else the model is holding. On Opus 5 there is more of that than there used to be. I went into why a line that worked on 4.x can go quiet on 5 in a separate piece, Opus 5: Delete your CLAUDE.md?: the model reaches for more of your rules at once and checks its own work by default, so even a sharp rule gets crowded out. Write the rule, but do not expect it to hold on its own. Output styles An output style is a step up, and the reason is where it lands. A CLAUDE.md file rides in as a user message after the system prompt; an output style modifies the system prompt itself, and Claude Code adds its instructions to the end of that prompt (per the output-styles docs). Same kind of instruction, but it travels through the session better. Being in the system prompt, it is not one more user-turn line competing with everything else you have said, and the docs note Claude Code re-reminds the model to follow the active style during the conversation, so the rule gets re-surfaced rather than decaying after one appearance. You can switch to a terser built-in style, or write your own. To turn the reply-shape rule from the last section into a style, save it at .claude/output-styles/reply-shape.md and give it a frontmatter header. The header is the part that makes it an output style rather than plain text: --- name: Reply shape description: "Answer-first, scannable replies; tables and bullets over prose walls" keep-coding-instructions: true --- ... the instructions from the first point ... The same five reply-shape lines from the last section go in the body below that header. keep-coding-instructions: true keeps Claude Code's built-in engineering behavior and changes only how it communicates. Then pick the style from /config under Output style. (The standalone /output-style command was removed; it lives under /config now.) It is read once at session start, so a change takes effect after /clear or a new session. Still instruction, so the model can still drift, but it drifts less than from a line buried in a file. A hook that gates the output The rule and the style are both instruction, and the model can weigh instruction and set it aside. A hook is different. It is a script the harness runs at a fixed moment, and it can refuse. That makes it the strongest of the three levers, and the one worth showing in full. Claude Code fires a Stop hook the moment the model finishes a turn, and hands the hook the finished reply on stdin as last_assistant_message, so it can read what was just written. If the reply runs long, exit 2 blocks the stop and sends a line back to the model telling it to answer again, shorter. Drop this in .claude/hooks/gate-length.sh and make it executable: #!/usr/bin/env bash # Stop hook: if the reply ran long, send it back once to tighten up. # The Stop event hands us the finished reply on stdin. reply="$(jq -r '.last_assistant_message // ""')" # Your bar. Word count here; a line count or a preamble check works the same way. limit=180 words="$(printf '%s' "$reply" | wc -w | tr -d ' ')" if [ "$words" -gt "$limit" ]; then # Exit 2 blocks the stop; this line goes back to the model as its instruction. echo "Your reply ran ${words} words; the budget is ${limit}. Rewrite it under ${limit} words: put the answer in the first sentence, then cut the preamble, the recap, and the summary of what you did." >&2 exit 2 fi exit 0 Then wire it in .claude/settings.json. A Stop hook takes no matcher: { "hooks": { "Stop": [ { "hooks": [ { "type": "command", "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/gate-length.sh" } ] } ] } } Change limit, or swap the word count for a line count or a grep for opening filler. It cannot loop forever: Claude Code caps a Stop hook at five consecutive blocks with no tool call between them, then lets the turn end. We run a version of this on our own agents. The system that writes and reviews the Reporails codebase has a Stop-boundary check that reads each reply and sends it back when it runs too verbose or breaks format. It fired on the drafts of this article more than once. Custom plugins By now you have three levers: a rule, a style, and a hook. A plugin is how you stop rebuilding them. It bundles any of the three so the setup travels with you across projects instead of getting re-pasted into each repo, and a Claude Code plugin can carry hooks, output styles, and rules together. It adds no strength of its own; the job is portability. To make one, drop a .claude-plugin/plugin.json manifest next to your hooks/ and rules, test it with claude --plugin-dir ./your-plugin, then install it, yours or someone else's, from a marketplace with /plugin install. Anthropic's plugins docs carry the manifest fields and the marketplace steps. Which one to reach for Reach for the least you can get away with. A CLAUDE.md rule for the parts a human reads too. An output style when you want the model leaning terser by default. The hook when you want a floor on length the model cannot talk its way past. A plugin once you are tired of setting those up again in every repo. The three levers are one move underneath: they decide what the model is holding when it answers, and whether anything checks the answer after it lands. The plugin only carries them. Reply length is the version of that you notice first. The harder version is which of your rules the model actually follows once you have written a hundred of them that quietly disagree, and that one is worth its own piece. It is the one I am writing next. I work on Reporails, deterministic diagnostics and governance for the instruction files, rules, and prompts that steer coding agents. It reads the steering surface you wrote down and diagnoses why your steering drifts, with measured evidence: which instructions couple to behavior, which name nothing the model can bind to, and where two rules cannot both hold. It does not run your model, and it does not vote; it measures the file.
This is a summary aggregated from Dev.to. Read the complete article on the original site:
Read full article at Dev.to