I'm a computer science undergraduate trying to build strong engineering judgment while using agentic coding tools on personal projects. I want to develop skills that will prepare me for industry, especially critical thinking, design, debugging, and understanding the code I ship.
My current idea is to write product requirements, architectural plans, and records of important design decisions before asking an AI tool to implement specific functionality. I would make the key decisions myself, then use AI mainly for coding assistance rather than blindly generating an entire application.
I'm unsure how to balance learning by writing code manually with the productivity benefits of AI tools. What processes or habits would help me keep learning effectively without giving up useful productivity gains?
3 Answers
Writing requirements and architecture notes is a good foundation, but make sure the documents stay practical instead of becoming a form of procrastination. A short design note is often enough: state the problem, list the constraints, explain the options you considered, and record why you chose one.
After the AI generates code, review it like a pull request. Trace the important paths, check error handling and security assumptions, and make sure you can explain every significant choice. AI will sometimes produce a clever solution, but it can also generate code that merely works while being difficult to maintain.
A running decision log is useful for this. Architecture Decision Records would fit that purpose well, as long as you keep them concise and focused on decisions that actually matter.
Be careful about treating generated code as automatically productive. Productivity is not just how quickly code appears; it also includes correctness, maintainability, security, and how much future cleanup the code creates. If you cannot explain the implementation or verify that it meets the requirements, you have mostly transferred the learning and risk elsewhere.
A useful workflow is to design the feature yourself, define acceptance tests, implement or outline the tricky parts manually, ask the AI for targeted help, and then test and review the result. Keep the scope small enough that you can understand the whole change.
Deliberately solve some difficult bugs without handing them straight to the AI. Debugging unfamiliar behavior, reading stack traces, forming hypotheses, and testing them is where a lot of engineering judgment develops.
You can still use AI afterward as a reviewer or to suggest alternative explanations, but first write down what you think is happening and try to fix it yourself. It may also help to implement smaller or more foundational pieces manually, then use AI for repetitive code, test cases, documentation, or a second opinion.

That makes sense. I’ll use concise ADRs rather than writing huge documents, and I’ll treat reviewing the generated code as part of the implementation instead of an optional cleanup step.