AI may help junior developers ship faster.
It may also slow down how they become senior.
That sounds like an argument against AI coding tools.
It is not.
Coding agents are excellent at removing repetitive work, exploring unfamiliar code, proposing first drafts, writing tests, and helping engineers move from an idea to an implementation.
But software engineering skill was never built only by completing tickets.
A lot of it was learned almost by accident.
- Tracing unfamiliar code
- Reading documentation because the first attempt failed
- Debugging a wrong assumption for two hours
- Comparing several imperfect approaches
- Seeing why a clean solution breaks in production
- Reviewing someone else's trade-offs
Those moments were frustrating.
They were also where engineers built mental models.
The invisible curriculum of software engineering
Formal learning can teach syntax, frameworks, algorithms, and design patterns.
Daily engineering teaches something different:
- Where abstractions leak
- Which assumptions fail under real traffic
- How data moves across a system
- Why an apparently small change has a large blast radius
- When a test suite is giving false confidence
- How product decisions become architectural constraints
- Which trade-offs matter six months later
That is the invisible curriculum of software engineering.
It is rarely written down as a course.
Engineers absorb it while investigating, debugging, reviewing, and recovering from mistakes.
Coding agents can shorten many of those activities.
That is good for delivery.
But it raises an uncomfortable question:
When the agent removes the struggle, does it also remove some of the learning?
A simple example
Imagine a junior developer is asked to fix a retry bug in a payment integration.
Without an agent, they may need to:
- Trace the request through several services.
- Read logs from failed attempts.
- Learn how the current retry mechanism works.
- Discover why retries can create duplicate operations.
- Read about idempotency.
- Compare fixed delays with exponential backoff.
- Add tests for failure cases.
- Explain the trade-off during review.
That process is slow.
It may also teach them about distributed systems, failure handling, observability, and production risk.
Now imagine the same developer gives a coding agent this task:
Fix the retry bug and add tests.
The agent inspects the repository, updates the retry logic, adds exponential backoff and jitter, writes tests, and presents a polished explanation.
The task may be completed much faster.
But what did the developer actually learn?
Could they explain why jitter matters?
Could they recognise an idempotency problem in another system?
Could they debug the code when the next failure does not match the generated tests?
Shipping the change and understanding the change are not the same outcome.
The risk of knowledge debt
A recent paper, Agents That Teach: Towards Designing Incidental Learning Back into AI-Assisted Software Development, describes this risk as knowledge debt.
Knowledge debt is the gap that accumulates when an agent makes changes a developer cannot fully understand, explain, or maintain independently.
It is similar to technical debt in one important way:
The cost may remain invisible until the system changes or fails.
A developer can remain productive while the agent is available and the task stays inside familiar boundaries.
The debt appears when they need to:
- Debug a new failure mode
- Modify the generated design
- Review a similar change from someone else
- Respond during an incident
- Make a decision without the same context
- Explain why the system behaves as it does
Not every AI-assisted change creates knowledge debt.
The debt appears when delegation replaces comprehension rather than accelerating it.
Some warning signs are:
- You can describe what changed, but not why that approach was chosen.
- You cannot explain which alternatives were rejected.
- You trust the tests but cannot explain what important risks they do not cover.
- You accept an architectural decision because the agent sounded confident.
- You struggle to continue once the generated solution leaves the happy path.
- The agent conversation contains more reasoning than the pull request or documentation.
Why this matters for becoming senior
The difference between a junior and a senior engineer is not simply the amount of code they can produce.
Senior engineers are expected to:
- Frame ambiguous problems
- Identify hidden constraints
- Predict failure modes
- Make trade-offs
- Understand blast radius
- Review other people's work
- Protect long-term system quality
- Make good decisions with incomplete information
Those abilities are built through repeated reasoning.
If AI completes more of the reasoning invisibly, a junior engineer may deliver more work without getting enough practice in the judgment required at the next level.
The danger is not that junior engineers will stop writing code.
The danger is that teams may mistake higher output for faster development of engineering capability.
The answer is not to use less AI
Telling engineers to avoid coding agents is neither realistic nor useful.
The better approach is to design learning back into the workflow.
Here are seven practices I find useful.
1. Predict before asking the agent
Before generating a solution, write down your current view:
- What is the likely root cause?
- Which part of the system is involved?
- What could fail?
- What evidence would prove the change is correct?
Your prediction does not need to be right.
The value comes from making your reasoning active before seeing the agent's answer.
You can then compare your model with the agent's model rather than passively accepting its output.
2. Ask for a map before asking for code
Do not begin every task with implementation.
Ask the agent to first:
- Trace the relevant code path
- Identify the important files and dependencies
- State its assumptions
- Highlight missing context
- Describe the current behaviour
- List possible approaches
This turns the agent into an exploration partner before it becomes an implementation engine.
It also gives you a chance to correct a misunderstanding before it becomes a large diff.
3. Ask which approaches it rejected
The final solution hides much of the useful learning.
Ask:
- What other approaches did you consider?
- Why did you reject them?
- Which trade-off made this option preferable?
- Under what conditions would another approach be better?
- Where are you least confident?
Senior judgment is often built by comparing reasonable options, not by memorising one correct answer.
4. Keep at least one important decision human-owned
The agent can explore, analyse, and recommend.
But for unfamiliar or high-impact work, keep an important decision explicitly owned by the engineer.
That decision might involve:
- Product behaviour
- A data model
- An API contract
- A security boundary
- An architectural dependency
- A migration strategy
- A rollout or rollback plan
The goal is not to create artificial human work.
It is to make sure the engineer still practises the decisions that build judgment.
5. Review the highest-risk reasoning, not only the final diff
Line-by-line review is necessary, but it is not enough.
Ask:
- Which assumption creates the most risk?
- What is the blast radius if this is wrong?
- Which edge case is hardest to observe?
- What do the tests not prove?
- Is the change reversible?
- Who will understand this during an incident?
AI can produce a convincing implementation around a weak assumption.
The most valuable review may be reviewing the decision behind the code.
6. Explain the change back in your own words
After the agent finishes, close the loop.
Explain:
- What changed
- Why it changed
- Why this approach was selected
- What could still go wrong
- How the change will be verified
- How it can be rolled back
This can become part of the pull request description or decision record.
A useful test is simple:
Could I explain this change to another engineer without reopening the agent conversation?
If not, some knowledge may still be trapped inside the tool.
7. Preserve occasional unaided practice
Not every task needs to become a lesson.
But some deliberate practice matters.
Occasionally:
- Trace the unfamiliar path manually.
- Debug before asking the agent for the answer.
- Write the first test yourself.
- Review a change without an AI summary.
- Solve the unfamiliar part before requesting optimisation.
- Predict the production failure before running the tests.
We do not become better at a skill merely by watching a tool perform it.
Some capabilities still need repetitions.
A learning-aware prompt for coding agents
Here is a prompt you can adapt:
Before changing any code:
1. Map the relevant code path and dependencies.
2. Explain the current behaviour.
3. State your assumptions and missing context.
4. Propose at least two approaches.
5. Explain the trade-offs and which approach you recommend.
6. Identify the highest-risk failure modes.
7. Wait for my decision before implementation.
After implementation:
8. Explain the most important design decision.
9. Describe what the tests prove and what they do not prove.
10. Give me one question that checks whether I understood the change.
11. Summarise the information that should remain in the pull request or documentation.
This will not remove every risk.
But it changes the interaction from:
Agent solves. Developer accepts.
to:
Agent explores. Developer decides. Both make the reasoning visible.
What teams can do
Individual habits help, but teams also shape how engineers learn.
A team using coding agents heavily could add a few lightweight practices:
Add reasoning to pull requests
Require the author to explain the highest-risk decision, not paste the agent's complete transcript.
Review understanding as well as correctness
Ask the author to describe the failure modes and trade-offs during review.
This is not an exam.
It is a way to confirm that knowledge remains inside the team.
Use agents to teach during real work
Ask agents to surface unfamiliar concepts, rejected alternatives, or architectural context while engineers are already solving a task.
Learning should be connected to the code in front of the developer, not delivered as generic advice.
Protect deep-work opportunities
Do not optimise every task for maximum delegation.
Some tasks are valuable because they expose engineers to unfamiliar systems, production behaviour, and complex decisions.
Measure more than output
More completed tasks or merged pull requests can be useful signals.
They do not tell you whether:
- Review effort increased
- Rework increased
- Engineers understand the generated systems
- On-call capability improved
- Junior engineers are building independent judgment
AI adoption should improve both delivery and engineering capability.
The coding agent we should want
The best coding agent will not only produce a correct patch.
It will help the engineer understand:
- The system it changed
- The alternatives it considered
- The trade-off it selected
- The risks that remain
- The evidence required to trust the result
That is a higher standard than code generation.
It treats learning as part of developer productivity rather than as a cost outside it.
AI can make engineers faster.
The better goal is to make them faster and more capable.
The best coding agents will not only help engineers finish the task.
They will help engineers become better at the task.
Top comments (3)
I appreciate how the article highlights the concept of "knowledge debt" and its potential implications on junior developers' learning curves. The example of a coding agent fixing a retry bug in a payment integration effectively illustrates how delegation can replace comprehension, leading to a gap in understanding. I've seen similar situations in my own experience, where relying on automated tools to generate code or solve problems can indeed accelerate shipping, but may hinder the development of critical thinking and problem-solving skills. What strategies do you think can be employed to balance the benefits of AI-assisted development with the need for junior developers to build a strong foundation in software engineering principles?
I think the balance is less about restricting AI and more about building stronger safety nets around how it is used.
Tests are one part of that, but the workflow can go further.
AI can help identify whether a change touches a critical part of the codebase, estimate its blast radius, and nudge the engineer toward deeper manual review when the risk is high.
Low-risk, reversible changes can move through automated review and test gates. High-risk changes should require stronger evidence, human understanding, and explicit ownership.
This also makes high-quality reliability metrics more important. Teams need failure signals earlier in the pipeline—not after the change reaches production.
The goal is a more pre-emptive quality strategy:
Generate quickly.
Classify risk early.
Automate what is safe.
Escalate what requires judgment.
Measure whether the safety nets are actually working.
AI creates some of these risks, but it can also help us build the testing, observability, and review systems needed to manage them much faster.
Some comments may only be visible to logged-in visitors. Sign in to view all comments.