La situation
Une entreprise de génération de leads qui vendait aux États-Unis, avec un produit qui devait faire trois choses à la fois : capter et qualifier des leads, décider ce que valait chacun d'eux et router des appels entre acheteurs et vendeurs en temps réel. Quand je suis arrivée, il n'y avait pas d'équipe d'ingénierie. Il y avait moi.
La qualité des leads était notée par une API tierce facturée à l'appel. Elle fonctionnait, au sens où elle renvoyait un nombre. Elle ne pouvait pas être ajustée, sa latence était le problème de quelqu'un d'autre, son prix était la décision de quelqu'un d'autre, et ses cas limites liés à la législation américaine sur le télémarketing étaient l'interprétation de quelqu'un d'autre.
Le modèle de scoring
Je l'ai remplacée par un modèle maison : conçu, étiqueté, entraîné, servi et évalué en interne, avec le pipeline de features qui l'alimentait.
Les entrées étaient la partie intéressante - device intelligence, type de ligne et consultations d'opérateur, données de réputation, événements comportementaux pendant le remplissage même du formulaire, et métadonnées de consentement. Qu'un numéro soit un mobile chez un grand opérateur, et que la personne ait rempli le formulaire en onze secondes ou en quatre-vingt-dix, en dit plus sur la valeur du lead que presque tout ce que les gens mettent dans les champs démographiques.
L'internaliser a apporté quatre choses que le fournisseur ne pouvait pas vendre : le contrôle de la latence, un coût par lead qui baissait avec le volume au lieu de monter, notre propre lecture des cas limites de conformité et - le plus important - la possibilité de décider comment le niveau de confiance devait piloter le routage et la tarification. Un score que vous ne pouvez pas interroger est un score sur lequel vous n'oserez jamais vraiment agir.
Le reste du produit
Un backend Django qui exposait à la fois REST et GraphQL, sur PostgreSQL pour les données transactionnelles et ClickHouse pour l'analytique de gros volume et la télémétrie de scoring - deux bases de données parce qu'un même type de requête ne convient pas aux deux, et c'est en prétendant le contraire que l'analytique finit par ralentir ce qui rapporte l'argent.
Le back-office d'administration exposait des API JWT qui introspectaient les métadonnées de l'admin de Django lui-même, si bien qu'ajouter un modèle l'exposait automatiquement aux clients mobiles. Cela faisait gagner une semaine à chaque fois et, plus précieux encore, supprimait une classe de bugs où l'application mobile et l'admin web n'étaient pas d'accord sur la forme d'un enregistrement.
Infrastructure d'appels de bout en bout : plusieurs plateformes de dialer et d'opérateurs pour les appels sortants et entrants, des services de routage, une couche de distribution entre acheteurs et vendeurs, et un backend maison qui orchestrait le flux en direct, de la numérotation jusqu'au transfert, à l'enregistrement et à la qualification de l'appel. Agents vocaux sur les appels sortants. Filtrage continu selon les listes d'opposition (do-not-call) et les règles de consentement au télémarketing, intégré à l'acceptation du lead et non ajouté après coup, parce qu'une vérification de conformité qui tourne après que vous avez déjà appelé est un constat de l'infraction, pas un contrôle.
Puis les parties que personne ne compte : un CMS maison, trois applications Flutter pour iOS et Android couvrant le B2B, le B2C et l'admin, et l'infrastructure de production - Ubuntu durci, Nginx, Docker, des mises en production sans coupure, DNS chez deux fournisseurs, certificats, pare-feu et bannissement des intrusions.
Ce que ça fait d'être la seule ingénieure
Clarifiant, surtout. Il n'y a personne avec qui négocier une interface et aucun endroit où un malentendu puisse se cacher. Mais cela plafonne sérieusement ce qui peut avancer en parallèle, et cela fait de la documentation un acte d'autodéfense plutôt qu'une politesse - la personne qui ne se souviendra pas pourquoi cette file a un délai de deux secondes, c'est moi, en mars.
Ce que je ferais autrement
J'aurais construit l'évaluation et la surveillance du modèle le même jour que le modèle, et pas après sa mise en production. Il fonctionnait bien, et je le savais grâce à l'évaluation hors ligne - mais pendant les premières semaines, je n'aurais pas pu démontrer rapidement qu'il fonctionnait toujours aussi bien en production. Cet angle mort est inconfortable, et il était évitable.