Marat Yuldashev

The Source of the Benchmark Is in Your Dashboards

There's a AI button now in our Tableau dashboards - uou click it and DataChat agent answers your question already knowing which dashboard you're looking at, which tab, which filters are selected. Users like it. It also, completely by accident, solved the problem from the previous post: where do you get a benchmark?

For the panel to answer "accordingly," each dashboard needs a skill — and writing one took our BI engineers almost a day of work. To improve that, I proposed generating the skills automatically from the dashboard's source code: create a draft, then iterate on it manually. But to check that a generated skill actually works, you need an eval. And there they were, for free: take each chart, look at the number on it, generate a question about that number, run it with the pre-activated skill — done. Each of those evals had the following parts: dashboard name, tab, chart title, all filters selected - and then the query.

It hit me: remove the dashboard mention and the filter specifics, and you have a pretty good eval, period. That is what MaratBench1 grew from.

Dashboards take time to create and usually survive multiple iterations; many users rely on them to answer their analytical questions. The data is up-to-date and verified by experts. Those are perfect golden answers for evals — the only thing missing is the questions to complete the picture.

Where the questions come from

As it turned out, our business is not that unique. It has all the same dashboards that track revenue, conversions, funnels, sales, marketing, etc. All of that is already described in hundreds of books and articles, deep inside an LLM's intelligence. So taking a screenshot and asking an LLM to generate a business question works exceptionally well. We had it backwards the whole time: we tried to write questions and then hunt for correct answers, when we could start from the verified answer and let the LLM reconstruct the question.

Meme comparing model sizes: a tiny dot labeled Claude Mythos at 175 billion parameters next to a huge cat silhouette labeled Le Chaton Fat at 100 trillion

I quickly collected a list of the most important and popular dashboards, iterated on it with feedback from colleagues, and now we have a source of truth that gives us:

Anatomy of one eval

We are lucky to have an AI-first data governance team here at Semrush. It had already laid out a very simple, concise, and effective structure for storing knowledge management in a git repo as plain .md files. We just needed a folder for our benchmarks:

/evals
  /maratbench1
    README.md
    revenue-001.yml
    revenue-002.yml
    signup-funnel-001.yml
    ...

What should each eval look like? My software development background forces me to keep things as simple as possible. Here is one, whole (the numbers and names are fake, the shape is real):

id: maratbench1-revenue-001
title: Monthly all-unit revenue, June 2026
query: >
  What was the total all-unit revenue
  from 1 June 2026 to 30 June 2026, in USD?
rubric:
  - The answer reports revenue for 1 June 2026 – 30 June 2026
    as USD 500M (fake), with 5% tolerance.
  - The tool-calling trace contains SQL queries to the table
    revenue_dash_2026_v3_certified.
  - The answer contains a reference to the revenue dashboard.
references:
  - https://tableau.internal/…/revenue-dashboard

A few things carry the weight here. The id is semantic — [bench]-[dashboard]-[serial] — so you can quickly tell a colleague which eval you are talking about. The query uses fixed dates in the past, and deliberately does not overspecify filters and categories: resolving that ambiguity correctly is the agent's job. Try to choose a question whose answer does not change too much retrospectively, and think how a good analyst would answer it. The references point to the dashboards used to verify the rubric, so when the rubric or the query turns out to be wrong, it is easy to fix.

We use an LLM as a judge to evaluate the agent's response, plus its tool-calling trace, against the criteria. If the criteria are clear true/false checks with minimal ambiguity, almost any modern LLM can do the judge's job extremely reliably. That way we keep the rubric modifiable, don't depend on the output format of the LLM, use the tool-calling trace as a measuring factor, and stay as flexible as possible.

Things we tried that didn't work

Comic of an engineer at a slot machine labeled LLM Judge: three runs of the same eval question score 0, 1, and 10

For a while I was making decisions from single runs. Then one eval scored 0, 1, and 10 on three consecutive runs of the identical question. Agents are non-deterministic all the way down; three repeats is the minimum that keeps you honest, and even then a one-point difference means nothing.

The pipeline

How we create the evals is straightforward:

Pick a popular, verified, not-a-shiny-new dashboard
→ Choose appropriate filters
→ Take wide and tall enough screenshots, save them as evidence
→ Come up with a good set of questions
→ Create a YAML
→ Run each question through the agent 3 times
→ If the agent answers inconsistently with the rubric, check whether
  that is an agent problem or your own mistake: a misinterpretation,
  a too-vague question, or a misreading of the screenshot

I would not recommend creating hundreds of questions per dashboard. Probably 3-10 is enough. The more queries you have, the higher the chance they go stale pretty soon. Keep it to the minimum necessary, but of good quality, so you can trust it.

Do you really need an eval framework?

Before adopting one, think twice. An eval framework stores a second copy of every conversation in its own storage and shows it to you as arrays of JSON while your application already stores the same conversations and already has a UI for them. Reviewing an agent run in something that looks like what the user saw, with tool-call details one click deeper, beats reading raw traces every time: you spot wrong answers and UI bugs in the same pass. So my advice: keep the eval UI as close to the product as possible.

So, how good is our agent?

Take my favorite failure: cancellation requests for one month. The agent confidently reported a number far from the one on the dashboard and claimed cancellations were growing when they were actually declining. A manager acting on that answer would be solving a problem that doesn't exist.

68 questions, 20 domains, every answer verified by hand against a dashboard. Our agent passes 26. That sounds like bad news, it's the best news we'd had all year, because for the first time the failure was measurable.

It took a couple of weeks of iteration to get there. How convenient that OpenAI released the 5.6 family of models and now we can measure how much better our agent will become. Right? As it turned out, the results were not what we expected. And there are some good reasons for that. But that's a story for the next post.