DEV Community

Sospeter Mong'are
Sospeter Mong'are

Posted on

Your AI Agent Is Not an Engineer

Building Reliable Software in the Age of Agentic Coding

A few weeks into using coding agents seriously, not for autocomplete, but for actually driving multi-file changes, wiring up integrations, standing up agent pipelines, I noticed a pattern. The code that came out looked right. It compiled, it ran, the demo worked. And then, days later, something broke in a way that made it obvious the agent had never actually understood the system it was working in. It had pattern-matched its way to a plausible-looking answer.

That's the core thing to internalize: a coding agent is a very good pattern completer, not an engineer. Engineers hold intent, constraints, failure modes, and tradeoffs in their heads at the same time. Agents hold a context window. Confusing the two is where reliability problems start.

What coding agents are actually good at

To be fair to the tools, they've earned their place in the workflow:

  • Boilerplate and scaffolding. CRUD endpoints, config files, test skeletons, repetitive glue code across a codebase.
  • Translating a clear spec into a first draft. If you can describe the shape of what you want precisely, an agent will get you 80% of the way there fast.
  • Working across unfamiliar syntax. An agent that's seen a thousand times more Terraform or SQL dialects than you have can save real research time.
  • Mechanical refactors. Rename this across 40 files, migrate this API surface, update this dependency's usage pattern everywhere it appears.

These are real productivity gains. The mistake is extrapolating from "good at boilerplate" to "can be trusted with architecture."

Where they fail

The failures aren't random, they cluster in predictable places:

  • Silent scope narrowing. Ask an agent to "handle errors properly" and it will handle the errors it can see in the current file, not the ones three layers up the call stack that your actual production traffic hits.
  • Confident wrongness. Agents don't have a strong signal for "I'm not sure." They'll write a Daraja API callback handler that looks idiomatic and is subtly wrong about idempotency, with the same confidence as one that's correct.
  • Local optimization, global blindness. An agent fixing a bug in one service has no model of the three other services that depend on the behavior it just changed.
  • Security as an afterthought. Left to their own devices, agents will happily hardcode a secret, skip input validation, or generate SQL that's one crafted string away from an injection, because none of that breaks the immediate task.
  • Test theater. Agents will write tests that pass, sometimes because they wrote the test to match the implementation's actual (wrong) behavior rather than the intended one.

None of this is a knock on the tools. It's what you'd expect from a system optimizing for "produce plausible next tokens" rather than "hold this system accountable over time."

Why fundamentals matter more, not less

The tempting narrative is that agentic coding makes engineering fundamentals less relevant, that if the AI writes the code, you don't need to understand it as deeply. The opposite is true.

When you're the one writing every line, your understanding is forced on you by the act of typing it. When an agent writes it, understanding becomes optional, and skipping it is exactly how systems accumulate debt nobody can explain later. The engineer's job shifts from writing correct code to specifying, verifying, and bounding correct code. That's arguably a harder skill, not an easier one. It requires the same grounding in data modeling, failure modes, concurrency, and system boundaries, just applied at review time instead of write time.

If you don't already know what a race condition looks like, you won't catch one in a 400-line diff an agent generated in nine seconds.

Context management

Most agent failures I've traced back aren't reasoning failures, they're context failures. The agent didn't have the right information in front of it, so it filled the gap with something plausible.

Practical habits that help:

  • Keep the agent's working context scoped to the smallest slice of the system that's actually relevant. A bloated context window doesn't mean better decisions, it often means diluted attention.
  • Externalize constraints instead of assuming they're inferred: rate limits, idempotency requirements, data retention rules, compliance boundaries. Say them explicitly, every time, rather than trusting the agent remembers them from three turns ago.
  • Treat the agent's memory of your codebase as a snapshot, not a live view. If you changed something in another session, don't assume it knows.

Testing AI-generated code

Agent-written code needs a different testing posture than human-written code, because the failure distribution is different. Where a human engineer tends to make errors of omission under time pressure, an agent tends to make errors of false confidence, it will implement something that looks complete but quietly diverges from the spec.

That argues for:

  • Writing the test cases yourself, or at minimum reviewing them line by line, rather than letting the agent write both the implementation and its own tests.
  • Testing the boundaries the agent wasn't explicitly told about, the empty list, the network timeout, the malformed webhook payload, since those are exactly where pattern-completion breaks down.
  • Running generated code against real, messy data before trusting it against clean fixtures.

Security risks

Agentic coding introduces a security surface that didn't exist five years ago, and it's not hypothetical:

  • Secrets leakage. Agents pulling credentials into logs, commits, or prompts they shouldn't.
  • Dependency sprawl. An agent reaching for a package to solve a small problem, without anyone evaluating its maintenance status or supply-chain risk.
  • Injection through generated code. String-built queries, unsanitized inputs, permissive CORS, the classic mistakes, just produced faster and in more places at once.
  • Prompt injection in agent pipelines. If your agent reads external content (a webpage, a customer message, a file) as part of its task, that content can carry instructions the agent will follow unless you've explicitly hardened against it.

None of this is solved by "the agent is usually careful." It's solved by treating every agent-touched surface as untrusted until reviewed, the same discipline you'd apply to a contributor you'd never met.

Reviewing agent decisions

Code review of agent output has to be different from code review of a colleague's PR, because the failure mode is different. A colleague's mistake usually comes with a reasoning trail you can interrogate. An agent's mistake often doesn't, it just produced the output.

That means review has to reconstruct the "why," not just check the "what":

  • Ask the agent to explain its reasoning before accepting a nontrivial change, and read the explanation critically, not as a formality.
  • Diff against intent, not just against the previous version. Does this change actually do what was asked, or does it do something adjacent that happens to pass the visible tests?
  • Be especially suspicious of changes that touch more files than the task seemed to require. That's often where an agent "helpfully" over-scoped.

Keeping humans in control

The workflows that hold up under real production load share a shape: agents propose, humans dispose. Concretely, that looks like:

  • Agents work in tightly scoped tasks with clear, checkable success criteria, not open-ended "improve this system" mandates.
  • Every agent-generated change goes through the same review gates as human-generated change, with no shortcut for "the AI wrote it so it's probably fine."
  • Irreversible or high-blast-radius actions, deployments, schema migrations, anything touching payments or customer data, require an explicit human approval step, not just an agent's self-assessed confidence.
  • Someone on the team remains accountable for understanding the system end to end, even if they didn't type most of the code.

The bottom line

Coding agents are a genuine force multiplier for the parts of engineering that were always mechanical. They are not a substitute for the parts that were never mechanical: judgment about tradeoffs, understanding of failure modes, and accountability for what ships. Building reliable software with agentic tools doesn't mean trusting them more as they get better. It means getting sharper about exactly where the boundary of their competence sits, and refusing to let that boundary quietly drift because the code that came out looked right.

Top comments (0)