AI gave a wrong answer

When the NL Q&A assistant gives the wrong answer, the fix is almost always in the semantic model. The LLM is faithful to what you declared — if the model is ambiguous, hallucinates are structured, not free-form.

First: see what it actually did

Click Trace on the assistant's answer. You see:

  1. The datasets considered (and why this one was picked).
  2. The QueryRequest Claude constructed.
  3. The rows returned.
  4. The natural-language composition.

Usually the mistake is visible in step 2 — wrong measure, wrong grain, wrong filter.

Common failure modes

Chose the wrong measure

"sales" matched both revenue and sales_count. We picked one and the answer is in ₹ when you wanted a row count (or vice versa).

Fix: in the measure declaration, add synonyms:

- id: revenue
  synonyms: [sales, turnover, topline, takings]
- id: sales_count
  synonyms: [order count, number of sales, txn count]

Synonyms are exposed to Claude at tool-binding time so the disambiguation happens cleanly.

Answered against the wrong dataset

You have five datasets, and "revenue by region" could mean three of them.

Fix: set primary: true on the dataset that should win ties, and add description: fields to every dataset that clearly delineate scope ("Retail sales in India only", "Wholesale exports only", …).

Used the wrong time grain

Asked "revenue last month" and got a per-day chart. Claude picked day instead of month.

Fix: declare a default_grain: month on the time dimension. Per-question overrides still work ("by day").

Aggregated the wrong way

Asked "average order value" and got AVG(order_value) when you wanted SUM(revenue) / COUNT(order_id).

Fix: declare aov as a ratio measure:

- id: aov
  type: ratio
  numerator: revenue
  denominator: order_count
  synonyms: [average order value, ticket size, avg ticket]

Ratio measures are aggregation-safe under any filter.

Missed an RLS filter

User said "total revenue for the company" and saw only their region. This is correct — RLS is invisible to the user and the model.

Fix: nothing — this is by design. If the user should see cross-region totals, they need a role that matches an unrestricted RLS rule.

When it's not the model

  • LLM outage — we use Anthropic with a degradation path to a smaller model. If Anthropic is down, we post a banner.
  • Prompt injection in row data — we never pass raw row values to the LLM, only schema and aggregates, so this is not a failure mode in OneAnalytics.
  • Genuinely unanswerable — if the underlying data doesn't support the question, Claude is instructed to say so. An honest "I can't answer" is a correct answer.

Getting help

If you've trace'd, tuned synonyms, and still get a wrong answer, file a ticket with:

  • Workspace + dataset ID
  • The exact question text
  • The trace ID of the wrong answer

We'll look at the internal prompt replay and either fix the model with you or improve the prompt template.