AI EngineeringZero to ProductionHome·About·What’s new·Contact
AI-Assisted Development · Chapter V1

Vibe Coding Fundamentals & AI-Driven Development

"Vibe coding" — describing what you want and letting AI write it — went from meme to daily practice fast. This chapter separates the useful core from the hype: what it is, where it genuinely accelerates you, where it quietly creates liabilities, and the disciplines that keep AI-generated code trustworthy.

⏱️ ~45 min🧭 Concepts + practice🎯 Beginner→Expert
🌱 Start here — from zero AI-assisted development, from scratch — how to write software with an AI as your pair — responsibly and effectively.

AI coding assistants (Claude Code, Cursor, Copilot, and others) can write, explain, and refactor code with you. Used well they're a huge accelerator; used blindly they introduce subtle bugs. This section covers the tools and — more importantly — the habits that make AI-assisted coding safe and productive.

The words you'll hear (in plain terms):

TermWhat it actually means
AI-assisted developmentcoding with an AI helper that suggests, writes, or edits code.
pair programmingtwo 'developers' working together — here, you + the AI.
autocomplete vs agentinline suggestions vs. an AI that edits files and runs commands.
verificationchecking the AI's output (read it, run tests) instead of trusting it.
prompt / contextwhat you tell the assistant + the code it can see, which shape its output.

What you need before starting:

  • Basic programming experience so you can judge the AI's output.
  • The Claude Code intro (C3) pairs well with this section.
  • The relevant tool installed (or read along to compare them).

New to the topic? Read this box, then take the chapters in order — each section is tagged essential → expert so you always know the depth you're at.

Learning objectives

  • Define vibe coding and AI-driven development, and where each fits.
  • Explain the spectrum from autocomplete to fully agentic coding.
  • Apply the core loop: intent → generate → verify → refine.
  • Name the real risks — trust, security, skill atrophy — and how to manage each.
  • Write prompts and set up context that make AI coding tools reliable.
This module is tool-agnostic firstV1 is the discipline that applies to every AI coding tool; V2–V5 are specific tools (Cursor, Antigravity, Amazon Q, Copilot). Claude Code — Anthropic's agentic coding tool — is covered in C3; everything you learn here applies to it too. Learn the fundamentals once, then the tools are variations.

What "vibe coding" actually is essential

Picture the two hours you'd normally lose to a boring task. You need a script that reads a folder of CSVs, merges them, and drops the duplicates. You know how — you just don't want to type it. So you describe it in a sentence, an AI writes forty lines, you run it, it works, you move on. That felt like magic, and it's why "vibe coding" spread from a joke to a daily habit almost overnight: for the first time, describing the what often gets you the how for free.

Here's the honest catch, and it's the whole reason this chapter exists. The word "vibe" is doing something sneaky — it quietly implies you don't have to look. And for that throwaway CSV script, fine, you probably don't. But the same one-sentence-and-ship reflex, pointed at the code that charges a customer's card or checks a password, is how teams ship bugs they can't even find later. The danger isn't the AI writing the code — it's you not reading it. Speed is real; the trap is treating all code as equally safe to skip reading.

The common beginner mistake is to think of vibe coding as a single thing you either do or don't do. It isn't. Think of it instead like a dimmer switch, not an on/off toggle: at one end you read and understand every line; at the other you accept the output blind. Every real task lives somewhere on that dial, and the professional move is choosing where deliberately based on what breaks if the code is wrong. A prototype you'll throw away tomorrow can sit near "blind" — the cost of a bug is that you rerun it. A payment path cannot — the cost of a bug is a chargeback and an incident review.

The term (coined in early 2025) describes coding by describing intent in natural language and letting an AI generate, run, and iterate on the code — often without reading every line. At its loosest it means "trust the vibes, ship what works." That's fine for a throwaway prototype and dangerous for production. The useful reframe: vibe coding is a spectrum of how much you delegate, and the skill is choosing the right point on it for the stakes.

The honest distinctionThere's vibe coding (accept AI output largely unread — great for prototypes, throwaways, learning) and AI-assisted engineering (AI writes, you review, test, and own every line — required for anything real). Same tools, different rigor. Trouble starts when people use prototype-grade trust for production code.

The delegation spectrum essential

