关于 answering-natural-language-questions-with-dbt
用于借助 dbt 回答业务数据问题的技能,优先使用语义层,并按需转向 SQL、模型发现或本地工件分析。它根据可用工具引导分析流程,并将开发和模型测试任务排除在数据问答之外。
主要功能
- 01通过语义层查询指标
- 02按需调整编译后的指标 SQL
- 03发现模型并检查模型详情
- 04分析 manifest 和 catalog 工件
- 05优先使用集市模型而非暂存模型
适用场景
- 01回答销售额或客户相关问题
- 02按筛选条件或维度查询指标
- 03没有语义层时探索模型
- 04根据本地 dbt 工件编写 SQL
MCP 相关
该技能描述了使用 list_metrics、query_metrics、get_model_details 和 execute_sql 等可用 MCP 工具的流程。没有 MCP 服务时,可分析本地 manifest 和 catalog 工件。
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ dbt-labs/ dbt-agent-skills --skill answering-natural-language-questions-with-dbt安装后在 Claude Code 中输入/answering-natural-language-questions-with-dbt确认已加载。
详细介绍
使用 dbt 回答自然语言问题
概述
使用当前最佳方法回答数据问题:优先使用语义层,然后修改 SQL,再发现模型,最后分析清单。始终穷尽所有选项,再说“无法回答”。
适用于: 用户提出的需要数据答案的业务问题
- “上个月的总销售额是多少?”
- “我们有多少活跃客户?”
- “按地区显示收入”
不适用于:
- 开发期间验证模型逻辑
- 测试 dbt 模型或语义层定义
- 构建或修改 dbt 模型
dbt run、dbt test或dbt build工作流
决策流程
flowchart TD
start([Business question received])
check_sl{Semantic layer tools available?}
list_metrics[list_metrics]
metric_exists{Relevant metric exists?}
get_dims[get_dimensions]
sl_sufficient{SL can answer directly?}
query_metrics[query_metrics]
answer([Return answer])
try_compiled[get_metrics_compiled_sql<br/>Modify SQL, execute_sql]
check_discovery{Model discovery tools available?}
try_discovery[get_mart_models<br/>get_model_details<br/>Write SQL, execute]
check_manifest{In dbt project?}
try_manifest[Analyze manifest/catalog<br/>Write SQL]
cannot([Cannot answer])
suggest{In dbt project?}
improvements[Suggest semantic layer changes]
done([Done])
start --> check_sl
check_sl -->|yes| list_metrics
check_sl -->|no| check_discovery
list_metrics --> metric_exists
metric_exists -->|yes| get_dims
metric_exists -->|no| check_discovery
get_dims --> sl_sufficient
sl_sufficient -->|yes| query_metrics
sl_sufficient -->|no| try_compiled
query_metrics --> answer
try_compiled -->|success| answer
try_compiled -->|fail| check_discovery
check_discovery -->|yes| try_discovery
check_discovery -->|no| check_manifest
try_discovery -->|success| answer
try_discovery -->|fail| check_manifest
check_manifest -->|yes| try_manifest
check_manifest -->|no| cannot
try_manifest -->|SQL ready| answer
answer --> suggest
cannot --> done
suggest -->|yes| improvements
suggest -->|no| done
improvements --> done
快速参考
| 优先级 | 条件 | 方法 | 工具 |
|---|---|---|---|
| 1 | 语义层已启用 | 直接查询指标 | list_metrics、get_dimensions、query_metrics |
| 2 | 语义层已启用,但需要少量修改(缺少维度、自定义筛选、case when、不同的聚合方式) | 修改编译后的 SQL | get_metrics_compiled_sql,然后使用 execute_sql |
| 3 | 没有语义层,发现工具已启用 | 探索模型并编写 SQL | get_mart_models、get_model_details,然后使用 show/execute_sql |
| 4 | 没有 MCP,位于 dbt 项目中 | 分析构件并编写 SQL | 读取 target/manifest.json、target/catalog.json |
方法 1:查询语义层
当 list_metrics 和 query_metrics 可用时:
list_metrics- 查找相关指标get_dimensions- 确认所需维度存在query_metrics- 使用适当的筛选条件执行查询
如果语义层无法直接回答(缺少维度、需要自定义逻辑)→ 转到方法 2。
方法 2:修改编译后的 SQL
当语义层中已有该指标,但需要少量修改时:
- 缺少维度(join + group by)
- 自定义筛选条件无法作为维度使用
- 用于自定义分类的 case when 逻辑
- 与定义不同的聚合方式
get_metrics_compiled_sql- 获取将要运行的 SQL(返回原始 SQL,而非 Jinja)- 修改 SQL,补充所需内容
- 使用
execute_sql运行原始 SQL - 始终建议:如果该修改可复用,则更新语义模型
-- Example: Adding sales_rep dimension
WITH base AS (
-- ... compiled metric logic (already resolved to table names) ...
)
SELECT base.*, reps.sales_rep_name
FROM base
JOIN analytics.dim_sales_reps reps ON base.rep_id = reps.id
GROUP BY ...
-- Example: Custom filter
SELECT * FROM (compiled_metric_sql) WHERE region = 'EMEA'
-- Example: Case when categorization
SELECT
CASE WHEN amount > 1000 THEN 'large' ELSE 'small' END as deal_size,
SUM(amount)
FROM (compiled_metric_sql)
GROUP BY 1
注意: 编译后的 SQL 包含解析完成的表名,而不是 {{ ref() }}。请直接使用返回的原始 SQL。
方法 3:发现模型
当没有语义层,但 get_all_models/get_model_details 可用时:
get_mart_models- 从集市模型开始,而不是暂存模型- 对相关模型使用
get_model_details- 了解架构 - 使用
{{ ref('model_name') }}编写 SQL - 使用
show --inline "..."或execute_sql
优先选择集市模型,而非暂存模型 - 集市模型已应用业务逻辑。
方法 4:分析清单/目录
当位于 dbt 项目中,但没有 MCP 服务时:
- 检查是否存在
target/manifest.json和target/catalog.json - 先筛选,再读取 - 这些文件可能很大
# Find mart models in manifest
jq '.nodes | to_entries | map(select(.key | startswith("model.") and contains("mart"))) | .[].value | {name: .name, schema: .schema, columns: .columns}' target/manifest.json
# Get column info from catalog
jq '.nodes["model.project_name.model_name"].columns' target/catalog.json
- 根据发现的架构编写 SQL
- 说明:“这段 SQL 应可在你的数据仓库中运行。由于我无法访问数据库,因此无法执行它。”
建议改进
位于 dbt 项目中时,回答后(或无法回答时)建议修改语义层:
| 缺口 | 建议 |
|---|---|
| 指标不存在 | “向语义模型添加指标定义” |
| 缺少维度 | “将 dimension_name 添加到语义模型的维度列表中” |
| 没有语义层 | “考虑为这些数据添加语义层” |
建议仅限于语义层级别。 不要建议:
- 修改数据库架构
- 修改 ETL 流水线
- “请数据工程团队帮忙……”
需要抵制的自我说服
| 你的想法…… | 实际情况 |
|---|---|
| “语义层不支持这个确切的查询” | 获取编译后的 SQL 并修改它(方法 2) |
| “没有 MCP 工具,帮不上忙” | 检查本地是否有清单或目录 |
| “用户急需结果,跳过系统性检查” | 系统性方法才是最快的途径 |
| “直接写 SQL 更快” | 语义层存在自有其道理——优先使用它 |
| “数据中不存在这个维度” | 它可能存在,只是未配置在语义层中 |
危险信号——立即停止
- 未检查语义层能否回答,就编写 SQL
- 未尝试全部 4 种方法,就声称“无法回答”
- 针对语义层缺口提出数据库层面的修复方案
- 未经筛选就读取整个 manifest.json
- 在存在 mart 模型时使用 staging 模型
- 用这种方式验证模型是否正确,而不是回答业务问题
常见错误
| 错误 | 修正方法 |
|---|---|
| 语义层(SL)无法直接回答时就放弃 | 获取编译后的 SQL 并修改它 |
| 查询 staging 模型 | 先使用 get_mart_models |
| 读取完整的 manifest.json | 使用 jq 进行筛选 |
| 建议修改 ETL | 将建议限定在语义层 |
| 未检查工具是否可用 | 先列出可用工具,再选择方法 |
评论
支持 Markdown