ooligo
n8n-flow

Détection d'anomalies dans le funnel de recrutement avec n8n

Difficulty
intermédiaire
Setup time
90min
For
recruiting-leader · talent-acquisition · recruiting-ops
Recruiting & TA

Stack

La plupart des équipes de recrutement découvrent les problèmes de funnel lors de la QBR trimestrielle. À ce moment-là, le poste est ouvert depuis soixante jours, deux des trois meilleurs candidats ont signé ailleurs, et le hiring manager a perdu confiance dans le pipeline. Ce workflow comble cet écart. Un flow n8n s’exécute chaque nuit contre votre ATS, calcule les taux de conversion et les temps de résidence par poste et par étape par rapport à une référence glissante sur 90 jours, signale les déviations statistiquement significatives, demande à Claude d’expliquer chacune en une ou deux phrases, et publie le résultat dans un canal Slack adapté au routage avant le stand-up du lendemain matin.

Le bundle dans apps/web/public/artifacts/hiring-funnel-anomaly-n8n/hiring-funnel-anomaly-n8n.json livre quinze nœuds entièrement configurés — deux déclencheurs planifiés, une extraction Ashby, un nœud Code d’agrégation avec la vraie logique d’anomalie, une recherche de référence Postgres, le détecteur, un insert dédoublonnant, l’appel narratif Claude, le formateur Slack, et un chemin parallèle de tendance temps-de-recrutement. Le _README.md compagnon documente les quatre credentials, les trois tables Postgres à créer, et une vérification en cinq étapes pour la première exécution qui teste chaque branche.

Quand l’utiliser

Déployez ce workflow quand votre équipe de recrutement gère au moins huit à dix postes actifs en parallèle, que l’équipe est sur le même ATS (Ashby, Greenhouse ou Lever) depuis au moins quatre-vingt-dix jours pour qu’une référence existe, et qu’au moins une personne de l’équipe possède la santé du funnel comme partie de son rôle. En dessous de ces seuils, le rapport signal-sur-bruit est mauvais : les références sont trop bruitées pour fixer un seuil de score z utile, et personne n’agira réellement sur l’alerte quand elle se déclenche.

L’autre prérequis est la discipline taxonomique. Si vos étapes sont nommées différemment pour chaque poste, ou si les hiring managers créent librement de nouvelles étapes en cours de recherche, l’agrégation par poste et par étape produira une longue traîne de paires (poste, étape) avec un taille d’échantillon d’un. La garde MIN_SAMPLE = 20 du détecteur les supprime, ce qui est correct, mais vous vous retrouverez sans aucun signal plutôt qu’avec un signal erroné. Corrigez d’abord la taxonomie des étapes.

Quand NE PAS l’utiliser

Ne déployez pas ce workflow si vous gérez moins de cinq postes actifs. Les maths ne fonctionnent pas — il n’y a pas assez d’événements par paire (poste, étape) pour calculer un écart-type de référence significatif, et vous passerez plus de temps à ajuster les seuils qu’à agir sur les alertes. Une revue manuelle hebdomadaire dans une feuille de calcul est vraiment meilleure à cette échelle.

Ne déployez pas ce workflow si votre ATS est le seul endroit où les données des candidats existent et que vous ne disposez pas encore d’un entrepôt analytique séparé. Le flow suppose que vous pouvez mettre en place une base de données Postgres autorisée à dupliquer les données des candidats. Si votre équipe de politique de confidentialité ou d’IA n’a pas encore approuvé la sortie des données des candidats de l’ATS, exécutez cet exercice uniquement sur des agrégats au niveau des étapes — supprimez le calcul de résidence au niveau candidat — et revenez quand la politique aura évolué.

Ne déployez pas ce workflow sur une taxonomie d’étapes qui change chaque semaine. La détection d’anomalies sur une définition d’« étape » en mouvement produit des alertes que personne ne peut interpréter. Stabilisez la taxonomie pendant au moins un trimestre avant d’activer le flow.

