Travaux sélectionnés
Systèmes en production
Six chantiers issus de ma mission actuelle comme Head of AI chez Crème de la Crème, l'une des plus grandes marketplaces freelance de France. Pour chacun : le problème, l'architecture, le résultat mesuré, et l'arbitrage que j'ai dû rendre.
Les six ont été construits dans la même entreprise : une marketplace où des milliers de freelances rencontrent les entreprises qui les cherchent, et où une équipe Sales doit faire ce rapprochement vite, juste, et sans voir des données qu'elle n'a pas à voir. C'est cette contrainte qui a façonné chacun des systèmes ci-dessous.
Je porte l'architecture et j'écris ces systèmes front et back, en menant le build avec des agents de code et en corrigeant ce qu'ils produisent ; ce qui part en production est relu par l'équipe engineering côté client. Le code appartient au client et les dépôts sont privés : l'architecture et les résultats mesurés se présentent de vive voix plutôt qu'en lien.
Ouvrir le back-office d’une entreprise au langage naturel
N’importe qui dans l’entreprise demande une chose en langage courant et elle est faite, sans traverser cinq écrans, et sans jamais voir une ligne à laquelle il n’a pas droit.
REQUÊTE
01 PERSONA
Accès au serveur par persona
02 TOOLS
Allowlist d’outils
03 LIGNES
Périmètre ligne à ligne
PAYLOAD
Projeté champ par champ. Le reste n’est jamais envoyé.
Le problème
Tout back-office mature exprime une partie de ses permissions par l’interface : ce qu’on peut faire, c’est en grande partie ce qu’on nous montre. Un serveur MCP n’a pas d’interface, donc pas de bouton à masquer. L’exposer suppose que chaque droit que l’application transmet par ce qu’elle affiche soit réénoncé comme une règle explicite, côté serveur, avant qu’un seul outil ne sorte, et que chacune de ces règles soit vérifiée dans le code plutôt que supposée.
Ce que ça débloque
- Les Sales, et à terme tout le monde, demandent en une phrase ce qui demandait un parcours de plusieurs écrans, et l’action est exécutée.
- Des tâches trop petites ou trop fastidieuses pour valoir la peine d’être déléguées peuvent aller à un agent, parce que l’agent hérite des droits de la personne qui demande et non de ceux d’un compte de service.
- Des briefs personnalisés assemblés depuis les données vivantes, au lieu d’être recopiés à la main avant un rendez-vous client.
- La même question posée par deux personnes renvoie deux réponses différentes, et aucune des deux n’apprend ce que l’autre peut voir.
Architecture
- Trois couches d’autorisation, toutes vérifiées côté serveur : qui peut atteindre le serveur, quels outils il peut appeler, quelles lignes il peut voir.
- Des personas dérivés des rôles existants, chaque périmètre étant calculé à partir des données plutôt que recopié d’une liste tenue à la main.
- Les outils sensibles s’adossent aux contrôles de permission que l’application évalue déjà côté serveur, plutôt qu’à une liste de rôles recopiée dans le serveur : la règle reste vraie par construction quand le back-office évolue, et un accès nominatif est couvert sans déploiement.
- Projection du payload champ par champ : aucun objet métier n’est renvoyé brut, donc un champ qui n’avait pas vocation à sortir ne peut pas sortir par accident.
- Double confirmation sur tout ce qu’un client finira par voir, une garde de confidentialité déterministe tenue hors du chemin d’écriture du modèle, et un audit trail requêtable à conservation bornée.
- OAuth 2.1 + PKCE sur Streamable HTTP, 49 outils, PostgreSQL.
L'arbitrage
L’essentiel du travail n’était pas l’API. C’était de répondre explicitement aux questions de sécurité que l’interface porte implicitement : comment on donne l’accès, ce qu’un salarié qui part perd et à quel moment, ce qui se passe la première fois qu’on demande à un outil une action irréversible. Quand un accès client OAuth manquant a bloqué la campagne d’intégration, j’ai écrit un script qui passe par la vraie boucle d’autorisation plutôt que d’ajouter un contournement au serveur. Ça a coûté deux jours, et c’est pour ça que le périmètre veut encore dire quelque chose.
Stack
Recherche hybride, scoring et jugement LLM borné
Un moteur de matching qui devait battre celui déjà en production, brief par brief, avant d’avoir le droit d’être livré.
BM25 · COMPÉTENCES · kNN · EXP
Quatre signaux de rappel
RRF
Reciprocal Rank Fusion
SCORING
Déterministe, sept dimensions, aucun modèle dans la boucle
JUGE
Un appel LLM par candidat, borné et parallélisé
SHORTLIST
Validée par un harnais d’eval contre la baseline de prod
Le problème
Un commercial répond à un brief client en trouvant les bons freelances, vite. Une recherche de marketplace qui classe sur le recouvrement de mots-clés rend une liste plate : à peu près la même forme de réponse quel que soit le brief, des profils forts enfouis sous la ligne de flottaison, et la géographie traitée comme un mot-clé de plus. Le mode de défaillance n’est pas le résultat vide, c’est qu’on ne peut plus distinguer un vrai match d’un profil de remplissage.
Ce que ça débloque
- Un brief qui imposait une recherche manuelle rend maintenant une shortlist qu’un commercial peut défendre devant un client.
- Le moteur rend ce qui correspond puis s’arrête, au lieu de compléter chaque brief jusqu’au même nombre fixe de profils.
- Sur le golden dataset, la version livrée ne rate aucun match attendu.
- Déployé auprès des Sales avant l’ouverture générale.
Architecture
- Rappel à quatre signaux (BM25, recouvrement de compétences, kNN vectoriel sur embeddings OpenAI stockés dans PostgreSQL/pgvector, et un index d’expériences), fusionnés par Reciprocal Rank Fusion.
- Scoring déterministe pondéré sur sept dimensions : reproductible, sans modèle dans la boucle.
- Une couche de LLM-as-a-judge bornée : un appel par candidat, plafonné et parallélisé, pour que le coût et la latence par brief restent plats quelle que soit la taille du vivier.
- Un harnais d’éval sur un golden dataset de briefs annotés, chacun portant un top 5 attendu et les faux positifs à exclure, exécuté contre la baseline de production avant toute décision de livraison.
L'arbitrage
Le harnais d’éval est venu avant le moteur, et le moteur n’a pas eu le droit de sortir tant qu’il ne battait pas l’existant sur le dataset plutôt que sur une démo. Une version tout-déterministe et une version tout-agentique ont été construites puis écartées : la première ne savait pas lire un brief, la seconde n’était pas reproductible deux fois. Conserver le moteur de recherche en place plutôt que le migrer a été évalué puis tranché avec le CTO.
Stack
Décision human-in-the-loop sur les candidatures entrantes
Le modèle tranche les cas nets. Un humain garde les cas ambigus, et c’est précisément ce qui rend l’automatisation acceptable.
ENTRANT
Scoré axe par axe, verdict à trois états
90 À 95 %
Tranché sans humain
LE RESTE
Routé en revue humaine, et reclassable a posteriori
Le problème
Chaque candidature pour rejoindre la marketplace était relue à la main. Ça coûtait au moins une heure par jour à une Product Manager, et tout le flux d’entrée s’arrêtait dès que cette personne n’était pas disponible.
Ce que ça débloque
- 90 à 95 % du flux entrant est tranché sans humain. Seuls quelques dossiers par jour remontent à une personne.
- Environ sept heures par semaine rendues à la Product Manager, et un traitement quasi temps réel au lieu d’un lot quotidien.
- Avant mise en service, le pipeline a été passé sur un échantillon représentatif de cinquante candidatures déjà tranchées par un humain, sans un seul désaccord.
- L’entrée sur la plateforme ne dépend plus de la présence d’une seule personne.
Architecture
- Des verdicts à trois états, scorés sur plusieurs axes indépendants plutôt que rabattus sur un score opaque unique.
- Des sorties structurées validées par schéma, pour qu’une décision malformée n’atteigne jamais le pipeline.
- Un pré-filtre d’admissibilité, et un routage par règles de toute anomalie ou tout doute vers un humain, qui peut aussi reclasser un dossier a posteriori.
- Le schéma est le contrat, pas le modèle. Le pipeline a traversé des générations de modèles sans changer ni le format de décision ni le flux de revue.
L'arbitrage
Trier vaut mieux qu’automatiser à 100 %. Garder un humain sur les cas durs est ce qui rend l’automatisation acceptable sur une décision aussi sensible que l’accès à la plateforme, et c’est ce qui a permis à la chose de sortir tout court.
Stack
Accès en langage naturel à une base de production, sous gouvernance
Une équipe non technique qui pose ses questions à la base de production en langage courant, en lecture seule par choix de gouvernance et non par limite technique.
QUESTION EN CLAIR
Posée par une équipe non technique
GARDE-FOUS CÂBLÉS
Consentement, exclusions, gestion des devises et LIMIT par défaut, appliqués par le template plutôt que mémorisés
HUMAIN · LECTURE SEULE
L’agent génère le SQL. Un humain le relit et l’exécute.
Le problème
Chaque extraction de données passait par une seule personne, et prenait de trente minutes à plusieurs heures. Et un schéma de production qui compte bien plus de tables que ce qu’on garde en tête ne se tend pas à un modèle en espérant que ça passe.
Ce que ça débloque
- Des extractions qui prenaient de trente minutes à plusieurs heures se font en quelques secondes, en self-service.
- Un commercial a traité une demande de cinq extractions et treize entités en une seule passe.
- Des règles métier qu’il fallait mémoriser sont désormais appliquées par le template de requête plutôt que par la mémoire de chacun.
- Le goulot d’étranglement est sorti de la boucle sur les questions de routine, et y reste sur celles qui comptent.
Architecture
- Un serveur MCP base de données avec découverte de schéma, plus une skill packagée qui porte le contexte métier que le schéma ne porte pas.
- Un schéma de référence documenté sur les tables qui comptent vraiment, un glossaire métier relié aux bonnes formules, et les pièges de jointure rendus explicites.
- Des règles métier câblées dans des templates de requête obligatoires plutôt que laissées à la mémoire de chacun : consentement, exclusions, gestion des devises, LIMIT par défaut, secrets jamais exposés.
L'arbitrage
À l’origine, l’agent exécutait et exportait seul. Faute d’un environnement sûr où exécuter, je l’ai restreint à générer du SQL qu’un humain relit et exécute. C’est une décision de gouvernance, pas une limite technique. Elle est documentée, et elle a une porte de sortie nommée : un rôle dédié en lecture seule.
Stack
Transformer un outil d’expert en capacité self-service
Acheter l’accès API plutôt que des sièges, et laisser un brief en langage courant écrire la syntaxe que personne n’avait envie d’apprendre.
BRIEF EN CLAIR
Écrit par un commercial, dans ses mots
TEMPLATE DE REQUÊTE
Une grammaire contrainte : le modèle remplit les cases, il n’écrit jamais les opérateurs
RELECTURE
La requête et les critères interprétés sont montrés avant exécution, pour qu’une mauvaise requête se lise comme un mauvais critère
Le problème
Un produit de recherche de talents de niche était enfermé derrière une poignée de licences payantes et une syntaxe booléenne que peu de gens savaient écrire. Tous les autres faisaient la queue derrière eux.
Ce que ça débloque
- Un outil que seule une poignée de détenteurs de licence pouvait utiliser est devenu accessible à toute l’équipe commerciale.
- Plus de 200 utilisations le premier mois.
- Plus besoin d’apprendre la syntaxe booléenne pour obtenir une recherche correcte.
Architecture
- Un module de back-office qui compile un brief en langage courant vers la syntaxe booléenne de l’éditeur : une grammaire contrainte plutôt qu’une génération libre, pour que le modèle remplisse les cases d’un template au lieu d’émettre des opérateurs qu’il peut se tromper.
- Chaque requête générée est montrée au commercial avant exécution, avec les critères interprétés écrits à côté : une mauvaise requête se lit comme un mauvais critère, pas comme une liste de résultats vide sans explication.
- Facturé à l’usage plutôt qu’au siège, ce qui a rendu l’ouverture à toute l’équipe moins chère que l’ajout de licences.
L'arbitrage
Le geste évident était d’acheter des licences. Choisir l’API voulait dire devenir responsable de la justesse des requêtes plutôt que de louer une interface éditeur qui s’en chargeait déjà, d’où la grammaire contrainte et la relecture humaine sur chaque requête. L’argument coût rendait la décision facile à défendre ; ce qui la rendait juste, c’est qu’une licence débloque une personne de plus et que l’API a débloqué l’équipe.
Stack
Packager le savoir-faire pour qu’il cesse de passer par une seule personne
Des composants modulaires et recombinables qui ont sorti des capacités de mes mains, et deux chantiers que j’ai arrêtés quand l’éditeur a rattrapé.
UN DÉPÔT
Des skills modulaires et recombinables tenues au même endroit
SYNCHRONISÉ
Une nouvelle skill est un fichier, plus un projet
L’ÉQUIPE
Des capacités qui passaient par moi tournent maintenant sans moi
ARRÊTÉS
Deux chantiers plus anciens stoppés une fois que l’éditeur a sorti l’équivalent
Le problème
Le savoir-faire qui marchait restait chez ceux qui l’avaient : préparation de compte, préparation de rendez-vous, qualification d’appels d’offres, onboarding, support. Pendant ce temps, certains chantiers précoces se faisaient discrètement rattraper par une roadmap éditeur.
Ce que ça débloque
- Des capacités qui passaient par moi tournent maintenant sans moi, seul test qui compte pour de l’outillage interne.
- Une nouvelle skill est un fichier dans un dépôt, plus un projet.
- Deux systèmes précoces arrêtés plutôt que maintenus, une fois que l’éditeur du CRM a sorti une capacité équivalente.
Architecture
- Un marketplace de skills métier modulaires et recombinables, distribuées à l’équipe Sales et tenues à jour depuis un dépôt plutôt que recopiées de main en main.
- Du sourcing et de l’enrichissement externes agentiques au-delà de la base interne, conçus et livrés en trois jours, en remplacement d’un outillage que j’étais seul à savoir manœuvrer.
- Un serveur MCP au-dessus du design system qui a ramené une maquette front alignée à une demi-journée, dans une période sans designer.
L'arbitrage
Construire en interne n’a de sens que si l’éditeur ne comblera pas le manque. J’ai arrêté les deux chantiers les plus anciens quand il l’a comblé. Savoir s’arrêter fait partie du métier, surtout dans une maison dont l’instinct est de construire.