
How I Try to Stay in Control When Coding with AI Agents - A Personal Experience
People are often obsessed with every new AI model that arrives: how much better it is, how fast it is, how large its context window is, how well it codes, how many benchmarks it beats.
That excitement is understandable. Capability matters.
But I think we talk much less about the other side of the equation: how to use that capability properly. As AI systems become more powerful, the responsibility of using them well increases too.
This is especially true in software development.
In the past, one of the things that limited bad or misguided development was the developer’s own physical and mental capacity. When a developer became tired, they eventually had to stop. That limitation was not ideal, but it acted as a natural brake. A tired developer could still make mistakes, but at least the work would slow down.
Generative AI changes this dynamic.
With AI coding agents, the old human limit is partially removed. The agent does not get tired in the same way. It can keep producing code, refactoring files, suggesting fixes, writing tests, and modifying architecture long after the human developer’s attention, judgment, and review capacity have started to decline.
I started noticing this not when using AI for small completions, but during longer development sessions. The dangerous moment was not when the agent made an obvious mistake. The dangerous moment was when I realized I was saying “continue” without fully reviewing what had just changed.
That is where the real risk begins.
The question is no longer just “Can AI write code?” The more important question is: “Can I keep AI-assisted development under control?”
The Problem: AI Can Overrun Human Understanding
AI coding agents introduce a new kind of development failure.
The problem is not simply that AI may generate bad code. Developers have always dealt with bad code, wrong assumptions, rushed decisions, and fragile abstractions.
The deeper risk is that AI can keep producing code after the human developer has lost the ability to fully understand, review, and control what is happening.
I call this overrun.
Overrun happens when AI-assisted development moves faster than the developer’s ability to understand, review, and control it.
The work may still look productive. Files change. Tests may pass. The agent may explain itself confidently. But if I cannot explain the change, identify the risks, review the diff, and decide whether to stop or revert, then control has already weakened.
A useful way to put it is this:
The code keeps advancing, but human ownership does not advance with it.
The uncomfortable part is that nothing may look obviously wrong at first. The loss of control is often gradual. I stop reading every line of the diff. I start scanning for obvious mistakes. I ask the agent to “clean it up” or “handle the edge cases.” Then I realize the change is larger than what I can comfortably hold in my head.
At that point, the problem is no longer just code quality. It is control.
The Many Forms of Overrun
Overrun is not one thing. It appears in several forms.
I find it useful to name these forms because it makes them easier to notice. Once I can name what is happening, I can stop earlier and bring the work back under control.
These forms often overlap. A speed overrun can create a diff overrun. A scope overrun can create an architecture overrun. A fatigue overrun can make all the others worse.
Still, the names are useful.
1. Pace and Size Overrun
This is about speed and volume.
AI can generate code faster than a human can review it. If an agent can produce ten files in two minutes, but I can review only two files carefully, then two files is the real safe batch size.
I can usually feel pace and size overrun when the diff becomes too large to hold in my head. I stop asking “Do I understand this?” and start asking “Does anything look obviously wrong?”
That is a weak review posture.
Speed overrun happens when the agent produces more code than I can understand in one review pass.
Diff overrun happens when too many files or concepts change at once.
The practical rule is simple:
No AI output should be larger than my current review capacity.
A healthy AI-assisted change should be easy to summarize:
- This commit adds a failing test for expired coupons.
- This commit fixes the coupon validation logic.
- This commit renames a helper for clarity.
If all of those are mixed together, the work is no longer shaped for human understanding.
2. Scope and Design Overrun
This is about where the task goes.
AI agents are often helpful because they notice related improvements. But that is also what makes them risky. A bug fix can become a refactor. A validation change can become an API redesign. A small feature can become an architecture cleanup.
Scope overrun happens when the work no longer matches the original mission.
A good test is this: can I still explain the change using the original task title?
If the task was “fix expired coupon validation,” but the diff includes API cleanup, helper extraction, snapshot updates, and a new validation layer, then the work has probably expanded too far.
Architecture overrun happens when the agent introduces new abstractions, layers, patterns, or structural decisions without explicit approval. The code may work, but the system may become harder to reason about.
A useful rule:
AI should not discover architecture while coding. Architecture should be discussed before implementation.
Refactor overrun happens when a small fix turns into cleanup or redesign. Refactoring is useful, but mixing it with behavior changes makes review harder.
A simple rule helps:
Bug fixes and refactors should be separate unless there is a clear reason to combine them.
Scope and design overruns are dangerous because they often feel productive. The agent is not obviously failing. It is doing too much.
3. Evidence and Trust Overrun
This is about confidence.
AI-generated code can look clean, use the right style, come with a confident explanation, and include tests. But plausibility is not evidence.
Trust overrun happens when I accept the code because it looks good, not because I have verified it.
Evidence may include passing tests, manual verification, edge case analysis, a clear diff summary, security considerations, and a rollback path.
A simple rule:
AI output is not trusted until it provides evidence.
Test overrun happens when the agent changes tests to match the implementation instead of proving the intended behavior. The test suite may pass, but the tests may no longer protect what I actually care about.
For important behavior, I prefer to define acceptance scenarios before implementation:
- Expired coupons must be rejected.
- Valid coupons must still be accepted.
- Existing discount behavior must not change.
- Invalid coupon formats must fail safely.
Context overrun happens when the agent solves the problem in isolation instead of following the existing project. The code may be good in general, but wrong for this codebase.
A useful instruction is:
Before implementing, find similar examples in the codebase and explain which pattern this change should follow.
Ownership overrun is the most serious form in this group. It happens when I can no longer explain the code that is about to be merged.
The final rule is simple:
No AI-generated code is mergeable unless I can explain it.
4. Risk and Power Overrun
This is about authority and consequences.
Some changes are more dangerous than others. A typo fix and an authorization change should not be treated with the same level of control. A local helper and a database migration are not the same kind of risk.
Dependency overrun happens when the agent adds a new package too easily. The agent may see a dependency as a shortcut. I inherit it as an ownership cost.
Before accepting a new dependency, I want to know:
- the reason it is needed
- an internal alternative
- license considerations
- maintenance status
- security risk
- runtime or bundle impact
Security overrun happens when the agent weakens validation, authorization, input handling, output handling, or sensitive data boundaries. Any change touching user input, authentication, permissions, data, shell commands, SQL, files, network calls, or secrets deserves stricter review.
For security-sensitive changes, I want to ask:
- How could this fail?
- How could this be abused?
- What input is untrusted?
- What authorization is required?
- What data could leak?
- What tests or checks prove the boundary still holds?
Permission overrun happens when the agent has more tool access than the task requires. A small task should not be performed with unnecessarily large power.
A simple rule:
The agent should have the least power needed for the current task.
For many tasks, the correct first step is not “edit the code.” It is:
Read the relevant files, explain the current behavior, suggest a plan, and do not change anything yet.
Fatigue overrun happens when I am tired, but the AI agent keeps generating.
A warning sign is when I start saying things like:
- continue
- fix all
- clean it up
- just handle it
At that point, the agent should become read-only.
Allowed in fatigue mode:
- summarize
- explain
- list risks
- review
- suggest tests
- create a plan
Not allowed in fatigue mode:
- write new code
- refactor
- change tests
- modify migrations
- touch security-sensitive code
AI removes the natural brake, so I need to create an intentional one.
The Simple Loop I Use to Stay in Control
All these forms of overrun point to the same underlying problem:
AI-assisted development can move faster than human understanding.
So my solution is not complicated. I try to create a simple control rhythm that keeps me in charge:
Frame Limit Build Check Stop or Continue
This is not meant to be a formal process. It is just a practical loop I use when working with AI coding agents.
Each step protects against a different kind of overrun:
- Frame helps prevent unclear goals and scope overrun.
- Limit helps prevent excessive permissions and uncontrolled changes.
- Build keeps output small enough to review.
- Check restores understanding before more code is produced.
- Stop or Continue makes stopping a normal part of responsible development.
This loop will not prevent every bad AI-generated change. It is not a substitute for tests, security review, or engineering judgment. Its value is simpler: it gives me a way to notice when the agent is starting to outrun me.
1. Frame
Before asking the agent to code, I define the mission.
Many failures start with a vague request like:
Fix this and clean it up.
A better frame is specific:
Goal: Fix expired coupon validation. Not allowed: API changes, database changes, or new dependencies. Done when: expired coupons fail and valid coupons still pass.
When I frame the work, I ask:
- What are we fixing or building?
- Why are we doing it?
- What is not part of this task?
- What would count as done?
The frame gives the work a center of gravity. It also gives me a standard to review against later. If the final change no longer matches the original frame, an overrun has started.
2. Limit
After framing the task, I give the agent explicit limits.
An AI agent may be able to edit many files, run commands, add dependencies, modify tests, refactor code, change architecture, or access tools. Responsible use means giving it only the freedom required for the current step.
I ask:
- Which files may it touch?
- How many files may it change?
- Can it modify tests?
- Can it add dependencies?
- Can it change architecture?
- Can it run commands?
- When must it stop?
For example:
Only change discount.ts and discount.test.ts. Do not add dependencies. Do not refactor unrelated code. Stop after the first implementation and explain the diff.
The rule is simple:
The agent should have the least freedom needed for the current step.
Limits do not make the agent less useful. Limits make the agent’s work reviewable.
3. Build
After framing and limiting the task, I let the agent build.
But I try to keep the build step small.
A risky build instruction is:
Fix everything and make it production ready.
A better instruction is:
Make the smallest change that fixes this bug. Do not modify more than two files. Stop after the change.
The purpose of Build is not to get the maximum amount of code from the agent. It is to get a controlled unit of change that I can inspect, understand, test, and own.
A good Build step should produce one focused thing:
- one small implementation
- one focused test
- one clear refactor
- one bounded investigation
- one isolated fix
The goal is not to match the agent’s speed. The goal is to keep the agent inside a pace that preserves human understanding.
4. Check
After the agent builds, I try not to immediately continue.
I check first.
I ask:
- What changed?
- Why did it change?
- Which files were touched?
- What tests prove it?
- What risks remain?
- What was intentionally not changed?
- How can I revert it?
The Check step is not only about verifying that the code works. It is about verifying that I still own the work.
The most useful question is:
Can I explain this change without asking the AI again?
If the answer is no, the work is not ready.
Checking is how I restore control before more code is produced.
5. Stop or Continue
After checking, I decide whether to continue.
I continue only if I can say:
- I understand the change.
- The scope is still controlled.
- The diff is reviewable.
- The evidence is enough.
- I can revert it.
If not, I stop.
Stopping is not a failure. It is part of the control process. It means the loop detected an overrun before the damage became harder to reverse.
When in doubt, I stop generation and switch the agent to read-only mode:
Summarize the current diff. Explain the risk. Identify what is outside scope. Suggest the smallest safe next step. Do not write code.
The loop only continues when understanding is restored.
The Real Goal
The goal of AI-assisted development is not simply to produce more code. More code is useful only if it comes with more clarity, more evidence, and more control. A healthy AI development process should make the developer faster without making them less accountable.
The moment code increases while understanding decreases, the system is being overrun.
I do not think the answer is to use AI agents less. The answer is to stop treating speed as the only measure of progress.
If an agent helps me write code faster but leaves me less able to explain, test, or own that code, I have not actually moved faster. I have only moved the risk forward.
So the habit I try to keep is simple:
Frame the work. Limit the agent. Build in small batches. Check deeply. Stop or continue based on whether ownership remains.
That is the essence of responsible AI-assisted development for me.
Leave a Reply
Your e-mail address will not be published. Required fields are marked *