Why Agents Prefer Shortcuts - And Why You Must Stop It
Understanding why LLMs prefer fragile scripts over robust systems and how to enforce Agentic Engineering.
Ask an LLM to build a user authentication system. You'll get a 400-line auth.ts with the user validation, password hashing, JWT generation, and the email-sending logic — all in one giant function. No models. No separate services. No tests. No separation of anything from anything.
It works.
And that's the problem.
The Path of Least Tokens
LLMs don't optimize for maintainability. They optimize for completion.
The fastest path from "write an auth system" to "here's your code" runs straight through a single file with no abstractions. And if you look at what these models trained on — Stack Overflow answers, tutorial blog posts, GitHub snippets — most of that code is intentionally simplified.
Nobody posts a 47-file enterprise architecture to answer "how do I handle user registration in Node.js?"
So the model learned that the expected answer is the simple one.
The Three Cheats
The same three patterns show up regardless of model or provider.
Global state abuse. Instead of passing data through explicit interfaces, the AI creates a god-object — some giant context or state variable that everything reads from and writes to. Convenient. Works. Completely unmaintainable the moment two developers (or two agents) touch the same codebase.
Silent failure. Everything gets wrapped in try/catch blocks that swallow errors. Or worse — the error is caught, "something went wrong" is logged, and execution continues as if nothing happened.
Database connections fail. HTTP requests time out. Files don't exist.
The code just... proceeds.
Implicit dependencies. The code assumes process.env.DATABASE_URL exists. It assumes redis is installed. It assumes the file system is writable. None of these are checked, documented, or handled.
How to Fix This
Don't fight the model. Constrain it.
Interface-First Development
Define the contracts before the AI writes logic. TypeScript interfaces, API schemas, database models. Everything.
interface AuthService {
register(data: SignupRequest): Promise<User>;
authenticate(credentials: LoginRequest): Promise<Session>;
resetPassword(email: string): Promise<void>;
validateToken(token: string): Promise<UserPayload>;
}
interface MailProvider {
sendWelcomeEmail(user: User): Promise<void>;
}
type UserStatus = 'pending' | 'active' | 'suspended' | 'deleted';
Now the AI's creativity is pinned to a rigid architectural spine. It can implement however it wants, but it must satisfy these interfaces.
The result is always more modular, more testable, and more maintainable.
The Multi-Step Build Loop
Don't ask the AI to "write the app."
That's how you get the 400-line auth file.
Instead, break it into verified steps:
- Generate the schema/types. Verify.
- Generate the unit tests. Verify.
- Implement the logic to pass those tests. Verify.
- Add error handling and logging. Verify.
Each step is a separate prompt. Each step gets verified before the next one starts. Slower — but you end up with code that actually works in production.
The Bigger Point
The transition from "LLM wrapper" to "agentic system" isn't about a fancier framework.
It's about recognizing that the AI will always take shortcuts unless shortcuts are structurally impossible.
A wrapper passes strings back and forth. An agentic system manages state, handles retries, observes its own reasoning — and crucially — doesn't trust itself.
The best agentic architectures treat the LLM the same way you'd treat a brilliant but unreliable contractor. Great ideas. Impressive speed.
But you'd better review the work before it goes live.
Frequently Asked Questions
Why do LLMs prefer building "monolithic" scripts over modular systems?
LLMs are trained on vast amounts of code snippets, many of which are simplified examples from tutorials or Stack Overflow. They also optimize for the shortest path to a valid-looking completion (the "path of least tokens"). Modular architecture requires more tokens and more complex cross-file reasoning, which models avoid by default.
What are the "Three Cheats" in AI-generated architecture?
The three most common architectural shortcuts are:
- Global State Abuse: Creating a single "god object" context for everything.
- Silent Failure: Swallowing errors in
try/catchblocks without proper recovery. - Implicit Dependencies: Assuming certain environment variables or files exist without explicitly checking for them.
How can I force an agent to follow better engineering practices?
The most effective way is through structural constraints. Define your interfaces, types, and schemas first. By giving the agent a predefined "skeleton," you force it to implement logic that fits into a robust, modular system rather than letting it decide the architecture on the fly.
Is multi-step implementation really worth the cost?
For production systems, yes. While asking an agent to "build the whole app" is cheaper and faster, the resulting technical debt is massive. Breaking the task into discrete, verified steps (Interfaces -> Tests -> Implementation -> Error Handling) ensures each component is production-grade.
How to cite
Pokhrel, N. (2026). "Why Agents Prefer Shortcuts - And Why You Must Stop It". Native Agents. https://nativeagents.dev/posts/current-limitations/agent-shortcuts-architecture