The Decision Stack: Rules, Predictions, Optimization & LLMs

10 min read Module 1 of 9 Lesson 3 of 25

What you'll learn

  • Describe the four layers of a decision stack: rules, predictive models, optimization, and LLM components
  • Choose the right layer for a given part of a decision based on data, structure and stakes
  • Explain the standard execution order: eligibility rules, scoring, optimization, guardrails
  • Recognize when a decision needs causal or sequential (bandit) methods instead of plain prediction
Building this at your company? For enterprise and company teams taking this to production: book a 30-minute session with our AI engineers for architecture guidance, code review, and a rollout plan for your use case.
Book a Team Session

Once the decision is specified, the next question is how to implement it. There are four families of technique, and almost every argument about “rules vs ML” or “should we use an LLM for this?” is really an argument about which family fits which part of the decision.

The answer in production is nearly always all of them, in layers. A loan decision might use rules for eligibility, a model for default probability, an optimizer for credit limits under portfolio risk constraints, and an LLM to read uploaded payslips. Each layer does what it’s good at.

Layer 1: Rules

Rules are deterministic if-then logic: “if age < 18, decline”, “if account is in collections, no offers”, “if order value > $5,000 and new customer, route to manual review”.

Good at: legal and policy requirements, crisp eligibility criteria, encoding expert knowledge when there’s little data, and anything an auditor will read line by line. Rules are transparent, testable and fast.

Bad at: weighing many weak signals, adapting to change, and handling the long tail. Rule systems grow by accretion. After a few years you have 3,000 rules with unclear precedence that nobody dares delete.

Use rules for what is allowed, not for what is best. Lesson 16 covers decision tables and the DMN standard, which keep rule sets maintainable.

Layer 2: Predictive models

Predictive models estimate the uncertain quantities in the decision: the probability of default, expected demand, the chance a customer churns under each possible offer.

Good at: combining hundreds of signals, learning from history, producing probabilities that can be weighed against costs.

Bad at: telling you what to do. A model outputs a number; turning it into an action needs an objective. They also only know about actions that appear in the training data, and they confuse correlation with effect. A model trained on history where the account team called only the most loyal customers will “learn” that calls cause loyalty.

Two specializations matter enough to get their own modules:

  • Causal models (Module 4) estimate what an action changes, the difference between the outcome with and without it. That’s what targeting decisions need.
  • Sequential and bandit methods (Module 5) handle decisions where acting generates the data you learn from, and where you have to explore actions you’re unsure about.

Layer 3: Optimization

Optimization chooses the best combination of actions given an objective and constraints. Linear programming, mixed-integer programming, constraint programming and their relatives.

Good at: allocation under shared limits. Budget across customers, inventory across stores, drivers across deliveries, staff across shifts. Whenever one decision affects what’s available for another, you need optimization, because choosing the best action for each unit independently ignores the coupling.

Bad at: dealing with uncertainty by itself. A solver takes inputs as given. Feed it point forecasts and it’ll confidently exploit their errors. Lessons 8 and 9 deal with this.

Layer 4: LLM components

Large language models are the newest layer, and the one most often misused.

Good at: reading unstructured input (support tickets, emails, contracts, call transcripts) and producing structured output; classifying intent and sentiment; drafting explanations and customer messages; acting as a flexible interface for people who review decisions.

Bad at: consistent arithmetic, producing calibrated probabilities, behaving identically on identical inputs, and resisting adversarial input. An LLM that decides loan approvals directly is a system you can’t audit, can’t reproduce, and can’t defend.

The pattern that works: LLMs as sensors (turn text into features the rest of the stack consumes) and drafters (produce explanations or messages that are checked before use), wrapped in validation. Lessons 17 and 18 build this.

How the layers fit together

The standard execution order in a production decision service:

