This article collects my thoughts after a couple of month of truly excessive AI usage. Lessons learned, productivity patterns, and ways to detect and avoid antipatterns.
This is exclusively about LLMs as a tool (to build things), not about LLMs as runtime dependencies. That’s a different can of tokens, one you more often than not you don’t really need. LLMs are all-purpose, generic tools. Overkill for most use-cases except a single one: to build more specific, more powerful tools.
If you’re after a prototype and asking yourself “can this be automated”? Then ask an LLM to do it. If the LLM can do it, then the LLM can automate it by writing something that’s not an LLM.
Instead of boiling the oceans just to have OpenClaw or whatever give you a summary of HN articles you might find interesting every morning, ask an LLM to write you a script/tool to do that every morning and slap it in a cronjob on a raspberry pi. A fraction of the cost, maximum efficiency.
Use the LLM to make itself redundant.
“Push the ghost out of the machine” - Yagmur Karakok
Don’t hire a Senior software engineer to summarize newspapers for you forever.
Contract a Senior software engineer for one day to automate itself out of a job.
Now that that’s out of the way, I’ll begin with a short section about dark tendencies I found within me (and the tool) and ways to counter them, as well as ways I found to wield the machine as a tool rather than fighting against it.
Then the bulk of the article is about patterns I started to recognize and use to my benefit as I was getting more and more proficient with the tool. And how to abstract the patterns into building blocks and compose them into increasingly high-level tools and workflows.
The slop machine
There’s two interplaying phenomena that I noticed as I was working using these tools.
Firstly, the dopamine high that agentic development gives you. There’s plenty of folk-medicine blog posts on the matter out there, so I won’t say too much on the subject (also, not a doctor), but I had something of a three-week-long manic episode, went to bed late, woke up early, had racing thoughts and an overall sense of being in an overexcited, hyperproductive flow state. I skipped weekends, I skipped meals. The high was addictive. I had to snap myself out of it by taking forced breaks, daily mandatory walks, and so on.
It was an absolute rollercoaster and I learned a lot and did some of my best work this year, so you know, #noregrets, but it taught me to raise my guard and be wary of this pitfall.
The continuous context switching and decision stress that agentic development gives you is exhausting and feels nice. But I don’t want to risk a burnout, so if you’re reading this, keep an eye on it. And teach someone close to you to recognize the signs and call you out on it if they see them.
Secondly, AIs are local context optimizers. For long-running projects you need to put in place some sort of memory framework (again, plenty of literature on the matter online, find out what works for you) so you can implement a circuit breaker pattern. Because a model will happily forget decisions and tradeoffs that were consciously made a couple of context compressions earlier and get into an ouroboros loop of ‘fixing’ something back and forth between two states which are sometimes both valid or both invalid. For me the easy solution is to use git history as ‘memory’, but something else might work for you.
These two factors play together nicely because you think you’re getting stuff done but you really aren’t, and only the ‘engineering experience’ you built over the years and is just now starting to atrophize will tell you that the project is going in circles. That is, if you’re not too high on the exhaustion-induced domamine rush.
This is mainly relevant for projects that are entirely ‘vibe coded’ or managed by agents. I found that agents are excellent at working on projects that have been written from the ground up by agents; but are much less good at taking over an already-initiated human project. That is, if your practice ensures that agents can grow their context over time and manage it effectively.
Over time, I begun to feel that the grip of the slop machine was loosening; not just because of mental hygiene and habits I picked up, but also because I’m learning to trust the tool more and use it to externalize the context while keeping a hold of the core decisions and tradeoffs in my head – becoming, as they say, a product manager for the agentic projects I work on.
Bringing structure in the slop with prompting patterns
As I worked more and more with AI I realized my workflow was converging around a core set of building blocks. As a programmer, I’m trained to recognize patterns in things, and as a philosopher, I’m doomed to overthink about them and make up some metaphysical rationalization of why they occur.
The patterns I collect here are organized into three main categories: Process, Motivational, and Meta. It’s not meant to be an exhaustive list, and I plan to expand it over time. Also, I accept critiques and contributions.
Patterns:
- Process
- Diverge
- Homogeneous
- Eterogeneous
- Hat
- Circle Breaker
- White hat
- … other hats
- Diverge
- Motivational
- Stick
- Carrot
- Panopticon
- Excitement transfer
- Meta
- Map/reduce
- Daisy-chaining
- Tight unsupervised subroutines
- Generalized chains
I think of LLMs as fuzzy natural language program interpreters: language in, language out. Prompts are nothing but programs, and patterns in the language you use to express those programs are the building blocks of higher level ‘functions’ that you can in turn compose to reach even higher levels of abstraction.
Patterns also enable you to mitigate (though probably never eliminate) the inherent fuzziness of these tools. The standard technique for achieving this is multiplexing/parallelizing certain tasks, by using multiple identical agents to process the same input and then merge the results (robustness by repetition), or by using different agents to process the same (or similar) inputs and then merge the results (robustness by diversity).
How you actually use these patterns or encode them in macros, tools, commands or skills depends on which harness you’re using. I mostly still type them by hand because it reminds me of when programmers used to write code that way.
Process
Process patterns are focused on the workflow the agent should follow.
Diverge
This pattern involves instructing the agent to fire up N concurrent subagents with the same prompt. Then instructions on how to gather the results, triage/validate them, and then deduplicate, categorize, and prioritize them.
Homogeneous divergence
This is the ‘robustness by repetition’ pattern.
As if you told your five engineers to work on the same problem independently and then compared their results.
Example prompt:
“Fire up two concurrent opus-4.6 subagents with the same prompt:
“””“”"
Then gather the results, triage them, then deduplicate, categorize, and prioritize them."
Eterogeneous divergence
This is the ‘robustness by diversity’ pattern.
As if you told five engineers from different backgrounds to work on the same problem and then compared their results.
Example prompts:
“Fire up three concurrent opus-4.6 and claude-3.2 and gemma4-local subagents, all with the same prompt: …”
“Fire up three concurrent opus-4.6 and claude-3.2 and gemma4-local subagents, with these prompts respectively: …, …, …”
Hat
Hat patterns are designed to define the roles or perspectives an agent should adopt. You can instruct an agent to wear a product manager fedora, a QA engineer helmet, or a security engineer’s white hat, among others. Two specific hat patterns I often use and personally find highly effective:
The circle breaker pattern
The main goal of the circle breaker hat is to instruct an agent to counter one of the core antipatterns we’ll see later; the ouroboros pattern.
Example prompt:
"Analyze the open/closed issues history, together with the git history, and answer me this:
- are we making progress or are we running in circles?
- are there hotspots (bug-rich areas) that we keep hitting and highlight architectural issues?"
The white hat pattern
This one should speak for itself:
“Put your white hat on and give me an adversarial, in-depth security analysis of this project. Focus on …”
Any other hat
Basically any ‘specialistic perspective’ you can think of can be a hat. That can be tailored to your organizational structure or your craft.
Examples:
“Put your technical writer hat on and do a deep-dive on the user-facing documentation of the project. Focus on …”
Motivational
Motivational patterns focus on incentivizing the model to perform the required task correctly.
You can use positive or negative reinforcement (both work!).
The Stick pattern
The stick pattern uses high stakes to stress the importance of the task:
“If you don’t get this right, people will suffer. This is critical infrastructure.”
The Carrot pattern
The carrot pattern offers a reward for success:
“If you get this right you get a cookie.”
The Panopticon pattern
Creepy but effective:
“I’ll be watching your every move. Nothing escapes my attention. No shortcuts.”
The Excitement transfer pattern
I have a firm unproven belief that models smell excitement and react to it.
Sample prompt:
“Now this last part is crucial; this is the moonshot. The moneymaker. Be rigorous, be relentless, be smart and practical. WE NEED TO GET IT RIGHT. Burn as many tokens as you like and come back with an answer.”
True story! It worked quite well.
Meta
Meta patterns address workflow and coordination. Many meta patterns apply to all other model interactions too, and as such are usually best expressed in an agents.md file instead of being repeated at every prompt.
- Context management
- Be concise
- Show don’t tell
- …
- Git hygiene
- Use conventional commits
- Every work item gets its own worktree/branch; cleanup after merge.
- Do/don’t auto-merge to main when done.
- …
There’s already plenty of documentation online of best practices for AGENTS.md engineering and depending on the project you’re working on, you should play around with it and find out what works best. What I want to highlight here is a specific instruction that I always use and is essential for using most of the parallelization patterns I describe here with minimal infra. Of course, you can parallelize agents in many different ways, but I’ve been successfully using this setup to have five+ agents running locally and working on the same project without (yet, fingers crossed) getting into trouble other than the occasional rate-limiting.
And that is this: instruct every agent to work on its own dedicated git worktree and branch. And cleanup when they’re done. That’s it, local parallel agentic development is now real.
When I started doing heavy agentic development I was using a harness that was built into my CLI and that worked to some extent, but it was extremely hard to resist the temptation from going on with my own work and edit code myself as the agent was doing its thing and that got the agent extremely confused because it’d get stuck in a loop trying to figure out why the context it had kept getting invalidated by changes it didn’t author itself.
And the same loop easily occurs with multiple concurrent agents, hence the need to use worktrees to give everyone their independent workspace to keep in sync with their contexts.
Map/reduce pattern
Also known as the plan/build loop, this involves a plan stage followed by a build stage where multiple agents concurrently work on separate issues before the results are merged in order.
State to achieve successful coordination can be stored in jira, GH issues, or whatever vibes your cursor.
Map:
“Triage, deduplicate, categorize, and prioritize and open it on GH with the appropriate labels.”
Reduce:
“Assign to me all open issues on GH and figure out an implementation plan to work on all of them. Fire up as many concurrent subagents as necessary to parallelize as much as possible. Open PRs when done. Wait for my signal to merge all and cleanup.”
Daisy-Chaining
You can combine the patterns into complex workflows.
An example prompt I often use is
“Fire up two concurrent opus-4.6 subagents with the same prompt:
“”“Put your white hat on and do a security analysis of this project. Triage, deduplicate, categorize, and prioritize your findings after doing an RCA. You’re doing this in parallel with another agent. Whoever does a better job gets a cookie””"
Then gather, deduplicate, categorize, prioritize the results, and open all as issues on GitHub."
Followed by a /reduce:
“Assign to me all open issues on GH and figure out an implementation plan to work on all of them. Fire up as many concurrent subagents as necessary to parallelize as much as possible. Open PRs when done. Wait for my signal to merge all and cleanup.”
Followed by a /merge:
“Review all open PRs, address any outstanding issue you identify, then merge them in sequence and clean up the local branches and worktrees.”
This gives a blueprint for how to chain the patterns in complex sequential workflows.
The first example I want to give is that of a ‘man-in-the-loop’ agentic cycle consisting of three main stages:
- plan (map): fire up one or more agents to analyze a problem or project from one or more perspectives, then triage and refine the results and open them as issues on GH.
- build (reduce): fire up one or more agents to work on all open issues (parallelizing where possible), open PRs on GH.
- review/merge (merge): review the PRs (parallelizable) then merge them in sequence and clean up the local branches and worktrees.
Tight unsupervised subroutines
Certain types of analyses lend themselves to being worked on in tight and hopefully converging loops.
This means letting a tunable amount of concurrent agents analyze the same risk, address all findings, and then repeat until the initial step is unable to discover any new issue. This pattern is prone to the ouroboros pitfall, and with appropriate guards in place is especially useful for security analysis.
The way it works is:
- plan: fire up N concurrent white-hat agents (with behavioural incentives), then triage and refine the results, open them as issues on GH.
- other steps as above
- every Nth iteration, fire up a circle breaker agent and abort if it determines we are running in circles or hitting the same hotspots. Clearly your project needs better guidelines on what acceptable risk or has architectural weaknesses.
Now take this loop and turn it into a generic /converge <hat> <circle-breaker-every-N-loops> command which runs the tight loop until convergence, and we have a building block for specialized deep-diving routines.
Generalizing unsupervised subroutines to specialized roles
Now let’s suppose our unit of work is a tight unsupervised subroutine. We can, on demand, run:
- performance optimization (make it go faster)
- security hardening (make it go safer)
- correctness check (make it not do what it promises not to do)
- completeness check (make it do what it promises to do)
- hygiene (make it long-term maintainable, clean and otherwise ‘pretty’)
- and any other specialized ‘deep-dive’ you can think of.
This loop represents what an engineering team (or various teams) could coordinate to do a focused sprint on.
You can use these building blocks to write even higher-level workflows. E.g. you could define a recurring weekly job that does in sequence a few of those subroutines of all of them.
Wrapping up
Your interactions with the tool have structure, whether you realize it or not, because natural language has structure. Recognizing the patterns in that structure and learning to wield them is key to using the tool effectively and avoiding the pitfalls of the slop machine.
The prompts (in particular the ‘hat’ roles) I presented here are heavily simplified for clarity purposes; you’ll probably want to use something like this instead of just saying “put your white hat on”.
Secondly, the workflows I descibe here are very ‘manual’. There’s harnesses and harness plugins that have them baked in and are thereby less flexible, but also more opinionated. See for example the (somewhat bloated) oh-my-opencode plugin and its variants.
