← Retour au blog

RSE et IA responsable indicateurs utiles

Lucian BLETAN

Mesurer l’IA responsable évite le greenwashing: on suit des indicateurs observables, reliés à des décisions concrètes. L’objectif est d’éclairer les arbitrages (qualité vs coût vs impact) et de documenter la progression. Cette page propose des axes simples, des métriques calculables avec vos journaux, et un mode opératoire reproductible en 2024.

prérequis

  • sources de vérité: journaux d’appels (latence, erreurs), métriques qualité (exactitude, citations), consommations énergie/coûts.
  • dictionnaire des métriques: définition, formule, unité, propriétaire, fréquence.
  • stockage minimal: tables normalisées (hebdo/quotidien) pour agréger et tracer l’historique.
  • boucle de décision: comité court (produit, data, RSE) et moments de revue planifiés.

aperçu rapide

  • couvrir 3 axes: social, environnemental, gouvernance (pas seulement le CO₂).
  • ne retenir que des indicateurs actionnables (liés à un levier ou à un SLA).
  • publier des définitions claires (unité, fenêtre, seuils) et des propriétaires.
  • automatiser la collecte et la publication (dashboards et exports).
  • couper ce qui n’apporte pas de valeur (feature toggle mesuré).

axes

  • social: accessibilité, inclusion, erreurs graves évitées, satisfaction.
  • environnemental: énergie, empreinte carbone estimée, déchets numériques.
  • gouvernance: transparence, réclamations traitées, incidents et temps de résolution.

IA responsable

social

accessibilite

inclusion

erreurs graves

satisfaction

environnemental

energie

empreinte carbone

dechets numeriques

gouvernance

transparence

reclamations

incidents

indicateurs concrets

  • taux de réponses citées vs non citées
  • erreurs graves par 10k réponses
  • énergie par 1k requêtes et coût carbone estimé
  • délai de traitement des réclamations (MTTR)
  • couverture accessibilité (pourcentage d’écrans conformes)
-- erreurs graves normalisées (par 10k réponses), hebdo
SELECT week,
       SUM(errors_severe) AS e,
       SUM(requests) AS r,
       ROUND(10000.0 * e / NULLIF(r,0), 2) AS err_10k
FROM llm_quality
GROUP BY week
ORDER BY week DESC;

-- taux de réponses avec citation
SELECT date_trunc('day', ts) AS d,
       AVG(CASE WHEN citations >= 1 THEN 1 ELSE 0 END) AS citations_rate
FROM rag_responses
WHERE ts >= CURRENT_DATE - INTERVAL '30 day'
GROUP BY 1
ORDER BY 1;

-- énergie par 1k requêtes + CO2e estimé (gCO2e/kWh)
WITH req AS (
  SELECT date_trunc('day', ts) AS d, COUNT(*) AS n
  FROM api_calls
  WHERE ts >= CURRENT_DATE - INTERVAL '30 day'
  GROUP BY 1
), en AS (
  SELECT date_trunc('day', ts) AS d, SUM(kwh) AS kwh, AVG(carbon_intensity_g_per_kwh) AS gco2_per_kwh
  FROM finops_energy
  WHERE ts >= CURRENT_DATE - INTERVAL '30 day'
  GROUP BY 1
)
SELECT en.d,
       ROUND(en.kwh / NULLIF(req.n,0) * 1000.0, 4) AS kwh_per_1k,
       ROUND(en.kwh * en.gco2_per_kwh / 1000.0, 1) AS kgco2e_day
FROM en JOIN req USING(d)
ORDER BY en.d DESC;

-- délai médian de traitement des réclamations
SELECT date_trunc('week', created_at) AS w,
       PERCENTILE_DISC(0.5) WITHIN GROUP (ORDER BY EXTRACT(EPOCH FROM (closed_at - created_at))/3600) AS mttr_h
FROM complaints
WHERE closed_at IS NOT NULL
GROUP BY 1
ORDER BY 1 DESC;

tutoriel pas-à-pas

étape 1: définir le cadre et les propriétaires

  • pour chaque indicateur: raison d’être, formule, unité, fenêtre (jour/semaine), seuils, propriétaire (équipe on-call).
  • publier un dictionnaire des métriques accessible à tous.
metric_catalog:
  - id: "citations_rate"
    axis: "gouvernance"
    formula: "réponses avec >=1 citation / réponses totales"
    unit: "ratio"
    window: "jour glissant"
    owner: "@support-ml"
    threshold_min: 0.98
  - id: "err_severe_10k"
    axis: "social"
    formula: "errors_severe / réponses * 10000"
    unit: "par 10k"
    window: "semaine"
    owner: "@quality"
    threshold_max: 5.0
  - id: "kwh_per_1k"
    axis: "environnemental"
    formula: "kWh / requêtes * 1000"
    unit: "kWh/1k req"
    window: "jour"
    owner: "@finops"

étape 2: instrumenter la collecte

  • enrichir les journaux d’appels (latence, statut, features activées).
  • consigner citations et erreurs à la source (middleware).
  • tracer énergie/coûts (par job, région) dans un schéma unifié.
CREATE TABLE IF NOT EXISTS observ.logs_calls (
  ts TIMESTAMP,
  user_id TEXT,
  feature TEXT,
  request_id TEXT,
  status TEXT,
  has_citation BOOLEAN,
  severe_error BOOLEAN
);

CREATE TABLE IF NOT EXISTS observ.finops_energy (
  ts TIMESTAMP,
  job TEXT,
  kwh DOUBLE PRECISION,
  carbon_intensity_g_per_kwh DOUBLE PRECISION,
  region TEXT
);

