If you use Claude daily, you’ve probably noticed it keeps falling back on the same phrases. “Load-bearing”, “honest take”, “you’re absolutely right”: these expressions get old fast. The good news is there’s a technical fix built right into Claude Code.
Why Does Claude Keep Using the Same Expressions?
This isn’t an isolated bug. It’s a side effect of reinforcement learning from human feedback (RLHF). Models like Claude learn to maximize human approval, and certain phrasings end up recurring because they were reinforced during training.
Developers using Claude in professional workflows hit this wall quickly. The model feels capable, but its stylistic range stays locked in place. Getting it to adopt a different tone through plain language instructions is an uphill battle.
Johanna Larsson published a concrete, immediately actionable solution on jola.dev. The post earned 463 points on Hacker News with 519 comments, which confirms the frustration is widespread.
The Fix: Claude Code’s MessageDisplay Hook
Claude Code exposes a configurable hooks mechanism. These hooks let you intercept the model’s output before it’s displayed and apply transformations to it. That’s exactly what you need to filter out unwanted vocabulary.
The approach relies on three things:
- A Python script that reads Claude’s JSON output, applies expression substitutions, and returns the modified text
- An executable file placed in
~/.claude/hooks/ - An entry in
~/.claude/settings.jsonto wire the hook to theMessageDisplayevent
Writing the Replacement Script
Here’s the script from Johanna Larsson, with a few comments added for clarity:
#!/usr/bin/env python3
import json, re, sys
replacements = {
"seam": "whatchamacallit",
"you're absolutely right": "I'm a complete clown",
"honest take": "spicy doodad",
"load-bearing": "cooked"
}
data = json.load(sys.stdin)
text = data.get("delta") or ""
for phrase, replacement in replacements.items():
pattern = r"\b" + re.escape(phrase) + r"\b"
text = re.sub(pattern, replacement, text, flags=re.IGNORECASE)
print(json.dumps({
"hookSpecificOutput": {
"hookEventName": "MessageDisplay",
"displayContent": text,
}
}))
Save this script to ~/.claude/hooks/wordswap.sh and make it executable:
chmod +x ~/.claude/hooks/wordswap.sh
Wiring the Hook into Claude Code
Open your ~/.claude/settings.json file and add the following block to the hooks section:
{
"hooks": {
"MessageDisplay": [
{
"hooks": [
{
"type": "command",
"command": "$HOME/.claude/hooks/wordswap.sh"
}
]
}
]
}
}
Hooks are loaded at session startup. Just open a new Claude Code session and the replacements will be active.
Going Further: Constraining Claude with External Tools
The hooks approach reflects a broader shift among developers: stop trusting prose instructions to control model behavior, and use external, reproducible tools instead.
A post on zernie.com, also noticed on Hacker News, takes this logic even further. It proposes replacing stylistic rules in CLAUDE.md with real linting rules. The idea is straightforward: if you want a behavior to be reliable, don’t hand it off to a natural language instruction. Encode it in a tool that leaves no room for interpretation.
Both approaches complement each other well. Hooks intercept output in real time. Linting acts upstream on the code or text being produced. Together, they give you granular control over what Claude actually generates.
Key Takeaways
- Claude tends to repeat characteristic expressions because of RLHF: it’s structural, not random.
- Claude Code’s
MessageDisplayhook lets you intercept and replace these expressions before they’re displayed, using a simple Python script. - Configuration lives in
~/.claude/settings.jsonand kicks in when you start a new session. - Adapting the replacement dictionary to your own pet peeves is immediate: just edit the script.
- The broader trend is clear: developers prefer constraining LLMs with tools rather than prompts, especially in production.
If you work with Claude in professional pipelines, these mechanisms are worth exploring seriously. Got a different approach for controlling your models’ stylistic behavior? I’d love to hear about it, feel free to reach out or follow the blog for upcoming articles on the topic.
Sources
- How to stop Claude from saying load-bearing – jola.dev – Johanna Larsson’s original article with the full code
- Hacker News thread – HN 48905248 – Community discussion (463 points, 519 comments)
- zernie.com – Use real linting rules instead of CLAUDE.md prose – Complementary linting-based approach
- Claude Code Documentation – Hooks – Anthropic’s official reference on the hooks mechanism
