Aller au contenu

Détection IA de signaux d'affaires : construire un système RevOps utile

Il y a un moment où les bases de données commerciales ne suffisent plus.

Elles savent dire qu'une entreprise existe. Elles donnent parfois un secteur, une taille, un site web, un compte LinkedIn, quelques contacts.

Mais elles répondent rarement à la question la plus intéressante :

Pourquoi cette entreprise mérite-t-elle d'être contactée maintenant ?

C'est cette question qui m'a progressivement amené à travailler sur un sujet plus large : la détection de signaux d'affaires avec de l'IA, du scraping, des workflows automatisés et un peu de logique RevOps. Pas pour construire une machine magique à vendre. Pas pour remplacer les commerciaux. Mais pour mieux préparer le travail commercial, comprendre les mouvements d'une entreprise, et transformer des données publiques assez bruyantes en contexte exploitable.

Cette page est un point d'entrée. Elle relie plusieurs expérimentations techniques menées autour du scraping, de la veille concurrentielle, des signaux d'expansion et de la prospection semi-automatisée, et explique le raisonnement global derrière ces projets.

En résumé

  • Ce que fait ce système : détecter automatiquement des signaux d'expansion, concurrentiels et techniques à partir de WTTJ, LinkedIn, Trustpilot et le web.
  • Stack principale : n8n · Scrapy · Supabase · OpenRouter · Redis · Apify.
  • La vraie difficulté : pas la collecte — filtrer le bruit, éviter les faux positifs, rendre la sortie actionnable.
  • Rôle de l'IA ici : classifier et résumer des signaux déjà structurés, jamais décider seule.
  • Ce que j'ai surtout appris : un système RevOps utile n'est pas celui qui automatise le plus, c'est celui qui rend le meilleur contexte disponible au bon moment.

Les notes techniques liées

  • Détecter les technologies web avec Scrapy

    Comment j'ai construit un moteur de détection de stack technique à partir du HTML, des scripts, des cookies, des headers et des signatures.

    Lire la note

  • La machine à leads SDR

    Comment j'ai assemblé une base d'entreprises, Hunter.io, des pain points, des références clients, n8n, Microsoft Lists et Power BI pour aider les SDR à mieux préparer leur prospection.

    Lire la note

  • Veille concurrentielle multi-source

    Comment j'ai croisé Trustpilot, LinkedIn, les sites web, Supabase et un LLM pour extraire des signaux concurrentiels utiles.

    Lire la note

  • Signaux d'expansion avec WTTJ, LinkedIn et n8n

    Comment j'ai utilisé WTTJ via Algolia, LinkedIn, des pages d'actualités et Redis pour détecter des indices de croissance chez des entreprises B2B.

    Lire la note


Le problème réel : les commerciaux manquent rarement de données

Le problème n'est pas d'avoir des données. En B2B, on peut déjà acheter ou enrichir beaucoup d'informations : nom, domaine, secteur, taille, pays, page LinkedIn, contacts, emails, postes, technologies supposées, levées de fonds, actualités publiques.

Le vrai problème est ailleurs.

La donnée brute dit rarement ce qu'il faut en faire.

Une entreprise de 300 salariés dans le SaaS peut être intéressante. Mais pourquoi maintenant ? Qu'est-ce qui a changé ? Est-ce qu'elle recrute ? Est-ce qu'elle ouvre un nouveau marché ? Est-ce qu'elle change de stack ? Est-ce qu'elle reçoit des avis négatifs sur son support ? Est-ce qu'elle cherche des profils qui indiquent une transformation interne ?

C'est là que la notion de signal d'affaires devient intéressante.

Le déclic

Une base commerciale décrit une entreprise. Un signal d'affaires décrit un mouvement.

Et dans beaucoup de contextes commerciaux, le mouvement est plus important que la fiche statique.


Ce que j'appelle un signal d'affaires

Un signal d'affaires n'est pas juste une actualité. C'est une information publique ou semi-structurée qui peut indiquer qu'une entreprise traverse un moment particulier.

Signal détecté Ce que ça peut suggérer Angle commercial possible
Recrutement massif sur WTTJ Croissance, expansion, structuration d'équipe Proposer une solution qui accompagne le passage à l'échelle
Nouveaux posts LinkedIn sur un marché Changement de positionnement ou ouverture commerciale Adapter le message à ce nouveau marché
Avis Trustpilot négatifs récurrents Friction client, problème support, problème produit Identifier un angle concurrentiel crédible
Changement de stack marketing Migration, maturité digitale, projet en cours Proposer un audit, une intégration ou une alternative
Publication d'une nouvelle page produit Nouvelle offre, repositionnement Surveiller l'évolution du discours commercial
Multiplication des contenus recrutement Croissance interne ou difficulté à attirer Repérer des priorités RH / opérationnelles

Le signal n'est pas forcément une preuve. C'est souvent un indice. Et c'est justement pour ça qu'il faut être prudent.

