Leveling up with AI
AI amplifies your skill level — if you're skilled, it makes you faster; if you're not, it makes you produce more bad code, faster. Here's how to stay in the driver's seat and get the acceleration without the mess.

If you've been riding the AI wave in software development and wondering how to get the speed without the mess, this post is for you. You'll walk away with a clear framework for staying in the driver's seat: four practices to cut AI slop, and how to level up your AI usage.
The last two years in software development can be defined as a high-speed train ride. Every three to four months there was a major breakthrough in AI, and more and more you adopted it to keep up with the trendsetters. It started with using AI to ask questions and help with code snippets, and has since grown to encompass every facet imaginable.
This is no different at SAP. SAP rivals other tech giants in the business sphere. To stay ahead, SAP changed course last year and fully committed to AI. One of the changes affects how we build features — we're not just adopting AI tools; we're redesigning our entire Product Development Lifecycle around AI to ship faster. The code is becoming cheaper to produce, but it sometimes comes at a price. You can see it already in the news, outages at companies that were caused by AI-written code. AI can produce slop tenfold. There is a great article examining the leaked Claude codebase, where someone took the time to check code that Anthropic apparently claims is 100% AI-written. Looking into it, you can easily see how best practices are avoided to accommodate for speed. This is why we have to strive for a reasonable success metric:
"Success = same AI usage, way less AI slop. And ultimately: fewer incidents, fewer runtime failures, more readable code."
To make this concrete, let me share a personal example that mirrors what I see at work. AI has also lowered the bar for entering into coding — or at least it gives that illusion. I work on a side project with a relative who is a skilled professional in the pharma industry. Tools like Base44 or Lovable, coupled with the ChatGPT Codex plugin, allowed him to materialize his ideas and produce a proof of concept — but not a product. The distinction matters, and I noticed three recurring patterns of AI slop when AI is used without sufficient engineering guidance.
Pattern 1: Self-Reinforcing Bad Decisions
What happened: AI checked the existing codebase, copied snake_case logic that was wrong, and multiplied it across new APIs.
Why it matters: Once you do something wrong, AI amplifies it — there is no critical thinking to catch the mistake.
Pattern 2: Silent "Fixes" That Serve No Purpose
What happened: The frontend called a non-existent API, threw an error, and AI added a mock response to silence it instead of fixing the root cause.
Why it matters: Technical debt accumulates invisibly; no one notices until months later.
Pattern 3: Breaking Changes with Hidden Ripple Effects
What happened: A database migration script order changed (likely due to duplicate version numbers), a checksum failed, and the server wouldn't start.
Why it matters: AI doesn't understand system-level dependencies; small changes can cascade.
Because code is now a cheap byproduct, this increases the time spent fixing code or adding new features on top of a shaky foundation. It took me five to six hours of refactoring — mostly deleting questionable code — to fix the failed service start. It was a constant back-and-forth trying to understand why the AI made certain choices and what the implications would be when addressing the issues. Deleting one thing often broke something else, due to the way AI had structured the logic.
Credit where credit is due. On the same project, I used Claude Code to refactor that messy code — because I had the engineering background to guide it. Later, after a code freeze, I used AI to fix all the broken tests my partner's changes had caused, tests I'd had to disable earlier. With proper direction, AI accelerated me. Without it, AI created a mess.
"So what's the difference? How do we get the acceleration without the mess?"
The Core Principle
"AI amplifies your skill level. If you're skilled, it makes you faster. If you're not, it makes you produce more bad code, faster."
I've identified four practices that make the difference.
Practice 1: AI is an Assistant, Not a Replacement
You own the architecture, the trade-offs, and the quality. That ownership extends to code review: when AI generates code, reviewing it becomes more critical, not less — because AI won't flag its own silent assumptions or missing error handling.
Example: "I used Cursor to scaffold REST APIs and define endpoints, but I manually reviewed error handling and edge cases because the AI assumed happy paths."
Practice 2: Stay in the Driver's Seat
Manually write code where you can; use AI to refactor and improve.
Example: "The snake_case problem happened because my partner never wrote the initial version himself — he let AI make the first architectural choice."
Practice 3: Always Verify with Tests
AI code can be wrong or non-idiomatic.
Example: "The mock API 'fix' would have been caught immediately if we had a test that expected a real API response. Tests are your guardrail."
Practice 4: Use AI Beyond Code Generation
Coding isn't the only bottleneck — planning, debugging, and documentation all benefit.
Example: "I used AI to help me understand legacy code relationships when debugging that migration failure. It saved me from reading ten files manually."
Leveling Up: From Level 3 to Level 4
The four practices above are the foundation — but they still describe Level 3 behaviour: you and AI, working together step by step. So what does Level 4 actually look like, and how do you get there?
At Level 4, AI implements full features from a spec; you review. The back-and-forth shrinks dramatically. Instead of guiding AI through every decision, you invest that energy upfront — writing a clear, complete specification — and then let AI execute it autonomously. Your primary activity shifts from writing code to reviewing it critically.
That shift sounds simple, but it requires three things to work well:
1. Write specs, not prompts
A Level 3 prompt might be: "Add an endpoint that returns user activity." A Level 4 spec looks more like a mini design document: the endpoint path, request/response shape, error cases, edge cases, and which existing patterns to follow. The more unambiguous your input, the less AI has to guess — and the less slop you get back. This is the "specification, not syntax" principle in action.
Example: Instead of "Add an endpoint that returns user activity", a Level 4 spec reads:
"Add a
GET /api/v1/users/{userId}/activityendpoint. Return a paginated list ofActivityEventobjects (seesrc/models/ActivityEvent.javafor the existing type). Use the same pagination pattern asGET /api/v1/users/{userId}/sessions. Return 404 if the user doesn't exist, 403 if the requesting user lacks permission. Exclude events of typeSYSTEM_INTERNAL. Add a test for each error case."
The AI now has a success criterion it can verify itself. There is no room for interpretation, so there is no room for slop.
2. Give AI the right context upfront
At Level 3, you correct AI mid-conversation when it goes off-track. At Level 4, you prevent it from going off-track in the first place. That means providing architecture notes, naming conventions, relevant existing code, and explicit constraints before AI starts. Tools like Claude Code's CLAUDE.md or Cursor's .cursorrules let you encode these standards once and have them applied automatically on every task.
Example: A CLAUDE.md for a typical backend service might include:
- All API responses use the ApiResponse<T> wrapper type (see src/types/ApiResponse.java)
- Database access goes through the repository layer — never query directly in controllers
- Use annotations for all input validation
- Error handling follows the pattern in src/exceptions/GlobalErrorHandler.java
- Always use specific type where applicable; use interfaces and abstract classes to narrow the type explicitly
- Always use Optional<T> to handle null pointers
Without this context, AI invents its own conventions. With it, the generated code fits your codebase on the first attempt — no mid-conversation corrections needed.
3. Shift your skill to code review
When AI writes a full feature, your job becomes catching what it got wrong. This requires a different kind of attention than writing code yourself — you're looking for silent assumptions, missing error handling, non-idiomatic patterns, and security gaps. Strong code review skills become your most important asset at Level 4. Tests (Practice 3) are your safety net; your review is the last line of defence.
Example: When reviewing an AI-generated database migration, I noticed it didn't wrap the operations in a transaction. The happy path worked perfectly — but on failure, the database would have been left in a partial state. The AI had no way to know this was a requirement; it wasn't in the spec. That's the kind of gap you only catch if you know what to look for. My review checklist for AI-generated code now always includes: Does it handle partial failure? Does it follow our error handling pattern? Are there any silent catch blocks that swallow exceptions?
The engineers who make this transition successfully aren't the ones who trust AI the most — they're the ones who have built enough engineering depth to know exactly where AI is likely to fail, and who design their workflow around catching those failures before they reach production.
Scaling to the Team
The four practices and the Level 4 transition above are framed as individual habits — but AI slop is rarely just an individual problem. When a whole team is generating code with AI, the failure modes multiply: inconsistent conventions, duplicated prompt work, and AI-generated code that slips through review because nobody agreed on what "good" looks like.
If you're a tech lead or engineering manager, here are three levers that make the biggest difference at the team level.
1. Shared context files
The CLAUDE.md and .cursorrules examples above shouldn't live on one engineer's machine — they belong in the repository, versioned alongside the code. A shared context file means every engineer's AI sessions start from the same baseline: the same naming conventions, the same architectural constraints, the same error-handling patterns. Without it, each engineer is effectively training their own AI on their own habits, and the codebase drifts.
2. AI usage guidelines
Teams benefit from a short, explicit agreement on when to use AI and when not to. This doesn't need to be a policy document — a one-page team norm is enough. Useful questions to answer: Which parts of the codebase are off-limits for autonomous AI generation (e.g., security-critical code, database migrations)? What's the minimum spec quality before handing a task to AI? Who is accountable for AI-generated code once it's merged?
3. A review checklist for AI-generated code
Standard code review catches logic errors. AI-generated code introduces a different class of problems: silent assumptions, missing error handling, non-idiomatic patterns, and security gaps that look plausible at a glance. A short, shared checklist — Does it handle partial failure? Does it follow our error-handling pattern? Are there silent catch blocks? — gives reviewers a consistent lens and makes it harder for AI slop to slip through. Over time, the checklist becomes a living document that captures the failure modes your team has actually encountered.
None of this requires a big process overhaul. Start with a shared context file in the repo, agree on two or three review questions for AI-generated PRs, and revisit after a sprint. The goal is the same as for individuals: same AI usage, way less slop.
What do all these practices have in common? Engineers who win are those who frame problems better. As many great engineers have pointed out: the future skill is specification, not syntax. The engineers who thrive with AI won't be those who prompt the most — they'll be those who think the clearest.
Published by...
