Skip to content
Fondazione ITS INCOM

Examples · General

Sums you can trust: let the model reason

An invoice with a wrong discount. Gemma answers in seconds, gpt-oss-120b thinks first. See which one finds the mistake, then let Python do the maths.

Intermediate · 30 min

The idea

Language models write numbers the way they write words: one piece at a time, guessing the most likely next one. That is why they can make a mistake in a sum while sounding completely sure.

Reasoning models work it out step by step before they answer. They are slower, and the steps cost tokens, but on maths they are much more reliable. At the school this is gpt-oss-120b.

What you need

A key and the openai library, as in Your first API call in Python.

The invoice

The terms say “10% discount on the material”. Look at it before you run the program: do you see the mistake?

INVOICE 2026/311 — Rete Ufficio Srl
12  Cat6 network cable, 3 m     EUR   4.90   EUR  58.80
 2  24-port managed switch      EUR 189.00   EUR 378.00
 6  hours of installation       EUR  45.00   EUR 270.00
                       Subtotal               EUR 706.80
           10% discount on material          -EUR  70.68
                       Taxable                EUR 636.12
                       VAT 22%                EUR 139.95
                       TOTAL                  EUR 776.07

The program

import os
import time

from openai import OpenAI

client = OpenAI(
    base_url="https://api.ai.itsincom.org/v1",
    api_key=os.environ["API_KEY"],
)

invoice = """INVOICE 2026/311 - Rete Ufficio Srl. Terms: 10% discount on the material.
12  Cat6 network cable, 3 m     EUR   4.90   EUR  58.80
 2  24-port managed switch      EUR 189.00   EUR 378.00
 6  hours of installation       EUR  45.00   EUR 270.00
Subtotal EUR 706.80
10% discount on material -EUR 70.68
Taxable EUR 636.12
VAT 22% EUR 139.95
TOTAL EUR 776.07"""

question = "Check this invoice step by step. Is it correct? If not, say what is wrong and give the right total."

for model in ["gemma-4-26b", "gpt-oss-120b"]:
    start = time.time()
    answer = client.chat.completions.create(
        model=model,
        messages=[{"role": "user", "content": f"{question}\n\n{invoice}"}],
    )
    seconds = time.time() - start
    print(f"=== {model}: {seconds:.0f} s, {answer.usage.completion_tokens} tokens")
    print(answer.choices[0].message.content, "\n")

What you should see

When we tried it, both found the mistake: Gemma in 5 seconds and 600 tokens, gpt-oss-120b in 20 seconds and 1'000 tokens, with a table of every step. So is reasoning useless? One invoice is not a test. Run it several times, change the numbers, add invoices with discounts on some lines and not on others: the difference between a model that reasons and one that does not shows up when you measure many cases, not one.

Now let Python do it

For money, the model explains and the program calculates. Decimal counts like an accountant; float does not.

from decimal import ROUND_HALF_UP, Decimal

cents = Decimal("0.01")
material = 12 * Decimal("4.90") + 2 * Decimal("189.00")
labour = 6 * Decimal("45.00")
discount = (material * Decimal("0.10")).quantize(cents, ROUND_HALF_UP)
taxable = material + labour - discount
vat = (taxable * Decimal("0.22")).quantize(cents, ROUND_HALF_UP)
print(discount, taxable, vat, taxable + vat)

The solution

The discount was applied to everything, installation included. On the material only it is 10% of 436.80, so EUR 43.68. Taxable EUR 663.12, VAT EUR 145.89, total EUR 809.01, not 776.07. This time the mistake is in the customer's favour, but the supplier will notice.

Exercise

All examples