Think about how much you'd trust a new intern versus a senior engineer. You'd let the intern draft a first pass and then check it closely; you'd let the senior take a whole feature and only skim the result. You already calibrate trust to competence and stakes every day — you just do it with people. AI coding tools ask you to do the same thing, except the "trust" comes in discrete levels, and if you don't notice which level you've picked, you'll apply the wrong amount of checking.

That's what this section is really about: not the tools, but the setting you're operating them at. An autocomplete that finishes your line is a very different act of trust from an agent that edits twelve files and runs your test suite while you get coffee. Same underlying model, wildly different amount of code you didn't personally write. The mistake almost everyone makes is sliding rightward — handing over more — because it feels productive, without sliding their verification rightward to match. That mismatch is the single most common way AI coding goes wrong.

Here's the counter-intuitive rule that trips people up: more delegation does not mean less work — it means the work changes shape. When you type the code, understanding is a free byproduct of writing it. When an agent types it, you have to buy that understanding separately, by reading and testing. So the far-right end of the spectrum doesn't hand you a finished result; it hands you a draft from a fast, confident, occasionally wrong stranger that you're now on the hook to review. The autonomy is real, but so is the review bill that comes with it. Read the diagram below as a dial you set per task — and remember that setting it higher raises, not lowers, the verification you owe.

AI coding tools sit at increasing levels of autonomy. Knowing which level you're operating at tells you how much verification you owe.

