ServicesÀ proposNotesContact Me contacter →
EN FR
Note

Reporting KPI via des requêtes directes à l'entrepôt

Pourquoi interroger l'entrepôt directement est plus fiable que le scraping de dashboards pour la livraison de KPIs planifiée — les patterns CLI BigQuery et Snowflake, comment structurer du SQL pré-écrit pour le reporting piloté par agent, et les compromis de l'approche.

Planté
bigquerysnowflakeanalyticsautomationdata engineering

Lorsque les données client se trouvent dans BigQuery ou Snowflake, interroger directement l’entrepôt est plus fiable que de scraper des dashboards pour le reporting KPI automatisé. L’approche : pré-écrire le SQL qui définit les KPIs, donner à l’agent l’accès pour l’exécuter, et le laisser formater les résultats. La requête retourne un ensemble de résultats déterministe sans fragilité d’interface ou surcharge de gestion de session.

Le pattern de base

L’approche est la même que celle utilisée dans la surveillance des échecs BigQuery et la surveillance des coûts Snowflake — pré-écrire le SQL qui calcule exactement ce que vous souhaitez, puis laisser l’agent l’exécuter et formater l’output.

Pour BigQuery :

Terminal window
bq query --format=json --use_legacy_sql=false \
"SELECT ... FROM \`project.dataset.table\` WHERE ..."

Pour Snowflake :

Terminal window
snowsql -q "SELECT ... FROM database.schema.table WHERE ..."

L’agent reçoit l’output JSON, lit les lignes et formate un résumé. Les capacités en langage naturel de l’agent gèrent l’étape d’interprétation qui nécessiterait autrement du code de parsing.

Rédiger la requête KPI

Le SQL pré-écrit est là où se concentre le vrai travail. Une requête KPI hebdomadaire utile fait trois choses :

  1. Retourner les métriques de cette semaine à côté de celles de la semaine dernière dans une seule requête (éviter deux requêtes séparées que l’agent doit mentalement joindre)
  2. Utiliser DATE_TRUNC ou similaire pour s’aligner sur des semaines calendaires nettes
  3. Produire des noms de colonnes lisibles que l’agent peut narrer sans traduction

Un résumé hebdomadaire du chiffre d’affaires pour un client pourrait ressembler à ceci :

SELECT
DATE_TRUNC(order__ordered_at, WEEK) AS week,
COUNT(DISTINCT order__id) AS orders,
ROUND(SUM(order__revenue), 2) AS total_revenue,
ROUND(AVG(order__revenue), 2) AS avg_order_value
FROM `client-project.analytics.mrt__sales__orders`
WHERE order__ordered_at >= DATE_SUB(CURRENT_DATE(), INTERVAL 14 DAY)
GROUP BY 1
ORDER BY 1 DESC

Cela retourne deux lignes : cette semaine et la semaine dernière. L’agent reçoit les données, calcule le pourcentage de variation entre elles et l’inclut dans le résumé. La fenêtre de lookback de 14 jours capture les deux semaines dans une seule requête plutôt que de nécessiter deux appels séparés avec des plages de dates différentes.

Le ROUND() sur les valeurs monétaires empêche l’agent de rapporter 47291.4872 quand le client attend €47 291,49. Les petits détails de formatage dans le SQL évitent d’avoir à configurer le formatage des nombres de l’agent via le prompt plus tard.

Structurer plusieurs requêtes KPI

Pour un client dont le rapport hebdomadaire couvre les sessions, les conversions et le chiffre d’affaires à partir de trois modèles différents, vous avez deux options : une requête compound qui joint tout, ou des requêtes séparées par domaine KPI.

Les requêtes séparées sont généralement préférables pour le reporting piloté par agent. Une seule requête monolithique qui joint les sessions GA4 aux données de commandes et aux dépenses publicitaires retourne un ensemble de résultats plus difficile à parser et narrer pour l’agent. Les requêtes séparées retournent des ensembles de résultats propres et simples. L’agent les exécute en séquence et compose le résumé à partir de plusieurs inputs.

Le message cron spécifie la séquence :

Exécutez le rapport KPI hebdomadaire pour Acme Corp :
1. Interrogez BigQuery pour les métriques de sessions GA4 en utilisant la requête dans ~/reports/acme/ga4-weekly.sql
2. Interrogez BigQuery pour les métriques de chiffre d'affaires en utilisant ~/reports/acme/revenue-weekly.sql
3. Comparez cette semaine à la semaine dernière pour les deux métriques
4. Formatez les résultats comme résumé Slack en suivant le format dans ~/reports/acme/summary-template.md
5. Postez dans le channel de reporting Acme

Les fichiers SQL se trouvent à côté de la configuration cron. L’agent les trouve, les exécute et assemble l’output. Stocker les requêtes sous forme de fichiers plutôt que de les intégrer dans le message cron les rend plus faciles à versionner, modifier et réutiliser.

L’avantage de fiabilité sur le scraping de dashboards

Les requêtes directes à l’entrepôt sont plus fiables que le scraping de dashboards sur toutes les dimensions importantes pour le reporting planifié :

