DEV Community

Cover image for The Engineering History of AI: Why Your LLM Hallucinations Are as Old as the 13th Century
Emmimal Alexander
Emmimal Alexander

Posted on

The Engineering History of AI: Why Your LLM Hallucinations Are as Old as the 13th Century

Hey devs, if you've ever deployed an AI model only to watch it confidently spit out nonsense (looking at you, "The capital of France is Florida"), you're not alone. As the author of Neural Networks and Deep Learning with Python and founder of EmiTechLogic, I teach engineers to build AI systems daily. But here's the rub: we obsess over training models without digging into why they fail.
Spoiler: Modern AI flops for the same reasons symbolic AI tanked 40 years ago. We've just shifted the failure mode from brittle rules to probabilistic hallucinations. In this post, I'll trace 70+ years of AI engineering—from a 13th-century philosopher's paper wheels to GPT-4's token roulette. It's not dry history; it's the debug toolkit for your next prod deployment.

Grab a coffee. Let's rewind.

Part 1: Combinatorial Explosion—Llull's Wheels to LLM Token Soup

Back in 1273, Ramon Llull built the OG "AI": rotating paper discs etched with concepts like Truth, Goodness, and Power. Spin 'em, combine 'em, boom—new ideas like "Truth + Wisdom = Enlightened Understanding."

Sounds cute, right? But with just 9 concepts, 3-way combos explode to 729 possibilities. Scale to 10? 1,000+. It's combinatorial explosion: infinite noise drowning rare insights.

Fast-forward to 2024: LLMs like GPT-4 don't "think"—they predict the next token from 50k+ vocab. Prompt: "The capital of France is..." Next token? "Paris" (likely), "Florida" (plausible from noisy data). No truth filter, just probabilistic pruning via training data.

Why it bites devs: You're shipping a search engine, not a knowledge base. Hallucinations? Baked in.

Fix it: Ground with RAG (Retrieval-Augmented Generation). Query a vector DB first, then generate. Code snippet for starters:

import openai
from chromadb import Client  # Or your fave vector store

def grounded_generate(prompt):
    # Retrieve relevant facts
    client = Client()
    collection = client.get_collection("facts")
    results = collection.query(query_texts=[prompt], n_results=3)

    # Augment prompt
    augmented = f"{prompt}\nBased on these facts: {results}"

    # Generate
    response = openai.ChatCompletion.create(
        model="gpt-4",
        messages=[{"role": "user", "content": augmented}]
    )
    return response.choices[0].message.content
Enter fullscreen mode Exit fullscreen mode

Never deploy raw LLMs for facts. Prune early.

Part 2: Turing's Abstraction Trap—Symbols vs. Reality

Alan Turing's 1936 Universal Machine proved smarts are platform-independent: one tape, infinite instructions. It birthed the Stored Program concept—your GPU juggles games, nets, and crypto because intelligence is just symbol flips.

But here's the dev gotcha: Abstraction creates a representation gap. Symbols (LISP atoms in '70s, embeddings today) drift from real-world truth.

Example: Train an ImageNet classifier to 95% accuracy. Deploy? It calls a husky a wolf (snowy backgrounds correlate, not cause). Or flops on rotated pics. Why? It learned patterns, not causality.

Pro tip: Stress-test on OOD (out-of-distribution) data. In PyTorch:

import torch
from torchvision import transforms

# Augment for OOD: rotations, noise
ood_transform = transforms.Compose([
    transforms.RandomRotation(30),
    transforms.GaussianBlur(kernel_size=5),
])

# Test loop...
model.eval()
with torch.no_grad():
    for batch in ood_loader:
        outputs = model(ood_transform(batch))
        # Log accuracy drop
Enter fullscreen mode Exit fullscreen mode

Bridge the gap: Validate outputs against real-world APIs.

Part 3: Symbolic AI's Crash (1980s) vs. Neural Fluidity (2024)

