I run engineering at a small agency. That means I’m the tech lead, the primary hands-on engineer, the architect, the code reviewer, and the person who decides when we ship. Across 30+ client engagements, the constraint has always been the same: more work than people, every project on a fixed timeline, every client expecting the quality of a team twice our size.
AI changed that equation. Not by saving me twenty minutes a day. It moved where the work is. What I spend my time on now is different, and so is how I plan a project.
The bottleneck was always implementation bandwidth
Before AI tooling got serious, agency engineering leadership was about allocation. You have N engineers and M projects. Every week is a puzzle: who works on what, what can be parallelized, what blocks what. The limiting factor was always implementation bandwidth. We could plan faster than we could build.
The typical agency failure mode was predictable. Scope creep eats the timeline. The engineer context-switches between three clients. Code quality drops. Bugs ship. The client loses trust. You throw hours at it to recover. Margins evaporate.
Every process I built was designed to fight that failure mode. CI/CD pipelines to catch bugs before they hit production. Code review standards to maintain quality under pressure. Automated testing to give us confidence when moving fast. These worked. Deployment errors dropped about 25%. Production bugs dropped about 40%. But the fundamental constraint, implementation bandwidth, didn’t change. We just got more reliable within the same capacity.
The limiting factor moved from writing to deciding
Now the limiting factor isn’t writing code. It’s deciding what to write, reviewing what was written, and making the architectural calls that an AI agent can’t make on its own.
On a typical client project today, this is what my day looks like versus two years ago:
| Activity | Before AI | After AI |
|---|---|---|
| Writing code | 60% | 20% (parts needing human judgment) |
| Reviewing AI-generated code | 0% | 30% |
| Architecture and system design | 20% | 25% |
| Writing specs and prompts | 0% | 15% |
| Code review (human-written) | 10% | 0% |
| Client communication | 10% | 10% |
Total output is up, but the nature of the work moved from production to direction. I spend more time writing specs now, because the spec determines the output. A vague spec produces vague code. A spec that pins down the edge cases, the data model, and the error handling produces code I will ship.
Which is the part I didn’t expect: the better the tooling gets, the more of my value sits in the decisions around the code rather than in the code.
The spec turned into the product
At an agency, the spec has always been important. But it used to be a communication artifact, something you wrote so the team was aligned, then deviated from as reality hit. The code was the product.
With AI agents doing significant implementation work, the spec is the product. The quality of the spec determines the quality of the output more than anything else. I now spend more time on a project spec than I used to spend on initial scaffolding.
A good AI-ready spec looks different from a traditional one:
- Explicit constraints over implicit knowledge. “Use the existing auth middleware” doesn’t work. You need “Import
authMiddlewarefromsrc/middleware/auth.tsand apply it to all routes under/api/admin.” - Concrete examples over abstract descriptions. “Handle errors gracefully” is useless. “Return
{ error: string, code: number }with appropriate HTTP status codes; 422 for validation failures, 404 for missing resources, 500 for unexpected errors” produces correct code. - Architecture decisions made upfront. AI agents are good at implementation and bad at judgment calls. Decide the database schema, the API contract, the component boundaries. Let the agent fill in the implementation.
This changed how I think about project planning. I front-load more time into the design phase because every hour spent on a precise spec saves three hours of reviewing and correcting AI output.
Reviewing more code than you can read
AI generates code faster than anyone can review it. The failure mode is rubber-stamping, where the volume gets high enough that you wave things through and end up shipping code nobody understood.
I’ve developed a triage system for reviewing AI-generated code:
Always review carefully: Authentication and authorization logic, data mutations, payment flows, anything touching user data. The cost of a bug here is existential for client trust.
Review for correctness: Business logic, API endpoints, data transformations. Scan for logical errors, missing edge cases, incorrect assumptions about the data model.
Spot check: Styling, component structure, boilerplate setup. If the patterns are established and the AI is following them, a quick scan is enough.
Trust but verify: Test output. If the tests pass and cover the important paths, the implementation is probably fine. But verify the tests themselves are testing the right things. A test that only asserts the function returns what it returns proves nothing.
This triage is something I’m still refining. The risk of AI-accelerated development isn’t that the code is bad. It’s that the review process doesn’t keep pace with the generation speed. You need discipline to slow down at the review stage even when everything else is moving faster.
Guardrails now pay off on day one
The investments that used to take weeks to pay off now compound immediately. CI/CD pipelines, linting rules, test coverage requirements, deployment automation. These always mattered, but they mattered over the long arc of a project.
With AI in the loop, they matter on day one. An AI agent that runs npm run build after every change and fixes its own errors is using your CI pipeline as a feedback loop. Test suites that catch regressions aren’t just safety nets for humans anymore. They’re feedback loops for agents.
Every standard you set, every guardrail you automate, directly improves AI output quality. This flips the ROI calculation on engineering infrastructure. Setting up comprehensive linting used to feel like overhead on a two-week agency sprint. Now it’s one of the highest-impact things you can do, because it shapes every line of AI-generated code for the duration of the project.
What changed in client conversations
Clients don’t care about your internal tooling. They care about timelines, quality, and cost. But AI changed all three in ways that affect the conversation.
Timelines compressed. Things that used to take a week take two or three days. This is great, but it creates a new expectation management challenge. If the client sees you delivering at 2x speed, they start expecting 2x speed on everything, including the parts that can’t be accelerated (design reviews, stakeholder alignment, third-party API integrations).
Scope conversations shifted. “That’s a two-week feature” used to end the scope discussion. Now the honest answer might be “that’s two days of implementation but a week of design and review.” The implementation isn’t the hard part anymore. Explaining that to a client who sees fast delivery and wants more of it requires a different conversation.
Quality arguments got easier. When I can show a client that we have automated testing, CI/CD, and structured code review on AI-generated code, the quality story is concrete. It’s harder for scope creep to erode quality when the guardrails are automated.
Three things I got wrong
Overestimating AI on greenfield, underestimating it on established codebases. I assumed AI would be best at starting from scratch. In practice, it’s better at working within established patterns. Once you have a component structure, a data model, and a test pattern, the AI replicates it reliably. The greenfield phase, where architectural decisions dominate, still needs heavy human involvement.
Trying to AI-accelerate everything at once. Not every part of agency work benefits equally. Client communication, architecture decisions, and design reviews are still fully human. I wasted time trying to use AI for meeting notes and status updates before realizing the bottleneck had already moved. Focus the acceleration on the actual bottleneck: implementation and testing.
Not investing enough in prompt engineering early. I treated prompts and specs as throwaway artifacts for the first few months. Once I started versioning specs, building up a library of project-specific context documents, and writing specs with the same rigor as code, output quality jumped noticeably. The spec library is now one of the most valuable assets in our workflow.
What is left when implementation is cheap
The question I keep coming back to is what engineering leadership means once implementation is cheap.
After a year of working this way, my answer is judgment. Which features matter, how the system should be shaped, what tradeoffs are acceptable, where to spend the quality budget, and when to throw out what the agent wrote.
None of that is new. It was just diluted before. When 60% of the day goes into typing, there isn’t much left for thinking about direction, and it’s easy to mistake being busy for making progress. That excuse is gone.
I don’t know how this settles for agencies generally. For ours it means the planning is now the expensive part, and I would rather have that problem than the old one.