In 2026, producing code is no longer the expensive part of software development.
Coding agents can explore a repository, implement features, write tests, run them, fix failures and review pull requests. A change that might once have taken hours can now appear in minutes.
That's useful. But it creates a different problem: we can generate implementation faster than we can properly understand it.
For me, that changes the job of the reviewer.
I care less about whether a piece of code was written by a developer, Copilot, Claude or another agent. What matters much more is whether the change makes sense in the context of the system and whether the team understands what it is about to own.
Good-looking code is easy to trust
One thing coding agents are very good at is producing code that looks convincing.
The naming is usually reasonable, formatting is clean, types are there, and tests may already exist.
That makes it surprisingly easy to review too quickly.
Imagine an agent generates this:
export async function getUser(id: string) {
try {
const response = await fetch(`/api/users/${id}`);
if (!response.ok) {
throw new Error("Failed to load user");
}
return response.json();
} catch (error) {
console.error(error);
throw error;
}
}
There is nothing obviously terrible about this. It probably works.
Now imagine the rest of the application already does this:
import { apiClient } from "@/lib/api";
import { logger } from "@/lib/logger";
const user = await apiClient.get(`/users/${id}`);
The generated version has just introduced another HTTP pattern, another error-handling strategy and direct use of console.error.
It may also bypass authentication, retries, tracing or other behavior already implemented in apiClient.
The code isn't necessarily wrong in isolation. It's wrong for the codebase.
That is one of the things I pay much more attention to today.
I usually read the requirement before the diff
When a pull request arrives, the natural reflex is to open the changed files immediately.
I try not to do that anymore, especially when a lot of the implementation was generated with an agent.
I first want to understand what the change was supposed to achieve.
Coding agents are very good at following instructions. The problem is that instructions are often incomplete.
Suppose the requirement says:
Only employees should be able to register.
An agent could easily generate a sophisticated email-validation utility that supports international domains, quoted addresses and a long list of RFC edge cases.
That might be technically correct, but it completely misses the point.
If the actual rule is simply that employees use a company address, this may be enough:
const isEmployeeEmail = (email: string) =>
email.endsWith("@company.com");
So before I spend time discussing abstractions or implementation details, I want to know whether the solution actually matches the requirement.
Did we miss an important business rule?
Did we solve a problem that wasn't really there?
Did the implementation make assumptions that were never part of the request?
These questions are not specific to AI. They were useful before Copilot existed.
AI just makes it much easier to generate a lot of polished code around the wrong assumption.
Repository context matters more than local correctness
Agents are getting much better at exploring existing projects.
They can search the repository, inspect nearby files, reuse utilities and follow project-specific instructions.
Modern AI reviewers can go further. Repository instructions, files such as AGENTS.md, agent skills and external context exposed through MCP can all give them a better understanding of the system.
That closes part of the gap.
But repository context is still not the same thing as domain knowledge, organizational memory or understanding why a decision was made three years ago.
A repository does not always contain the full story.
Some decisions only make sense if you know the history of the product.
Maybe an application deliberately avoids global state because the team spent months removing it.
Maybe an API client has unusual retry logic because one external service is unreliable.
Maybe an abstraction looks awkward because several teams depend on it.
Maybe a field that looks obsolete is still needed by an older mobile client.
An agent may see the code without knowing any of that.
This is where an experienced reviewer can still bring context that doesn't exist in the task description or even in the repository itself.
When I review a change, I pay attention to whether it introduces a second way of solving a problem that the project already knows how to solve.
I also look for new dependencies, duplicated utilities or abstractions that don't really match the surrounding code.
AI did not invent architectural inconsistency.
It simply made it easier to create more of it, faster.
Passing tests don't always mean what they used to
This is one of the areas where my review habits have changed the most.
A few years ago, a pull request with good test coverage gave me a fairly strong signal that the author had thought through the behavior.
Today, the implementation and the tests may both have been generated by the same agent from the same prompt.
That means they can share the same misunderstanding.
Imagine the requirement is:
A user cannot cancel an order after shipment.
The implementation is:
function canCancel(status: OrderStatus) {
return status !== "delivered";
}
And the generated tests are:
expect(canCancel("pending")).toBe(true);
expect(canCancel("delivered")).toBe(false);
Everything is green.
The problem is that "shipped" was the important state.
The tests prove that the implementation behaves as expected by the implementation.
They don't prove that the implementation matches the business rule.
So I still care about test coverage, but I spend more time checking where the test cases came from.
For important business logic, I want at least some cases to be derived from acceptance criteria, domain rules or known edge cases rather than from the code itself.
Security is still where I slow down
Security-sensitive code has always deserved more scrutiny.
What AI changes is how easily an implementation can look complete while still missing the policy behind the mechanism.
Imagine an agent adds this check:
if (req.user.role !== "admin") {
return res.status(403).end();
}
const customer = await db.customer.findUnique({
where: { id: req.params.id },
});
return res.json(customer);
The authorization check is there.
The code is readable.
The tests might even confirm that non-admin users receive a 403.
But imagine this is a multi-tenant application.
The real business rule may be:
An admin can only access customers belonging to their own organization.
The agent implemented the visible security mechanism — role-based authorization — but missed the actual policy.
The query should probably also be constrained by something like:
const customer = await db.customer.findFirst({
where: {
id: req.params.id,
organizationId: req.user.organizationId,
},
});
This is the kind of mistake I worry about more with generated code.
Not because agents are uniquely bad at security, but because they can implement the obvious mechanism very convincingly while missing a constraint that only exists in domain knowledge or product rules.
I deliberately spend more time around authentication, authorization, tenant boundaries, permissions, database queries, user input, file access, payments and personal data.
Static analysis, security scanners and AI reviewers are useful here.
I want them in the pipeline because they catch things humans miss.
But they cannot infer every business permission rule.
Sometimes the dangerous part is not the code that is present.
It's the constraint that never made it into the implementation.
I stopped using AI-generated volume as the main signal
The amount of generated code can still be a useful secondary signal.
A huge one-shot diff deserves attention simply because there is more surface to understand.
But I don't use AI-generated volume as the primary measure of review depth.
An agent can refactor hundreds of repetitive lines without changing much risk.
A ten-line change to authorization, payments, IAM permissions or a database migration can be far more important.
So I look first at what the change can affect.
A small styling change deserves a small review.
A new permission model deserves much more attention, regardless of whether it took a developer two hours to write or an agent thirty seconds to generate.
For me, risk and blast radius matter more than how much of the diff came from AI.
Let automation do the first pass
By 2026, AI is not only generating code.
It is reviewing it too.
I think that's a good thing.
I want automation to take the first pass before another developer spends attention on the pull request.
Linters, type checkers and static analysis can catch deterministic problems.
AI reviewers can go further: inspect surrounding code, flag suspicious logic, follow repository-specific instructions and increasingly pull in additional context.
That is useful.
But I don't see it as replacing the human review.
I see it as changing where human attention is most valuable.
There is already some evidence that this distinction matters.
A 2026 study of 1.02 million reviewed pull requests across 207 GitHub projects found that some agent-involved review patterns were associated with faster review decisions, but those efficiency gains did not translate into better review quality according to the study's measures.
That leaves the human reviewer more time for the questions that are harder to automate.
Does the change make sense?
Does it fit the architecture?
What happens when it fails?
Are we introducing a new risk?
Will the team still be comfortable maintaining this code later?
That's a better use of review time than arguing about something ESLint could have fixed automatically.
"Why?" is still one of the best review comments
One thing I have noticed since using coding agents more often is that I ask very simple questions in reviews.
Why do we need this abstraction?
Do we already solve this somewhere else?
What happens if this call fails?
Why are we introducing this dependency?
Does this actually match the requirement?
Could this be simpler?
None of those are specifically AI-related questions.
They are just normal engineering questions.
That's also why I'm less convinced that "AI code review" needs to be treated as an entirely separate discipline.
Most of the problems are familiar.
Developers were already over-engineering before Copilot.
We already introduced unnecessary dependencies, missed edge cases and misunderstood requirements.
The main difference is that agents can now produce these mistakes at a much higher speed and often wrap them in code that looks perfectly reasonable.
The developer still owns the result
If I submit code generated by an agent, I still consider it my code.
I should be able to explain what the change does, why this approach was chosen, what assumptions it makes and where the important risks are.
If I can't explain why a piece of code exists, I probably shouldn't be asking someone else to approve it.
That doesn't mean memorizing every generated line or pretending the agent wasn't involved.
It just means that using AI does not remove responsibility from the developer who submits the change.
For me, that's one of the most important habits to keep as these tools become more capable.
How I actually review these changes
I don't follow a strict framework.
Most of the time, I start by checking whether the pull request solves the right problem.
Then I look at how well the implementation fits the existing codebase and where the real risk is.
After that, I spend more time on things like permissions, failure modes, edge cases and whether the tests reflect the requirement rather than simply confirming the implementation.
How deep I go depends entirely on the change.
A CSS adjustment doesn't need the same level of attention as an authorization rule.
A mechanical refactor isn't the same as changing how data is persisted.
A new dependency may deserve more discussion than fifty lines of ordinary application code.
That sounds obvious, but I find it more useful than trying to invent a special review process based on how much AI was involved.
What this looks like at team level
The harder question is not how one developer should review AI-assisted code.
It's how a team keeps review quality consistent when agents can generate more changes, more quickly, across multiple repositories.
I don't think the answer is to add an "AI-generated" label and review everything more aggressively.
I would rather make the risk visible.
A pull request touching authorization, payments, IAM, migrations, public APIs or sensitive data should probably trigger a different level of review than a mechanical refactor or a styling change.
That can be reflected in the workflow:
- require additional reviewers for high-risk areas;
- run stronger CI or security checks when sensitive paths change;
- make acceptance criteria explicit before implementation starts — review starts before the diff exists;
- ask authors to call out assumptions, failure modes and risky decisions in the pull request;
- keep some test cases independent from the implementation, especially for important business rules;
- use AI reviewers as an early pass, not as the final approval boundary.
The important part is that these rules should be based on what the change can affect, not on whether the code came from an agent.
At team scale, AI makes it even more important to route human attention toward the changes where context, judgment and accountability matter most.
What changed for me
AI hasn't made me distrust every generated line.
If anything, I spend less time obsessing over individual lines than I did before.
I'm more interested in the decisions behind them.
Implementation is getting cheaper.
Generating another version is cheap.
Writing basic tests is cheap.
Refactoring is cheap.
Understanding the domain is not.
Knowing which edge case actually matters is not.
Making a good architectural trade-off is not.
And taking responsibility for what goes into production certainly isn't.
The biggest change in code review, at least for me, is that AI makes implementation faster without making understanding faster.
A good review is therefore less about proving that the code works in isolation and more about making sure the team understands the change it is about to own.
I suspect that will matter even more as coding agents continue to improve.
Your Turn
I'm curious how this has changed for other teams.
When you review AI-assisted code today, what do you find yourself checking more carefully than you did a few years ago?
And what do you no longer trust just because CI is green?
I'd be interested to hear how your own review habits have changed.
Further Reading
A few resources that are useful regardless of whether the code was written by a developer or generated with an agent:
- Google Engineering Practices — Google's code review guidelines
- GitHub Copilot Code Review documentation — repository instructions, agent skills, additional context and human validation
- From Human-Centric to Agentic Code Review: The Impact of Different Generations of Generative AI Technology on Review Quality — 2026 empirical study of 1.02 million reviewed pull requests
- GitHub Pull Request Documentation — pull request and review workflows
- OWASP Code Review Guide — security-focused code review
- ESLint — JavaScript and TypeScript linting
- SonarQube — static analysis and maintainability
- Snyk — dependency and application security analysis
Top comments (0)