I have about two years of professional experience as a backend software engineer. Early in my career, I learned by reading documentation, debugging problems myself, studying existing code, and taking ownership of a backend project. I was genuinely enjoying the process.
A few months ago, I joined a much larger company expecting to learn from experienced engineers and see how large-scale systems are built. Instead, I have become heavily dependent on AI coding tools over the last six months. They have made me more productive, but I feel like I am losing the part of development that helped me build real understanding.
I used to review generated code carefully and make sure I understood it. Now the codebases are large enough that I often cannot fully follow what the AI is doing, so I sometimes trust its interpretation of the system instead of developing my own. I am worried that I am becoming good at shipping code without becoming a better engineer.
My manager suggested using AI as a learning tool rather than depending on coworkers for mentorship, but I am not sure how to do that effectively. How can I use AI without outsourcing the thinking and learning parts of engineering? If you were two years into your career today, what fundamentals would you prioritize, and should junior engineers use AI differently from experienced engineers?
4 Answers
There is no single correct level of AI usage. Some teams expect rapid delivery, while others restrict agent-generated production code because the review and maintenance cost is too high. The important distinction is whether you remain accountable for the result.
Keep changes small and easy to review. Start with a clear design, limit how much code the tool writes at once, require tests, and inspect the diff rather than accepting a large generated change. Treat AI output as an untrusted contribution from a fast junior developer: useful, but it needs context, correction, and careful review.
Use AI as a reviewer and tutor, not as the person making every decision. Before asking it to change code, write down your own understanding of the problem, constraints, likely files involved, and a rough solution. Ask the AI to critique that plan or point out edge cases, but keep the final design decision yours.
It is also useful to have it explain existing code, generate tests, identify security concerns, or compare two approaches. Ask it to show its assumptions and challenge its confidence. If you cannot explain the resulting change to another engineer, it is not ready to merge. For difficult areas, recreate a smaller version in a scratch project or trace the execution manually.
A practical compromise is to have the AI produce a plan, stubs, or tests first. You can then implement the important logic yourself while still benefiting from faster investigation and feedback.
Do not neglect the fundamentals that remain valuable regardless of tooling: data structures, databases, networking, operating systems, testing, observability, security, API design, and system architecture. More importantly, learn how the systems at your company actually work—deployment paths, ownership boundaries, failure modes, data flows, and why key design decisions were made.
Try taking one feature or service and understanding it end to end. Read the code without immediately asking AI for a summary, map the dependencies, inspect its tests and production metrics, and write down questions for a senior teammate. The goal is not to hand-write every line forever; it is to build enough context to recognize a bad design and make good tradeoffs.
Your role will probably involve more than writing individual functions, but that does not mean code-level understanding is obsolete. Architecture, product judgment, communicating with stakeholders, debugging production behavior, and taking ownership all depend on understanding the implementation well enough to evaluate it.
Use work tasks as learning opportunities instead of doing a separate AI course after hours. When you receive an unfamiliar issue, first investigate it yourself, then ask AI to explain the parts you found confusing or challenge your proposed fix. Keep a short notebook of concepts, commands, design decisions, and mistakes. Over time, that will give you a much stronger foundation than blindly maximizing output speed.

That approach also helps with delivery pressure. A small plan, focused diff, and targeted tests are usually safer than asking an agent to modify half the repository and hoping the result works.