Enfin, ne déployez pas ce workflow si la réponse de votre équipe à une alerte de funnel serait « nous le savions déjà ». La valeur du workflow est la latence de 24 heures sur une métrique qui surgirait autrement dans 60 jours. Si vous avez déjà un stand-up quotidien où c’est examiné en direct, l’alerte est redondante.

Configuration

Construisez d’abord la référence. Exécutez un remplissage ponctuel sur les 90 derniers jours en utilisant le même endpoint de flux d’applications Ashby que le workflow utilise, groupez par (role_id, from_stage, to_stage), et écrivez conversion_rate_mean, conversion_rate_stddev, dwell_seconds_p50, stage_sla_seconds et sample_size dans la table funnel_baselines. Le DDL pour cette table — et pour role_tth_baselines et anomaly_alerts — se trouve dans le _README.md du bundle.

Importez hiring-funnel-anomaly-n8n.json du bundle dans n8n. Le workflow est livré inactif intentionnellement. Ouvrez Paramètres et confirmez que le fuseau horaire correspond aux heures de travail de votre équipe ; les deux nœuds Cron évaluent leurs expressions dans le fuseau horaire du workflow, pas en UTC. Créez les quatre credentials référencés par nom dans le JSON : PLACEHOLDER_ASHBY_CRED_ID, PLACEHOLDER_POSTGRES_CRED_ID, PLACEHOLDER_ANTHROPIC_CRED_ID, PLACEHOLDER_SLACK_CRED_ID. Le README explique chacun, y compris les portées Slack (chat:write, chat:write.public) et la forme Header Auth Anthropic.

Effectuez la vérification en cinq étapes pour la première exécution avant d’activer. L’étape deux — insérer une ligne de référence synthétique garantie de se déclencher — est celle que la plupart des gens sautent et se demandent ensuite pourquoi aucune alerte ne se déclenche ; faites-la. L’étape trois confirme que la clé de dédoublonnage fait son travail, ce qui est la garde de coût pour l’appel Claude.

Rafraîchissez les références mensuellement. Les taux de conversion dérivent avec la saisonnalité, les conditions du marché et la composition de l’équipe, et une référence obsolète produit soit du spam d’alertes soit des régressions manquées. Le rafraîchissement est la même requête qui a construit la référence ; cronez-la comme un workflow n8n séparé ou comme un job SQL côté Postgres.

Ce que le flow fait

Le Cron de 2h déclenche une extraction du flux d’applications Ashby pour les dernières 24 heures. Le nœud Code agrégateur regroupe les événements par (role_id, from_stage, to_stage), calcule le taux de conversion et le temps de résidence médian d’aujourd’hui pour chaque paire, et émet un élément par paire. Le nœud Postgres Lookup Baseline joint chaque paire à sa ligne de référence. Le nœud Code Detect Anomalies applique trois règles : un score z de conversion d’étape en dessous de -2,0 par rapport à la moyenne de référence est signalé comme stage_conversion_drop, un temps de résidence médian dépassant stage_sla_seconds * 1,5 est signalé comme candidate_stalled, et une paire (poste, étape) avec zéro événement aujourd’hui et moins de 20 événements historiques est signalée comme new_role_no_movement avec une note de faible sévérité indiquant que les seuils ont été supprimés.

Chaque signalement est écrit dans anomaly_alerts avec une dedupe_key de role::from_stage::to_stage::anomaly_type::yyyy-mm-dd sous une clause ON CONFLICT DO NOTHING. Seuls les inserts qui ont retourné une ligne — c’est-à-dire les alertes qui n’existaient pas déjà pour aujourd’hui — procèdent à l’appel narratif Claude et au post Slack. C’est la garde de coût : une ré-exécution le même jour ne facture pas deux fois Anthropic et ne poste pas deux fois dans Slack. Le formateur Slack route selon le type d’anomalie : les chutes au niveau d’étape et les candidats bloqués vont dans #recruiting-alerts, les tendances temps-de-recrutement et les nouveaux-postes-sans-mouvement vont dans #recruiting-leadership, et les chutes de canal source vont dans #sourcing.

