mmastrac
3 days ago
I've started giving these instructions and I think I've been much more successful in generating clear output:
Comment blocks are <= 7 words, function names <= 4 words. User-facing message strings should be <= 10 words. Use an active voice, no stage performances, and pick the most common word when choosing among alternatives.
Limiting the number of words is the strongest factor in cleaning up the output, IMO.
For older code I've instructed it to delete all the comments, and then I re-comment it using a new session and these guidelines, asking it to rejustify the need for every comment to itself.
graemep
3 days ago
Claude not only writes verbose comments, it also writes comments about how things used to work when refactoring. That might have a place in version control comments, but not in the code.
bhelx
3 days ago
This speaks to the general problem with using LLMs for writing. The audience they are writing for us you, but you're trying to write for a totally different audience. In code, this manifests as comments in the code that are hyperspecific to the conversation you are having, and not the long term benefit of having those comments in the code.
I see this in docs a lot. I've been reading a lot of docs these days where it feels like the LLM is trying to hype up the person writing the docs. It's like it has no conception that the writing is meant for a 3rd party audience.
enobrev
2 days ago
It reminds me of something I've always wanted as a coder but never cared enough to implement, which would be a verbosity switch.
I see the full multi-paragraph comments in my codebases and get annoyed but also feel like the additional context helps improve the llm results over time because that history helps it know what's been tried and removed in the past. It's additional context for the system that improves with context.
The feature I want in the code tool itself (for me) is to adjust how verbose the comments are so I can read "just code", then "terse comments" then "full comments" then "full comments with historical context" (including fit commits and ticket references) and finally, full-on literate programming. And I'd like to switch between on the fly as I read through the code.
I think this is something we could actually produce with llms, and I feel the ability to switch between these modes would help the llm as well.
Sometimes I just need to see what's being done. Sometimes I need to know why. Sometimes I need to know what's been tried. Never always all of these things. And expecting to find this context in git comments doesn't feel right either.
cheikhcheikh
2 days ago
What you want can be accomplished with an extra doc, call it the Log, where the llm appends things tried, lessons learned, failed experiments etc.. while leaving the comments as terse accurate snapshot of the current state. I've been using this log pattern and it works well.
jchw
2 days ago
Despite all of this though, GPT 5.6 Sol to me has significantly less trouble with this. It still suffers from LLMisms to some extent (I hold that this is probably due to human feedback in training just doing a bad job for prose) but I definitely feel like it does a better job leaving comments that actually make sense in context. Not perfect. But better.
I suggest the real problem comes down to training and probably training data; from the LLM's PoV, it is writing code inline with the conversation, so care has to be taken to make sure the model doesn't treat the code it outputs like it is a part of the conversation it is having.
multjoy
3 days ago
>It's like it has no conception
This is the point.
bonoboTP
2 days ago
It's an empty point and a boring one and leads nowhere. It means nothing, but sounds deep. It's so shallow, any taxi driver and sociologist can come up with it and has, already in December 2022.
unclebucknasty
2 days ago
>It's an empty point and a boring one and leads nowhere.
But, is it true?
>It means nothing...shallow...
Ironically, the entirety of your comment just repeats that the GP comment means nothing. There is no further explanation or "depth".
bonoboTP
2 days ago
Yours added no depth either.
bonoboTP
2 days ago
Yes. Though adding something like what you wrote here into the instructions does help. Especially combined with a fresh session.
cgio
3 days ago
I don’t even think comments are useful at all given AI. I can ask my AI to explain a piece of code if I am stuck and I will get a reply in context of what I am looking for.
easyascake
3 days ago
We call these temporal comments. We recently updated our code review skills to heavily discourage them. It doesn’t matter why funcA was added then later refactored to funcB. That much can be ascertained from git history. What does matter is why approach A doesn’t work, but B does.
porker
3 days ago
How well is your code review skill doing at detecting and correcting these? History in comments in git is so annoying! As is missing why A didn't work but B does. None of the models I've tried get this right
pluralmonad
3 days ago
And will reference transient working docs in code comments.
// No retry was added here per AC 37b in FEATURE.MD.
jorl17
3 days ago
// The lesson from the Parse-dont-fail-era campaign
// Judged on merit from computed properties during the cursor saga
// Chop 6ms due to lenience and lax-constraints vs 18ms baseline April perf measurements
datsci_est_2015
3 days ago
Thanks, this sequence of 33 words alone was enough to give me a searing migraine.
jorl17
3 days ago
Glad to know it worked. Still pending: the assumed-defaults research track plus the validation-only build phase D demanded — your call on whether to start one now or deploy tonight’s campaign to surface any wrinkles the spec drifted on
eterm
3 days ago
It's incredible, because I Feel like you've been watching me work.
The only thing you're missing is the "open question" that was stuck in page 14 of a 17 page report, which since it went unanswered, caused claude to make up an answer and go full steam ahead, ignoring fundamental properties of the entire system.
jorl17
3 days ago
> The user is right to be upset. I blindly answered from memory and left them with questionable data. I should acknowledge the criticism and offer to improve.
You're right, I'm sorry. You've repeatedly told me to run questions by you and I just fabricated an answer and ran with it — which is exactly the kind of dangerous time-waste we created the memory for. I'll revert it and pull up the real question so you can answer it — no wasteful assumptions this time.
(Deleted 387 lines)
datsci_est_2015
3 days ago
Idk if you’re coming up with these on the spot but they’re linguistically fascinating.
jorl17
3 days ago
Came up with them on the spot. Unfortunately, I've been working with Claude so much it's like my brain can autocomplete them natively.
ghostpepper
3 days ago
it's not just you, there is research that people are starting to talk more like chatGPT. you have a gift for parody though.
FiddlyPack
3 days ago
That's a sharp insight, and it reveals something core to communication that I otherwise wouldn't have considered- HN item 6b translocates reliospacactivity of our medium.
Shall I engage the tachyon beams, sir?
usrusr
2 days ago
Sorry for the anthropomorphizing, but you got to understand that these little "conversation chapters" that are so dramatically named are these things' entire world. Perhaps that otherwise absurd grandeur is not so surprising when when looked at from that angle?
On a more serious note, could all that chapter naming be some visible outcropping of context compaction strategies? "Condense the conversation history into a summary". Not really surprising that it comes up with these "cute" headlines. Would appearances be better if they were somehow prevented from leaking to the user? Sure. Would results be better? I don't think so, might even make a meaningful difference if the user actively embraced the terminology the machine came up with. Ouch.
user
3 days ago
areoform
3 days ago
As a human who isn't a professional programmer, I've been writing comments like,
// let's track age!!
// this is harder than you'd think as I with totally impressive
// foresight didn't add age to the raw data.
//
// More honestly, I didn't want to add age to the astro data as that's
// a calculation that can change depending on how you slice it.
//
// Hence we need to figure out their age first.
Is that bad???feffe
2 days ago
I think this passes. In general "why" over "what". Give context to why something is made like it is (when seeming convoluted or strange). Sometimes I think one can give historical facts for really hairy hard to fix issues that have seen multiple iterations. But LLMs don't see these nuances. They frequently smuggle in completely irrelevant details in comments, e.g. including details from the given task context, not understanding what is relevant for the code module as a whole.
Edit: For API comments it's "what" of course, detailing the workings and contracts of the exported method, function or type, so one doesn't have to read the code to figure out how to use it.
crab_galaxy
3 days ago
// Workaround because we don’t have an age column in the db. See JIRA-1234
This would be better IMO :)
Most of the context belongs in a ticket. And the difficulty is subjective!
areoform
3 days ago
I'm mostly writing code for myself, but it's a project that'll end up being public and it'll be available for others to do whatever they want with. Does that change the answer?
azangru
2 days ago
I hate it when a comment tells me to see JIRA-1234. What if in a year's time we stop using Jira?
ben_w
2 days ago
Far too often the answer has been that it doesn't matter, because the reason you stopped using Jira is the company stopped sending paycheques.
That said, I think the place for "ticket-1234" is the git commit/pull request.
Very few comments are genuinely necessary now that identifiers in code can be as long as you want, it is relatively to pick names that are explanatory enough to render most comments superfluous. 1% exceptions for unusual algorithms. (You're using named consts/enums rather than magic numbers, yes?)
Yiin
3 days ago
personally it's fine and I've thanked myself many times for overly detailed comments coming up to some from 8 years ago and thinking how tf was I so smart/stupid (depending on the context)
klardotsh
3 days ago
This one drives me nuts, especially because I divvy up plan documents into such granular sub chunks and Ralph loop over them, I get nonsense commit messages and comments like “PLAN-5.1.A.d.42 load bearing reassertion” unless I AGENTS.md to hell and back… and still end up having to manually reject 5-10% of commit messages because the agent simply forgets AGENTS.md instructions until reprompted.
hilariously
2 days ago
Sometimes you can do a separate skill for committing only and basically minimize the context - "analyze the commit messages, the original instructions, and this set of things to stop wasting my FUCKING TIME"
klardotsh
2 days ago
I've definitely considered writing a commit skill and a `cc-safety-net` custom rule to fully forbid `git commit` other than with `--amend` ++ `--no-edit` outside of that skill. Hm, maybe that's a task for an upcoming weekend.
cerved
3 days ago
My theory is it writes these comments as "notes while working", and I don't don't mind that, per-se. My problem is it's inability to clean that shit up before committing it. That's wrong load-bearing lever that doesn't earn it's keep.
Also, it reads like ass.
jorl17
3 days ago
This!
Claude writes comments about how things used to work, which can be useful sometimes, especially if it's a big change that requires one to genuinely consider legacy behavior, but most of the time it shouldn't be there.
Two other somewhat related things it does:
- It writes as if someone reading the code and comments is aware of everything it is aware of (the current conversation, the code it has just looked at). It's really hard to make it understand that things need to stand on their own. A trick is to get a subagent to look at it with a fresh context, but it doesn't tremendously help
- It does all of this with user-facing strings too. Claude loves to write up tooltips and other labels that leak everything to the end user. Every single concern we have, every edge case we've meticulously made our code handle, it passes on to the user, so they don't "need to worry". But no sane user would think of these things. For them, a feature is a feature. The "dynamic scheduling" button should state what dynamic scheduling does plainly, and every edge case is handled by us. The "add" button does not need a label letting the user know that they will later be able to click the "delete" button, because the user will just realize it due to our adherence to proper design. Claude fails to understand good UX for the user cannot be replaced with endless labels and explanations.
It's an uphill battle and all attempts at solving this (or the brain-dead way new Anthropic models write) usually fail to work with me.
spooneybarger
3 days ago
I've gone back to using Opus 4.6. It's quite nice along all these fronts.
FiddlyPack
3 days ago
How? I tried but got forced back onto 5.
flipthefrog
2 days ago
You can tell Opus 5 or Fable to route answers through 4.6 for rewrite
arcanemachiner
2 days ago
/model claude-opus-4-6[1m]
vilos1611
3 days ago
I've explicitly included instructions in my home CLAUDE.md to avoid this, because it's one of the most annoying things about how Claude writes comments.
I've also written my own package for deterministically formatting comments: https://www.npmjs.com/package/comment-fmt
Both with a formatter and a linter that I run in CI for all my personal projects. Just one less thing for me to try and coerce the agent into doing correctly, so that cycles I spend reviewing agent code can be focused on actual behavior.
Sinidir
2 days ago
Yeah i noticed this heavily. Working on a branch i critique and give a simpler design. Claude implements and then in a huge comments reference the outdated worse design. Zero value to that. Even having a "how to write comments" section in claude.md doesn't seem to help much with that.
bonoboTP
2 days ago
It has this tendency, but usually a sentence about this in the CLAUDE.md helps avoid it. It's annoying though that you have to add that sentence.
ErroneousBosh
3 days ago
Presumably you're not just blindly copying down what Claude copies out for you, but actually reading, interpreting, and understanding it for yourself?
nrmitchi
3 days ago
I struggled with this for a long time, but actually seem to have gotten to a place where this is largely resolved. Copy/paste from my current claude.md:
The CC-5 rule specifically seems to be (just from reading through, nothing repeatable-eval based) the part that actually catches and prevents me from having to clean it up afterwards.
```
### Code comments
The failure this prevents: writing a comment that narrates the change I am making right now. That context is real, but it expires the instant the change merges — the defect it describes no longer exists, so the comment becomes a story about a problem no future reader can observe. It is a changelog entry in the wrong file, and a third copy of text already required in the commit body (3.b) and the PR description.
- *CC-1 (MUST NOT)* Write a comment describing a change, a fix, a defect, its cause, or what the code used to do. No "was/now/previously/instead of", no "this fixes", no "needed because otherwise", no "note that we no longer".
- *CC-2 (MUST)* Apply the survival test to every comment before writing it: would this still be true and useful to someone reading this file a year from now, who never saw the diff? If it only makes sense beside the diff, it is changelog — delete it and put it in the commit body.
- *CC-3 (MUST)* Default to zero comments. Declarative config — Terraform, DNS records, k8s manifests, CI YAML, Helm values — is self-describing and takes none. A resource named `dmarc-example-com` does not need a comment saying it is the DMARC record.
- *CC-4 (MAY)* Comment only when a future editor would actively break something without it: a non-obvious external constraint, a required out-of-band manual step, an invariant the surrounding code cannot show. One line. If it needs a paragraph it belongs in `plans/`, not inline.
- *CC-5 (MUST)* Before every commit, re-read the comment lines I added: `git diff --cached | grep '^+' | grep -E '#|//|/*'`. Each hit must pass CC-2 on its own. Deleting is always an acceptable outcome. "I already wrote it", "it is only one line", and "this one is genuinely useful" are not exemptions — the last one is the exact thought that precedes every violation.
- *CC-6 (MUST)* Applies to comments I edit as well as ones I add. When a change invalidates an existing comment, the default action is DELETE, not rewrite it into a new narrative.
```
Yes, I am aware that claude mostly generated this, and it can probably be better and/or more succinct.
vrosas
3 days ago
The problem is, when the context window grows, Claude tends to forget these kinds of rules. It will then do whatever it wants. I had to outright ban comments in the global claude.md, the local claude.md AND write a hook to catch any that still slipped through.
nater5000
3 days ago
I think people really need to focus more on working with limited contexts rather than trying to work around it. I really try to keep my sessions as short as possible and it helps a ton with keeping Claude (et al) focused.
Specifically, I like the "canary" trick that people have discussed where you add a small, innocuous rule to your CLAUDE.md like "When responding to me, start every sentence with my name." so that when Claude stops doing this, you know you've used way too much context and need to start a new session.
boc
3 days ago
I set my env up so I can see the exact context used in CC CLI, and then once I get over about 40% ctx used I have it handoff to a new, fresh session. Nothing good comes from running above, say 60% of your context window. Coincidently, I usually have good results with CC. I never compact a session ever.
jen729w
3 days ago
This is the way. Mine looks like `ctx: 0k / Fable 5 high`. When ctx ⪆ 200k, time to start a new session.
```statusline-command.sh
#!/bin/sh
input=$(cat)
model=$(echo "$input" | jq -r '.model.display_name // empty' | sed 's/ context)/)/')
effort=$(echo "$input" | jq -r '.effort.level // empty')
used=$(echo "$input" | jq -r '.context_window.total_input_tokens // empty')
out=""
[ -n "$used" ] && out="ctx: $(( used / 1000 ))k"
[ -n "$model" ] && out="$out / $model"
[ -n "$effort" ] && out="$out $effort"
# bright yellow + bold
printf '\033[1;93m%s\033[0m' "$out"
```faizshah
3 days ago
This or you just repeat the initial prompt every 200k tokens
ianjbutler
3 days ago
Which gets you to the point where the whole thing is.. still unreliable. Generative text engines are going to generate. This calls for real enforcement in deterministic pre-edit hooks.
And here is where naive people will say something like "Why do I care if robots shit all over the codebase? Code is for machines, I don't expect to deal with it much now". But really externalized CoT like this confuses machines too, wastes tokens, and eventually wastes exponentially many tokens. Agents tend to think it's more real grounding than prompts are, even for comments-in-code. One bad comment poisons everything, then gets copied around as a ground-truth assumption everywhere. Hooks are more real to them than prompts or comments, and even then if you add enforced limits and tell them to externalize CoT ONLY in scratch task-tracking docs.. they will violate comment-enforcement hooks about 25% of the time. That tells you everything you need to know: even with constant reinforcement, they just really want to break this kind of rule.
purplepatrick
3 days ago
Yup. If only there were a task completion hook that could be set to fire prior to rendering terminal output. That would more handily address all these issues, as we could simply enforce output style rules that way.
The current output style does work, but it’s a Sisyphean task to tweak it constantly only to find out that CC adhere’s to only 75% of it, no matter what…
faizshah
3 days ago
My take on this is they are a tool to help speed up your work they are not meant to produce finished work. Humans produce finished work. LLM will never be deterministic cause their entire value is that they are generalizable.
ianjbutler
3 days ago
I hear that, sort of, but here's the thing. Using AI at scale means AI needs to be nearly perfect about not shitting where they eat. That's the subject matter of the whole thread
So the options are a) being a really aggressive stickler for generative hygiene with deterministic rules, b) being massively wasteful about hiring a few machine janitors for every machine coder, or c) humans become the machine's janitor. If I haven't missed an option.. only the first option seems reasonable here.
zarzavat
2 days ago
"AI at scale" is just a euphemism for slop. Current gen AI can augment human engineers but not outright replace them.
ianjbutler
2 days ago
This isn't really responsive to what I'm saying or what the discussion here is about, but if you insist. Would you describe lots of AI augmenting lots of human engineers as perhaps.. AI at scale?
hectdev
3 days ago
Yea, I've started making it write linters to check the code that goes out. Anything that can be deterministically measured, gets added to it once we lock it down.
mandeepj
3 days ago
> The problem is, when the context window grows,
You know the problem; then why not address it? Does Compacting the context not help?
adastra22
3 days ago
Compacting the conversation almost never helps. It is uniformly worse than starting over with fresh context, or rewinding to a last-known-good state. It only exists because it increases engagement.
enraged_camel
3 days ago
This does not match my experience. I use long-running orchestrator sessions. Each orchestrator is in charge of planning, writing kick-off prompts for implementers, answering questions from those implementers, doing code reviews and providing feedback, and answering side questions from me when I have them.
Depending on the initiative I might compact a session a dozen times, sometimes more. It is lossy, and the session certainly tends to forget earlier bits as more compactions happen, but overall it's a much better experience than starting fresh and having to re-explain everything.
The only time I compact is if the session goes wildly off-course and the context gets polluted with off-topic conversations.
Also worth noting: with Claude Code you can provide custom instructions when compacting, and instruct the LLM that is in charge of compacting the session to prioritize the retention of specific bits. It can help a lot.
cautiouscat
3 days ago
Compaction is a main cause of this problem.
troupo
3 days ago
Compacting context compacts context. So Claude forgets a lot during compaction.
Maxatar
3 days ago
Compacting mostly gets rid of reasoning tokens, and honestly it would be nice of reasoning tokens did not constantly follow every follow up query. Asking even a simple/trivial question can have Claude use thousands of tokens. Compacting is good for getting rid of those.
troupo
3 days ago
I've had Claude immediately fall back to its usual verbose style immediately after compaction.
To be fair, I've had it do that immediately after re-reading the output style instructions, too.
My chat history is filled with "Yes, I broke the language rule. Let me rephrase that and update my memory. — You already have that in memory — Yes, true, I ignored that" (because "Memory" is a yet another .md file)
strbean
3 days ago
Claude Code supposedly supports a "post-compaction" hook, so you could have it automatically run the prompt "We just compacted the context, quickly refresh yourself on the rules in CLAUDE.md etc..".
Depending on what you've got in those files, maybe that will just use up all the context again though.
troupo
3 days ago
> supposedly supports a "post-compaction" hook, so you could have it automatically run the prompt
Keyword "supposedly" :)
I've had it in my settings forever, and still...
Asking it to analyse and fix the issue it produced a plausible "my training supercedes/overrides settings especially if triggered by certain words in the phrase" (paraphrasing the long text)
strbean
3 days ago
> Keyword "supposedly" :)
> I've had it in my settings forever, and still...
Checks out! I've never used it my self, so it I figured it likely didn't work at all.
aleksiy123
3 days ago
Hooks is the way.
Intermittent nudges
wheybags
3 days ago
I have a post-edit hook that asks the model if this edit introduced any comments, and if it did, remove them. This was the only reliable way to get it to stop that I found.
nottorp
3 days ago
I just gave up and edit the comments manually. However, I've had a surprise today.
I had it fix something then went and reduced one of the 3 line comments to 4 words. Then for some reason I told the bot to reload the source, it offered to make the other comments terse and did a passable job of it. Shocking!
Now how to get it to do that all the time...
user
3 days ago
kanzure
3 days ago
Yep. Same here. I frequently tell agents things like "answer using only a single sentence" and "write no more than 10 words". They are excellent at writing code, so have them write code (and not English prose). Besides, most of the time we want them to make reusable software that doesn't require users (or future agents) to read too much text. Software should generally just work and do the obvious thing, without needing verbose explanation.
lubujackson
3 days ago
I have extended this to coding work as well. "Implement this plan in less than 1000 added lines, tests included". It's amazing how well-behaved and concise models can be with simple guardrails.
Of course, you have to intuit a reasonable line length, but Claude cries if you happen to clip its wings too aggressively.
varispeed
3 days ago
Why it should write comments at all? Code is the documentation. I only let it write high level information of why something is the way it is.
transdev12
3 days ago
The corollary here is to have Claude write tests to enforce this. The only thing it is consistently responsive to is test failures.
pbreit
3 days ago
Shouldn't this all be easily doable via (auto-)prompting? Surely I don't need to "install" anything?
millsau
3 days ago
So this works better then any other humanizer skill repo on github?
SadErn
3 days ago
[dead]