[1/4] Code with LLMs and a PLAN
I'm fortunate enough to work every day with the state-of-the-art coding agents, most recently Claude Code, and I've also explored various resources from developers who push the boundaries and produce significant work with top-tier agents. We all need to level up together in this wild west of AI coding and share the good, the bad, and the ugly along the way. So, I'll be flooding everyone's inboxes with four articles on my most recent experiences and learnings in the space over the next few days.
Your very fundamental first step to get right when coding with LLM agents is your process. It's actual teamwork. On the highest level, it should look like this:
- Make the LLM agent create a PLAN.md based on your detailed requirements.
- Fix the PLAN.md, remove redundancies, add missing pieces.
/clear
context.- Ask the LLM agent to implement the PLAN.md.
- Review - Refine. Maybe throw away and rewrite the PLAN, repeat.
How do I know? Because when I first started working with agents, using Junie in RubyMine, and now Claude Code, I just provided them with tasks that included as much detail as I thought they would need. Once I started following the process after learning about it in the "Babysitting Coding Agents" Changelog episode, I felt the quality of the output increase massively, and the needed refinement of the prompts decreased.
One reason it works is probably that the PLAN.md is structured in a way that makes it easier for the LLM to implement. The other is that you refine the PLAN.md. In that process, you often improve the original requirements and become more specific about the implementation.
I have some thoughts on PLAN.md and coding with LLM agent squads/swarms, but that's for a future post.
Another interesting aspect is that several people in our Rails Builders groups reported using Gemini for planning because it can likely ingest your entire codebase or most of it, thanks to its enormous token limit. Others use Claude Desktop for planning, I guess, to save tokens if they don't already run on something like Claude Code Max (currently $100/mo).
Let's look at one example of how it worked out for me most recently.
Real world example with a twist
We have a massively fun project at ClickFunnels, transforming the best parts of our public API into an MCP server that LLMs can interact with. I can hardly fathom how much this approach saved me time. And I'm sure what I did would have taken someone really strong in LLM coding even fewer steps and less time to figure out, but here is how I went about it step by step.
We have about 150 endpoints in the public and a very large OpenAPI spec which Claude Code can't even ingest at once, it has to search inside and get the relevant parts piece by piece. We wanted to expand our initial spike of 7 MCP tools to approximately 100.
I gave it an early version of the prompt below:
get all the possible actions, response attributes, request
parameters, filters, validation constraints and descriptions from the
@cf-v2-openapi.json. Make sure the tool descriptions are populated with the
right info for the LLMs to work with. Just write a PLAN.md don't code anything yet.
I let it implement the first version of the MCP server tools with the result of that prompt, and noticed that the prompt needs to be more detailed. So, I discarded the current implementation and made the prompt more detailed. The second version of the prompt created a PLAN that looked something like this:
#### CRUD Orders::Tag
- [ ] `create_order_tag` - Create order tag
- **Endpoint**: `POST /workspaces/{workspace_id}/orders/tags`
- **Description**: Create a new order tag in the workspace for organizing and categorizing orders
- **Parameters**: workspace_id (path)
- **Request Body**:
- name (string, required) - Name of the order tag
- color (string, optional) - Tag color (hex code like "#FF5733")
- **Response**: 201 Created with OrdersTag containing ALL fields:
- id (integer) - Tag ID
- public_id (string) - Tag public ID
- workspace_id (integer) - Workspace ID
- name (string) - Tag name
- color (string) - Tag color
- created_at (string) - Created at datetime
- updated_at (string) - Updated at datetime
I first implemented that PLAN with a few API resources that we have at ClickFunnels, reviewing and testing the output.
And here's the twist: with the following resources that I implemented, after more refinements to my PLAN.md, the tools were working pretty well, and I stopped watching the process at some point. I let the LLM extend the PLAN.md based on the existing PLAN.md and the existing tested code, guided by the prompt I provided. Here's the final prompt that found its housing in our CLAUDE.md
for that project:
[...]
## Adding new tools
Our OPENAPI_PLAN.md currently serves as a source for extending the server with new tools. A good way to do this is to use a prompt like this:
/clear context first
```prompt
We also need tools for [Namespace]::[Resource] and [OTHER] resources. Fix the
PLAN.md to have these resources and plan similarly to how you planned the other
resources, like Sales::Opportunities (OR OTHER RESOURCE EXAMPLE SIMILAR TO THE
NEW RESOURCE). get all the possible actions, response attributes, request
parameters, filters, validation constraints and descriptions from the
@cf-v2-openapi.json. Make sure the tool descriptions are populated with the
right info for the LLMs to work with. After you have planned and committed the
plan, implement the newly added plan for the mentioned resources. Test the new
implementation in the existing test files and run the tests with npm test --
--run and check for type issues with npx tsc --noEmit.
```
[...]
[Namespace]::[Resource] and [OTHER] are the only placeholders that I now change when adding a new set of tools through one or more API resources.
In a future post, I will discuss parallelizing the entire sorcery.
We push each other to build better together in the Rails Builders groups and there's rarely a session where we don't talk about AI and LLMs so...
This week is the last chance to secure an open spot in Rails Builders 2 (free), which runs until the end of August. After that, we'll finalize the groups in the existing formations. If you know me, just hit reply. If we haven't spoken yet, press the button. 👇
Resources
Check out these guys who share in detail their process of how they build and extend real databases with LLMs on the bleeding edge of AI coding:
- "Vibe Coding" book authors on YouTube.
- The famous Babysitting Agents podcast episode.
- Claude Code for grownups video.
- Patterns of Application Development Using AI by Obie Fernandez.
And just a funny back-reference if you want to travel time and see how quickly everything changes in this new era:
- My wildly outdated first baby steps documented in March 2025 and updated several times already here.
Happy coding and learning with LLMs! 🤖