Photo by PJH on Unsplash

On this page

This page compares traditional software with AI-based software. Both run on the same computers and are often called from the same code. The difference is where the logic comes from and how sure you can be about the result.

Traditional software: rules written by people

In a traditional program, a developer decides every rule. The program receives input, applies those rules step by step, and returns output. A spam filter written this way checks for words the developer chose:

src/is-spam.ts
const blockedWords = ['lottery', 'winner', 'free money'];
export function isSpam(subject: string): boolean {
const text = subject.toLowerCase();
return blockedWords.some((word) => text.includes(word));
}

The behavior is fully defined by the code. The same input always gives the same output. When the filter misses a spam message, a developer reads the code, finds the gap, and adds a rule. This works well as long as a person can describe the rules completely.

Machine learning: rules learned from examples

Some problems have rules nobody can write down. Recognizing a cat in a photo, transcribing speech, or judging whether an email is spam in all its variations are examples. Machine learning reverses the process. Instead of writing the rules, you collect examples with the correct answers, and a training algorithm finds the rules itself. The result is a model: a large set of numbers that encodes those learned rules.

Diagram 1
flowchart LR
  subgraph traditional["Traditional software"]
    direction LR
    rules["Rules written by a developer"] --> program1["Program"]
    input1["Input"] --> program1
    program1 --> output1["Output"]
  end
  subgraph ml["Machine learning"]
    direction LR
    examples["Examples with correct answers"] --> training["Training"]
    training --> model["Model with learned rules"]
    input2["New input"] --> model
    model --> output2["Predicted output"]
  end

The spam filter now asks a trained model instead of checking a list:

src/is-spam.ts
import { spamModel } from './spam-model';
export async function isSpam(subject: string): Promise<boolean> {
const { spamProbability } = await spamModel.predict(subject);
return spamProbability > 0.9;
}

Two things changed. The rules are no longer in the code; they are inside the model, and nobody can read them line by line. The model also returns a probability, not a yes or no. The threshold of 0.9 is a business decision: a lower value catches more spam and also blocks more legitimate mail.

Generative AI: instructions in plain language

Large language models add a third style. A general model already exists, trained on a large share of the public internet. You do not train it for your task. You describe the task in natural language, in a prompt, and the model produces text, code, or structured data in return.

The program is now a combination of a model you did not build and instructions that are written in words rather than code. A small change in wording can change the result, and the same prompt can return different answers on different runs.

What differs in practice

Aspect Traditional software AI-based software
Source of logic Code written by developers Learned from data, or steered by a prompt
Output Exact and repeatable Probable, can vary between runs
How you check it Unit tests with expected results Evaluation on many examples, with a success rate
Typical failure An error or crash in a known place A confident, plausible answer that is wrong
Explaining a result Read the code path Hard; the model cannot be read like code
How you change it Edit the code Change the data, retrain, or reword the prompt
Running cost Small CPU time GPU time or a paid API call per request
What it needs A precise specification Data or examples, and tolerance for some errors

Correctness and determinism

A traditional function that adds tax to a price is either correct or has a bug. An AI model is right most of the time, and its error rate is part of the design. A model that classifies support tickets correctly 95 percent of the time can be very useful, but one in twenty tickets will be wrong. The question is not whether it makes mistakes, but whether the mistakes are acceptable and caught.

Testing and evaluation

A unit test states that a given input produces a given output. That works for code. For a model, a single example proves little. Teams build an evaluation set: hundreds or thousands of inputs with known good answers. They measure the share of correct results and run the set again after every change to the model or the prompt. Evaluating AI models shows how to build one.

Failure modes

When traditional code fails, it usually fails visibly: an exception, a wrong total, a crash. AI fails quietly. A language model can invent a source, a function, or a fact and present it in fluent, confident language. This is called a hallucination. Systems built on AI need checks for that: validation of outputs, references to sources, or a human who reviews important results.

Cost and speed

Traditional code runs in microseconds on cheap hardware. A call to a large language model takes from a fraction of a second to many seconds and costs money for each request, based on the amount of text. A task that runs millions of times a day can be cheap with code and expensive with a model. The cost of AI works through an example.

When to choose which

Use traditional code when the rules are known and must be exact. Billing, tax, access control, data validation, and anything with legal consequences belong here. Code is also the better choice when the same answer must come out every time, or when the result must be explainable to an auditor.

Use AI when the rules cannot be written down, but examples exist or the task can be described in words. Understanding language, summarizing documents, recognizing images and speech, translating, drafting text and code, and sorting unstructured input are typical cases. AI also fits when an occasional mistake is acceptable, or when a person reviews the result.

A useful test: if you can write the rules as a clear specification, write code. If you can only describe the task by example or in words, consider a model.

Combining both

Most real systems use both. Code does the parts that must be exact, and a model does the parts that need judgment. The code also checks what the model returns. In the example below, a model sorts support tickets into queues. The code limits the answer to known values and sends anything unexpected to a person:

src/route-ticket.ts
const queues = ['billing', 'technical', 'account'] as const;
type Queue = (typeof queues)[number];
export async function routeTicket(text: string): Promise<Queue | 'manual-review'> {
const answer = await askModel(
`Classify this support ticket as one of: ${queues.join(', ')}. Reply with one word.\n\n${text}`,
);
const queue = answer.trim().toLowerCase();
return queues.includes(queue as Queue) ? (queue as Queue) : 'manual-review';
}

askModel stands for whichever model API the application uses. The pattern stays the same: the model proposes, the code validates, and anything outside the expected range goes to a fallback. Agentic AI takes this a step further, with the model deciding which code to call.

Check your understanding

Question 1 of 6

0 of 6 checked

  1. 1. When does a traditional, rule-based program work well?

Search articles

Type a word to search published articles.

Open the search page