Autocompleteline/block Chat / edityou drive Agentmulti-file, runs Autonomouswhole tasks more delegation → more verification you owe before trusting the output Four levels of delegation. Autocomplete finishes your line (Copilot's original mode). Chat/edit answers and edits on request. Agent makes multi-file changes and runs commands (Cursor agent, Claude Code). Autonomous takes whole tasks. The further right, the more the verification burden shifts to you — because you wrote less of it.
🗺️ How to read this diagram

First, what is vibe coding? It means describing what you want in plain English and letting an AI write the code — sometimes without reading every line. This picture shows that "letting the AI do it" is not one thing but a sliding scale of how much work you hand over. Read the line from left to right: the further right, the more the AI does on its own.

  • The horizontal line is the scale of delegation — how much you trust the AI to do without you. Each coloured dot is one level, labelled above it, with a short hint below.
  • Autocomplete (far left, green): the AI finishes the single line or block you're already typing — the smallest step, like a smarter tab-complete.
  • Chat / edit (blue): you ask it questions and it edits code on request — the note "you drive" means you're still steering every move.
  • Agent (purple): now it changes many files and even runs commands by itself ("multi-file, runs") — you're supervising, not typing.
  • Autonomous (far right, amber): you hand it a whole task and it works largely on its own.
  • The line of text at the bottom is the whole point: more delegation → more verification you owe. The more the AI wrote, the harder you must check it before trusting it, because you wrote less of it yourself.

In short: There's no "best" spot on this line — pick the level that matches the stakes. A throwaway script can sit far right; code that ships to real users belongs left, where you check more.

The core loop: intent → generate → verify → refine essential

Imagine ordering food in a language you barely speak. You point at the menu (intent), the kitchen cooks (generate), the plate arrives — and here's the moment that matters — you taste it before you pay (verify), and if it's wrong you clarify and reorder (refine). Nobody sane pays for a dish they haven't tasted just because it looked right through the kitchen window. Yet that is exactly what "accept the AI's code without running it" is: paying for the meal off the photo. This section is about the one discipline that turns AI coding from gambling into engineering.

The loop is worth naming step by step because each step has an owner, and getting the owners wrong is where sessions fall apart. Intent is yours — the tool cannot know what "done" means for you, so vague intent ("make it better") yields vague code, every time. Generate is the tool's job, and it's genuinely good at it. Verify is yours again, and it's the one people quietly drop because generation felt like the finish line. Refine is yours too — and the skill is correcting the intent ("it must reject negative amounts") rather than just barking "no, try again," because a sharper intent is what makes the next lap converge instead of wandering.

Why single out verify as load-bearing? Because it's the only step where you catch the failure mode that makes AI code dangerous: code that is confidently, plausibly wrong. A human beginner writes code that looks shaky, so you check it. An AI writes code that looks polished and reads like a senior engineer wrote it — clean names, sensible structure — while silently mishandling the empty list, the leap year, the concurrent write. The polish disarms your suspicion at exactly the moment you should be most suspicious. Verify is how you refuse to be disarmed: you read the diff, you run it, you run tests, and you scale that effort to the stakes. Skip it and you haven't saved time — you've just moved the bug-finding to production, where it's far more expensive. The entire craft of AI-assisted engineering is, at bottom, the refusal to skip the amber box below.

Every productive AI-coding session, at any autonomy level, runs the same loop. The one step people skip — verify — is the one that separates shipping from shipping bugs.

Intent Generate Verify Refine refine feeds the next intent — verify is NOT optional Verify is the load-bearing step. State intent clearly → let the tool generate → verify it (read it, run it, test it) → refine the intent and repeat. Skip verify and you're not coding, you're gambling. The whole discipline of AI-assisted engineering is refusing to skip it.
🗺️ How to read this diagram

This is the repeating cycle every good AI-coding session follows, no matter which tool you use. Read the four boxes left to right, then notice the curved arrow underneath that loops back to the start — that's why it's called a loop, not a straight line.

  • Intent (first box): you say clearly what you want — the goal, any rules, and what "done" looks like. Vague intent gives vague code.
  • Generate: the AI writes the code from your intent. This is the step people think is the whole job — it isn't.
  • The straight arrows between boxes show the normal forward flow: intent leads to generate, which leads to verify, which leads to refine.
  • Verify (shown in amber, the emphasised box): you check the result — read it, run it, run tests. The red caption warns this step is NOT optional: skipping it means you're "gambling," not coding.
  • Refine: you sharpen your request based on what you saw, then the curved arrow at the bottom carries you back to Intent to go round again. Each lap gets the code closer to what you actually meant.

In short: The one habit that separates shipping working software from shipping bugs is never skipping Verify. If you remember one thing from this diagram, remember that the loop always passes through the amber box.

StepWhat good looks like
IntentSpecific goal + constraints + "done" criteria — the Chapter 2 prompt discipline, applied to code
GenerateLet the tool write it; give it the right context (see §Context below)
VerifyRead the diff, run it, run tests, check edge cases — proportional to the stakes
RefineCorrect the intent (not just "no, try again"); the loop converges when intent is sharp

Where it accelerates you — and where it doesn't intermediate

Here's the mental model that predicts almost every case: an AI coding tool is a phenomenally well-read pattern-matcher, not a reasoner. It has seen millions of REST endpoints, config files, and test skeletons, so when your task rhymes with something common, it reproduces the pattern faster and more accurately than you could type it. But when your task is genuinely novel — a tricky invariant, a domain nobody blogs about, a bug whose cause lives three files away — there's no pattern to match, and it does what a confident student does on an exam it didn't study for: it produces something fluent and plausible that may be wrong.

So the useful question before you delegate isn't "can the AI do this?" — it usually looks like it can — but "has the world done this a thousand times before?" If yes, lean in hard: scaffolding a Flask route, writing a batch of unit tests, converting JSON to a dataclass, explaining a gnarly regex someone else wrote. These are where you get the 3× speed-up with almost no risk, because they're both common and cheap to verify. If the task is rare, subtle, or high-stakes, the tool becomes a junior assistant you must supervise closely, not an oracle — useful for a first draft, dangerous as a final answer.

The common trap is a seductive inversion: because the AI handles the hard-looking boilerplate so smoothly, people start trusting it with the genuinely hard stuff too — the architecture, the security boundary, the concurrency model — and relegate themselves to tidying the boilerplate. That's exactly backwards. The table below sorts the terrain; read the right column not as "never use AI here" but as "here you're the engineer and it's the intern, so verify like one is watching over your shoulder."

Has the world done this a thousand times? YES — common boilerplate · tests · config cheap to verify NO — rare / subtle novel logic · architecture security · hidden bugs ← lean in: AI accelerates supervise like an intern → same tool, opposite amount of trust — sort by how cheaply you can check it Sort by "has the world done this before?", not by "can the AI do it?" Common, cheap-to-verify work (left) is where you lean in for a real speed-up; rare, subtle, or high-stakes work (right) is where the AI becomes an intern you supervise line by line.
🗺️ How to read this diagram

Read it left to right along the single axis: the one question at the top — "has the world done this a thousand times?" — splits every coding task into two zones.

  • The green box on the left is the YES zone: common work the model has seen millions of times — boilerplate, tests, config — and which is also cheap to verify. Both things are true at once, which is what makes it safe to hand over.
  • The red box on the right is the NO zone: novel logic, architecture, security, or a bug whose cause is out of view. There's no pattern to copy, so fluent output here can be quietly wrong.
  • The labels under the axis tell you the move for each end: on the left you lean in and treat the AI as an accelerator; on the right you supervise it like a junior intern and check every line.
  • The payoff is the bottom line: it's the same tool both times — what changes is how much trust the task has earned, and you decide that by how cheaply you can check the result.

In short: Don't ask whether the AI can do a task — ask whether the task is common and cheap to verify. That answer tells you which end of the axis you're on.

AI coding shines at…AI coding struggles with…
Boilerplate, scaffolding, configNovel algorithms & subtle logic
Familiar patterns in popular languagesObscure libraries / niche domains (little training data)
Tests, docs, refactors with clear intentDeep architecture decisions
Explaining unfamiliar codeDebugging where the root cause isn't in view
Prototypes & one-off scriptsSecurity-critical or high-blast-radius code
Delegate the tedious, own the criticalThe highest-value use is offloading the 70% of coding that's mechanical so you spend your attention on the 30% that's genuinely hard — architecture, edge cases, security. Inverting that (letting AI make the architectural calls while you tidy the boilerplate) is how projects go wrong.

The real risks intermediate

Every powerful tool has a way it hurts you, and knowing it is what separates a professional from an enthusiast. A chainsaw cuts wood fast and takes fingers; the pro doesn't fear it, they wear the guard and keep their hands clear. AI coding is the same. The risks below aren't arguments for going back to typing everything by hand — that ship has sailed and the productivity is real. They're the specific hazards you learn to handle on purpose, so the speed is a gain and not a liability you discover in an incident review.

What makes these risks slippery is that none of them announce themselves. Slow code you notice; a crash you notice. But subtly-wrong code passes the demo, hardcoded secrets sit quietly in the repo until someone scrapes them, and skill atrophy feels great right up until the day the tool is down and you can't debug your own service. The failure is deferred and invisible, which is exactly why it needs a deliberate habit rather than good intentions — you cannot rely on the problem to interrupt you.

One risk deserves calling out because it's the least technical and the most corrosive: skill atrophy. If you use the AI to avoid understanding — accepting code you couldn't have written and wouldn't recognize as broken — you slowly hollow out the very judgment that lets you verify its next answer. It's a doom loop: the less you understand, the less you can check, so the more you must blindly trust. The escape is to use the tool as a tutor, not a crutch — read what you accept, ask it why, and make sure every session leaves you a slightly better engineer, not a more dependent one. The table maps each risk to the concrete move that defuses it.

These aren't reasons to avoid AI coding — they're the things a professional manages deliberately.

RiskWhat it looks likeHow to manage it
Trust / correctnessConfident code that's subtly wrong; passes a glance, fails an edge caseVerify proportional to stakes; tests are your safety net
SecurityInjected vulnerabilities, hardcoded secrets, unsafe defaultsReview security-sensitive code line by line; scan; never trust generated auth/crypto blindly (T1)
Skill atrophyYou can generate it but no longer understand itRead what you accept; understand before you ship; use it to learn, not to avoid learning
MaintainabilityFast-generated code you can't debug or extend laterOwn the code as if you wrote it — because you're responsible for it
Hallucinated APIsCalls to functions/packages that don't existRun it; the compiler/tests catch these fast
You own every line you ship — full stop"The AI wrote it" is not a defense in a code review, an incident, or a security audit. When you commit AI-generated code, you are vouching for it exactly as if you typed it. That single principle resolves most vibe-coding debates: if you're not willing to own it, don't ship it.

Making AI coding tools reliable intermediate

Imagine handing a task to a brilliant contractor who started this morning, has never seen your codebase, and will forget everything by tomorrow. That's your AI coding tool on every fresh request. It doesn't know you run tests with make test, that you use httpx not requests, or that the legacy/ folder is radioactive and must never be touched. If you don't tell it, it will guess — competently and confidently — and its guesses will be generically reasonable and specifically wrong for your project. Reliability, then, isn't a property of the model; it's a property of how well you brief it.

This is the same lever you already met in prompting, just pointed at code: the output is downstream of the context and the intent, so the highest-leverage thing you can do is stop leaving them to chance. The good news is that most of this briefing is write-once. A project rules file — CLAUDE.md, .cursorrules, whatever your tool reads — captures your conventions, test command, and no-go zones a single time and re-feeds them into every session automatically, so you're not re-explaining your project on every prompt. The rest is per-request discipline: point at the right files, say specifically what "done" means, and on anything large ask for a plan before a diff, because it is far cheaper to redirect a paragraph than to untangle a twelve-file change.

The single mindset shift that makes all of it click: the prompt is still the program. Vague in, vague out was always true of code; it's just now literally true of the English you type. "Make it output JSON" is under-specified in exactly the way a bad ticket is — so it comes back under-specified. "Add a --json flag that prints the result as JSON, and include a test" states a contract and an acceptance check, so the first generation is something you can verify rather than merely read. You're not chatting with the tool; you're writing a spec, and the sharper the spec, the fewer laps around the loop you take. The habits in the table below are just that principle broken into moves you can reuse across every tool in this module.

Tool output quality is mostly a function of the context and intent you give it — the same lesson as prompting (Chapter 2) and Claude Code's CLAUDE.md (C3). These habits transfer across every tool in this module.

HabitWhy it works
Give it your conventionsA project rules file (CLAUDE.md, .cursorrules, etc.) stops it guessing your style, test cmd, and no-go zones
Be specific about intent"Add a --json flag that prints the result as JSON, with a test" beats "make it output JSON"
Point at the right filesRelevant context in, relevant code out; irrelevant context dilutes it
Ask for a plan first on big changesCheaper to redirect a plan than a 12-file diff (C3)
Tell it to verify"Run the tests and fix failures before finishing" turns a generator into a checker
Prompt discipline is coding discipline nowEverything you learned in Chapter 2 — be specific, state constraints, give examples, define done — is exactly what makes an AI coding tool produce code you can trust. The prompt is still the program, even when the program is a pull request.

Common pitfalls advanced

The mistakes below all share one root, and spotting it is worth more than memorizing the list. Every pitfall here is a version of the same slip: trusting output in proportion to how good it looks rather than how well it's been checked. AI-generated code looks good by default — that's what the model is optimized for — so your eyes hand out trust the code hasn't earned. Almost everything that goes wrong in AI-assisted coding is that gap between looks right and is verified right.

Notice that these aren't exotic edge cases; they're the boring, everyday reflexes of a busy engineer under deadline. Skipping the test because the demo worked. Reusing prototype-grade trust on code that's now in front of customers. Accepting a clever block you don't fully follow because it compiles and you're tired. None of them feel reckless in the moment — each feels like reasonable efficiency — which is precisely why they're pitfalls and not just "bad practices." The fix is never "try harder"; it's a concrete habit that fires whether or not you're paying attention: a test that must pass, a rules file that's always loaded, an explain-it-back gate before you merge. Read the table as a set of tripwires to install, not virtues to aspire to.

PitfallFix
Skipping the verify stepRead, run, and test proportional to the stakes — always
Prototype-grade trust on production codeMatch rigor to blast radius; own every shipped line
Trusting generated auth/crypto/security codeReview it line by line; scan; never ship it unread (T1)
Vague intent ("make it better")Specific goal + constraints + done-criteria
Accepting code you don't understandUnderstand before you ship; you own it either way
No project rules fileGive the tool your conventions once, reuse every session

Exercises advanced

Exercise V1.1 — Locate yourself on the spectrum

Context: Knowing your own delegation habits is the first step to calibrating them. Placing real tasks on the spectrum reveals whether you over- or under-verify for the stakes.

Your task: For three recent coding tasks, place each on the delegation spectrum (autocomplete → autonomous) and say what verification the stakes actually demanded.

Requirements:

  • Place each of three real tasks on the autocomplete–autonomous spectrum
  • State the verification level the stakes actually demanded for each
  • Judge whether you were over- or under-verifying on any of them
  • Tie the verdict back to how cheaply each result could be checked

💡 Hint: Compare the autonomy you used against the verification the stakes deserved — the gap is your miscalibration.

Exercise V1.2 — Run the loop deliberately

Context: The fastest way to feel why verify is non-negotiable is to run the same feature twice: once accepting the first output unread, once through the full loop. The difference is usually a hidden edge-case bug.

Your task: Pick a small feature and do two passes — one accepting the AI's first output unread, one running the full intent→generate→verify→refine loop — then compare.

Requirements:

  • Run pass 1: accept the first generation without reading it
  • Run pass 2: run the full loop with real verification and refinement
  • Compare on bugs, edge cases, and how well each matched your actual intent
  • Draw the conclusion about why the verify step is non-negotiable for anything real

💡 Hint: The unverified pass usually looks fine and hides one edge-case bug — the loop catches it exactly at the verify step.

Show what to look for

The unverified pass usually looks fine and hides an edge-case bug or a mismatch with what you meant. The verified loop catches it in the "verify" step — which is exactly why that step is non-negotiable for anything real.

Exercise V1.3 — Write a project rules file

Context: A project rules file is the reusable context that makes any AI coding tool behave like it knows your project. Writing one now powers the rest of the V2–V5 exercises.

Your task: For a project you know, write the rules file you'd give any AI coding tool.

Requirements:

  • Include the test command and the lint command
  • Include at least two project conventions
  • Include one ‘never touch this’ rule
  • Keep it reusable — this same file will power the V2–V5 exercises

💡 Hint: Encode your project's specifics (commands, conventions, no-go zones), not generic best practices the tool already knows.

🪜 Practice ladder beginner → industry

Six graded exercises, easy to real-world. Try each before opening its solution.

Exercise 1 · The core loop, namedBeginner

Context: Every AI coding workflow runs the same loop, and each step has one thing the tool cannot supply for you. Naming them is how you spot which step you're skipping when things go wrong.

Your task: State the four steps of the vibe-coding core loop and, for each, name the one thing you must supply that the tool cannot.

Requirements:

  • List the loop: intent → generate → verify → refine
  • For intent, supply a precise, testable description of ‘done’
  • For generate, supply the context (files, constraints, examples) the model needs
  • For verify, supply the judgment on whether it meets intent and is correct
  • For refine, supply the specific correction, not ‘try again’
  • State that the loop fails when you skip verify and let generated code accumulate unchecked

💡 Hint: The tool owns generation; you own intent and verification — map each step to which side supplies it.

Show solution

The loop is intent → generate → verify → refine.

StepYou must supply
IntentA precise, testable description of what ‘done’ means
GenerateThe context (files, constraints, examples) the model needs
VerifyJudgment: does this actually meet the intent & is it correct?
RefineThe specific correction, not ‘try again’

The tool generates; you own intent and verification. The loop fails when you skip verify and let generated code accumulate unchecked.

Exercise 2 · Delegation spectrum + task fitIntermediate

Context: Delegation should scale with how cheaply you can verify the result. Matching the level of autonomy to the task is the difference between acceleration and a mess.

Your task: For autocomplete, chat/scoped-edit, and autonomous-agent modes, give one task each where that level is the right amount of delegation.

Requirements:

  • Autocomplete: a task verified instantly as you read it (e.g. familiar boilerplate)
  • Chat/scoped edit: a bounded change you can diff and review in one pass (refactor a function, write a test)
  • Autonomous agent: a well-specified, low-risk, test-covered multi-file chore with contained blast radius
  • State the principle: delegation scales with how cheaply you can verify — high autonomy on unverifiable work is where it goes wrong

💡 Hint: Pick the level by asking how fast you can check the output, not how much you'd like to hand off.

Show solution
Delegation levelGood-fit taskWhy
Autocomplete (line/block)Filling boilerplate you already know the shape ofVerification is instant — you read the line as it appears
Chat / scoped editRefactor a function, write a test, explain codeBounded change you can diff and review in one pass
Autonomous agentWell-specified, low-risk multi-file chore (rename, migrate a pattern) with testsVerifiable by the test suite; blast radius contained

Principle: delegation should scale with how cheaply you can verify the result. High autonomy on unverifiable work is where vibe coding goes wrong.

Exercise 3 · A pitfall and its guardAdvanced

Context: The most dangerous vibe-coding pitfall is accepting code you don't understand: it compiles, the demo works, it merges — and no one can debug it later. The guard is a concrete habit, not good intentions.

Your task: Pick the most dangerous common pitfall and describe the concrete habit that guards against it.

Requirements:

  • Name the pitfall: accepting code you don't understand
  • Describe the ‘explain-back’ gate before accepting a non-trivial generation
  • The gate requires you to state what it does line-by-line, what inputs break it, and why this approach over the obvious alternative
  • If you can't explain it, you don't merge — you ask the tool to explain, add a pinning test, or rewrite it simpler
  • Explain that the habit turns generated code into understood code, the only kind you can maintain

💡 Hint: The test is whether you could defend every line in review as if you'd typed it yourself.

Show solution

Most dangerous pitfall: accepting code you don't understand. It compiles, the demo works, so it merges — and no one on the team can debug it later or spot that it silently mishandles an edge case.

Guard: the ‘explain-back’ gate. Before accepting a non-trivial generation, require yourself to state (a) what it does line-by-line, (b) what inputs break it, and (c) why this approach over the obvious alternative. If you can't, you don't merge it — you ask the tool to explain, add a test that pins the behavior, or rewrite it simpler.

The habit turns generated code into understood code, which is the only kind you can maintain.

Exercise 4 · Reliable prompts: before vs afterExpert

Context: A weak prompt costs you four rounds of iteration; a reliable prompt front-loads the verification criteria so the first generation is already checkable. Seeing the before/after makes the payoff concrete.

Your task: Rewrite the weak request ‘write a function to parse the file’ into a reliable prompt and explain what each addition buys.

Requirements:

  • The rewrite pins the signature and return type (removes shape ambiguity)
  • It specifies explicit error behavior for the edge cases you'd otherwise re-prompt for
  • It encodes non-functional constraints (e.g. stream, don't load whole file)
  • It asks for tests so verify becomes a one-command check, not a read-through
  • Explain what each addition buys in fewer iteration rounds

💡 Hint: A reliable prompt states the contract and the acceptance test up front so the first output can be checked, not just read.

Show solution

Before: ‘write a function to parse the file’ — ambiguous format, no contract, no error behavior. You will iterate 4 times.

After:

Write parse_orders(path: str) -> list[Order].
- Input: a CSV with headers id,customer,total_cents (total_cents is an int).
- Return a list of Order dataclasses (define it).
- Skip rows with a missing id; raise ValueError on a non-integer total_cents.
- Do not read the whole file into memory; stream line by line.
- Include a docstring and 3 pytest cases: happy path, missing id, bad total.
AdditionBuys
Signature + return typeRemoves shape ambiguity
Explicit error behaviorPins the edge cases you'd otherwise re-prompt for
‘stream line by line’Encodes the non-functional constraint (memory)
‘3 pytest cases’Makes verify a one-command check, not a read-through

A reliable prompt front-loads the verification criteria so the first generation is checkable.

Exercise 5 · A team standard for AI-generated codeProfessional

Context: When a team adopts AI coding tools, the risk isn't slower typing — it's unowned, untested, unreviewable code slipping in under ‘the AI wrote it.’ A short PR standard keeps the velocity without the erosion.

Your task: Write the 5-point PR standard that keeps velocity without eroding code quality as a team adopts AI coding tools.

Requirements:

  • Author owns it fully — ‘the AI wrote it’ is not a review defense
  • Tests are mandatory for generated logic (generation makes them cheap)
  • No unexplained code — if a reviewer asks ‘why?’ and the author can't answer, it doesn't merge
  • Diffs must be reviewable — reject giant agent dumps, require scoped commits
  • Secrets & licensing check on generated code
  • Explain that the standard keeps the gain (fast authoring) while blocking the loss (unowned/untested/unreviewable code)

💡 Hint: Each rule targets one specific way generated code erodes quality — ownership, testing, understanding, reviewability, and provenance.

Show solution
  1. Author owns it fully. ‘The AI wrote it’ is not a defense in review; the human author is accountable for correctness as if hand-written.
  2. Tests are mandatory for generated logic. Generation makes writing tests cheap, so there is no excuse — behavior must be pinned.
  3. No unexplained code. If a reviewer asks ‘why this?’ the author must answer; if they can't, it doesn't merge.
  4. Diff must be reviewable. Reject 2000-line agent dumps; require scoped, reviewable commits even if generated.
  5. Secrets & licensing check. Scan generated code for hard-coded secrets and verbatim-copied licensed snippets.

The standard keeps the gain (speed of authoring) while blocking the loss (unowned, untested, unreviewable code).

Exercise 6 · Rescuing a vibe-coded prototype for productionIndustry scenario

Context: ‘Works in the demo’ optimizes for the happy path; production is defined by the paths the demo never hit. Rescuing a vibe-coded prototype is an assess-then-harden job, not a blind rewrite.

Your task: Give the assessment plan and hardening checklist for taking a vibe-coded prototype that demos perfectly to production.

Requirements:

  • Assess first: map what exists, list actual features, and separate understood parts from ‘magic’ (highest risk)
  • Find the missing edges the demo skipped: bad input, empty state, concurrency, network failure, large inputs
  • Harden across correctness (tests over real behavior before changing anything), input handling, secrets/config, failure modes, observability, and data safety
  • State the lesson: vibe coding defers the verification and edge-case work — budget for it explicitly instead of trusting the demo

💡 Hint: Don't rewrite blindly — pin current behavior with tests first, then harden the paths the demo never exercised.

Show solution

Reality: ‘works in the demo’ optimizes for the happy path; production is defined by the paths the demo never hit. Do not rewrite blindly — assess, then harden.

  1. Map what exists: read the code, list the actual features, and identify which parts are understood vs magic. Magic parts are highest risk.
  2. Find the missing edges: what happens on bad input, empty state, concurrent use, network failure, and large inputs? Prototypes almost never handle these.
Hardening areaAction
CorrectnessAdd a test suite over real behavior before changing anything
Input handlingValidate & sanitize all external input; define error responses
Secrets/configMove hard-coded keys to config; rotate anything committed
Failure modesTimeouts, retries, graceful degradation on dependency failure
ObservabilityLogging + metrics so prod failures are diagnosable
Data safetyBackups/migrations; no destructive ops without guards

Lesson: vibe coding is excellent for reaching a working prototype fast; the production cost is the verification and edge-case work it deferred. Budget for that explicitly instead of trusting the demo.

✓ Checkpoint — you can move on when you can…

  • Define vibe coding vs AI-assisted engineering and when each fits.
  • Place a tool/task on the delegation spectrum and its verification burden.
  • Run the intent→generate→verify→refine loop and explain why verify is essential.
  • Name the key risks and how you'd manage each.
  • Set up context/rules that make an AI coding tool reliable.
🏗️ Toward the capstoneYou could build large parts of the AI DevOps Engineer with an AI coding tool — but the safety gate, the risk classification, and anything touching prod are exactly the "own every line, verify hard" code this chapter warns you not to vibe. Knowing which parts to delegate and which to write carefully is the FDE's judgment (Chapter 7), applied to your own workflow. See Claude Code, the agentic coding tool →

Knowledge check check yourself

✓ Knowledge check

The lesson frames the intent -> generate -> verify -> refine loop and calls one step the "load-bearing" one. Which step, and why is skipping it described as "gambling, not coding"?

Show answer
Verify is load-bearing. Skipping it means you ship code you never read, ran, or tested, so any subtle bug or edge-case failure reaches production unchecked — you're trusting output you can't vouch for.
✓ Knowledge check

According to the delegation spectrum, why does moving further right (toward autonomous agents) increase the verification you owe rather than decrease your workload?

Show answer
The further right you sit, the less of the code you actually wrote yourself, so more of the correctness burden shifts to you as reviewer — you must verify proportionally harder precisely because the AI, not you, produced it.
© 2026 studybydoing.in · AI Engineering: Zero to Production · All rights reserved. · About · Privacy Policy · Terms · Contact
Educational content, provided as-is and without warranty. Code samples are examples — review, test, and adapt them before using in production. See the Terms of Use & Disclaimer. Use at your own risk.
© studybydoing.in