The problem
Language models are good at explaining and bad at arithmetic and prices. In a trading app, one confidently invented price is a real financial mistake for the user.
Separating roles
All trade math (routing, pricing, liquidity) is ordinary Swift covered by 30 unit tests. The LLM gets the finished route and writes a short summary. The system prompt is explicit:
"Never invent card names, prices, comps, values, percentages, or market data. Do not do trade math."
Generation is deterministic (temperature: 0), capped at 180 tokens, and returns a typed @Generable structure.
The safety validator
TradeSummarySafetyValidator checks every summary against the input before it is shown:
- Any dollar figure not present in the input → rejected
- Any card name not present in the input → rejected
- Too long → rejected
A rejected summary is replaced with a template summary built from the real numbers. The user never sees an invented value.
Directing the build
I wrote an Agents.md specification for the AI coding agents covering architecture rules, a required test list, and boundaries such as:
"Apple Intelligence may explain a route, but it must not decide prices or invent trade math."
What this shows for AI training roles
- Checking that model claims are supported by the source
- Knowing what a model should and shouldn't be trusted to do
- Writing constraint documents that AI agents follow
- Range beyond education: a consumer app built for a hobby