Répondre à des questions en langage naturel avec dbt
Aperçu
Répondre à des questions de données en utilisant la meilleure méthode disponible : couche sémantique d'abord, puis modification SQL, puis découverte de modèles, puis analyse du manifeste. Épuisez toujours les options avant de dire « impossible de répondre ».
À utiliser pour : Questions métier des utilisateurs qui nécessitent des réponses basées sur les données
- « Quel était le total des ventes le mois dernier ? »
- « Combien de clients actifs avons-nous ? »
- « Montre-moi le revenu par région »
À ne pas utiliser pour :
- Valider la logique des modèles pendant le développement
- Tester les modèles dbt ou les définitions de couche sémantique
- Construire ou modifier les modèles dbt
- Les workflows
dbt run,dbt testoudbt build
Flux de décision
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
Référence rapide
| Priorité | Condition | Approche | Outils |
|---|---|---|---|
| 1 | Couche sémantique active | Interroger les métriques directement | list_metrics, get_dimensions, query_metrics |
| 2 | SL active mais modifications mineures nécessaires (dimension manquante, filtre personnalisé, case when, agrégation différente) | Modifier le SQL compilé | get_metrics_compiled_sql, puis execute_sql |
| 3 | Pas de SL, outils de découverte actifs | Explorer les modèles, écrire SQL | get_mart_models, get_model_details, puis show/execute_sql |
| 4 | Pas de MCP, dans un projet dbt | Analyser les artefacts, écrire SQL | Lire target/manifest.json, target/catalog.json |
Approche 1 : Requête de couche sémantique
Quand list_metrics et query_metrics sont disponibles :
list_metrics- trouver la métrique pertinenteget_dimensions- vérifier que les dimensions requises existentquery_metrics- exécuter avec les filtres appropriés
Si la couche sémantique ne peut pas répondre directement (dimension manquante, logique personnalisée nécessaire) → passer à l'approche 2.
Approche 2 : SQL compilé modifié
Quand la couche sémantique a la métrique mais a besoin de modifications mineures :
- Dimension manquante (jointure + group by)
- Filtre personnalisé non disponible comme dimension
- Logique case when pour une catégorisation personnalisée
- Agrégation différente de celle définie
get_metrics_compiled_sql- obtenir le SQL qui s'exécuterait (retourne du SQL brut, pas du Jinja)- Modifier le SQL pour ajouter ce qui est nécessaire
execute_sqlpour exécuter le SQL brut- Toujours suggérer de mettre à jour le modèle sémantique si la modification serait réutilisable
-- Exemple : Ajouter une dimension sales_rep
WITH base AS (
-- ... logique métrique compilée (déjà résolue en noms de table) ...
)
SELECT base.*, reps.sales_rep_name
FROM base
JOIN analytics.dim_sales_reps reps ON base.rep_id = reps.id
GROUP BY ...
-- Exemple : Filtre personnalisé
SELECT * FROM (compiled_metric_sql) WHERE region = 'EMEA'
-- Exemple : Catégorisation case when
SELECT
CASE WHEN amount > 1000 THEN 'large' ELSE 'small' END as deal_size,
SUM(amount)
FROM (compiled_metric_sql)
GROUP BY 1
Remarque : Le SQL compilé contient les noms de table résolus, pas {{ ref() }}. Travaillez avec le SQL brut tel que retourné.
Approche 3 : Découverte de modèles
Quand pas de couche sémantique mais get_all_models/get_model_details disponible :
get_mart_models- commencer par les marts, pas le stagingget_model_detailspour les modèles pertinents - comprendre le schéma- Écrire du SQL en utilisant
{{ ref('model_name') }} show --inline "..."ouexecute_sql
Préférez les marts au staging - les marts ont la logique métier appliquée.
Approche 4 : Analyse du manifeste/catalogue
Quand dans un projet dbt mais pas de serveur MCP :
- Vérifier la présence de
target/manifest.jsonettarget/catalog.json - Filtrer avant de lire - ces fichiers peuvent être volumineux
# Trouver les modèles mart dans le manifeste
jq '.nodes | to_entries | map(select(.key | startswith("model.") and contains("mart"))) | .[].value | {name: .name, schema: .schema, columns: .columns}' target/manifest.json
# Obtenir les infos de colonnes du catalogue
jq '.nodes["model.project_name.model_name"].columns' target/catalog.json
- Écrire du SQL basé sur le schéma découvert
- Expliquer : « Ce SQL devrait s'exécuter dans votre entrepôt. Je ne peux pas l'exécuter sans accès à la base de données. »
Suggérer des améliorations
Quand dans un projet dbt, suggérer des changements de couche sémantique après avoir répondu (ou quand impossible de répondre) :
| Lacune | Suggestion |
|---|---|
| La métrique n'existe pas | « Ajouter une définition de métrique à votre modèle sémantique » |
| Dimension manquante | « Ajouter dimension_name à la liste des dimensions dans le modèle sémantique » |
| Pas de couche sémantique | « Envisager d'ajouter une couche sémantique pour ces données » |
Restez au niveau de la couche sémantique. N'SUGGÉREZ PAS :
- Des changements de schéma de base de données
- Des modifications de pipeline ETL
- « Demandez à votre équipe d'ingénierie données... »
Rationalisations à éviter
| Vous pensez... | Réalité |
|---|---|
| « La couche sémantique ne supporte pas exactement cette requête » | Obtenir le SQL compilé et le modifier (Approche 2) |
| « Pas d'outils MCP, impossible d'aider » | Vérifier le manifeste/catalogue localement |
| « L'utilisateur a besoin de cela rapidement, ignorer la vérification systématique » | L'approche systématique EST le chemin le plus rapide |
| « Juste écrire du SQL, c'est plus rapide » | La couche sémantique existe pour une raison - l'utiliser d'abord |
| « La dimension n'existe pas dans les données » | Elle existe peut-être mais pas dans la config de la couche sémantique |
Signaux d'alarme - STOP
- Écrire du SQL sans vérifier si la couche sémantique peut répondre
- Dire « impossible de répondre » sans essayer les 4 approches
- Suggérer des corrections au niveau de la base de données pour des lacunes de couche sémantique
- Lire l'intégralité du manifest.json sans filtrer
- Utiliser les modèles de staging quand des modèles mart existent
- Utiliser ceci pour valider la correction des modèles au lieu de répondre aux questions métier
Erreurs courantes
| Erreur | Correction |
|---|---|
| Abandonner quand SL ne peut pas répondre directement | Obtenir le SQL compilé et le modifier |
| Interroger les modèles de staging | Utiliser d'abord get_mart_models |
| Lire le manifest.json complet | Utiliser jq pour filtrer |
| Suggérer des changements ETL | Garder les suggestions au niveau de la couche sémantique |
| Ne pas vérifier la disponibilité des outils | Lister les outils disponibles avant de choisir une approche |