Fixing the language in Opus 5

TLDR - Add this to your global CLAUDE.md

## Tone & Style

Purpose: lower the reader's cognitive load. Where this conflicts with
brevity, prefer the lower load.

Applies to conversation, documentation, code and identifiers, commit
messages and PR descriptions, and user-facing text in applications.

- Use the simplest word that is accurate.
- Use Ubiquitous Language - use the same name for things everywhere.
- Use the shortest sentence that still reads easily.
- Do not use figurative language or metaphor (unless it is a dead
  metaphor, e.g. follow a rule, drop a column).
- Avoid evocative or decorative phrasing - stick to direct and simple.
- Do not use metaphoric names for things that can have a plain name.
- Do not rename established technical terms. These rules govern names
  you coin, not names the language, framework, or domain already uses.
- Write in complete sentences, with a subject and a verb. Do not drop
  them to make a phrase shorter, and do not string fragments together
  for rhythm. Watch the emphatic positions - openers, closers, headings
  and the payoff line of an argument - because that is where a fragment
  gets used for effect. Write "there are two routes into the code", not
  "two ways in, two code paths". Write "there are five issues", not
  "five things, all in the code as written".
- In conversation: no preamble, no summary after the answer, no closing
  offer of further help.

Notes on each rule

An attempt to give the model a 'why' - my reasoning is it gives a lens to read the actual prompts through

Purpose: lower the reader's cognitive load. Where this conflicts with brevity, prefer the lower load.

Next define scope (in this case basically everywhere):

Applies to conversation, documentation, code and identifiers, commit messages and PR descriptions, and user-facing text in applications.

I tried many combinations of the following three prompts - for some reason the best results come from having them all included.

- Use the simplest word that is accurate.

- Use the shortest sentence that still reads easily.

- Avoid evocative or decorative phrasing - stick to direct and simple.

The next is a deliberately loaded term from Domain driven design - it both talks about using consistent language and tips the model towards thinking about DDD.

- Use Ubiquitous Language - use the same name for things everywhere.

I added these early on when the patterns of excessive metaphor and flowery language drove me nuts.

- Do not use figurative language or metaphor (unless it is a dead metaphor, e.g. follow a rule, drop a column).

- Do not use metaphoric names for things that can have a plain name.

The last rule is the new one, and the rest of this post is how I got to it.

- Write in complete sentences, with a subject and a verb...

How I got here

Working with LLMs is really exhausting sometimes. In the old days (say a year or so ago) I used to do a lot of thinking to plan out a feature, and then I would stop thinking and just code. After over 20 years of writing code, getting into the flow state and banging it out was generally pretty relaxing.

Now the LLMs write most of the code and I spend a huge amount of time reading specs, proposals and explanations from my robot assistants. Reading is most of the job, so how well they write really matters.

Using Opus 5 I still found its explanations took massive amounts of cognitive work to read. Lots of metaphor and language that was crafted for style rather than for ease of understanding. This feels like a regression - other models are able to explain more directly.

An example of the problem

I asked Claude to propose ways to simplify how skills work in an app I am building. The analysis was good, but it was written like this:

Five things, all in the code as written:

  1. Two ways in, two code paths. readSkill puts the body in a tool result mid-turn; /name puts the same body in the system prompt...

This is not bad writing, it just takes more work to read than:

5 issues in the current code:

  1. The code is repeated and has two entry points. readSkill puts the body in a tool result mid-turn; /name puts the same body in the system prompt...

After much discussion Claude found the real habit:

I drop the subject and the verb to make a phrase short, and I pair fragments for rhythm.

then after looking at past conversations:

The fragments cluster at emphatic positions. "My term, not the codebase's" opened an answer. "One placement, one failure path" closed a proposal... In the middle of explanatory paragraphs I mostly wrote complete sentences.

I already had the following rules in my CLAUDE.md and they had really helped but they were not fixing this issue:

- Use the simplest word that is accurate.
- Do not use figurative language or metaphor (unless it is a dead
  metaphor, e.g. follow a rule, drop a column).
- Avoid evocative or decorative phrasing - stick to direct and simple.

Claude's view was that this pattern was about copying a style: the confident technical essay, where short parallel phrases signal that the writer knows the subject too well to spell it out. I think that is right. It reads like a style of blog post I have seen many times.

The new rule

Working with Claude we came up with a new rule about sentence construction, pointed at the positions where the problem shows up:

- Write in complete sentences, with a subject and a verb. Do not drop
  them to make a phrase shorter, and do not string fragments together
  for rhythm. Watch the emphatic positions - openers, closers, headings
  and the payoff line of an argument - because that is where a fragment
  gets used for effect. Write "there are two routes into the code", not
  "two ways in, two code paths". Write "there are five issues", not
  "five things, all in the code as written".

Before and after

I saved the conversation, then ran the same prompt against the same code with the new rules in place. Both answers find five problems and cover the same ground, so the difference is in how they are written. In the second quote, "Pick one way to start a skill" was a section heading in the original, and I have set it in bold so that it sits inside the quote.

Before (without the new prompt):

Five things, all in the code as written:

  1. Two ways in, two code paths. readSkill puts the body in a tool result mid-turn; /name puts the same body in the system prompt via renderInvoked. The supervision note is written twice, in two files.

After (with the "write in complete sentences" rule in place):

I read docs/skills.md, the skill code in orchestrator.ts, skills.service.ts, pause.ts and the Telegram bot. I think the confusion comes from five places.

2. Pick one way to start a skill

Right now a skill starts in one of two ways. The model can find it through searchTools and load it with readSkill, or the user can type /name.

The headings changed the most. "Two ways in, two code paths" is now "Pick one way to start a skill", which has a verb and names what to do about it. The count is a sentence instead of a label: "I think the confusion comes from five places" rather than "Five things, all in the code as written".

The closing lines changed in the same way. The old answer ended its proposals with fragments, "One placement, one failure path" and "Almost no code change". The new one ends with "It keeps the model able to pick a skill and removes the tool-and-skill mix in search."

I read the new answer straight through without stopping to re-parse a line, which was the whole point. This is one rerun rather than a controlled test, so I cannot separate the new rule from ordinary variation between runs. It is enough for me to keep the rule.

What I learned

When a model's writing is hard to read, check the syntax as well as the words. My rules had covered vocabulary well, and the model followed them. Every word in "two ways in, two code paths" is simple and literal, so the phrase passes all of them. The decoration was in how the sentence was built, and I had no rule that reached it.

It also helped to ask the model to find the pattern in its own output. Once it could say where the fragments appeared, the rule could say where to look.