I’ve spent a long time breaking new developers into languages, and I’m watching the apprenticeship that worked for thirty years come apart. Here’s what I’m noticing — and why I think the change runs deeper than most of the takes I’m reading.
Teaching a junior used to be slow, patient work. You handed them small tasks, waited for a pull request, and taught through the comments. Over months they accumulated a vocabulary of functions and a feel for the language. Volume of typing earned trust. That apprenticeship is finished.
What replaces it matters enormously, because the industry has lunged at the wrong answer. The wrong answer is vibing: pointing an agent at a problem and accepting whatever comes back. Vibing feels productive, and it produces juniors who can’t tell good code from code that merely runs. It skips the exact judgment that holds software together. Worse, it offers no avenue for growth — there’s nothing to learn from a result you never examined.
There’s a better path, and once you see it the whole training problem reframes itself. Juniors still write code. They just write it differently. And the act of coding has quietly become an act of teaching — you’re constantly instructing an agent, by example, by interface, by prompt. That’s the insight I keep coming back to: coding is training now, so teaching has to be too.
Coding didn’t go away. It got surgical.
Start here, because this is where people misread the moment. “The agent writes the code” does not mean the human stops touching it. It means every keystroke becomes intentional. There are three moments when a developer still reaches into the editor, and all three are teaching:
Stub the seam. You write the empty function blocks and the module’s interface — the shape of the thing — and hand the bodies to the agent. You’ve taught it the contract; it fills it in.
Offer guidance and insight. Some functions are hard or rare enough that the agent flails. You write that one yourself — not as a rescue, but because your insight is faster and more correct than three rounds of prompting.
Exemplar coding. When the agent keeps missing a concept, write something small that demonstrates it, then say: “build with these concepts.” Code as instruction, in the most literal sense.
Every one of these is the opposite of vibing. The keystrokes are few and deliberate, and each one steers.
🎯 Join Groxio's Newsletter
Weekly lessons on Elixir, system design, and AI-assisted development — plus stories from our training and mentoring sessions.
We respect your privacy. No spam, unsubscribe anytime.
Portion control: planning small enough to finish
The most important skill a junior can build now is carving their own work into pieces small enough to finish completely. Not “mostly done.” Done. Half-finished is the new failure mode, because a half-finished agent task is a tangle nobody can review and nobody can trust.
This is harder than it sounds. Finding the natural seams in a feature requires understanding the system — and juniors arrive without that understanding. So it has to be taught directly, and the plan has to live in the repo. Planning documentation, written and maintained through agentic tooling, becomes a real artifact: versioned, revisited, corrected. The plan isn’t in your head. It’s a file the agent reads and the reviewer checks.
Small scope is the difference between a pull request a human can actually review and a two-thousand-line submission you have no choice but to throw away. Portion control is risk control.
Reviewing: design beats vocabulary
Reviewing is now the core competence, and here’s the part that changes training the most: review leans on design judgment, not function recall.
The old junior spent years building a vocabulary — which function does what, what’s in the standard library, the idioms of the framework. Agents have that vocabulary cold. What they don’t reliably have is taste about structure.
The hardest, most durable thing to learn is inversion of control, where the engine calls your code rather than the other way around. Two Elixir examples: OTP, the system behind Elixir’s concurrency and self-healing software, and Phoenix LiveView, which delivers single-page applications and rich flows without custom JavaScript. Both are tough to learn because the OTP engine or the web server is in charge, not your code — so you can’t simply read a function description to understand them. You have to understand the framework’s flow of control, and that takes training and experience.
So that’s where the teaching budget goes now. Framework design and implementation. Idiomatic layering — what belongs in the context, what belongs in the web layer, what belongs in a pure function. Component boundaries. Clean interfaces between APIs. The question driving every review is the same: what does a good seam look like, and does this code respect it?
Red/green: knowing when to throw it away
Agents go off the rails. The skills are noticing, knowing why, knowing early, and knowing what to do about it.
What to do is almost always the same: throw it away and prompt better. Not salvage. This is the instinct juniors fight hardest, because they’ve watched the agent produce three hundred lines and they want to fix them. But fixing bad generated code is slower and worse than regenerating from a sharper prompt. The work was cheap to make and it’s cheap to remake.
That only works if discarding is cheap, which makes git discipline non-negotiable. Small commits. A branch per attempt. Clean reverts. When throwing away a bad direction costs one git reset, juniors learn to do it without flinching. When it costs an afternoon of untangling, they cling to sunk cost — and sunk cost is the trap that swallows them.
Prompts are code
If the agent writes much of the code, the prompts that direct it are the highest-leverage text in the project. Treat them that way.
The source of truth for prompts is the repository. A prompt is metaprogramming in English — a program that writes programs — and it deserves everything we give other code: version control, review, diffs, history. A prompt that lives in someone’s chat window or their head is technical debt you can’t see.
There’s a corollary juniors miss. Agents accumulate memory and context, and not all of it is good. Stale instructions and old assumptions quietly reinforce bad behavior long after they’ve stopped being true. Pruning that memory — knowing when to disregard what the agent “knows” — is hygiene, not an afterthought. Reviewing the work means reviewing what shaped it.
So how do we actually train?
If the daily act of coding has become teaching, then training has to look like teaching-by-doing too. The long classroom block is the wrong vehicle — you can’t lecture someone into design judgment.
So the work is mentoring, and pairing. Real repositories, a senior alongside, decisions made out loud. The lesson lands in the moment a choice is made, not in a slide deck two weeks earlier.
The senior’s job changes too. The old senior comment-bombed a pull request line by line, salvaging it into shape. The more useful move now is to look at a bad PR, throw it away, and teach into that moment: here’s why this was the wrong seam, here’s the prompt that would have produced a better one, now try again. Spending a day rescuing a doomed branch teaches a junior nothing except that bad work gets rescued. Discarding it well — with the lesson attached — teaches them everything.
Training seniors to throw work away gracefully turns out to matter as much as training juniors to plan it.
The role moved up the stack
None of this shrinks the junior developer. It moves the job up the stack, from production to judgment — from “can you write this function” to “should this function exist, where does it belong, and is the agent’s version good enough to keep.”
That’s a harder job, and a better one. The organizations that grow real engineers from here won’t be the ones that adopt agents fastest. They’ll be the ones that remember coding was always a way of learning — and rebuild their teaching around that, instead of vibing their way past it.
🛠 Train Through the AI Coding Crisis
This post is from Bruce Tate's series on what the AI coding crisis is doing to engineering teams — and what it would take to train through it instead of around it. Groxio runs private training and ongoing advisory for engineering teams using AI with Elixir, Phoenix, OTP, LiveView, Ecto, Ash, and Postgres. We start with a diagnostic conversation about where your review queue, your seniors, and your codebase actually are.
— Bruce