Skip to content

Tutorial: build a model and ask questions

In about ten minutes you'll go from an empty folder to a governed semantic model, all by talking to your coding agent: connect a database, build the model, ask questions, see how a number is computed, explain why it changed, and list records. You type no YAML and no SQL.

The times below were measured in Claude Code with dosi 0.2.0, where the agent answers through dosi's MCP tools. Codex goes through the same steps, and so does DeepSeek Harness through dosi's CLI; only the Claude Code extras (/dosi, the lineage pane) are missing there.

Prerequisites

The Dosi plugin is installed in your agent: Claude Code, Codex or DeepSeek Harness. The duckdb CLI on your PATH is recommended: the agent uses it to look at the tables while it builds the model, and it opens the file read-only.

Get the data

The sample database holds about 190,000 orders from 5,000 customers for 500 products, January to June 2024:

$ mkdir dosi-try && cd dosi-try
$ curl -fsSLO https://dosi.datus.ai/orders-200k.duckdb
$ claude

(Or start codex, or open the folder in DeepSeek Harness.) You can ask in any language; the agent answers in yours.

Step 1 — Connect, about 20 seconds

Connect to my data

The plugin finds orders-200k.duckdb, writes a local connection to dosi-connections.yaml, adds that file to .gitignore, and tests the connection. There is no question to answer: a local file needs no password. You get one line saying local (DuckDB) is connected.

With your own data, this step reads your dbt profiles or Cube .env instead, or asks where the data lives; see The Dosi plugin.

Step 2 — Build a semantic model, about 2 minutes

Build a semantic model for this data

The agent narrates each step while it:

  1. looks at the three tables, their columns and row counts with duckdb -readonly;
  2. writes dosi/model.yaml layer by layer: the datasets and their two relationships, then base metrics (all orders), derived metrics (completed orders only, average order value, cancellation rate), then window metrics (month over month, running total, rank and share by region). Every save is validated;
  3. checks the metrics against numbers computed straight from the tables, month by region.

It ends with a short report: what it built, what it checked, and what it left out. In our run it left out margin (products have a unit cost, but orders carry no quantity) and pointed out that revenue fell from April while cancellations rose. If it asks about business meaning, each question comes with a recommended answer: reply "use the recommendations", or pick your own.

The model is the agent's work, so names and the number of metrics vary from run to run; expect three datasets, two relationships and around fifteen metrics.

Step 3 — Ask a question, about 15 seconds

What is revenue by region and month?

The answer is one sentence, a table, and a footer naming the connection and the row count:

Month east north south west
2024-01 828,295 873,411 787,968 815,180
2024-02 780,978 827,827 736,401 767,729
2024-03 836,333 869,080 784,512 808,314
2024-04 760,525 783,051 711,572 379,848
2024-05 767,920 829,721 722,549 384,489
2024-06 749,397 782,363 720,806 378,603

Here revenue is the amount of completed orders, the definition the model settled in step 2. Ask follow-ups freely ("only north", "by week", "month over month?"); say "show me the SQL" to see what dosi ran.

Step 4 — See how a number is computed, about 15 seconds

How is revenue calculated?

The agent walks the metric back to its table and answers with a small tree: revenue keeps only the orders with status = 'completed', on top of the sum of the order amount, which the orders dataset reads from the orders table. It also says how a breakdown attaches: region through the customer who placed the order, month through the order date.

In Claude Code, /dosi lineage revenue opens the full graph in a pane. Ask for a lineage page to get a self-contained HTML file instead.

Step 5 — Explain a change, about 20 seconds

Why was revenue lower in Q2 than in Q1?

The agent runs dosi's attribution over region and category, then one breakdown to confirm what it found. Revenue fell from 9.72 million to 7.97 million (−18%), and the answer splits the drop into parts that add up to the total:

Part Q1 Q2 Change
West region, all categories 2,391,223 1,142,941 −1,248,282
Electronics in the other three regions 1,868,003 1,348,770 −519,233
Everything else 5,456,802 5,479,134 +22,332

From April the west region lost about a third of its orders and its cancellation rate rose from about 8% to 28%; electronics kept its order count everywhere, but its average order value fell by about 28%. That is how the sample data was generated, so you can check that the agent found both causes.

Step 6 — List records, about 20 seconds

List the 10 largest orders with customer region and product category

This is a question about rows, not totals: the agent uses dosi's select, which joins customers and products for you. In the sample data the largest amount, 216.81, is shared by 31 orders, and the agent says so rather than presenting an arbitrary ten as the top ten.

What you have now

dosi/model.yaml          # the semantic model: commit it
dosi-connections.yaml    # the connection, git-ignored
orders-200k.duckdb

Commit dosi/: everyone who pulls the repository gets the same metric definitions, whichever agent they use. After a few questions about customers, orders and products, the plugin also offers to build an ontology once (Claude Code), so you can ask by business concept.

Where to next

  • Connect a warehouse


    The same steps on your own data: Snowflake, BigQuery, Postgres, StarRocks and more.

  • The Dosi plugin


    What each skill does, how passwords stay out of the conversation, and how the agents differ.