Un signal n'est pas une vérité

Une offre d'emploi ne prouve pas qu'une entreprise est en hypercroissance. Un avis négatif ne prouve pas qu'un concurrent est en difficulté. Un script détecté dans le HTML ne prouve pas toujours qu'une techno est réellement utilisée.

Le système doit aider à formuler une hypothèse, pas produire une certitude artificielle.


Pourquoi ce sujet m'a intéressé

Au départ, je ne pensais pas travailler sur un "système RevOps".

Je partais de problèmes beaucoup plus concrets. Dans mes workflows de prospection, je passais trop de temps à ouvrir des sites web, inspecter le code source, regarder les scripts chargés, chercher des outils marketing, vérifier si une entreprise publiait encore, lire des posts LinkedIn peu exploitables, regarder des offres d'emploi, croiser des informations dans plusieurs onglets, et essayer de transformer tout ça en message commercial crédible.

Chaque tâche était simple. Mais l'ensemble était lent, répétitif et difficile à industrialiser proprement.

Le sujet m'a intéressé parce qu'il se situe exactement entre plusieurs domaines que j'aime bien : le web, le scraping, l'automatisation, l'IA, la donnée, la prospection, les workflows opérationnels et la logique produit.

Ce n'est pas seulement un sujet technique. C'est aussi un sujet de design de système.

Comment collecter de l'information sans se noyer ? Comment garder un raisonnement compréhensible ? Comment éviter que l'IA décide tout à notre place ? Comment construire un outil utile pour quelqu'un qui doit vraiment vendre derrière ?


Ce que je voulais construire

Je voulais construire une couche de renseignement commercial exploitable. Pas un CRM. Pas une plateforme "AI SDR" autonome. Pas un outil qui envoie automatiquement 10 000 messages.

Plutôt un système qui aide à répondre à quelques questions simples :

  • quelles entreprises méritent d'être regardées cette semaine ?
  • pourquoi maintenant ?
  • quel est le contexte détecté ?
  • quelle source permet de le vérifier ?
  • quel angle commercial pourrait être pertinent ?
  • quel message pourrait être préparé, mais pas envoyé sans validation ?
Données publiques
Collecte automatisée
Extraction de signaux
Qualification IA
Priorisation
Action commerciale assistée

Ce qui m'intéressait surtout, c'était le passage entre information disponible et information actionnable.


Les contraintes de départ

Je n'avais pas envie de partir sur une architecture trop théorique.

Contrainte Conséquence
Budget limité Éviter les APIs trop chères ou les plateformes fermées
Besoin d'itérer vite Utiliser n8n, Python, Supabase, OpenRouter
Sources hétérogènes Prévoir du nettoyage, des fallbacks, des erreurs
Résultats exploitables par des humains Garder les sources, les preuves et le raisonnement
Pas de boîte noire totale Éviter un scoring IA impossible à expliquer
Données web instables Accepter les timeouts, les faux positifs, les pages cassées

La tentation aurait été de tout rendre "intelligent". Mais plus j'avançais, plus je me rendais compte que la robustesse venait surtout de composants simples : des sources bien identifiées, des règles lisibles, des prompts cadrés, une sortie JSON stricte, une déduplication basique, un scoring explicable.

Ce que j'ai appris assez vite

Un système RevOps utile n'est pas forcément celui qui automatise le plus. C'est souvent celui qui rend le meilleur contexte disponible au bon moment.


Pourquoi les solutions existantes ne me convenaient pas

Il existe déjà beaucoup d'outils autour de la sales intelligence, de la veille, de l'enrichissement ou de l'intent data. Le problème, dans mon cas, n'était pas leur existence. C'était leur manque de souplesse pour expérimenter.

Type d'outil Ce qui me gênait
Bases de données B2B Données utiles, mais souvent statiques
Outils d'intent data Scoring opaque, difficile à auditer
Outils de veille Trop génériques, beaucoup de bruit
Extensions de détection techno Peu adaptées aux workflows automatisés
Plateformes sales intelligence Coût élevé, logique fermée
Scrapers clé en main Peu personnalisables, dépendance forte

Je voulais pouvoir modifier rapidement les sources, les règles de détection, les seuils, les prompts, les formats de sortie et les actions déclenchées derrière. Et surtout, je voulais voir le raisonnement.

Une information commerciale n'est pas utile simplement parce qu'elle existe. Elle devient utile quand on comprend d'où elle vient, pourquoi elle a été retenue, ce qu'elle suggère, et ce qu'elle ne permet pas d'affirmer.


Architecture globale

Au fil des projets, l'architecture générale a commencé à ressembler à ça :