Output déterministe. La requête retourne exactement ce qu’on lui dit de retourner. Aucun risque que l’agent ait extrait des chiffres de la mauvaise section d’une page, aucune dépendance aux sélecteurs CSS qui changent quand un développeur met à jour l’interface.

Échec explicite. Si la requête échoue — mauvaises credentials, table manquante, panne BigQuery — vous obtenez une erreur, pas des données incorrectes. Les échecs silencieux, qui représentent le danger central du scraping de dashboards, ne s’appliquent pas aux requêtes SQL.

Accès aux données sous-jacentes. Les dashboards montrent une vue pré-filtrée. Les requêtes d’entrepôt donnent accès aux données sous-jacentes, ce qui signifie que vous pouvez calculer les métriques exactement comme vous le souhaitez plutôt que d’être limité à ce que le dashboard expose.

Pas de gestion de session. Il n’y a pas de sessions de navigateur à actualiser, pas de tokens OAuth pour un login d’interface à expirer. Les credentials d’entrepôt ont leur propre cycle de vie (clés de compte de service, rotation de mot de passe), mais elles sont plus simples à gérer que la persistance des sessions de navigateur.

Le compromis est que vous avez besoin de credentials d’entrepôt pour chaque client, et vous devez écrire et maintenir le SQL. Le scraping de dashboards ne nécessite rien de tout cela — juste une URL et une session de navigateur. Pour des configurations rapides ou des clients sans accès à l’entrepôt, le scraping peut réellement être la seule option. Pour tout ce qui est client-facing et récurrent, les requêtes d’entrepôt valent le coût de configuration.

Gérer le SQL entre clients

Pour un cabinet de conseil gérant 3 à 5 clients, la question pratique est de savoir comment organiser les requêtes pour ne pas avoir à les chercher lors de la configuration ou du débogage d’un job cron.

Une structure de répertoire simple par client fonctionne bien :

~/openclaw-reports/
├── acme/
│ ├── ga4-weekly.sql
│ ├── revenue-weekly.sql
│ └── summary-template.md
├── client-b/
│ ├── snowflake-sessions.sql
│ ├── conversion-weekly.sql
│ └── summary-template.md
└── client-c/
└── bigquery-pipeline-stats.sql

Versionnez ce répertoire. Les requêtes SQL changent — de nouveaux KPIs sont ajoutés, les noms de colonnes dans les modèles mart changent, les clients veulent des découpages différents des données. Traiter ces fichiers comme du code (avec des commits, un historique de modifications et la possibilité de revenir en arrière) est préférable à les modifier sur place en espérant se souvenir de ce qui a changé quand un rapport a l’air différent la semaine suivante.

La mise en garde sur la fiabilité des calculs

Le SQL pré-écrit prend en charge la majeure partie du travail de calcul, ce qui réduit l’un des risques les plus importants dans le reporting piloté par agent : les erreurs mathématiques des LLM.

Si vous demandez à l’agent de calculer une variation en pourcentage à partir de deux chiffres dans son contexte — « les sessions sont passées de 11 895 la semaine dernière à 12 847 cette semaine » — il se trompera parfois dans le pourcentage. Non pas parce que le modèle est mauvais en arithmétique, mais parce que les LLM sont des prédicteurs statistiques de texte, et ils prédisent des chiffres plausibles plutôt que de les calculer. Les mêmes résultats de requête peuvent produire des affirmations de pourcentage différentes selon les exécutions.

Faites les calculs dans le SQL à la place. Ajoutez une colonne calculée :

SELECT
this_week.orders,
last_week.orders AS orders_last_week,
ROUND(
(this_week.orders - last_week.orders) * 100.0 / last_week.orders,
1
) AS orders_pct_change
FROM ...

L’agent reçoit une ligne qui dit déjà orders_pct_change: 8.0. Il rapporte ↑ 8%. Pas d’arithmétique dans le LLM.

C’est le principe général pour tout workflow analytique piloté par agent : pousser les calculs dans la couche de données, donner à l’agent des chiffres pré-calculés à narrer. Le travail de l’agent est l’interprétation et le formatage, pas les maths. Voir Format de résumé KPI pour Slack pour savoir comment cela s’applique côté output.

Exigences en matière de credentials

Interroger l’entrepôt nécessite des credentials. Pour BigQuery, cela implique généralement un fichier de clé de compte de service et la CLI bq configurée avec GOOGLE_APPLICATION_CREDENTIALS. Pour Snowflake, cela implique snowsql installé et un profil de connexion configuré.

Pour les configurations multi-clients, l’accès à l’entrepôt de chaque client nécessite ses propres credentials. C’est là que la situation sécuritaire se complique — voir la Architecture de reporting multi-client par agent pour gérer l’isolation des credentials par client, et les Risques de sécurité OpenClaw — Ce qui est documenté pour comprendre pourquoi le stockage de credentials en clair sur une seule machine représente un risque significatif lorsque vous passez à plus d’un client.

En résumé : les credentials d’entrepôt stockées dans ~/.openclaw/config/ ou dans des variables d’environnement sur la machine hôte sont à risque si la machine est compromise. Une machine dédiée par client (ou au minimum, des comptes utilisateurs séparés avec des répertoires de configuration séparés) est la bonne architecture pour le travail en agence, pas une machine partagée avec les clés des cinq clients au même endroit.