Thinking Like an AI Builder
Building on a probabilistic component changes how you design, test, and ship. The habits that separate AI products that work from impressive demos that don't.
You've now seen the whole arc in miniature: an idea, a stack, a setup, and a working feature that improved once you tested it on messy input. Before Module 1 goes deeper into how models work, step back and look at what just changed about how you build software.
Every habit you have as a developer assumes your components are deterministic: same input, same output, and a passing test means the code works. A language model breaks that assumption. Its output can vary between runs, its inputs are unbounded, and when it fails it usually fails fluently, with a confident, well-written wrong answer. This lesson covers the habits that let you build reliable products on that kind of component anyway: defining "good" before you build, reading outputs in bulk, designing for the wrong answer, keeping code in charge, and treating cost, latency, and model changes as requirements from day one.
What changes when a component is probabilistic
In conventional software, you write a spec, implement it, and assert equality in a test. If calculateTax(100) returns 8.25 once, it returns 8.25 forever. An AI feature behaves differently in three ways that matter:
- Outputs vary. The same prompt and input can produce different wording, different emphasis, and occasionally a different answer. "It works" stops being a yes or no and becomes a rate: it works on 97% of inputs, or 80%.
- Inputs are unbounded. A form field accepts what you validate. A "summarize this" box accepts anything a human can paste, in any language, at any length, including text crafted to manipulate the model.
- Failures look like successes. A crashed function throws. A model that misreads a ticket returns a perfectly formatted, plausible, wrong summary, and nothing in your logs says so.
The first point is easy to underestimate. Send a genuinely borderline ticket, say "I was charged twice after the app crashed during checkout," to a classifier five times, and the label may flip between billing and bug. That variation is information, not just noise: it usually points to an ambiguity in your task definition rather than a weakness in the model. The fix here is a rule in the prompt ("if money was charged incorrectly, use billing, even if a bug caused it"), not a bigger model. You'll run this experiment yourself, and see why it happens, in How LLMs Generate Text.
None of this makes AI features unreliable by nature. It means reliability comes from the system you build around the model rather than from the model alone. The rest of this lesson is that system, in the form of habits.
Habit 1: Define "good" before you build
The most expensive mistake in AI feature work is building first and deciding what success means later. Without a definition, every prompt change is judged by how the last two outputs felt, and you'll go in circles.
Before writing a prompt, write a short feature brief. It takes fifteen minutes and saves days:
# Feature: Ticket summary on open
**User and moment:** A support agent opening a ticket with 10+ messages.
**Job:** Answer "where are we, and what do I do next?" in under 10 seconds of reading.
**Input:** Ticket subject and full message thread (can be 50+ messages, any language).
**Output:** Headline, list of open requests, status, what's been tried.
**Good looks like:**
- Every distinct customer request appears
- Order numbers, amounts, and dates match the thread exactly
- No promises or diagnoses that aren't in the thread
**When it's wrong:** Agent sees the full thread below; "summary missed something" button.
**Budget:** Under 3 seconds; cost per summary well under a cent at expected volume.
**First 20 test cases:** Pulled from last month's longest tickets.Notice how much of this is about the failure case and the budget. Those lines will shape your design more than the prompt will. The "good looks like" list becomes your first checks, exactly like the keyword checks you wrote in Your First AI Feature.
Habit 2: Read outputs in bulk
The most valuable debugging technique in AI building is also the least glamorous: look at a lot of real outputs, side by side with their inputs. Not two or three; thirty to fifty, from realistic inputs.
When you read in bulk, patterns appear that no single example reveals. You'll notice that summaries of long threads consistently drop the earliest messages, or that tickets written in a hurry get classified as "bug" too often, or that one customer's signature block keeps getting summarized as a request. Each pattern is a specific, fixable failure.
A simple practice that works:
- Collect 30 or more real inputs (anonymized where needed) and run them through your feature.
- Read each output against its input and write a one-line note on anything wrong.
- Group the notes into categories ("dropped second request," "invented an order number").
- Fix the biggest category first, then rerun everything.
This is called error analysis, and Module 9 turns it into a formal method. The habit to build now is simply refusing to judge a feature from a handful of examples.
Habit 3: Design for the wrong answer
Your feature will sometimes be wrong. The question isn't whether, but what happens next. Two properties decide how much a mistake costs: stakes (how bad is a wrong output?) and reversibility (how easily can someone catch and undo it?).
| Easy to catch and undo | Hard to catch or undo | |
|---|---|---|
| Low stakes | Automate freely: tags, suggested titles, search ranking | Automate with spot checks: summaries stored in reports |
| High stakes | Human confirms each one: drafted replies, suggested refunds | Don't let the model decide: payments, permissions, account deletion |
Most good AI features live in the left column, and the design patterns that keep them there are worth memorizing:
- Draft, don't send. The model writes; a person approves.
- Show the source. Put the original next to the AI output so errors are visible.
- Make undo cheap. A wrong tag should take one click to fix.
- Fall back gracefully. When the call fails, is refused, or times out, the product still works, just without the AI part.
- Route uncertainty to people. When a case is ambiguous, send it to a review queue instead of guessing.
Designing for Uncertainty and Errors in Module 8 covers the interface side of this in depth.
Habit 4: Let code own what code does well
You met this division of labor in What Makes Something an AI Product?: the model is good at reading, writing, and judgment, and unreliable at arithmetic, counting, exact lookups, and enforcing rules. As a habit, it means drawing a firm line in every feature: the model produces language and labels; code makes decisions and does math.
In practice that looks like:
- The model classifies a ticket's urgency; code applies the SLA rules to that label.
- The model extracts an amount from an email; code checks it against the order in the database before anything happens.
- The model assigns each ticket to a theme; code counts the tickets per theme.
- The model returns structured output matching a schema; code validates it and rejects anything that doesn't fit.
Every check your code performs on model output is a place where a fluent wrong answer gets caught before a user sees it. Module 4 covers schemas and validation; for now, treat model output like user input: useful, but untrusted until checked.
Habit 5: Treat cost, latency, and change as requirements
Three properties of AI features are easy to ignore in a prototype and painful to retrofit:
Cost. Every call costs money, and the cost scales with usage and input length. A feature that costs a fraction of a cent per use is fine at a hundred users and a line item at a hundred thousand. Estimate cost per use from the start and log token usage on every call, as you saw in The AI Builder Stack.
Latency. Model calls take seconds. Decide early whether a feature runs while the user waits (stream the output, keep it short) or in the background (precompute summaries when a message arrives). That choice shapes your architecture.
Change. Providers release new models, retire old ones, and sometimes change behavior. A prompt tuned on one model may behave differently on the next. Your protection is the same small set of habits: model IDs in one module, prompts in version control, and an eval set you can rerun in minutes when you switch. With those in place, a model upgrade is an afternoon of testing instead of a week of surprises.
Demo thinking vs. product thinking
Put the habits together and you get a different way of working. Here's the same feature built two ways:
Demo thinking. Write a prompt, try it on three inputs you made up, see that the outputs look good, and ship it. When a user reports a bad summary, tweak the prompt until that one input works. Find out about the cost from the invoice. Find out a model update changed behavior from a support ticket.
Product thinking. Write a brief that defines the job, what good looks like, and what happens when it's wrong. Build a test set from real inputs. Read 30 outputs before shipping and fix the biggest failure category. Log cost and latency per call. Put the source next to every output and give users a one-click way to flag mistakes. Rerun the test set before every prompt or model change.
The second version takes a little longer up front. It's also the only one that's still working six months later.
- Pick the strongest feature idea from the exercises earlier in this module.
- Write a feature brief using the template above: user and moment, job, input, output, what good looks like (at least three checkable bullets), what happens when it's wrong, budget, and where your first test cases will come from.
- Place the feature in the stakes and reversibility table. If it lands on the right side, redesign it until it moves left.
- List two things that code, not the model, should own in this feature.
Success looks like: a one-page brief someone else could build from, with a defined failure path and at least three things you could check automatically.
- Models vary between runs, accept unbounded input, and fail fluently, so reliability comes from the system around the model.
- Define good before you build: a short feature brief with checkable criteria, a failure path, and a budget.
- Read outputs in bulk (30 or more) and fix failures by category, not one input at a time.
- Design for the wrong answer by weighing stakes against reversibility; draft, show sources, make undo cheap, and fall back gracefully.
- The model produces language and labels; code does math, enforces rules, and validates everything.
- Treat cost, latency, and model changes as requirements from day one.
Next: How LLMs Generate Text: A Builder's Mental Model — Module 1 begins with what's happening inside the model, and what it means for the features you build.