Back to blog

9 min read · 2026-05-08

14 ways Pulse prevents LLM hallucination

Most "AI assistants" trust the language model. Pulse doesn't. Before Vex answers a question, we check the answer against ground truth — 14 different ways. Here's the full list.

The pattern: pre-fetch, then reply

When you ask "what's 100 USD in NOK", a typical LLM answers from training data — months stale, often wrong by 10%+. Vex does this instead:

  1. Detect the intent (currency conversion).
  2. Fetch real-time ground truth (Frankfurter ECB API).
  3. Inject the real answer into the model's context as a "system" message.
  4. Let the model phrase the answer — but if its reply doesn't quote the real number, override with a formatted summary.

Step 4 is the kicker. Even with the right data in context, small local models sometimes hedge or invent. We scan the reply for the real digits; if missing, we replace the model's text with our own. The user always gets the real number.

The 14 categories

Each one fires before the LLM speaks. Each one has an example query that triggers it.

  • ☁️Weather· wttr.in#

    Example: weather in Oslo tomorrow

    Catches: model inventing temperatures or saying 'I can't access real-time data'

  • 📰News· Hacker News Algolia#

    Example: top stories on hacker news

    Catches: model citing 6-month-old training data as 'today's news'

  • 📈Stocks· Yahoo Finance chart API#

    Example: AAPL stock price

    Catches: model claiming AAPL is at $150 when it's actually $287

  • Crypto· CoinGecko#

    Example: BTC price

    Catches: model invented Bitcoin ETF stocks instead of crypto, or guessed at price

  • 🍝Recipes· TheMealDB#

    Example: recipe for carbonara

    Catches: model improvising fake ingredient quantities

  • Sports· TheSportsDB#

    Example: next match for Arsenal

    Catches: model citing fixtures from training data — wrong dates, wrong opponents

  • 🌐Translation· Local qwen2.5:7b via pulse-translate#

    Example: translate hello world to norwegian

    Catches: small chat model returning wrong language entirely

  • 🧮Math· api.mathjs.org#

    Example: what is 9876 * 12345

    Catches: any LLM trying to do exact arithmetic — they can't

  • 🕐Time· Local Intl.DateTimeFormat#

    Example: what time in Tokyo

    Catches: model saying 'I don't have access to current time'

  • 📚Wikipedia· Wikipedia REST API#

    Example: tell me about Inception

    Catches: model inventing director, cast, year details

  • 💱Currency· Frankfurter (ECB rates)#

    Example: 100 USD to NOK

    Catches: model using exchange rate from its training data — off by 10%+

  • 📏Units· api.mathjs.org with unit syntax#

    Example: 5 miles to km

    Catches: model rounding wrong or using stale conversion factors

  • 🗺️Geocoding· OpenStreetMap Nominatim#

    Example: where is Mt Everest

    Catches: model inventing coordinates that look plausible but are wrong

Why this matters

When a finance team asks "what's our NOK exposure on this $50K invoice", the difference between $4,532 (wrong, from training data) and $461,660 (right, from ECB) is the difference between a usable assistant and a liability. The same is true for medical doses, legal citations, sports scores, weather forecasts, and currency conversions.

The LLM is the formatter. The grounded data is the source of truth. That's the entire architecture.

The cost

Free. All 14 ground sources are public APIs without keys (or local compute). The fastest path is also the cheapest. There's no "premium tier Pulse+ but only on weekdays" gimmick — the local Vex you self-host has all 14.

The dashboard

Admin users can open /app/admin/grounded-stats and see, in real time, how often each fire triggered and how many hallucinations the digit-scan layer caught. That's a measurable answer to "is Pulse giving me real data, or LLM noise?"

No other AI workspace shows you that number. Most don't track it.

What's next

We're adding TMDB-richer movie data, distance routing, math integer formatting (no more 6.99e+5), and per-user counters. The architecture scales — adding a new fire is roughly 60 lines of code: a regex, a fetch, a system message, a fallback.

See it for yourself

Self-host Pulse. Open the grounded-stats dashboard. Watch the counters tick up as you use the assistant. That's the metric we built around.

Create your workspace