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:
- The datasets considered (and why this one was picked).
- The
QueryRequestClaude constructed. - The rows returned.
- 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.