AI-Assisted Coding: How to Use It Without Losing Your Skills
There’s a conversation happening in engineering teams right now about AI coding tools: Are they actually useful? Are developers who use them becoming less capable? Will they replace junior engineers? The answers are yes, yes (if used carelessly), and no - but none of those require much elaboration. What’s more useful is understanding how to use these tools well.
The engineers getting the most value from AI coding tools share a specific pattern: they use AI to handle things they already know how to do, not things they haven’t learned yet. That distinction matters more than any other.
Where AI Coding Tools Genuinely Help
Boilerplate and scaffolding: Writing the structure of a REST endpoint, a test class, a database migration, a React component - these involve a lot of code that follows predictable patterns. AI tools generate this quickly and accurately. The time savings are real.
Completing code you’re already writing: When you know the approach and are partway through implementing it, autocomplete suggestions can save significant keystrokes. The model has seen patterns like yours thousands of times and can often complete your thought correctly.
Translation across syntactic contexts: Converting a JavaScript snippet to TypeScript, translating SQL to an ORM query, reshaping a data structure - these mechanical transformations are tedious to do manually and AI does them well.
Documentation and comments: Generating docstrings, describing what a function does, writing a commit message that summarizes a diff. Writing about code is different from writing code, and AI is good at it.
Generating test cases: Given a function, AI tools can suggest test cases that cover obvious paths. They’re not as good at thinking about subtle edge cases as a developer who understands the domain, but they’ll cover the obvious ones and often suggest some you hadn’t thought of.
Where They Mislead You
Confident wrongness: AI coding tools will generate incorrect code with the same confidence as correct code. A hallucinated API method, a misremembered function signature, a subtly wrong algorithm - these are visually indistinguishable from correct suggestions. If you accept suggestions without reading and understanding them, you will ship bugs from AI-generated code that you would not have written yourself.
Plausible but insecure code: AI models have been trained on the entire internet, which includes enormous quantities of bad code - insecure password handling, SQL injection vulnerabilities, outdated patterns. The model doesn’t know which patterns are secure and which aren’t. When you ask for “a function to authenticate a user,” you might get something that works but stores passwords incorrectly. Security code requires extra scrutiny.
Solutions to the wrong problem: When you describe a problem in natural language and ask for a solution, you get a solution to the literal words you used. If your description of the problem was imprecise or incomplete, the solution will be precisely and completely wrong for your actual situation. This is not an AI failure - it’s a specification failure. The model has no access to the context you didn’t provide.
Dependency on unverified information: AI tools may suggest libraries, APIs, or configuration options that don’t exist, or that exist but have different interfaces than described, or that exist and work as described but were deprecated two years ago. Always verify.
The Skill Atrophy Risk
This is the concern that has some real basis.
If you consistently use AI to write the parts of code you find difficult - the algorithm you don’t quite understand, the concurrency pattern you haven’t internalized, the debugging work you find tedious - you stop exercising those skills. Over time, you lose them.
The specific risk isn’t “AI writes the code so you don’t.” It’s subtler: you use AI suggestions as a shortcut past understanding. You see a suggestion that looks right, accept it, it passes tests, and you move on without actually understanding what it does. When a bug appears in that code six months later, you can’t reason about it.
The pattern that avoids this: use AI to write code you already know how to write. When you encounter something you don’t understand in a suggestion, slow down and understand it before accepting. When you’re learning something new, write it yourself first.
This isn’t idealism. It’s self-interested pragmatism. The engineer who understands the code in their codebase is more effective, earns more trust, and is more valuable than the engineer who doesn’t know how the code they shipped works.
Prompting for Better Results
A few patterns that consistently improve output quality:
Provide context: Don’t ask for “a function to fetch users.” Ask for “a Python function that queries a Postgres database using asyncpg to fetch users by email, returning a Pydantic model with fields id, email, and created_at.” The more specific the specification, the less the model has to guess.
Share your existing code: If you’re extending an existing system, include the relevant interfaces, types, and patterns. The model will follow the style and constraints of what you show it.
Ask for explanation: “Write this and explain each part.” Even if you understand the code, the explanation sometimes reveals assumptions you hadn’t noticed.
Iterate with corrections: The first response is a starting point, not a final answer. “The returned type should be Optional, and the function should handle the case where the user doesn’t exist” is a normal follow-up.
Review the output before running it: Read the generated code. This seems obvious but doesn’t always happen. The five seconds of reading is what separates finding the bug before it’s committed from finding it after it’s in production.
The Honest Assessment
AI coding tools make experienced engineers faster at work they already know how to do. They don’t substitute for knowing how to do it.
The engineers I’ve seen struggle with these tools fall into two categories: those who don’t use them at all (and give up real productivity gains) and those who use them as a substitute for thinking (and accumulate code they don’t understand).
The productive middle is using AI to handle the mechanical parts of work while keeping the thinking firmly in your own hands. You decide the architecture. You decide the approach. You understand what the code does. AI writes the boilerplate faster than you would.
That’s a good division of labor. The judgment, the context, the understanding - those stay with you.