Hacker News new | ask | show | jobs
by zem 16 days ago
unlike the op, I've been having a wonderful time using claude, both at work and for my own personal projects, so I will share what has worked for me, just in case it resonates with anyone else.

my anecdotal advice is to avoid the entire "agent" temptation, and treat the LLM as a code generator. have a single session running at a time. come up with a plan, iterate on it until you are satisfied, then tell it to execute the plan, and watch it. not necessarily to the extent of reading the scroll (though I sometimes do do that too!) but as it finishes each step look over what it has done, suggest improvements and course corrections, and then let it go on to the next step. at the end you will have a pretty good grasp of the state of the code, and the overall time it will take you isn't really any longer than trying to churn out reams of code and then go through it all at once.

the other option if you want something closer to a one shot workflow is to go into far more detail during the planning stage, have it describe not just architectural details but actual code (if you're a senior engineer especially you probably know what the key pieces of code that will drive a lot of other decisions mechanically are likely to be).

also refactoring is cheaper than it has ever been, if something feels hard to grasp to you stop and work with the LLM until you like the looks of it better.

and again, the key bit is to have one LLM doing one thing at a time, and to stay engaged in the process while it does so.

6 comments

Agree with this. I have learned to interact with Claude the same way. Detailed hashing it out at the beginning, then finally execute, even maybe with your scaffolding at the beginning to guide the process. I tried writing this process down in a 'zen of Claude' as a reminder https://github.com/ctomkow/claude/blob/main/README.md I've started being able refactor legacy code into a new architecture with great success. Work I've been putting off due to the grind of the work.

Edit: I will say it's taken me some months of working with Claude to get to this working process. If you let claude operate with free reign, the inevitable mess and struggle it runs into burns and stresses you out. Also, keeping up with some manual coding when you feel like it and punting to Claude when you have had enough manual coding ensures you still feel in control of the codebase.

Sounds very reasonable. It is similar to what I do. I have a chat completely separate from my editor, where I only paste necessary pieces of code, that should be considered, add some constraints or ideas to discuss and once I am satisfied, I copy back code into my editor, where I might rename things and might further improve things. Other times, I just code it myself, when it is already clear to me or seems enjoyable. I think for me it is important to engage in doing things oneself, here and there, and make the architectural decisions, to actually feel a connection to a project and develop an in-depth understanding.
I agree I think Vibe coding (even with myraid loops) is more burnouty than using it like an assistant and being closer to the output.
Unfortunately the incremental approach doesn't help when it comes to the review step by another user, they've still gotta take it as a lump and apply fresh eyes on it.
not if you break your work into a stack of PRs, which is the standard practice for my team at work. you just keep adding PRs to the top of the stack while the reviewer proceeds from the bottom. if something changes you propagate the change up the stack, which LLMs are also pretty good at doing.
I'm all in favor of stacking PR's to break reviews into chunks, but if they're being used to explain the reasoning or correctness of the final code to a reviewer, then that's a process-smell. It's like "teaching to the test", a shortcut that will hurt in the long run.

We want to end up with code that makes sense generally, to whomever is editing or or debugging it in the future. That next-person usually won't (or shouldn't need to) mine the git history to understand the current project in front of them.

i'm not sure i understand your objection. here's a concrete example of what i'm talking about:say i want to add a new feature to my code analyser, exception-aware code analysis. it ends up being 2000 lines worth of diffs, touching a bunch of files, and definitely too much to review in one go. so what i do is, first i write a doc file describing the feature, to show what i'm working towards. then i write a small commit, "add a new `exception_handlers` member to the context struct, and a small class containing its datatype", and upload it for review. why is this new member needed? see the plan doc pointed to by the commit message! now i needn't wait for it to be reviewed, i can stack another commit on top of it, "populate the exception_handlers info by walking the AST". it depends on the exception_handlers member being in the struct, but, crucially, it doesn't depend on that code being merged in, because it's there in the stack below this commit. i can keep adding things like "inherit exception_handlers when analysing function calls", "validate that all explicitly raised exceptions are caught by an exception handler in the current scope", etc - there are a lot of moving parts to analyse exception handling, but each commit is fairly small, does one precise thing, and is therefore relatively easy to review.

when the stack is complete and all the commits are uploaded to wherever (we use phabricator but i'm sure github has an equivalent) for review i just need to sit back (or work on something else) while my reviewer(s) go through each commit and validate that it looks like it does what it says on the tin. as soon as the bottom of the stack gets approved i can merge it in, or i can wait for everything to be reviewed. if there are any changes i do them and rebase the rest of the stack on top of the changed commit, fixing merge conflicts if needed. (it really helps if your tooling supports this workflow, of course!). and when it's all reviewed and merged, the effect is exactly the same as if i'd just sent in a 2000 line combined commit and merged it in - there's no need to go look through the git history for anything, the code will hopefully make sense as part of the codebase.

I've found that I can go back and forth between two workstreams (at most) but beyond that my brain gets fried from the context switching.
I've also been having a wonderful time with the other approach, churning out reams of code for a mobile app.

It is taxing, the context switching is not easy. It takes effort to keep up with 3-5 conversations, remember what you deployed to the device, what is to be tested, and what feedback needs to be provided.

At the end of the day I am proud of the results, and I feel like I achieved something.

Contrary to popular belief it is still often hard work to vibecode.

Lots of QA work, UX decisions, debugging and steering efforts, as well as weighing architectural concerns and what should or should not be refactored.

While the code basically writes itself, the app still does not create itself on its own. Not to mention business and market research, as well as App Store Optimization.