A curated collection of Agent Skills for working with dbt, to help AI agents understand and execute dbt workflows more effectively.
90
90%
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Advisory
Suggest reviewing before use
This is the authoring guide for the latest dbt Semantic Layer YAML spec, supported in dbt Core 1.12+ and Fusion (always).
In the latest spec, semantic models are configured as metadata annotations on your dbt models rather than as separate top-level resources. Measures are replaced by simple metrics defined directly within models.
Add a semantic_model: block to the model's YAML with enabled: true. Set agg_time_dimension at the model level to the primary time column. If the model does not have a time column, warn the user that it cannot contain time-based metrics. Ask the user if they want to create a derived time dimension.
models:
- name: orders
semantic_model:
enabled: true
agg_time_dimension: ordered_atIdentify the primary key column (check for _id suffix, uniqueness tests, or explicit config). Add an entity: block to that column's entry. If the model has foreign keys, define those as entity: type: foreign.
models:
- name: orders
semantic_model:
enabled: true
agg_time_dimension: ordered_at
columns:
- name: order_id
entity:
type: primary
name: order
- name: customer_id
entity:
type: foreign
name: customerEntity types: primary, foreign, unique, natural (SCD Type II only).
Scan columns for dimension candidates:
dimension: type: time with granularity at the column leveldimension: type: categoricalPresent suggested dimensions to user for confirmation.
models:
- name: orders
semantic_model:
enabled: true
agg_time_dimension: ordered_at
columns:
- name: order_id
entity:
type: primary
name: order
- name: customer_id
entity:
type: foreign
name: customer
- name: ordered_at
granularity: day
dimension:
type: time
- name: order_status
dimension:
type: categoricalCreate simple metrics for the model. For each metric, collect: name, description, label, aggregation type, and expression. Supported agg types: sum, min, max, average, median, count, count_distinct, percentile, sum_boolean.
models:
- name: orders
semantic_model:
enabled: true
agg_time_dimension: ordered_at
columns:
- name: order_id
entity:
type: primary
name: order
- name: customer_id
entity:
type: foreign
name: customer
- name: ordered_at
granularity: day
dimension:
type: time
- name: order_status
dimension:
type: categorical
metrics:
- name: order_count
type: simple
label: Order Count
agg: count
expr: 1
- name: total_revenue
type: simple
label: Total Revenue
agg: sum
expr: amount
- name: average_order_value
type: simple
label: Average Order Value
agg: avg
expr: amountUse the derived_semantics block for dimensions or entities that are not a direct 1:1 mapping to a physical column. The expr field is required.
models:
- name: orders
[...]
derived_semantics:
dimensions:
- name: order_size_bucket
type: categorical
expr: "case when amount > 100 then 'large' else 'small' end"
label: "Order Size"
entities:
- name: user
type: foreign
expr: "substring(id_order from 2)"Simple metrics support these additional properties:
models:
- name: orders
[...]
metrics:
- name: customers
type: simple
label: Count of customers
agg: count
expr: customers
fill_nulls_with: 0 # Replace nulls with this value
join_to_timespine: true # Join to time spine to fill missing dates
agg_time_dimension: my_other_time_column # Override model's default time dimension
filter: "{{ Dimension('customer__customer_total') }} >= 20"For percentile aggregation:
models:
- name: orders
[...]
metrics:
- name: revenue_p95
type: simple
label: Revenue P95
agg: percentile
expr: amount
percentile: 95.0
percentile_type: discrete # discrete or continuousSimple metrics defined within a model serve as building blocks. Advanced metrics that reference simple metrics within the same model go under the model's metrics: key. Advanced metrics that reference metrics across different models go under the top-level metrics: key.
Combine multiple metrics using an expression.
models:
- name: orders
[...]
metrics:
- name: order_gross_profit
description: "Gross profit from each order."
label: Order gross profit
type: derived
expr: revenue - cost
input_metrics:
- name: order_total
alias: revenue
- name: order_cost
alias: costWith offset window (period-over-period):
models:
- name: orders
[...]
metrics:
- name: order_total_growth_mom
description: "Percentage growth of orders compared to 1 month ago"
label: Order total growth % M/M
type: derived
expr: (order_total - order_total_prev_month) * 100 / order_total_prev_month
input_metrics:
- name: order_total
- name: order_total
alias: order_total_prev_month
offset_window: 1 monthWith filter on input metric:
models:
- name: orders
[...]
metrics:
- name: food_order_gross_profit
label: Food order gross profit
type: derived
expr: revenue - cost
input_metrics:
- name: order_total
alias: revenue
filter: |
{{ Dimension('order__is_food_order') }} = True
- name: order_cost
alias: cost
filter: |
{{ Dimension('order__is_food_order') }} = TrueAggregate a metric over a running window or grain-to-date period. Requires a time spine.
metrics:
- name: cumulative_order_total
label: "Cumulative order total (All-Time)"
description: "The cumulative value of all orders"
type: cumulative
input_metric: order_total
- name: cumulative_order_total_l1m
label: "Cumulative order total (L1M)"
description: "Trailing 1-month cumulative order total"
type: cumulative
window: 1 month
input_metric: order_total
- name: cumulative_order_total_mtd
label: "Cumulative order total (MTD)"
description: "The month-to-date value of all orders"
type: cumulative
grain_to_date: month
input_metric: order_totalWith period_agg for re-aggregation at non-default granularity:
metrics:
- name: cumulative_revenue
description: "The cumulative revenue for all orders."
label: "Cumulative revenue (all-time)"
type: cumulative
input_metric: revenue
period_agg: first # first | last | average. Defaults to first.window and grain_to_date cannot be used together.
Create a ratio between two metrics. Numerator and denominator can be strings (metric name) or dicts (with name, filter, alias).
metrics:
- name: food_order_pct
description: "The food order count as a ratio of the total order count"
label: Food order ratio
type: ratio
numerator: food_orders
denominator: ordersWith filter and alias:
metrics:
- name: frequent_purchaser_ratio
description: Fraction of active users who qualify as frequent purchasers
type: ratio
numerator:
name: distinct_purchasers
filter: |
{{ Dimension('customer__is_frequent_purchaser') }}
alias: frequent_purchasers
denominator:
name: distinct_purchasersMeasure how often one event leads to another for a specific entity within a time window.
metrics:
- name: visit_to_buy_conversion_rate_7d
description: "Conversion rate from visiting to transaction in 7 days"
type: conversion
label: Visit to buy conversion rate (7-day window)
entity: user
calculation: conversion_rate # conversion_rate (default) or conversions
base_metric:
name: visits
filter: "{{ Dimension('visits__referrer_id') }} = 'facebook'"
conversion_metric: buys
window: 7 daysWith constant properties (ensure same dimension value across base and conversion events):
metrics:
- name: view_item_detail_to_purchase_with_same_item
description: "Conversion rate for users who viewed and purchased the same item"
type: conversion
label: View item detail > Purchase
entity: user
calculation: conversions
base_metric: view_item_detail
conversion_metric: purchase
window: 1 week
constant_properties:
- base_property: product
conversion_property: productFor metrics depending on multiple semantic models, define them at the top-level metrics: key:
metrics:
- name: orders_per_session
type: ratio
numerator: orders
denominator: sessions
config:
group: example_group
tags:
- example_tag
meta:
owner: "@someone"For slowly changing dimension tables, use validity_params on time dimensions and natural entity type:
models:
- name: sales_person_tiers
semantic_model:
enabled: true
agg_time_dimension: tier_start
primary_entity: sales_person
columns:
- name: start_date
granularity: day
dimension:
type: time
name: tier_start
label: "Start date of tier"
validity_params:
is_start: true
- name: end_date
granularity: day
dimension:
type: time
name: tier_end
label: "End date of tier"
validity_params:
is_end: true
- name: tier
dimension:
type: categorical
name: tier
- name: sales_person_id
entity:
type: natural
name: sales_personSCD Type II semantic models cannot contain simple metrics.
semantic_model: block at model level with enabled: trueagg_time_dimension: at model level (not nested under semantic_model:)entity: and dimension: blocks on columns (a column can have one or the other, not both)granularity: required at column level for time dimensionsmetrics: array at model level for single-model metricsmetrics: key for cross-model metrics (derived, ratio, cumulative, conversion only)derived_semantics: for computed dimensions/entities not tied to a single column| Pitfall | Fix |
|---|---|
Missing agg_time_dimension | Every semantic model needs a default time dimension |
granularity inside dimension: block | Must be at column level, not nested under dimension: |
| Defining a column as both an entity and a dimension | A column can only be one or the other |
Simple metrics in top-level metrics: | Top-level is only for cross-model advanced metrics |
Using window and grain_to_date together | Cumulative metrics can only have one |
Missing input_metrics on derived metrics | Must list metrics used in expr |
Using type_params or measures | Those are legacy spec syntax; this spec uses direct keys |
evals
scenarios
dbt-docs-arguments
dbt-docs-unit-test-fixtures
dbt-job-failure
dbt-unit-test-format-choice
example-yaml-error
fusion-migration-triage-basic
fusion-migration-triage-blocked
fusion-triage-cat-a-static-analysis
fusion-triage-cat-b-dict-meta-get
fusion-triage-cat-b-unexpected-config
fusion-triage-cat-b-unused-schema
fusion-triage-cat-b-yaml-syntax
fusion-triage-cat-c-hardcoded-fqn
src
tests
scripts
skills
dbt
skills
adding-dbt-unit-test
references
answering-natural-language-questions-with-dbt
building-dbt-semantic-layer
configuring-dbt-mcp-server
fetching-dbt-docs
scripts
running-dbt-commands
troubleshooting-dbt-job-errors
references
using-dbt-for-analytics-engineering
working-with-dbt-mesh
dbt-extras
skills
creating-mermaid-dbt-dag
using-dbt-index
dbt-migration
skills
migrating-dbt-core-to-fusion
migrating-dbt-project-across-platforms