Module 1 · Why AI Engineering Is Engineering ⏱ 18 min

What AI Commoditised — and What It Did Not

By the end of this lesson you will be able to:
  • Draw the line between work a language model now does for free and the engineering judgment that still pays
  • Decide, for a given task, whether a deterministic function beats a model on cost, latency, and reliability
  • Explain why a model is a component inside a system, not the system itself

Something changed between 2023 and 2026, and naming it precisely is the first real skill in AI engineering. Generating a chunk of boilerplate, writing a one-off script to call an API, turning a plain-English request into a regular expression, summarising a long document — a language model now does all of that for almost nothing. The barrier to producing code and text collapsed.

What did not collapse is everything that turns a model into a feature you can ship to paying users. Deciding whether a model should be involved at all, feeding it the right context, bounding what it costs, checking whether its answer is actually correct — that work is still engineering, and it is still where the salary sits. This lesson draws that line cleanly.

flowchart TD
  A["a request arrives"] --> Q{"fixed format,<br/>rule-verifiable?"}
  Q --> D["deterministic code<br/>cheap, exact, fast"]
  Q --> M["model plus full system<br/>where judgement is needed"]
  style D fill:#166534,color:#fff
  style M fill:#6d28d9,color:#fff
The commoditisation line: a task with a fixed format and a rule-verifiable answer belongs to deterministic code, not to a model.

What the model commoditised

Be specific. A model is now the fastest way to draft a function you can describe in one sentence, to translate a curl command into your language's HTTP client, or to produce a first pass of a regex for a fiddly format. These are generation tasks: open-ended output, no single right answer, where a fluent guess beats ten minutes of typing. The model replaced the typing, not the thinking.

What it did not

Judgment did not get commoditised. Should this endpoint call a model at all, or would a twenty-line deterministic function do the job better, faster, and a thousand times cheaper? That is not a prompt — it is a design decision, and the wrong answer turns a cheap feature into an expensive, flaky one. The instinct to ask that question, every time, is what hiring managers screen for.

A senior instinct encoded as a function: score the task, reach for the cheaper tool when the score is high. Press Run.
function classifyTask(t) {
  let score = 0;                       // higher = stronger case for deterministic code
  if (t.fixedFormat) score += 2;       // e.g. pull a date out of a known layout
  if (t.ruleCanVerify) score += 2;     // a regex or lookup can check the answer
  if (t.outputIsBounded) score += 1;   // yes/no, a number, an enum
  if (t.needsJudgement) score -= 3;    // open-ended, correctness needs a human eye
  return score >= 2 ? "deterministic" : "model";
}

console.log(classifyTask({ fixedFormat: true, ruleCanVerify: true, outputIsBounded: true, needsJudgement: false }));
console.log(classifyTask({ fixedFormat: false, ruleCanVerify: false, outputIsBounded: false, needsJudgement: true }));

A model is a component, not a product

The mental model that survives is this: a language model is one component inside a larger system, the way a database or a regex engine is a component. You would never ship a product that was only a database — you ship the read and write logic, the schema, the migrations, the connection pool. The same is true here. The model is the part that produces fluent output; the system around it is the part that makes that output safe, cheap, and correct enough to rely on.

That surrounding system is mostly ordinary software — branches, loops, lookups, tests — and ordinary software is exactly what a model is worst at replacing, because it has to be right every single time.

flowchart LR
  T["extract a postcode<br/>from a fixed format"] --> R["regex: microseconds,<br/>free, always correct"]
  T --> L["model: far more cost,<br/>far more latency, sometimes wrong"]
  style R fill:#166534,color:#fff
  style L fill:#b91c1c,color:#fff
The trap: one fixed-format task, two routes. The deterministic route wins on cost, latency, and reliability.

The classic trap: throw an LLM at it

Every team that adopts a model hits the same trap. A task arrives — extract the postcode from an address, validate an email, sort a list, pull a total out of a receipt — and someone routes it to the model because the model is new and impressive. The result feels magical for a week. Then the bill arrives, the latency creeps up, and one request in fifty returns something the model invented instead of extracted.

The fix is the instinct this lesson trains. If a task has a fixed format and a rule can verify correctness, do not send it to a model. A regex extracts a postcode in microseconds for free and gets it right every time. The model costs many times more, takes far longer, and is occasionally wrong. Reach for the cheaper tool on purpose.

The three things that still pay

If generation is commoditised, what is left to be good at? Three things, and they are the spine of this course. First, systems — the deterministic pipeline around the model: a router that decides what kind of request this is, a retriever that fetches the context the model needs, a guard that checks the answer before a user sees it. Second, evaluation — a way to measure whether a change made the feature better or worse, because you cannot improve what you cannot score. Third, cost and latency control — knowing, before you ship, what one request will cost and how long it will take. None of these are prompts; all of them are code you can test.

