My first experience with AI in the IDE was simple autocomplete.
You type a function name, wait for the gray ghost text to appear, press Tab, and move on.
It was useful for utility functions, regex patterns, boilerplate, and repetitive code.
Then AI coding agents arrived.
Instead of operating inside a single file and predicting the next few lines, modern agents can work across a repository. They can inspect multiple files, trace dependencies, plan changes, edit code, run terminal commands, read build errors, and iterate on their implementation.
When I stopped treating AI as an autocomplete tool and started giving it real repository-level tasks on production code, my workflow changed significantly.
The interesting part isn't that AI can write code faster.
It's what happens to the developer's role when implementation becomes much cheaper.
1. What Changed in My Workflow
The mental shift is simple:
You stop being primarily a typist and start acting more like a Tech Lead directing a very fast junior engineer.
The traditional workflow looks something like:
Read Task
↓
Find Relevant Files
↓
Design Solution
↓
Write Code
↓
Test
↓
Debug
With an AI coding agent:
Define Context & Constraints
↓
Direct Agent
↓
Multi-File Work
↓
Verify & Iterate
↓
Review Diff
↓
Validate in Runtime
I'm still responsible for the solution.
But I spend less time typing repetitive code and more time thinking about:
- Architecture
- Data flow
- Constraints
- Edge cases
- Performance
- Runtime behavior
That's probably the biggest change I've noticed.
2. Where AI Agents Actually Save Time
There are three areas where I've found them particularly useful.
Cross-File Refactoring
A seemingly small change can easily span multiple layers:
API Service
↓
Transformation
↓
Custom Hook
↓
Component
↓
Tests
An agent can trace those relationships and make coordinated changes much faster than manually searching through every file.
For example, instead of spending time finding every reference to a renamed property, I can ask:
"Trace all consumers of this property, update the implementation consistently, and don't change the public API."
The important part is the constraint.
Without constraints, the agent may solve the problem correctly while also changing things you didn't ask it to change.
Debugging and Flow Tracing
Some of the hardest bugs aren't caused by complicated code.
They're caused by several simple pieces interacting in unexpected ways.
For example:
Auth Event
↓
Token Refresh
↓
Background Operation
↓
State Update
↓
UI Update
Instead of immediately asking an agent to fix the bug, I often ask it to investigate first:
"Trace what happens if
refreshAuth()resolves whilefetchNextPage()is still running. Don't modify the code yet. Identify possible race conditions and lifecycle issues."
That makes the agent useful as a codebase exploration tool, not just a code generator.
Test Generation
AI is also very good at generating the first version of repetitive tests.
For example:
- Empty responses
- Missing fields
- Network failures
- Retry behavior
- Boundary conditions
- Rapid unmounts
- Cleanup behavior
But generated tests still need review.
A passing test doesn't necessarily mean the right behavior is being tested.
3. A Real-World Example
One example from my own workflow was a performance issue in a React Native Android TV application.
The Home screen contained multiple horizontal content rails. During a background refresh, fresh data had to be merged into the existing UI without unnecessarily rebuilding everything.
Instead of asking:
"Fix the performance issue."
I asked the agent to first trace the data flow and identify where new object and array references were being created.
The agent found that the merge path was recreating more of the data structure than necessary.
The eventual approach was simple:
Update only the rails whose data changed and preserve references for unchanged data.
That part worked well.
But during the refactor, the agent also changed the keys used by some list items.
The code was valid.
The tests passed.
But on Android TV, the change affected focus behavior because some items were being treated as new components.
This is the kind of problem that illustrates the current boundary of AI coding agents.
The agent was good at understanding the data transformation problem.
It wasn't automatically aware that component identity was also important to the platform's focus behavior.
A developer familiar with the application and runtime had to catch that.
And that's an important lesson:
AI can understand the code without fully understanding the system.
4. Where AI Agents Fail
Once you use agents on production code, their blind spots become pretty obvious.
Over-Engineering
Ask an agent to create a small caching helper and you might get:
CacheManager
↓
CacheRepository
↓
CacheFactory
↓
CacheStrategy
↓
CacheProvider
When all you needed was:
getCache(key);
setCache(key, value);
AI tends to generalize.
Production code often benefits from being boring.
If the problem is simple, the solution should probably be simple too.
Framework-Specific Behavior
AI is very good at common React and JavaScript patterns.
But production applications often depend on platform-specific behavior.
In an Android TV application, for example, you may need to reason about:
- Spatial focus navigation
- List virtualization
- Component identity
- JavaScript runtime behavior
- Native bridge costs
- Animation workloads
- Device-specific memory constraints
The generated code can be valid React Native code and still be the wrong solution for the platform.
Runtime Performance
AI often optimizes for code that looks clean and idiomatic.
But performance is contextual.
For example, multiple array operations aren't automatically bad. The problem is unnecessary allocations when that work happens repeatedly in a performance-critical path.
A cleaner-looking implementation isn't necessarily a faster one.
That's why:
Performance should be measured, not assumed.
Native Code and Build Systems
I am particularly cautious when agents modify native code or build configuration.
Gradle, Kotlin, C++, native modules, SDK versions, and generated code can all interact in ways that aren't obvious from a single file.
An agent can produce a configuration that looks completely reasonable and still fail because of an environment-level dependency or version mismatch.
The terminal output is often more useful than the generated code itself.
Hidden Architectural Rules
Every mature codebase has rules that aren't necessarily written down.
For example:
"This state must never be read synchronously during startup."
Or:
"This component must preserve its identity because focus state depends on it."
Or:
"Don't introduce another caching layer here."
These rules often live in team knowledge rather than documentation.
An AI agent can't reliably follow constraints it doesn't know exist.
5. How I Use AI Agents Safely
My workflow is fairly simple:
Context
↓
Constraints
↓
Small Task
↓
Verification
↓
Diff Review
↓
Runtime Validation
1. Give it context
Don't immediately ask it to implement the feature.
First ask it to understand the existing implementation and identify the relevant files.
2. Set constraints
I explicitly state things like:
Don't add dependencies.
Don't change the public API.
Follow the existing architecture.
Don't modify files outside the requested scope.
Constraints are often more valuable than a longer description of the desired implementation.
3. Keep tasks small
Instead of:
"Implement the entire caching architecture."
Break it down:
1. Analyze the current data flow.
2. Implement the storage utility.
3. Add tests.
4. Integrate it into the existing hook.
5. Validate the behavior.
Small tasks make incorrect assumptions easier to catch.
4. Let the agent verify its work
If the project has automated checks, let the agent run them:
npm run lint
npm test
The useful loop is:
Implement
↓
Run
↓
Fail
↓
Inspect
↓
Fix
↓
Run Again
5. Review the diff
This is the part I don't skip.
I review AI-generated changes almost like code from another engineer.
I ask:
- Why did this file change?
- Why was this abstraction introduced?
- Did behavior change outside the requirement?
- Were dependencies added?
- Were new allocations introduced?
- Are timers and listeners cleaned up?
- Did component identity change?
- Was existing state accidentally mutated?
The question isn't only:
"Does this work?"
It's:
"Why did the agent make these decisions?"
6. Validate on real hardware
For applications where runtime behavior matters, tests aren't enough.
A React Native Android TV application can pass its tests and still:
- Drop frames
- Consume too much memory
- Lose focus
- Freeze under load
- Behave differently on low-end hardware
So the final verification loop needs to include the real environment.
6. What Developers Need to Get Better At
As AI handles more of the mechanical implementation work, I think several engineering skills become more important.
Architecture
Knowing where code belongs and how systems should interact.
Constraints
Being able to define requirements, boundaries, and invariants precisely.
Debugging
Understanding why something happens rather than simply changing code until the symptom disappears.
Performance
Knowing how to measure memory, CPU, rendering, and runtime behavior.
Platform Knowledge
Understanding what happens beneath the framework.
Code Review
Being able to recognize subtle problems in code you didn't personally write.
That last one may become especially important.
If an AI agent can generate hundreds of lines of code in seconds, the ability to evaluate those lines correctly becomes more valuable—not less.
7. The New Engineering Loop
I don't think the future looks like:
Human → AI → Code
I think it's closer to:
Human defines the problem
↓
AI investigates
↓
Human validates the approach
↓
AI implements
↓
AI verifies
↓
Human reviews
↓
Real-world validation
↓
Ship
The human remains responsible for the outcome.
The AI accelerates the execution.
That's a much more useful mental model than:
"AI replaces developers."
Conclusion
After using AI coding agents on production code, my biggest takeaway isn't that AI writes code faster.
That's already obvious.
The more interesting change is that the bottleneck moves.
Previously, a significant amount of engineering time was spent translating a known solution into code.
AI can now handle much more of that translation.
The difficult questions become:
- What should we build?
- Where should it live?
- What constraints matter?
- What can break?
- What are the performance implications?
- How do we know the solution is actually correct?
AI coding agents are incredibly useful when you treat them as implementation and investigation partners.
They're dangerous when you treat them as autonomous engineers whose decisions don't need review.
The workflow that works best for me is simple:
Give AI enough context to understand the problem, enough constraints to avoid unnecessary decisions, enough tooling to verify its work, and enough human oversight to catch what it can't see.
The better AI becomes at writing code, the more valuable good engineering judgment becomes.
And that's probably the biggest change AI coding agents have brought to my workflow.

Top comments (0)