Le Cron de 3h exécute le chemin parallèle de tendance temps-de-recrutement contre une table hires. Il remodèle les lignes où la moyenne glissante sur 7 jours dépasse le seuil dans la même enveloppe d’alerte et les fait passer par le même chemin de dédoublonnage et de post.

Réalité des coûts

Pour une équipe de 30 postes exécutant ceci chaque nuit, attendez environ 600 agrégations (poste, étape) par jour. L’extraction Ashby et les recherches Postgres ne coûtent pratiquement rien. L’appel narratif Claude utilise claude-sonnet-4-6 avec un plafond de 256 tokens et ne se déclenche que sur les alertes nouvellement insérées — pour une équipe saine, c’est typiquement 0 à 3 alertes par nuit, soit environ 0,05-0,15 $ par nuit en tokens. Un pic de 20 régressions simultanées coûte environ 1,00 $. La clé de dédoublonnage garde les ré-exécutions gratuites.

n8n auto-hébergé sur un VPS à 20 $/mois gère cette charge avec de la marge ; le plan Starter n8n Cloud (24 $/mois) convient aussi. Postgres peut être la même instance qui alimente tout le reste que vous exécutez — les trois tables sont petites, peu fréquentées, et indexées sur une seule clé composite. Le coût marginal total est dominé par le temps humain pour maintenir la référence à jour et la taxonomie des étapes stable, pas par l’exécution.

Si vous remplacez Opus pour l’appel narratif, prévoyez un multiplicateur de coût de tokens d’environ 5x ; c’est rarement justifié pour une explication d’une à deux phrases.

Métriques de succès

Suivez la latence médiane entre le début réel d’une régression (poste, étape) et l’action de l’équipe de recrutement à ce sujet. Avant ce flow, cette latence est typiquement de deux à six semaines (la prochaine revue de pipeline). Avec le flow déployé et suivi, elle devrait tomber à 24-48 heures. Si ce n’est pas le cas — si les alertes se déclenchent et que personne n’agit — le problème n’est pas le détecteur, c’est le routage ou le seuil, et la correction est soit de resserrer les canaux jusqu’à ce que l’alerte atteigne une personne ayant l’autorité d’agir, soit de relâcher le seuil de score z jusqu’à ce que le volume d’alertes corresponde à ce que l’équipe peut absorber.

Une métrique secondaire à observer : alertes rejetées sans action en pourcentage du total. Au-dessus de 30 %, vous alertez sur du bruit ; en dessous de 5 %, vous sous-alertez probablement et manquez des signaux.

Alternatives

L’alternative DIY est un job Python ou SQL qui exécute la même agrégation et poste dans Slack via webhook. Ça fonctionne et le coût par événement est plus faible, mais le graphe n8n est la documentation — un ingénieur recruiting-ops qui rejoint le trimestre prochain peut ouvrir le workflow, voir les huit nœuds dans l’ordre, et comprendre le système sans lire de code. Le chemin DIY saute aussi typiquement l’insert de dédoublonnage et la garde de coût autour de l’appel LLM, ce qui est là que viennent les factures.

L’alternative prête à l’emploi est d’acheter Gem, Ashby Analytics ou Datapeople pour le reporting de funnel. Ce sont de bons produits et la bonne réponse pour les équipes qui veulent des tableaux de bord gérés et ne veulent pas posséder une table de référence Postgres. Ce sont la mauvaise réponse quand vous voulez des alertes d’anomalies dans Slack avec une narrative jointe, car aucun d’eux ne livre ça aujourd’hui ; ils livrent des tableaux de bord que quelqu’un doit penser à vérifier. Le compromis est : payer le vendeur et perdre la latence d’alerte, ou posséder le flow n8n et gagner le signal de 24 heures au prix de gérer Postgres.