Run the classifier across a mixed list and read which tasks a model never earns.
function classifyTask(t) {
  let score = 0;
  if (t.fixedFormat) score += 2;
  if (t.ruleCanVerify) score += 2;
  if (t.outputIsBounded) score += 1;
  if (t.needsJudgement) score -= 3;
  return score >= 2 ? "deterministic" : "model";
}

const tasks = [
  { name: "extract postcode", fixedFormat: true, ruleCanVerify: true, outputIsBounded: true, needsJudgement: false },
  { name: "draft a marketing email", fixedFormat: false, ruleCanVerify: false, outputIsBounded: false, needsJudgement: true }
];
tasks.forEach((t) => console.log(t.name + " -> " + classifyTask(t)));
flowchart TD
  P["what still pays in 2026"] --> S["systems: the deterministic<br/>pipeline around the model"]
  P --> E["evaluation: score every<br/>change before it ships"]
  P --> C["cost and latency: budget<br/>a request before you build it"]
  style P fill:#3776ab,color:#fff
Generation is commoditised; the three durable skills are systems, evaluation, and cost control.
The wrong choice has a measurable price. Same task, two routes — read the latency gap. Run it.
function costEstimate(route) {
  // latency in ms, cost in micro-dollars per call (illustrative, fixed numbers)
  if (route === "regex") return { latencyMs: 1, microDollars: 0 };
  if (route === "model") return { latencyMs: 900, microDollars: 500 };
  return { latencyMs: 0, microDollars: 0 };
}

const regex = costEstimate("regex");
const model = costEstimate("model");
console.log("latency penalty: " + (model.latencyMs / regex.latencyMs) + "x");
console.log("a task a model never earned, routed to one anyway");
Exercise

What does this print? The classifier adds 2 for a fixed format and 2 again when a rule can verify the answer.

function classifyTask(t) {
  let score = 0;
  if (t.fixedFormat) score += 2;
  if (t.ruleCanVerify) score += 2;
  if (t.outputIsBounded) score += 1;
  if (t.needsJudgement) score -= 3;
  return score >= 2 ? "deterministic" : "model";
}

console.log(classifyTask({ fixedFormat: true, ruleCanVerify: true, outputIsBounded: false, needsJudgement: false }));
Exercise

Write classifyTask(t) that scores a task and returns "deterministic" when the score is 2 or higher, otherwise "model". Add 2 for fixedFormat, 2 for ruleCanVerify, 1 for outputIsBounded, and subtract 3 for needsJudgement.

function classifyTask(t) {
  // score the task, then return "deterministic" or "model"
}
Exercise

This classifier has the judgement signal backwards: it adds 3 when a task needs human judgement, so open-ended tasks wrongly score as deterministic. Judgement should push the task towards the model. Change the one operator that fixes it.

function classifyTask(t) {
  let score = 0;
  if (t.fixedFormat) score += 2;
  if (t.ruleCanVerify) score += 2;
  if (t.outputIsBounded) score += 1;
  if (t.needsJudgement) score += 3;
  return score >= 2 ? "deterministic" : "model";
}
Exercise

Write nonModelTasks(tasks) that returns an array of the names of every task classifyTask calls "deterministic" — the work you would NOT send to a model. classifyTask is provided for you; use it, do not rewrite it.

function classifyTask(t) {
  let score = 0;
  if (t.fixedFormat) score += 2;
  if (t.ruleCanVerify) score += 2;
  if (t.outputIsBounded) score += 1;
  if (t.needsJudgement) score -= 3;
  return score >= 2 ? "deterministic" : "model";
}

function nonModelTasks(tasks) {
  // return the names of the tasks that are "deterministic"
}
Exercise

Which task should you NOT route to a language model — a deterministic tool does it better?

Recap

  • A model commoditised generation — drafting code, one-off scripts, first-pass regexes, summaries. It replaced the typing, not the thinking.
  • It did not commoditise judgment: deciding whether to call a model at all, and building the system that makes its output safe, cheap, and correct.
  • A model is a component inside a system, not the system itself. Most of that system is ordinary, testable software.
  • The classic trap is throwing an LLM at a deterministic task — paying many times more for something a regex does perfectly.
  • The durable skills are systems, evaluation, and cost control — the focus of the rest of this module.

Next you will map the parts of that surrounding system and see that most of an AI product is code you already know how to write and test.

Checkpoint quiz

What did language models commoditise — and what did they leave intact?

A teammate says 'the model is the product.' Which view is more durable?

Go deeper — technical resources