What happens when you let the LLMs drive technical work? Lessons on agentic models, effective delegation, and AI-assisted engineering.
- Context
- Tactics
- Provide essential context by speccing before coding
- Improve specs by having models critique each other
- Explore alternative implementations in parallel
- Complete independent tasks concurrently
- Observations
- Software engineering skills still matter
- Agentic coding enables mobile development
- Writing concise explanations is a transferable skill
- Suggestions
- Embrace the expanded surface area for creativity
- Move yourself up the value chain
- Participate more in the “what” and “why”, not just the “how”
- Expanding the breadth of your toolset
- Conclusion
Context
Here are practical patterns, observations, and lessons I’ve collected while adopting LLM/Gen AI-assisted software engineering in both hobby projects and my day-to-day work as a software engineer and engineering manager.
One idea in particular that shifted my perspective. In an interview with Simon Willison, he argues that effective LLMs use requires intentional practice - including the exercise of completing tasks entirely through prompting - no manual edits.
As someone who enjoys programming, this felt counterintuitive (and expensive). I’d always treated LLM output as a starting point, not the final draft - it just needed to be good-enough fo me to take over.
But once I approached this hands-off style as a practice kata of sorts, it made sense. Like learning any skill, the more repetitions you do, the faster you learn.
What follows are the patterns that emerged from that practice.
Tactics
Provide essential context by speccing before coding
Vibe Speccing is a semi-automated way to ensure that LLMs actually understand your tasks before touching code. Luke Bechtel’s post outlines the pitfalls of underspecified requests and offers concrete prompts to preempt them.
His observation is that this same need exists for delegating to humans well:
Too little context and the LLM flails. Too much and it gets lost, or expensive…The way we solve this with humans is to write a concise set of specs (AKA requirements / PRDs)…
When tasking an LLM with tackling any non-trivial task, the first step should be to have at least one model go through the speccing process with you.
This often surfaces requirements or constraints I hadn’t considered. The earlier invalid assumptions are spotted, the cheaper they are to correct.
Improve specs by having models critique each other
When developing specs, pass the plans from one model to another and ask them to:
- Identify where they agree
- Identify disagreements and rationale
- Note: this can be useful when creating Architecture Decision Record (ADR)s
- Ask clarifying questions
- Identify improvements to their own spec that they plan to incorporate and suggest improvements to the other
Repeat for as many rounds as useful. You can then pick a single winning approach or have the agents implement their respective approaches in parallel to compare the final results directly.
Ask models to output their proposals to Markdown files. Then have each model review the others’ write-ups.
Explore alternative implementations in parallel
Instead of relying on branching alone, you can create multiple working copies of a repo and let each model take conflicting approaches concurrently.
You can instruct models to:
- Duplicate the repo
cdinto the relevant copygit branchinside each before beginning work
This was a paradigm shift from treating one working copy as the “canonical” workspace. Parallel focus needs parallel environments.
An instance where this was useful was when I was considering pivoting from SwiftData to vanilla CloudKit for the data layer of an app I was working on. After having models implement both versions, I was able to see how much more code I’d have to own with each approach, making the trade-offs more concrete. The side-by-side comparison allowed me to make an informed decision in minutes instead of hours more of conceptual analysis.
Once a winning approach emerges, push that branch, delete the temporary copies, and resume working in your main repo.
Complete independent tasks concurrently
Leverage multiple agents in the same repo copy. When tasks touch separate parts of the codebase, you can spawn multiple instances of Claude/Codex/your preferred model(s) to work on them concurrently.
Two options:
- You manually review, stage, and commit the changes
- Or instruct models to commit and then clean up later via tools like
git rebase -i
This multiplies throughput when tasks are scoped correctly.
This could even be as simple as speccing out your next feature while the current one is being implemented.
Observations
Software engineering skills still matter
If you've done any amount of LLM-assisted work, you've likely experienced this:
You give the model a task.
It writes something plausible-sounding and even correct-looking. But you spot a design flaw or an impossibility (like calling an API that doesn’t actually exist).
You point out the issue or ask for clarification. The model excitedly replies with, “You're absolutely right!” and revises the plan.
Each of these moments where you catch something represents potentially hours or even days of time saved through applying hard-earned experience.
Intuition for failure modes and tradeoffs remains highly valuable when working with LLMs.
In that way, domain knowledge and the ability to read and write code still matter.
Agentic coding enables mobile development
This may warrant a dedicated write-up of its own. In short, LLM-driven development enables a new way of working: start prompts from anywhere, iterate on output from anywhere.
- Jot down an idea as a note (as part of my existing writing habits).
- Refine the idea into a prompt.
- SSH into my development machine - from any personal device that can act as a terminal - and fire off the prompt. This could be done from a phone while away from home.
- Follow up on the results later - again, from any of my devices that can run a terminal, not just my laptop.
Writing concise explanations is a transferable skill
Practices like vibe speccing combined with making prompt-only updates have strengthened a skill that I’d already considered a strength of mine: the ability to describe requirements concisely. As part of my day-to-day work, this is a skill I draw on often. So the incremental gains have been both surprising and immediately beneficial.
To quote Obsidian’s CEO Steph Ango in his post Concise explanations accelerate progress
If you want to progress faster, write concise explanations...The sooner your idea is understood, the sooner others can build on it...
Working with Gen AI is very much like introducing another collaborator to your projects.
Communication allows combined efforts to be additive, not subtractive, by moving everyone in the same direction.
Suggestions
Embrace the expanded surface area for creativity
A colleague shared a graph that captured this well.
My interpretation: by relaxing the fear/challenge-based criteria in project selection, my surface areas for creativity and curiosity has functionally increased.
LLMs allow you to be less prone to rejecting ideas because they seem too hard, and more likely to reject them for the better reason of not being sufficiently interesting.
Even if the effect is primarily psychological, more ideas get nurtured this way.
Move yourself up the value chain
Participate more in the “what” and “why”, not just the “how”
If the trend toward AI-driven white-collar work continues, the craft of software engineering will look very different going forward. Specifically, I believe there will be a greater overlap between engineering and product roles.
This is a reminder that software engineering is about delivering solutions, not just coding. Invest in understanding whatever problem space you’re in (or want to be in), including who the stakeholders are, their pain points, and what they see as opportunities.
Expanding the breadth of your toolset
Leverage existing skills as a jumping-off point into new disciplines.
In one particular week, I contributed to a Web (Typescript) project, a Backend (Java) project, and a Data Engineering (Python) task. I wouldn’t have attempted to touch all three disciplines without LLM support - backed by collaboration with domain experts to validate the work.
That allowed me to take things off engineers’ queues that may have been at risk of slipping, allowing them to maintain focus.
The ability to drive impact in new ways, including unblocking teammates across domains, is increasingly accessible to anyone willing to stretch.
If you're web-focused, try some backend work. If you're backend-focused, try data engineering, and so on. LLMs lower the barriers to exploration.
Conclusion
The joy of the wizardry is that when you get good at solving one problem, they give you another.
– Brennan Lee Mulligan, Worlds Beyond Number
In many ways, that’s been the arc of my journey; AI-assisted development feels like the next challenge. I’m betting that domain knowledge, experience-based intuition, and understanding of / empathy for stakeholders will remain valuable even as LLMs dramatically shrink the distance between having an idea and shipping something.
The “just-barely-good-enough” output of a non-expert wielding LLMs might be enough to determine whether an idea is worth pursuing further. And the output of a domain expert steering an LLM might carry that same idea all the way to a production-ready state.
So the question isn’t whether to adopt AI-assisted development. It’s how to integrate it into your workflows while still practicing the craft and rigor that make your profession worth practicing.
Try vibe speccing your next idea.