How I use Claude Code
claude ai llm development practice
2025-06-25
I've been using Claude Code a lot recently, and I've settled on a workflow that's been producing really good results. The short version is: use two separate Claude instances to challenge each other.
The first step, especially when working in an existing codebase, is context gathering. With Claude Code in "plan mode," I'll give it a detailed overview of the project structure. Something like:
"Examine this codebase in detail. The dependencies are documented in
@pyproject.toml
, and take note of the environment variables for configuration in@docker-compose.yml
. The tests can be run withmake test
."
If there's any API or package documentation I've already downloaded, I'll put it into the codebase in an api_docs/
folder, and explicitly tell the LLM to "examine the additional documentation in @api_docs/
." I've found this particularly effective when working with APIs that publish a Swagger specification; just save a copy in api_docs/
and let the LLM learn.
With the groundwork laid, I'll then set out the upcoming context, still in planning mode:
"Our goal is to plan the delivery of feature X, Y, Z. Create for me a phased plan to build these features. Each phase should follow a theme, and each phase should contain an explicit test and documentation task. Ask any clarification questions as you need."
This usually leads to a few rounds of question and answer as we refine the context. Eventually, as the questions dry up, I'll instruct Claude to "Now, write this plan to .implementation_plan.md
."
This is where the second Claude instance comes in. My first prompt to this instance is:
"Based on this codebase, and the plan in
.implementation_plan.md
, critique this plan and help me understand where it's underspecified, or lacking in necessary context. Tell me where you think the plan is weak, and where you would struggle."
This burns a lot of tokens, as this second instance does a lot of reading and thinking in the background, essentially delivering the phase without writing the source files, but it's worthwhile. I consistently get useful feedback that I can then feed back to the first instance.
I'll then challenge the first Claude with the output from the second:
"Based on this critique, consider the points raised, and improve the plan."
After another round of this (and it's usually only two exchanges at most), the .implementation_plan.md
is usually pretty robust.
At this point, I'll put the first Claude instance into "auto mode." I usually grant broad permission to any tools Claude might need; the only tools I insist on running manually are git commit
and git push
. My prompting now goes phase-by-phase: "Consider the codebase, and begin implementing the first phase of .implementation_plan.md
."
Usually, Claude needs a little prompting to actually run the tests after creating them, but I'll also run them manually to keep an eye on things. I've noticed Claude can be a bit overzealous with testing, generating complex mocks and factories. I don't mind these existing, but I like to keep a handle on test suite bloat, and I'll encourage Claude to mark tests as slow if necessary and exclude them from the default test scripts.
At the end of each phase, I'll ask the second Claude instance to "evaluate the progress in this codebase against the current .implementation_plan.md
, and provide feedback." This often produces useful challenges for the primary Claude instance, and a few rounds of back-and-forth helps ensure the phase is genuinely "complete" and nothing has been missed.
I'll then finish the phase with a test run, a commit, and the instruction to "update .implementation_plan.md
with the progress so far." This is followed by /clear
ing the context of the first Claude. I find this "reset" helps prevent the LLM from going off-track. Then it's back to the start for the next phase.
Generally, I find Claude's phased plans are unafraid of front-loading the difficult work. The early phases are usually the most complex, with later phases focusing on simpler tasks like UI work or optimization. So, once the early phases are complete, delivery becomes smoother and less hand-holding is needed from the second Claude instance.