A Year of AI in Production Workflows
We started integrating AI tools into our development process in early 2024. Not as an experiment or a side project — as part of our actual client work. Copilot for code completion, Claude for architecture discussions and code review, ChatGPT for research and content drafting, Cursor as an AI-augmented editor.
After more than a year of daily use, the picture is more nuanced than either the hype or the skepticism suggests. AI hasn’t replaced developers. It hasn’t made us 10x faster across the board. But it has fundamentally changed how we work, and the developers who adapt to it are measurably more productive than those who don’t.
Here’s what we’ve actually found.
What Works Exceptionally Well
Boilerplate Generation
This is the clearest win. Writing repetitive code — form validation, API endpoint scaffolding, database schema definitions, test setup, configuration files — is exactly the kind of work AI handles well. The patterns are well-established, the context is usually self-contained, and the cost of a minor error is low because the developer reviews the output immediately.
// Prompt: "Create a Zod schema for a contact form with
// name, email, phone (optional), company, message,
// and a budget range enum"
// AI output (usable with minor adjustments):
import { z } from 'zod';
const budgetRange = z.enum([
'under-5k',
'5k-15k',
'15k-50k',
'50k-plus',
'not-sure'
]);
export const contactFormSchema = z.object({
name: z.string().min(2, 'Name must be at least 2 characters'),
email: z.string().email('Invalid email address'),
phone: z.string().optional(),
company: z.string().min(1, 'Company name is required'),
message: z.string().min(10, 'Please provide more detail'),
budget: budgetRange,
});
export type ContactFormData = z.infer<typeof contactFormSchema>;
This took seconds instead of minutes. The output is correct, follows conventions, and includes reasonable validation messages. For a developer who writes schemas like this regularly, the time savings compound significantly.
Explaining Unfamiliar Code
When working with a new codebase or an unfamiliar library, AI is remarkably effective at explaining what code does. Paste in a complex function, ask “what does this do and why,” and you’ll get a clear explanation that would have taken 20 minutes of documentation reading to piece together.
This is particularly valuable when inheriting projects. We recently took over a client project with 40,000 lines of poorly documented React code. AI-assisted code review let us build a mental model of the system in days instead of weeks.
Writing Tests
Test generation is another strong use case. Given a function and a description of expected behavior, AI produces reasonable test cases — including edge cases that developers sometimes forget. The tests usually need refinement, but starting from a solid draft is much faster than starting from scratch.
Documentation and Comments
AI writes clear, accurate documentation for functions, APIs, and components. It’s particularly good at generating JSDoc comments, README sections, and API documentation from code. The output tends to be more thorough than what most developers write manually, because developers typically under-document (we’re guilty of this too).
Regular Expressions and Complex Queries
Pattern matching, SQL queries, and data transformation logic — tasks where the syntax is precise and easy to get wrong — are excellent AI use cases. Describing what you want in natural language and getting a correct regex or SQL query saves time and reduces frustration.
What Doesn’t Work
Architecture Decisions
AI will confidently suggest architectures, but it optimizes for the patterns most common in its training data — which means it tends toward over-engineered solutions. Ask it to design a system for a small corporate website and you’ll get recommendations for state management libraries, API layers, and caching strategies that aren’t needed.
Architecture requires understanding constraints, trade-offs, organizational context, and business goals. AI has access to none of these. Use it as a sounding board, not a decision-maker.
Complex Business Logic
When the logic involves domain-specific rules, edge cases that emerge from business requirements, or state management across multiple interacting components, AI output becomes unreliable. It generates plausible-looking code that passes a superficial review but fails in production scenarios the AI couldn’t anticipate.
We’ve learned to be especially cautious with AI-generated code that handles money, dates across time zones, or permission logic. These domains are full of subtle rules that look simple but aren’t.
Security-Critical Code
Never trust AI-generated code for authentication, authorization, encryption, or input sanitization without thorough review. AI reproduces patterns from its training data, which includes plenty of insecure code. It might suggest using MD5 for password hashing, skip CSRF protection, or implement JWT validation incorrectly.
Security code should be written by developers who understand the threat model, reviewed by someone with security expertise, and tested against known attack vectors. AI can assist, but the responsibility stays with humans.
Novel Problem-Solving
When you’re doing something genuinely new — integrating two systems that haven’t been integrated before, optimizing for unusual constraints, or building a feature without clear precedent — AI’s value drops sharply. It can only recombine patterns it’s seen. True novelty requires understanding that AI doesn’t have.
How It Changes the Developer’s Role
The most significant impact isn’t productivity metrics — it’s how AI changes what developers spend their time on.
More Time on Design, Less on Typing
When boilerplate generation is handled by AI, developers spend proportionally more time on system design, code review, and architectural decisions. These are higher-leverage activities. The developer’s value shifts from “can write code quickly” to “can make good decisions about what code to write.”
Review Skills Become Critical
Reading and evaluating AI-generated code is a different skill than writing code from scratch. You need to spot subtle errors, recognize anti-patterns, evaluate whether the approach is appropriate for the context, and understand the implications of code you didn’t write yourself.
Developers who are good reviewers get more value from AI tools than developers who are only good writers. This has implications for how we hire and train.
The Knowledge Paradox
Here’s a counterintuitive finding: AI tools are most valuable to experienced developers and least valuable to beginners. An experienced developer can evaluate AI output, correct errors, and integrate suggestions into a coherent architecture. A beginner lacks the context to distinguish good suggestions from bad ones.
This creates a paradox: the people who need help most benefit least, and the people who need help least benefit most. We’ve adjusted our mentoring approach accordingly — junior developers pair with seniors during AI-assisted work until they develop the judgment to evaluate AI output independently.
Our Current Workflow
Here’s how AI tools are integrated into our daily practice:
- Code editor: Cursor with Claude integration for inline code completion and chat-based assistance. Used for boilerplate, refactoring, and quick explanations.
- Architecture discussions: Claude for exploring trade-offs, reviewing technical proposals, and rubber-ducking complex problems. Always treated as a conversation partner, never as an authority.
- Code review: AI-assisted first pass to identify potential issues, followed by human review focused on architectural fit and business logic correctness.
- Documentation: AI drafts, human edits. Produces better documentation than either alone.
- Research: AI for initial orientation on unfamiliar technologies, followed by primary sources (official docs, source code) for decisions that matter.
The Bottom Line
AI-assisted development is real and valuable, but it’s a multiplier, not a replacement. It multiplies the effectiveness of good developers and the mistakes of careless ones. It changes what we spend time on but doesn’t reduce the need for engineering judgment.
The developers who thrive in this environment are the ones who treat AI as a tool — powerful, useful, and requiring skill to use well. The ones who struggle are those who either refuse to use it at all or trust it without verification.
Use it for what it’s good at. Verify everything. Keep thinking.