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:
(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:
- looks at the three tables, their columns and row counts with
duckdb -readonly; - writes
dosi/model.yamllayer 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; - 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¶
-
The same steps on your own data: Snowflake, BigQuery, Postgres, StarRocks and more.
-
What each skill does, how passwords stay out of the conversation, and how the agents differ.