étape 3: normaliser et agréger

  • vues matérialisées quotidiennes/hebdo.
  • éviter les agrégations ad hoc différentes selon les équipes.
CREATE MATERIALIZED VIEW IF NOT EXISTS observ.mv_daily AS
SELECT date_trunc('day', ts) AS d,
       COUNT(*) AS requests,
       SUM(CASE WHEN has_citation THEN 1 ELSE 0 END) AS cited,
       SUM(CASE WHEN severe_error THEN 1 ELSE 0 END) AS errors_severe
FROM observ.logs_calls
GROUP BY 1;

REFRESH MATERIALIZED VIEW observ.mv_daily;

étape 4: publier et comparer aux seuils

  • dashboards par axe + export CSV/JSON.
  • alerte si seuil franchi (avec lien vers runbook).
-- alerte si citations_rate < 0.98 hier
WITH y AS (
  SELECT d, cited::float/NULLIF(requests,0) AS rate
  FROM observ.mv_daily
  WHERE d = CURRENT_DATE - 1
)
INSERT INTO alerts(kind, details, created_at)
SELECT 'citations_low',
       JSON_BUILD_OBJECT('date', d, 'rate', rate),
       NOW()
FROM y
WHERE rate < 0.98;

étape 5: relier indicateurs et décisions

  • chaque alerte déclenche une action et un compte rendu (toggle, fix, rollback, optimisation).
  • suivre l’impact des leviers (avant/après) dans un changelog.
decision_log:
  id: "opt-rag-2024-04-citations"
  before: {citations_rate: 0.93, kwh_per_1k: 0.52}
  change: "imposer citations et réduire chunks à 6"
  after: {citations_rate: 0.985, kwh_per_1k: 0.49}
  owner: "@support-ml"

leviers (pragmatiques)

  • prompts plus courts, caches, modèles plus petits/quantifiés.
  • affichage clair des limites et des sources (citations obligatoires).
  • canaux de réclamation visibles et traitement chronométré.
  • désactiver ce qui n’apporte pas de valeur (feature flag mesuré).
  • supprimer les données et journaux inutiles (TTL, archivage froid).

ok

ko

mesurer

comparer aux seuils

surveiller

choisir un levier

expérimenter avant/après

déployer si gain prouvé

exemples complets

cas 1: tableau quotidien “citations vs non-citations”

SELECT d,
       cited,
       requests - cited AS non_cited,
       ROUND(cited::float/NULLIF(requests,0), 3) AS rate
FROM observ.mv_daily
ORDER BY d DESC
LIMIT 30;

explications: un ratio < 0.98 indique soit des sources non référencées, soit une configuration RAG à corriger.

cas 2: énergie unifiée par feature (30 jours)

WITH calls AS (
  SELECT feature, COUNT(*) AS req
  FROM observ.logs_calls
  WHERE ts >= CURRENT_DATE - INTERVAL '30 day'
  GROUP BY 1
), e AS (
  SELECT SUM(kwh) AS kwh
  FROM observ.finops_energy
  WHERE ts >= CURRENT_DATE - INTERVAL '30 day'
)
SELECT c.feature,
       c.req,
       ROUND((SELECT kwh FROM e) / NULLIF(c.req,0) * 1000.0, 4) AS kwh_per_1k_est
FROM calls c
ORDER BY kwh_per_1k_est DESC;

explications: estime le coût énergétique spécifique d’une fonctionnalité pour cibler les optimisations.

cas 3: MTTR réclamations et taux de résolution

SELECT date_trunc('week', created_at) AS w,
       COUNT(*) AS opened,
       SUM(CASE WHEN closed_at IS NOT NULL THEN 1 ELSE 0 END) AS closed,
       ROUND(100.0*SUM(CASE WHEN closed_at IS NOT NULL THEN 1 ELSE 0 END)/COUNT(*),1) AS close_rate_pct,
       PERCENTILE_DISC(0.5) WITHIN GROUP (ORDER BY EXTRACT(EPOCH FROM (closed_at - created_at))/3600) AS mttr_h
FROM complaints
GROUP BY 1
ORDER BY 1 DESC;

explications: suit la capacité à traiter les réclamations (gouvernance) et le délai médian de résolution.

erreurs courantes et solutions

  • indicateurs vagues → pas d’action → choisir des métriques reliées à un levier concret (citations, MTTR, kWh/1k).
  • focus CO₂ seul → oublis → équilibrer social, environnemental, gouvernance.
  • zéro transparence → défiance → publier définitions, propriétaires et seuils.
  • agrégations incohérentes → confusion → vues matérialisées communes et dictionnaire partagé.
  • collecte bruyante → coûts et PII → filtrer en entrée, anonymiser, rétention courte.

faq

  • Comment choisir un petit nombre d’indicateurs utiles ? Limitez-vous à 2–3 par axe, reliés à des décisions claires (déploiement, rollback, optimisation).

  • Comment estimer le CO₂ sans capteurs matériels ? Multipliez les kWh (ou coûts convertis) par un facteur carbone régional (gCO₂e/kWh) documenté et stable dans le temps.

  • Faut-il un outil dédié pour démarrer ? Non. Des tables de logs, quelques vues matérialisées et un dashboard suffisent. Outillez ensuite si besoin.

  • Que faire si une métrique chute en-dessous du seuil ? Ouvrir un incident, déclencher un levier (ex: forcer les citations), mesurer l’effet et documenter la décision.

  • Comment éviter le greenwashing dans les rapports ? Publiez les formules, les unités, les fenêtres de calcul, les limites connues et les décisions prises à partir des métriques.