Expert systems ruled the '80s: MYCIN diagnosed like pros, XCON saved DEC millions. But they crumbled on:

  1. Frame Problem: Infinite rules for "make coffee" (don't use gasoline!).
  2. Knowledge Bottleneck: Can't code "gut feel."
  3. Brittleness: One edge case? Crash.

Neural nets flip it: Learn from data, generalize probabilistically. But now? Too fluid—hallucinations, black boxes, stochastic outputs.

Symbolic AI (1980s) Neural Nets (2024)
Rigid: Crashes on outliers Fluid: Hallucinates subtly
Interpretable logic Black-box vibes
Deterministic Stochastic chaos

We're hybridizing: RAG for facts, function calling for rules. Like this OpenAI tweak:

tools = [{"type": "function", "function": {"name": "get_weather"}}]

response = openai.ChatCompletion.create(
    model="gpt-4",
    messages=[{"role": "user", "content": "What's the weather?"}],
    tools=tools
)
# Forces tool use over guesswork
Enter fullscreen mode Exit fullscreen mode

Escape rigidity, don't drown in chaos.

Part 4: XOR's Ghost—Why LLMs Suck at Math

1969: Minsky/Papert nuked single-layer perceptrons with XOR proof (non-linearly separable). Killed nets for 20 years—til backprop layered up.
Today: LLMs butcher arithmetic. "127 × 384?" It tokenizes, predicts "plausible" (48,768? Nah, 48,769 sometimes). No symbolic compute, just stats.
Hack it: Parse + execute deterministically.

import re
import openai

def smart_calc(prompt):
    # LLM parses
    parse_prompt = f"Extract math expr from: {prompt}"
    expr = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=[{"role": "user", "content": parse_prompt}]
    ).choices[0].message.content

    # Eval safely (use sympy for complex)
    try:
        result = eval(expr)  # WARNING: Sandbox in prod!
    except:
        result = "Invalid expr"

    # Format back
    return f"Result: {result}"
Enter fullscreen mode Exit fullscreen mode

Route math to code interpreters. Architecture mismatch? Bolt on tools.

Part 5: GPUs' Bitter Lesson—Scale Costs Real Money

2012: AlexNet + GPUs crushed ImageNet. Why? Matrix math parallelizes like a dream on thousands of cores. Sutton's "Bitter Lesson": Compute > cleverness.
But 2024 reality: Inference ain't free. GPT-4? ~$0.03-0.06/1k tokens. 1k users × 40 queries? $1,800/mo surprise.
Budget hacks:

  1. Cache queries (FAISS for semantic dupes).
  2. Right-size models (3.5-turbo = 10x cheaper).
  3. Trim contexts.
from sentence_transformers import SentenceTransformer
import faiss

model = SentenceTransformer('all-MiniLM-L6-v2')
index = faiss.IndexFlatL2(384)  # Embed dim

# Cache hit? Skip API.
query_emb = model.encode(query)
D, I = index.search(query_emb, 1)
if D[0][0] < 0.5:  # Threshold
    return cache[I[0][0]]
Enter fullscreen mode Exit fullscreen mode

Scale smart, not just big.

Part 6: Transformers' Speed Trade-Off—Context Cliffs

RNNs chugged sequentially (vanishing gradients killed long mem). 2017 Transformers? Self-attention parallelizes everything—QKV vectors let words "talk" instantly.

Wins: GPT-scale. Losses: Fixed windows (8k-128k tokens). Exceed? Silent truncate → garbage out.

From my code-review bot: 2k-line file → "All good!" (bug on line 1.8k ignored).

Defend: Token-count upfront.

import tiktoken

enc = tiktoken.encoding_for_model("gpt-4")
tokens = len(enc.encode(full_prompt))

if tokens > 8192:
    # Chunk it
    chunks = [full_prompt[i:i+7000] for i in range(0, len(full_prompt), 7000)]
    results = [grounded_generate(c) for c in chunks]
    return "\n".join(results)
Enter fullscreen mode Exit fullscreen mode

Chunk, validate, scale windows wisely ($$$).

Part 7: Hallucination's Root—Open-World Probability

Symbolic AI: Closed world—"Don't know" if missing. LLMs: Open-world autocomplete. High-prob token? "Confident" BS.

Fix: Neurosymbolic hybrids. Parse intent (neural) → fetch facts (symbolic) → generate (neural).
That's RAG gold.

TL;DR: 7 Engineering Fixes from 750 Years of AI Fails

  1. Explosion: Prune with sampling/top-p.
  2. Abstraction: OOD tests + validators.
  3. Brittleness: RAG/function calls.
  4. Linearity: Tool routing (math → eval).
  5. Hardware: Cache, right-size, budget 5x.
  6. Context: Token guards + chunking.
  7. Halluc: Ground in retrieval.

Wrapping Up: History as Your Prod Shield
From Llull's discs to Transformer cliffs, AI's eternal dance: Explore (generate) vs. Verify (constrain). We're integrating symbolic bones into neural flesh.
Build reliable? Study the scars. Check my GitHub repo .

For the full, deep dive—including diagrams, extended examples, and more historical reconstructions—head over to the original post on EmiTechLogic.

Top comments (0)