flowchart TD
    A[Sources publiques] --> B[Collecte automatisée]

    A1[Sites web] --> B
    A2[LinkedIn] --> B
    A3[WTTJ] --> B
    A4[Trustpilot] --> B
    A5[Bases entreprises] --> B

    B --> C[Nettoyage & normalisation]
    C --> D[Extraction de signaux]

    D --> D1[Signaux techniques]
    D --> D2[Signaux d'expansion]
    D --> D3[Signaux concurrentiels]
    D --> D4[Signaux de prospection]

    D1 --> E[Qualification IA]
    D2 --> E
    D3 --> E
    D4 --> E

    E --> F[Scoring explicable]
    F --> G[Stockage Supabase]
    G --> H[Interface opérationnelle]

    H --> I[Action SDR]
    H --> J[Veille RevOps]
    H --> K[Reporting]

L'idée importante : l'IA n'est pas placée au début. Je ne l'utilise pas pour "deviner" à partir de rien. Je l'utilise après une étape de collecte et de structuration.

flowchart LR
    A[Donnée brute] --> B[Parsing]
    B --> C[Contexte structuré]
    C --> D[Analyse IA]
    D --> E[JSON exploitable]
    E --> F[Action humaine]

Principe de conception

Plus l'entrée envoyée au LLM est structurée, plus la sortie est stable. Le prompt ne doit pas compenser un pipeline de données trop sale.


Les grandes familles de signaux

J'ai progressivement distingué plusieurs familles de signaux.

mindmap
  root((Signaux d'affaires))
    Technique
      Stack marketing
      CMS
      CRM
      Tracking
      Dette technique visible
    Expansion
      Recrutement
      Nouveaux marchés
      Nouvelles offres
      Croissance équipe
    Concurrentiel
      Avis clients
      Positionnement
      Pricing
      Changements produit
    Commercial
      Pain points probables
      Références pertinentes
      Angles de message
      Priorité SDR

Cette catégorisation m'a aidé à éviter de tout mélanger. Un signal technique n'a pas le même niveau de preuve qu'un signal d'expansion. Un avis Trustpilot n'a pas la même nature qu'une offre WTTJ. Chaque source a son utilité, mais aussi ses angles morts.


Stack utilisée

La stack a évolué au fil des expérimentations, mais plusieurs briques sont revenues régulièrement.

Outil Rôle Pourquoi ce choix
Scrapy Crawling web et collecte HTML Rapide, structuré, adapté au volume
Playwright Fallback JavaScript Utile quand le HTML initial est vide
n8n Orchestration des workflows Rapide pour prototyper et connecter les briques
Supabase Stockage structuré Simple, PostgreSQL, pratique pour historiser
OpenRouter Appels LLM Flexible, permet de tester plusieurs modèles
GPT-4o-mini Analyse IA à coût raisonnable Suffisant pour classification et extraction
Apify Collecte LinkedIn Évite de maintenir un scraper fragile
Hunter.io Enrichissement entreprises / contacts Utile pour passer de l'entreprise au contact
Redis Contrôle de concurrence Évite de saturer les APIs externes
Microsoft Lists Interface SDR simple Compréhensible par une équipe opérationnelle
Power BI Reporting Permet de suivre volume, statuts et performance

Pourquoi n8n

n8n m'a servi de colonne vertébrale. Pas parce que c'est parfait, mais parce que c'est très efficace pour tester rapidement des chaînes d'actions. Ce que j'ai apprécié : visualiser le workflow, brancher rapidement des APIs, tester un prompt, inspecter les entrées/sorties, relancer une exécution, prototyper avant de coder proprement.

Ce que j'ai moins aimé : les workflows deviennent vite gros, la lisibilité baisse quand il y a trop de branches, et certaines transformations complexes seraient plus propres en code.

Le piège n8n

n8n donne l'impression qu'on peut tout assembler très vite. C'est vrai au début. Mais dès que la logique métier grossit, il faut être discipliné : nommage, sous-workflows, logs, sorties normalisées, gestion des erreurs.

Pourquoi Scrapy

Scrapy est entré dans le système par le projet de détection de technologies web. Au départ, je voulais simplement éviter d'ouvrir les sites un par un pour comprendre leur stack.

Le point clé : Scrapy ne détecte rien à lui seul. Il collecte des signaux. La logique métier est ailleurs : dans les signatures, le scoring et l'interprétation.

flowchart TD
    A[Liste de domaines] --> B[Spider Scrapy]
    B --> C[HTML]
    B --> D[Scripts]
    B --> E[Headers]
    B --> F[Cookies]
    B --> G[Meta tags]

    C --> H[Moteur de signatures]
    D --> H
    E --> H
    F --> H
    G --> H

    H --> I[Score de confiance]
    I --> J[Technologies détectées]
    J --> K[Workflow RevOps]

Pour aller plus loin sur cette partie : Construire un détecteur de technologies web avec Scrapy

Pourquoi Supabase

Supabase m'a surtout servi à garder un socle propre : entreprises, domaines, signaux, résultats de crawl, slugs WTTJ, enrichissements, statuts, historique.

La tentation au début est de tout faire passer dans des fichiers JSON ou CSV. C'est suffisant pour tester. Mais dès qu'on veut comparer dans le temps, dédupliquer, scorer et historiser, une base devient nécessaire.

Structure simplifiée :

create table companies (
  id uuid primary key default gen_random_uuid(),
  name text,
  domain text,
  linkedin_url text,
  industry text,
  headcount text,
  country text,
  wttj_slug text,
  created_at timestamptz default now()
);

create table business_signals (
  id uuid primary key default gen_random_uuid(),
  company_id uuid references companies(id),
  source text,
  signal_type text,
  title text,
  summary text,
  evidence_url text,
  confidence_score numeric,
  detected_at timestamptz default now(),
  raw_payload jsonb,
  prompt_version text
);

Pourquoi l'IA, mais pas partout

L'IA est utile dans ce système, mais seulement à certains endroits.

Je l'ai utilisée pour résumer des signaux, classer des informations, identifier un angle commercial, distinguer bruit et signal, formuler une hypothèse, générer une sortie JSON, et préparer une fiche commerciale.

Je l'ai évitée pour décider seule de la vérité, scraper, dédupliquer sans clé stable, remplacer les règles simples, masquer les sources, ou inventer un contexte manquant.

Règle personnelle

Si une règle simple suffit, je préfère une règle simple. L'IA arrive quand le contexte devient ambigu, narratif ou difficile à réduire à une condition.


Construction étape par étape

Étape 1 — Construire une base d'entreprises

Tout commence par une liste. Dans le projet de machine à leads SDR, j'ai commencé avec une base de sites web d'entreprises issue de plusieurs sources. L'objectif n'était pas d'avoir une base parfaite dès le départ — c'était même l'inverse : accepter une base imparfaite, puis utiliser les étapes suivantes pour filtrer.

flowchart LR
    A[Sources domaines] --> B[Nettoyage]
    B --> C[Déduplication]
    C --> D[Base entreprises]
    D --> E[Crawl]
    E --> F[Qualification]

On a souvent envie de commencer par "la donnée parfaite". En pratique, elle n'existe pas. On démarre avec du bruit, puis on construit des mécanismes pour filtrer, enrichir, scorer, exclure et apprendre.

Étape 2 — Détecter des signaux techniques

La première famille de signaux industrialisée concerne les technologies web.

{
  "domain": "example-store.com",
  "technologies": [
    {
      "name": "Shopify",
      "confidence": 0.97,
      "signals": ["cdn.shopify.com", "_shopify_y", "shopify-checkout"]
    },
    {
      "name": "Klaviyo",
      "confidence": 0.91,
      "signals": ["static.klaviyo.com", "__kla_id"]
    }
  ],
  "meta": {
    "crawl_time_ms": 1840,
    "javascript_rendered": false,
    "redirects": 1
  }
}

Ce type de sortie peut être réutilisé pour identifier des entreprises qui utilisent une techno concurrente, détecter des stacks e-commerce, estimer une maturité marketing, alimenter un scoring ou personnaliser un message. Mais ça impose une discipline : chaque détection doit garder ses preuves.

Étape 3 — Enrichir les entreprises et les contacts

Une fois les entreprises filtrées, l'étape suivante consiste à enrichir. Dans le workflow SDR, Hunter.io servait à récupérer des informations entreprise, des contacts, des postes et parfois des emails.

Mais l'enrichissement seul ne suffit pas. Un contact sans contexte donne souvent un message générique. Un contexte sans contact reste difficile à actionner. Il faut les deux.

Point terrain

Le plus difficile n'est pas de trouver des contacts. Le plus difficile est de ne pas générer une liste de contacts inutiles.

Étape 4 — Croiser avec des pain points et références

La personnalisation ne doit pas venir uniquement du LLM. Dans mon approche, j'ai préféré préparer des bases métier : pain points par technologie concurrente, références clients par secteur, arguments différenciants, capacités d'intégration.

Le LLM ne part donc pas d'une page blanche. Il reçoit un contexte cadré :

{
  "company": {
    "name": "Example Company",
    "industry": "Retail",
    "detected_technologies": ["Klaviyo", "Shopify"]
  },
  "pain_points": [
    "difficulté à synchroniser les données CRM",
    "segmentation limitée sur certains scénarios avancés"
  ],
  "relevant_references": [
    {
      "name": "Client A",
      "sector": "Retail",
      "use_case": "automatisation CRM + email"
    }
  ],
  "commercial_goal": "préparer un angle de prospection contextualisé"
}

Au lieu de demander "Écris un email personnalisé pour cette entreprise", on demande plutôt : "À partir des signaux détectés, des pain points connus et des références pertinentes, propose un angle commercial prudent, vérifiable et utile pour un SDR." La différence de qualité de sortie est significative.

Étape 5 — Détecter des signaux d'expansion

Les signaux d'expansion viennent de sources complémentaires.

Source Ce qu'elle peut révéler Limite principale
WTTJ Recrutements actifs, métiers recherchés, localisation Nécessite un bon mapping entreprise / slug
LinkedIn Annonces publiques, lancements, partenariats Beaucoup de bruit
Pages actualités Discours officiel, nouveaux marchés, nouvelles offres Structures web hétérogènes
flowchart TD
    A[(Supabase entreprises)] --> B[n8n Scheduler]
    B --> C{Loop entreprises}

    C --> D[WTTJ via Algolia]
    C --> E[LinkedIn via Apify]
    C --> F[Pages actualités]

    D --> G[Parsing jobs]
    E --> H[Parsing posts]
    F --> I[Parsing contenus]

    G --> J[Contexte structuré]
    H --> J
    I --> J

    J --> K[Analyse IA]
    K --> L[JSON signaux]
    L --> M[(Supabase)]

Un apprentissage important sur WTTJ : passer par les requêtes Algolia visibles côté frontend est beaucoup plus stable que parser du HTML. Ce n'est pas un hack — c'est le fonctionnement normal d'une clé search-only côté client. Mais ça crée une autre difficulté : il faut connaître le bon slug WTTJ de l'entreprise.

Erreur classique

Quand le slug est absent, l'API peut retourner zéro résultat sans erreur. Techniquement, tout fonctionne. Fonctionnellement, le signal est perdu.

Pour le détail : Détecter les signaux d'expansion d'entreprises avec WTTJ, LinkedIn et n8n

Étape 6 — Construire une veille concurrentielle multi-source

La veille concurrentielle ajoute une autre difficulté : le signal est rarement isolé. Un avis Trustpilot seul peut être anecdotique. Un post LinkedIn seul peut être de la communication. Quand plusieurs sources racontent quelque chose de cohérent, le signal devient plus intéressant.

flowchart TD
    A[Concurrent] --> B[Trustpilot]
    A --> C[LinkedIn]
    A --> D[Site web / blog]

    B --> E[Frictions clients]
    C --> F[Mouvements visibles]
    D --> G[Discours officiel]

    E --> H[Assemblage contexte]
    F --> H
    G --> H

    H --> I[Analyse IA]
    I --> J[Signal concurrentiel]
    J --> K[Priorisation]
Exemple de sortie attendue
{
  "competitor": "Example Competitor",
  "signal_type": "customer_support_weakness",
  "confidence": 0.78,
  "sources": ["trustpilot", "linkedin"],
  "summary": "Plusieurs avis récents mentionnent des délais de réponse élevés. En parallèle, l'entreprise communique sur une forte croissance client.",
  "commercial_angle": "Positionner la qualité d'accompagnement et la réactivité support comme différenciants, sans attaquer frontalement le concurrent.",
  "evidence": [
    { "source": "trustpilot", "url": "https://example.com/review/123" },
    { "source": "linkedin", "url": "https://linkedin.com/posts/example" }
  ]
}

Pour le détail : Construire une veille concurrentielle multi-source avec Trustpilot, LinkedIn et le web

Étape 7 — Rendre le système actionnable pour les SDR

Un signal qui reste dans une base ne sert pas à grand-chose. Il faut une sortie opérationnelle.

Dans le projet SDR, l'interface passait par Microsoft Lists, avec des statuts simples :

Statut prospect Statut email Statut commercial
nouveau non envoyé à traiter
en cours envoyé relance
clos répondu rendez-vous
hors cible erreur refus

Ce n'est pas l'interface la plus glamour. Mais elle est compréhensible par une équipe qui travaille déjà dans un environnement Microsoft.

flowchart LR
    A[Signaux qualifiés] --> B[Priorisation]
    B --> C[Assignation SDR]
    C --> D[Microsoft Lists]
    D --> E[Notification Teams]
    D --> F[Suivi statuts]
    F --> G[Power BI]

Ce qui a marché

L'adoption dépend moins de la sophistication du système que de la clarté de la sortie. Si le commercial comprend pourquoi une entreprise apparaît dans sa liste, le système devient utile.


Modèle de scoring

Je n'ai pas cherché à créer un score parfait. J'ai essayé de créer un score lisible.

def compute_signal_score(signal):
    score = 0

    if signal["source"] == "wttj":
        score += 20
    if signal["source"] == "linkedin":
        score += 10
    if signal["source"] == "trustpilot":
        score += 15

    if signal.get("recency_days", 999) <= 30:
        score += 20
    if signal.get("has_multiple_sources"):
        score += 25
    if signal.get("matches_icp"):
        score += 20

    return min(score, 100)

Ce scoring est volontairement simple. Il ne prétend pas produire une vérité statistique. Il sert à ordonner, filtrer, prioriser. Dans un système opérationnel, c'est souvent suffisant pour commencer.

À améliorer plus tard

Le scoring devient plus intelligent avec l'historique : quels signaux mènent vraiment à une réponse ? quels signaux produisent des rendez-vous ? quels signaux sont surtout du bruit ?


Répartition indicative des signaux

Après plusieurs semaines d'exécution, voilà comment se répartissent les signaux et leur pertinence estimée :

pie title Répartition des signaux détectés par source
    "LinkedIn" : 35
    "WTTJ" : 25
    "Sites web / actualités" : 20
    "Trustpilot" : 12
    "Détection technique" : 8

Le ratio signal/bruit varie beaucoup selon la source :

Source Pertinence estimée Commentaire
Détection technique ~70% Signal précis si les signatures sont bonnes
WTTJ ~65% Fiable, mais dépend du slug et de la déduplication
Trustpilot ~55% Biais vers les expériences extrêmes
Sites web / actualités ~45% Hétérogène, blogs souvent abandonnés
LinkedIn ~25% Beaucoup de contenu marque employeur générique

Les erreurs et problèmes rencontrés

1. Croire que la donnée web est propre

Elle ne l'est pas. Les sites redirigent mal. Les certificats expirent. Les pages changent. Les contenus sont rendus en JavaScript. Les blogs n'ont pas de dates. Les slugs ne correspondent pas aux noms d'entreprise. Les APIs répondent différemment selon les cas.

Dans un workflow de détection de signaux, les cas limites sont la norme.

Le vrai coût

Le coût principal n'est pas l'écriture du premier crawler. Le coût principal est la gestion des exceptions.

2. Déclencher l'IA trop tôt

Au début, on peut être tenté d'envoyer beaucoup de contenu brut au LLM. Problèmes rencontrés : réponses trop longues, hallucinations, mauvaise hiérarchisation, difficulté à parser, coût plus élevé, résultats difficiles à comparer.

Ce qui fonctionne mieux :

flowchart LR
    A[Contenu brut] --> B[Nettoyage]
    B --> C[Extraction champs utiles]
    C --> D[Contexte structuré]
    D --> E[Prompt cadré]
    E --> F[JSON strict]

3. Sous-estimer la déduplication

Un signal peut réapparaître plusieurs fois : même post LinkedIn récupéré deux fois, offre WTTJ republiée, page actualité crawlée à plusieurs dates, avis client déjà analysé.

La solution simple : générer un hash.

import hashlib

def make_signal_hash(company_id, source, title, published_at):
    raw = f"{company_id}:{source}:{title}:{published_at}".lower().strip()
    return hashlib.sha256(raw.encode("utf-8")).hexdigest()

4. Confondre volume et valeur

Plus de signaux ne veut pas dire meilleur système. Un workflow qui remonte 200 signaux faibles par semaine devient vite inutilisable.

Mauvais indicateur Meilleur indicateur
Nombre de signaux détectés Nombre de signaux actionnables
Nombre de sources crawlées Qualité des sources utiles
Nombre d'emails générés Taux de messages réellement validés
Nombre d'entreprises enrichies Nombre d'entreprises pertinentes
Score moyen Conversion par type de signal

Formulation simple

Le but n'est pas de trouver plus d'informations. Le but est de réduire le temps nécessaire pour comprendre quoi faire.


Ce qui a marché

Le croisement des sources

Chaque source seule est imparfaite. Mais le croisement change beaucoup de choses.

Source 1 Source 2 Interprétation plus solide
WTTJ : recrutements Sales LinkedIn : annonce nouveau marché Expansion commerciale probable
Trustpilot : plaintes support Site web : discours premium support Angle concurrentiel à vérifier
Détection techno concurrente Référence client pertinente Message SDR plus contextualisé
Blog entreprise actif Recrutements produit Transformation ou lancement en cours

Les sorties JSON strictes

Un autre point qui a bien fonctionné : forcer les sorties structurées.

{
  "is_relevant": true,
  "signal_type": "expansion",
  "confidence": 0.82,
  "summary": "L'entreprise recrute plusieurs profils commerciaux en Europe, ce qui suggère une phase d'expansion.",
  "evidence": {
    "source": "wttj",
    "url": "https://example.com/jobs"
  },
  "recommended_action": "préparer une approche orientée accompagnement de croissance"
}

Le JSON strict rend le système plus testable, plus stockable, plus exploitable et plus facile à comparer dans le temps.

Garder l'humain dans la boucle

L'objectif n'est pas que le système décide seul. L'objectif est qu'il prépare mieux le travail humain. Le SDR doit pouvoir voir la source, comprendre le raisonnement, invalider un signal, modifier un statut, adapter le message, décider de ne pas contacter.

flowchart TD
    A[Système détecte] --> B[Humain vérifie]
    B --> C[Humain ajuste]
    C --> D[Action commerciale]
    D --> E[Résultat]
    E --> F[Apprentissage futur]

Le bon compromis

Automatiser la préparation. Garder la décision humaine.


Ce que j'ai appris

  • Logs propres dès le départ. Erreurs gérées, timeouts, retries, sorties typées, sources conservées, déduplication, prompts versionnés, scoring lisible, stockage historique. Les détails ennuyeux font la qualité du système.
  • Inspecter le réseau avant de scraper. WTTJ aurait demandé plusieurs jours en parsing HTML. Algolia l'a réduit à moins d'une heure. Ouvrir les DevTools en premier est devenu un réflexe.
  • Logger "0 résultats" différemment des erreurs. Un retour vide peut être correct ou symptomatique. Les traiter pareil masque des bugs.
  • Un signal n'a de valeur que s'il aide à prendre une décision. Il faut donc penser l'affichage autant que la collecte. Un bon signal doit répondre à quatre questions : qu'est-ce qui a été détecté ? pourquoi est-ce potentiellement important ? quelle preuve peut-on consulter ? que peut-on faire ensuite ?
  • Le total brut est un leurre. La variation dans le temps est plus utile que le volume instantané. Ce qu'il faudrait, c'est un historique sur 4 semaines glissantes.
  • Le persona dans le prompt change la qualité de sortie. "Analyse" produit des résumés. "Tu cherches des opportunités upsell concrètes" produit des actions.
  • Le RevOps n'est pas seulement une question d'outillage. C'est une façon de relier la donnée, les workflows, les équipes commerciales, les outils existants, le reporting et les apprentissages terrain.
  • La valeur vient de la boucle complète. Sans retour terrain, le système reste une machine à produire des hypothèses. Avec retour terrain, il peut devenir progressivement meilleur.
flowchart LR
    A[Collecte] --> B[Qualification]
    B --> C[Action]
    C --> D[Résultat]
    D --> E[Analyse]
    E --> A

Limites actuelles

Le scraping reste fragile

Même avec Scrapy, Playwright, Apify ou des APIs indirectes, la collecte reste dépendante de sources externes : changements de structure HTML, protections anti-bot, rendu JavaScript coûteux, pages supprimées, contenu non daté, APIs non documentées, coûts variables selon le volume.

Il faut accepter cette fragilité dès le départ.

Les signaux ne sont pas tous comparables

Un recrutement WTTJ, un avis Trustpilot, un script Klaviyo et un post LinkedIn n'ont pas la même fiabilité, la même fraîcheur, le même biais, la même valeur commerciale, ni le même niveau de preuve. Le scoring doit donc rester prudent.

Le système ne comprend pas tout

Il voit ce qui est public. Il ne voit pas les projets internes, les discussions commerciales, les changements d'organisation non publiés, les outils backend, les arbitrages budgétaires, les vrais cycles d'achat.

À ne pas oublier

Un système de signaux ne lit pas dans la tête des entreprises. Il observe des traces publiques et propose des hypothèses.

Le passage à l'échelle demande une autre rigueur

Un prototype qui fonctionne sur 100 entreprises ne fonctionne pas forcément sur 10 000. À plus grande échelle, il faut traiter sérieusement la concurrence d'exécution, les quotas API, les coûts, la pagination, les erreurs silencieuses, les reprises après échec et la gouvernance des données.


Ce que je referais autrement

Je versionnerais les prompts dès le départ

Au début, les prompts évoluent vite. On modifie une phrase, on ajoute un champ, on change une consigne, puis on ne sait plus quelle version a produit quel résultat.

/prompts
  /signals
    expansion_v1.md
    expansion_v2.md
    competitor_watch_v1.md
  /sales
    email_generation_v1.md
    account_brief_v1.md

Avec en base : alter table business_signals add column prompt_version text;

Je construirais un jeu de test métier

Pas seulement des tests techniques. Un vrai jeu de cas :

Cas Résultat attendu
5 offres WTTJ récentes dans plusieurs pays Signal expansion
Post LinkedIn marque employeur générique Non pertinent
10 avis négatifs récents sur le support Signal concurrentiel
Blog abandonné depuis 2 ans Ignorer
Détection techno avec un seul mot HTML ambigu Confiance faible

C'est probablement ce qui manque le plus dans beaucoup de workflows IA : des tests métier.

Je séparerais plus tôt orchestration et logique métier

n8n est très pratique, mais toute la logique ne doit pas vivre dans les nodes.

flowchart TD
    A[n8n orchestration] --> B[Services métier]
    B --> C[Scraping]
    B --> D[Scoring]
    B --> E[Déduplication]
    B --> F[LLM analysis]
    B --> G[Storage]

    G --> H[Interface]
    H --> I[Feedback utilisateur]
    I --> G

Évolution du système

flowchart LR
    P[Prototype\nScrapy local] --> W[Premier workflow\nn8n + enrichissement]
    W --> Q[Qualification IA\nJSON strict]
    Q --> S[Stockage\nSupabase + historique]
    S --> I[Interface SDR\nLists + Teams]
    I --> R[Reporting\nPower BI]
    R --> N[Prochaine étape\nfeedback loop + scoring adaptatif]

FAQ

Qu'est-ce qu'un signal d'affaires en B2B ?

Un signal d'affaires est une information publique ou semi-structurée qui indique qu'une entreprise traverse un moment particulier : recrutement massif, changement de stack, avis clients négatifs récurrents, annonce d'expansion géographique.

Contrairement à une fiche statique d'entreprise, un signal décrit un mouvement, pas un état. C'est ce mouvement qui rend une prise de contact commerciale mieux timée.

Quelles sources utiliser pour détecter des signaux d'affaires ?

Dans ma pratique, la détection de technologies web (Scrapy) et les offres WTTJ via Algolia ont le meilleur ratio signal/bruit. LinkedIn génère beaucoup de bruit mais reste utile pour les annonces d'expansion combinées avec d'autres sources. Trustpilot est intéressant pour les signaux concurrentiels.

La clé : un signal confirmé par plusieurs sources est beaucoup plus fiable qu'un signal isolé.

Faut-il vraiment de l'IA pour détecter des signaux d'affaires ?

Non, pas forcément. Les règles simples suffisent pour beaucoup de signaux : plus de 15 offres WTTJ récentes dans deux pays différents est un signal d'expansion lisible sans LLM.

L'IA devient utile quand le contexte devient ambigu ou narratif : résumer des posts LinkedIn, qualifier si un changement de stack est pertinent selon l'offre, ou identifier un angle dans un ensemble de signaux hétérogènes.

Comment éviter les faux positifs dans un système RevOps ?

Trois mécanismes m'ont le plus aidé :

  1. Déduplication par hash — évite qu'une offre republiée génère un nouveau signal.
  2. Croisement de sources — exiger plusieurs sources concordantes avant de scorer fort.
  3. JSON strict dans les prompts — forcer une sortie structurée plutôt qu'une interprétation libre.

Et surtout : garder l'humain dans la boucle. Le système prépare, l'humain valide.

Quel modèle IA pour qualifier des signaux d'affaires ?

Pour des tâches de classification, extraction structurée et résumé, gpt-4o-mini via OpenRouter offre un bon rapport coût/qualité. La qualité de sortie dépend surtout du prompt et de la qualité du contexte envoyé, pas uniquement du modèle. Un contexte bien structuré avec un prompt cadré produit des résultats plus stables qu'un contexte bruité envoyé à un modèle plus puissant.

Comment rendre le système utilisable par une équipe commerciale ?

L'adoption dépend surtout de la clarté de la sortie. Si le commercial comprend pourquoi une entreprise apparaît dans sa liste — avec la source, le contexte et une piste d'action — le système devient utile. Si la sortie est une liste de scores inexpliqués, elle sera ignorée.

Dans mon projet SDR, Microsoft Lists avec des statuts simples et des notifications Teams a mieux fonctionné qu'une interface sur-engineerée.


Conclusion : ce que ce projet raconte vraiment

Avec le recul, je n'ai pas seulement construit des workflows de scraping ou de prospection.

J'ai exploré une question assez simple :

Comment aider une équipe commerciale à mieux comprendre le bon moment pour agir ?

La réponse n'est pas uniquement technique. Elle passe par de la donnée, du scraping, de l'IA, de l'orchestration. Mais elle passe surtout par une discipline : ne pas confondre information, signal et décision.

Une information est quelque chose que l'on collecte. Un signal est une information qui suggère un mouvement. Une décision reste un acte humain, contextualisé, parfois prudent.

C'est pour ça que je trouve le sujet intéressant. Il oblige à construire des systèmes concrets, imparfaits, mais utiles. Des systèmes qui ne remplacent pas le travail commercial, mais qui peuvent le rendre moins répétitif, plus contextualisé et plus intelligent.

Il reste beaucoup de choses à améliorer : scoring adaptatif, feedback loop, meilleure historisation, interface dédiée, tests métier, monitoring des sources, mesure réelle de l'impact commercial.

Mais la direction me semble bonne : partir des traces publiques, les structurer, les croiser, les qualifier, les rendre actionnables, puis laisser l'humain décider. C'est probablement là que l'IA est la plus intéressante dans un contexte RevOps — pas comme une couche magique au-dessus du commercial, mais comme un moteur discret de préparation, de synthèse et de contexte.


À lire ensuite

  • Scraping & détection technique

    Construire un moteur de détection de technologies web avec Scrapy.

    Lire

  • Prospection semi-automatisée

    Construire une machine à leads SDR avec enrichissement, scoring et suivi opérationnel.

    Lire

  • Veille concurrentielle

    Croiser Trustpilot, LinkedIn et le web pour détecter des mouvements concurrents.

    Lire

  • Signaux d'expansion

    Utiliser WTTJ, LinkedIn, Algolia et n8n pour détecter des indices de croissance.

    Lire