L’alternative statu quo — la revue de pipeline trimestrielle — est ce que la plupart des équipes font déjà. Elle ne coûte rien et fait remonter les mêmes régressions, juste soixante jours plus tard. Si vos postes prennent six mois à pourvoir et qu’un signal avec soixante jours de retard vous laisse encore le temps de corriger le tir, le statu quo convient vraiment.

Points de vigilance

La fatigue des alertes est le mode d’échec dominant. Une équipe qui reçoit dix alertes chaque matin commencera à toutes les ignorer en une semaine, y compris celle qui comptait. La garde est les constantes MIN_SAMPLE = 20 et Z_THRESHOLD = 2,0 dans le nœud Code Detect Anomalies, plus le DWELL_MULTIPLIER = 1,5 pour les candidats bloqués. Commencez avec ces valeurs, regardez le canal pendant les trois premières nuits, et resserrez — pas relâchez — jusqu’à ce que le matin médian amène 0 à 2 alertes. Relâchez plus tard si vous constatez que vous manquez de vraies régressions.

La dérive de référence produit des faux négatifs silencieux. Les taux de conversion changent avec le marché du travail, le mix de sourcing de l’équipe et le poste lui-même. Une référence calculée en novembre sur un marché actif sous-signalera dans un marché mou et sur-signalera dans un marché tendu. La garde est le rafraîchissement mensuel de funnel_baselines et role_tth_baselines depuis la même requête qui les a construits — planifiez-le comme un workflow n8n récurrent ou un job Postgres et traitez l’échec de ce rafraîchissement comme un incident P1.

L’action automatique sur une alerte de recrutement est presque toujours fausse. La narrative que Claude retourne est de la corrélation, pas de la causalité ; la traiter comme une directive (« la conversion a chuté de 30 %, rejeter automatiquement tous les no-shows à l’entretien téléphonique ») aggravera le problème. La garde est structurelle : le flow n’a pas de chemin de ré-écriture vers l’ATS. Si un futur contributeur propose d’en ajouter un, refusez. L’IA fait remonter l’anomalie ; les humains diagnostiquent et agissent.

Les données privilégiées des candidats quittent l’ATS. Les tables Postgres contiennent role_id, les noms d’étapes, les taux de conversion et les temps de résidence, ce qui est uniquement agrégé par conception — mais une extension imprudente qui ajoute les noms ou coordonnées des candidats pour permettre des narratives plus riches créera une nouvelle surface de confidentialité. La garde est le schéma dans _README.md : les tables n’ont intentionnellement aucune colonne identifiant les candidats. Si un contributeur veut les ajouter, faites passer le changement par votre revue de confidentialité et de politique IA.

L’attribution par canal source n’est aussi bonne que les données ATS. L’alerte optionnelle source_channel_drop (référencée dans la carte de routage Slack mais non activée par défaut dans le bundle) dépend du fait que chaque candidat dispose d’une attribution source propre dans Ashby. Si votre équipe est négligente dans le tagging des sources, l’alerte se déclenchera sur des problèmes de qualité des données, pas sur de vrais problèmes de canal. La garde est une vérification de prérequis : n’activez pas ce type d’alerte jusqu’à ce que l’attribution source soit au moins complète à 90 % dans votre export ATS. Vérifiez avec une requête SQL d’une ligne sur le flux d’applications avant de l’activer.

Stack

Ce flow suppose n8n pour l’orchestration, Ashby (ou Greenhouse / Lever) comme ATS, Postgres pour la référence et l’état des alertes, Claude pour l’explication narrative, et Slack pour la livraison. C’est le complément opérationnel aux métriques définies dans métriques du funnel de recrutement et utilise la distinction temps-de-recrutement vs temps-de-pourvoiement dans le chemin de vérification des tendances.

Files in this artifact

Download all (.zip)