flowchart TB
    IN["Decision request\nunit + context"] --> E["1. Eligibility rules\nremove disallowed actions"]
    E --> F["2. Feature building\nincl. LLM extraction from text"]
    F --> S["3. Scoring\npredict outcome per eligible action"]
    S --> O["4. Optimization / selection\nmaximize objective under constraints"]
    O --> G["5. Guardrails\npost-checks, escalation to humans"]
    G --> OUT["Action + reason codes\nlogged with propensity"]

    style IN fill:#EEF0F7,stroke:#6366F1,color:#0F172A
    style E fill:#fff7ed,stroke:#f59e0b,color:#0F172A
    style F fill:#f0fdf9,stroke:#0D9488,color:#0F172A
    style S fill:#f0fdf9,stroke:#0D9488,color:#0F172A
    style O fill:#f0fdf9,stroke:#0D9488,color:#0F172A
    style G fill:#fff7ed,stroke:#f59e0b,color:#0F172A
    style OUT fill:#EEF0F7,stroke:#6366F1,color:#0F172A

Rules come first because there is no point scoring actions you aren’t allowed to take, and because filtering early makes the scoring and optimization cheaper. Guardrails come last because they check the final decision against limits the optimizer might have bent: unusual action volumes, conflicts with recent decisions for the same customer, or inputs that look like an attack.

The output isn’t just an action. It’s an action plus the reason codes that explain it and the propensity (the probability this action was chosen), both logged. You’ll need reasons for explanations and audits (Lesson 22) and propensities for evaluating future policies from logs (Lesson 15).

Choosing the right layer

When you’re deciding how to implement a piece of a decision, these questions point at the right layer:

QuestionIf yes
Is it a legal, contractual or safety requirement with a crisp definition?Rule
Is there an uncertain quantity that history can estimate?Predictive model
Does the action’s effect differ by unit, and do you need to target it?Causal / uplift model
Do decisions share a limited resource?Optimization
Are some actions untried, or does the world change quickly?Bandit / experiment
Is the input unstructured text, images or documents?LLM or other ML extractor
Is the stake high and the case unusual?Human review

Here’s what the running retention example looks like as a skeleton. Every later module fills in one of these functions:

from dataclasses import dataclass

@dataclass
class Decision:
    customer_id: str
    action: str
    expected_value: float
    reasons: list[str]
    propensity: float          # P(this action | context) under the policy
    policy_version: str

def decide_batch(customers, budget) -> list[Decision]:
    # 1. Rules: eligible actions per customer (Lesson 16)
    eligible = {c.id: eligible_actions(c) for c in customers}

    # 2-3. Features + scoring: uplift per (customer, action) (Modules 2, 4, 6)
    values = {
        (c.id, a): expected_margin_gain(c, a)
        for c in customers for a in eligible[c.id]
    }

    # 4. Optimization: allocate the budget (Module 3)
    plan = allocate_offers(values, costs=OFFER_COSTS, budget=budget)

    # 5. Guardrails + exploration + logging (Modules 5, 6, 8)
    return [apply_guardrails(d) for d in add_exploration(plan)]

What not to do

Three failure patterns show up again and again:

  • One layer for everything. A 3,000-rule system trying to do what a model should, or a model trying to learn a legal requirement from examples. Use each layer for its strength.
  • LLM as the whole stack. “Give the model the customer record and ask what offer to send” produces a demo in a day and a system you can’t evaluate, explain or control in production.
  • Optimization on uncalibrated inputs. Solvers trust their inputs completely. If the probabilities going in are off, the optimizer will find and exploit every error.

That last point is where Module 2 starts: making predictions good enough for a decision to trust.

Knowledge Check

4 questions to test your understanding

1 A bank must decline any applicant under 18. Which layer should implement this?

2 You score every customer independently and take the top-scoring offer for each. What is this approach missing when there is a shared monthly offer budget?

3 Where are LLMs most reliably useful inside a decision system today?

4 The retention team wants to know which offer works best, but has never tried two of the five offers. What does the decision stack need?

Go further with expert guidance

Ready to build production AI?
Talk to our R&D team.

These courses give you the foundation. Our embedded AI teams take you from prototype to production in 30–90 days, with your team, your codebase, your goals. Book a free strategy call to see how we can accelerate your AI initiative.

30 minutes · No obligation · Expert AI engineers, not sales reps

AI Architecture Review

Audit your current stack and identify high-impact improvements

Project Review

Get expert feedback on your AI implementation and codebase

Team Mentoring

Upskill your engineers with hands-on AI coaching sessions

AI Strategy

Define your AI roadmap, prioritization, and implementation plan