Projets
EN FR
Étude de cas · loicsans.me (independent project) · 2026 · 10 min de lecture

Il lit chaque mot de ce site, et il refuse toujours de vous dire de m'embaucher.

Un assistant conversationnel ancré dans les études de cas et le journal de ce site, en français et en anglais. Pas d'étape de recherche, tout le corpus entre dans le contexte à chaque question. Il dit quand il ne sait pas, et il refuse la seule question à laquelle il aurait le plus intérêt à répondre. En ligne sur loicsans.me/ask.

Posez-lui une question
Client
loicsans.me (independent project)
Rôle
Designer et développeur (solo)
Année
2026
Disciplines
AI ProductConversational UXPrivacy by DesignFront-end EngineeringR&D0→1 Product
It reads every word of this site, and it still won't tell you to hire me.

La question à laquelle un portfolio ne répond jamais

Un recruteur avec six minutes et onze onglets ouverts a une seule question, et ce n'est jamais "racontez-moi votre processus". C'est "a-t-il fait de la fintech", ou "sait-il livrer ou seulement dessiner", ou "est-il libre en mars". Un portfolio les oblige à lire six études de cas pour le savoir. La plupart ne le font pas. Ils en parcourent deux, devinent, et ferment l'onglet. J'ai donc construit ce qui répond directement : un assistant qui a lu chaque mot de ce site et qui en parle, dans l'une ou l'autre langue. Puis j'ai passé l'essentiel du projet à décider ce qu'il devait refuser de faire.

La contrainte que personne n'a imposée

Pas de client, pas de budget, pas de comité. C'est là le piège, pas la liberté. Un assistant de portfolio qui ne rend de comptes à personne devient un vendeur, et un vendeur sur son propre site vaut moins que rien, parce que chaque visiteur sait qui a écrit les instructions. J'ai donc posé la contrainte moi-même, et je l'ai rendue structurelle plutôt que déclarative. L'assistant peut décrire ce que dit le site. Il peut dire qu'il ne sait pas. Il ne peut pas vous dire quoi conclure à mon sujet.

Ancrer, pas convaincre

Le mode d'échec ici n'est pas de se tromper. C'est d'être fluide, plausible et invérifiable sur la carrière de quelqu'un, au seul endroit où le visiteur n'a aucun moyen de vérifier. Le problème de conception n'a donc jamais été "bien répondre aux questions". C'était comment construire une chose qui reste attachée à une source, qui reconnaît la limite de ce qu'elle sait, et qui décline la question à laquelle elle a tout intérêt à répondre.

Le pipeline amélioré par l'IA

Quatre étapes. Un principe : la sortie du modèle est une entrée non fiable, d'un bout à l'autre.

ÉTAPE 01

Décider ce qu'il refuse

Le problème
Un assistant sur un portfolio a une incitation évidente : vendre. Demandez à n'importe quel modèle compétent si son auteur convient à votre poste et il produira un oui fluide. Ce sera convaincant, et sans valeur, parce que c'est mon site et mes instructions.
La méthode
Rédigé les refus avant les capacités. Trois. Il ne prédira pas comment je me comporterais dans un contexte qu'il ne connaît pas. Il ne présentera pas sa propre déduction comme une affirmation de ma part. Il ne comblera pas un trou par une supposition plausible, il nomme le trou et renvoie vers mon e-mail. Les instructions ont ensuite été construites autour, avec une suite de sondes qui teste chacun contre l'endpoint en production.
L'IA gère
Rédiger des propositions d'instructions, et générer des questions adverses conçues pour lui soutirer une réponse commerciale.
Je maîtrise
La décision que refuser de vendre est la fonctionnalité, pas une limite dont il faudrait s'excuser. Un portfolio qui vous dit quoi penser de son auteur ne vous a rien dit. La crédibilité vient de ce que l'assistant accepte de dire que le site ne traite pas ce point.
Le résultat
Demandez-lui si je conviens à votre poste et il décline, décrit ce que j'ai réellement fait, et vous donne mon e-mail. C'est une réponse qu'un recruteur peut utiliser.
ÉTAPE 02

Tout le site dedans, pas de recherche

Le problème
Le réflexe pour "discuter avec mes documents" est la recherche vectorielle : découper le corpus, l'indexer, extraire les trois passages les plus proches, répondre à partir d'eux. C'est le défaut parce que c'est ce qu'on fait quand le corpus dépasse la fenêtre de contexte. Personne ne vérifie si le sien la dépasse.
La méthode
Mesuré d'abord. Chaque étude de cas, chaque article, chaque page, plus un fichier de faits tenu à la main, dans les deux langues, faisaient 66 443 tokens. Cela tient largement. Tout le site entre donc dans les instructions à chaque question, mis en cache entre les tours pour que la deuxième question coûte une fraction de la première.
L'IA gère
Construire l'extracteur de corpus à travers trois conventions bilingues différentes dans les fichiers de contenu, et l'outillage de comptage de tokens.
Je maîtrise
Le jugement que la recherche vectorielle était le mauvais outil à cette taille. Elle répond à partir des passages qu'elle a choisis, et c'est ainsi qu'une réponse assurée se construit sur la mauvaise page. À 66k tokens, cette étape achète une économie et coûte de la justesse. En dessous d'un certain seuil, l'architecture sophistiquée est la moins bonne.
Le résultat
Aucun fragment n'est jamais manqué, parce qu'il n'y a pas de découpage. Une question qui traverse quatre études de cas trouve réponse aussi facilement qu'une question sur un seul projet.
ÉTAPE 03

Traiter la sortie comme non fiable

Le problème
Le modèle renvoie du markdown. L'afficher revient à transformer un texte produit par un modèle de langage en HTML dans le navigateur d'un visiteur, ce qui est une surface d'injection, qu'on le voie ainsi ou non.
La méthode
Écrit un analyseur qui reconnaît exactement deux choses, les liens internes et le gras, et échappe tout le reste. Puis écrit les tests qui tentent de le contourner avant d'en croire une ligne.
L'IA gère
Le premier jet de l'analyseur et les premiers cas de test.
Je maîtrise
Décider que la liste blanche tenait en deux constructions plutôt qu'une bibliothèque markdown. Un analyseur qui gère les images, le HTML brut et des protocoles arbitraires est une surface plus large que ce que cette fonctionnalité demande, et chaque construction non prise en charge est une classe de bug que je n'ai pas eu à examiner.
Le résultat
Les réponses s'affichent dans la typographie du site au lieu d'astérisques bruts, et le chemin de rendu porte un test qui cherche spécifiquement à en sortir.
Note honnête
La première version du motif de lien autorisait les URL relatives au protocole. Un modèle amené à émettre un lien commençant par deux barres obliques aurait produit un lien externe fonctionnel sur mon propre domaine. C'est le test qui l'a attrapé, pas ma relecture du code.
ÉTAPE 04

Assez peu cher pour rester allumé

Le problème
Mettre tout le site dans le contexte à chaque question est la bonne architecture, et la chère. La première version tournait sur le plus gros modèle disponible, à environ 0,54 $ la conversation. Un après-midi de tests a coûté 5 $. À ce prix, on l'éteint discrètement.
La méthode
Deux changements, mesurés plutôt que devinés. Passage à un modèle intermédiaire après avoir confirmé que la qualité tenait sur le jeu de sondes. Et découverte d'un vrai défaut : le découpeur de corpus ne traitait les clés bilingues qu'au premier niveau, si bien que le texte français imbriqué fuyait dans le corpus anglais et réciproquement. Le corriger a fait passer le corpus de 86 762 tokens à 66 443.
L'IA gère
Faire le calcul de coût entre les paliers de modèles et les tarifs de lecture et d'écriture de cache, et construire la sonde de comptage.
Je maîtrise
La décision de mesurer avant d'optimiser. Le compte exact venait de l'endpoint de comptage de l'API, gratuit et précis. L'estimation que je lisais dans le log de build était 25 pour cent trop basse, le genre d'erreur qui vous envoie optimiser la mauvaise chose.
Le résultat
0,25 $ la conversation, contre 0,54 $, et 77 284 tokens aujourd'hui. Un plafond ferme de 20 conversations par jour sur tout le site borne une mauvaise journée à environ 6 $.
Note honnête
Puis la rédaction de cette étude de cas l'a fait remonter. Le corpus est dans le corpus, donc ces 8 104 tokens sont facturés à chaque question posée, et une conversation à froid coûte désormais 0,29 $ au lieu de 0,25 $. Apprendre au constructeur à lire la page /ask, que l'assistant n'avait jamais pu voir, en a ajouté 979. Les deux en valent la peine. Aucun des deux n'était gratuit, et c'est précisément le genre de dérive qu'un système cesse de signaler dès qu'on cesse de le mesurer.

L'adresse qui n'existait pas

loicsans.me · Site Assistant · 2026

En le testant un après-midi, j'ai demandé comment le contacter. Il m'a donné une adresse e-mail chez loicsans.me. Cette adresse n'a jamais existé. Mon e-mail est chez loicsans.com, et rien dans le corpus ne disait le contraire. Le modèle avait vu le domaine sur lequel il tournait, vu une section contact, et produit l'adresse qui aurait dû être vraie. C'est l'échec qui compte dans un système ancré, et ce n'est pas celui qu'on anticipe. Ce n'est pas une invention qu'on attrape en lisant, parce que ce n'est faux d'aucune manière qu'un lecteur remarquerait. C'est de la bonne forme. Un visiteur écrit, le message revient en erreur, et la dernière chose qu'a faite mon portfolio est de lui avoir fait perdre son temps. Le correctif a pris deux lignes : fixer l'adresse dans les instructions, et ajouter une sonde qui la demande à chaque test. La leçon a pris plus longtemps. Ancrer un modèle dans un corpus ne l'empêche pas de combler les trous, cela déplace seulement les trous. Chaque fait qu'un système ne peut pas se permettre de voir inventé doit être énoncé plutôt que déduit, puis testé à chaque exécution.

Là où l'IA s'arrête et le jugement commence

Trois endroits où le modèle n'a servi à rien, et un où il a activement induit en erreur. Il ne pouvait pas me dire quoi refuser. Chargé de rédiger les refus, il a produit des formules prudentes qui ne s'engageaient à rien. Il ne pouvait pas juger ses propres réponses. J'ai écrit la suite de tests trois fois. Les deux premières versions vérifiaient la formulation et faisaient échouer des refus corrects parce qu'ils employaient d'autres mots. Un test qui contrôle le vocabulaire au lieu du comportement est pire que pas de test : il fait échouer les bonnes exécutions et passer les mauvaises. La version finale vérifie la propriété, et j'ai validé le prédicat hors ligne contre trois vrais refus et trois réponses fabriquées avant de dépenser un appel d'API de plus. Et il s'est trompé avec assurance sur sa propre adresse de contact, ce qui est l'histoire ci-dessus.

Ce que ça a livré

En ligne, et il dit non

Il tourne sur loicsans.me/ask dans les deux langues. Demandez-lui si je conviens à votre poste et il décline, décrit ce que j'ai réellement fait, et vous donne mon e-mail. Ce refus est la partie que je défendrais le plus fermement.

Coût divisé par deux, avec un bug derrière

De 0,54 $ à 0,25 $ par conversation, via un changement de modèle et un découpeur de corpus qui dupliquait silencieusement le texte français dans le corpus anglais. 86 762 tokens sont devenus 66 443. L'économie est réelle, et la moitié venait d'un défaut plutôt que d'une optimisation. Ajouter cette étude de cas l'a depuis porté à 77 284, parce que le corpus contient le corpus.

Une promesse de confidentialité que le code applique

La question et la date, rien d'autre. Aucune adresse, aucun hash, aucun identifiant de session, aucun moyen de regrouper les questions d'une même personne. Supprimées à 90 jours par un nettoyage dont le motif de clé est écrit assez strictement pour ne pas pouvoir atteindre les compteurs de limitation. La page /ask le dit en clair au lieu de l'enfouir.

56 tests, y compris ceux qui font mal

Le rendu est testé contre un lien qui tente de quitter le domaine. Les instructions sont sondées sur l'adresse qu'elles ont un jour inventée. Le découpeur de corpus a un test pour le bug d'imbrication qui est passé en production.

Journal des décisions

Les décisions qui comptaient, et ce qui a changé mon avis. Les revirements restent au dossier, ce sont eux qui ont quelque chose à apprendre.

01
Mettre tout le site dans le contexte à chaque question

Au lieu de : Recherche vectorielle sur un corpus découpé et indexé

À 66k tokens, le corpus entier tient. La recherche répondrait à partir des trois passages qu'elle a extraits, ce qui est précisément comment des réponses assurées se construisent sur la mauvaise page.

02
Refuser d'évaluer si je conviens à un poste

Au lieu de : Y répondre de façon convaincante, c'est un portfolio après tout

Un assistant qui recommande son propre auteur n'a rien dit au visiteur qui soit digne de confiance. Le refus est ce qui rend le reste crédible.

03
Enregistrer la question et la date, rien d'autre

Au lieu de : Un identifiant de session, pour lire les conversations en fils

Je voulais savoir ce que le site n'explique pas. Cela demande la question, pas la personne. Un identifiant de fil aurait rendu chaque ligne traçable en échange d'un bénéfice dont je n'avais pas besoin.

04
Passer du modèle de pointe au modèle intermédiaire Inversé

Au lieu de : Rester sur le plus gros modèle pour la qualité des réponses

0,54 $ par conversation, c'est un interrupteur qu'on finit par couper. La qualité tenait sur le jeu de sondes, donc le supplément n'achetait rien de mesurable.

05
Plafonner tout le site à 20 conversations par jour

Au lieu de : Une limite par visiteur généreuse et rien de global

Chaque conversation à froid paie la mise en cache du corpus. Un plafond par visiteur borne un abuseur, un plafond global borne la facture.

06
Vérifier le comportement, pas la formulation, dans les tests Inversé

Au lieu de : Comparer à la formulation attendue d'une bonne réponse

Deux versions ont fait échouer des refus corrects parce qu'ils employaient d'autres mots. Un test qui contrôle le vocabulaire fait échouer les bonnes exécutions et passer les mauvaises.

Le guide réutilisable

01
Concevoir les refus d'abord

Ce qu'un système ne fera pas est une décision produit, pas une considération de sécurité ajoutée après coup. Écrivez les refus avant les capacités et le reste de la conception s'organise autour d'eux. Sur un portfolio, le refus, c'est la crédibilité.

02
Mesurer avant d'architecturer

La recherche vectorielle est la réponse réflexe à "discuter avec mes documents" parce que la plupart des corpus n'entrent pas dans le contexte. Comptez le vôtre avant de supposer qu'il n'y entre pas. L'architecture sophistiquée est parfois la moins bonne, et la mesure est le seul moyen de le découvrir.

03
La sortie du modèle est une entrée non fiable

Un texte produit par un modèle et affiché dans un navigateur est une surface d'injection, au même titre qu'un texte tapé par un inconnu. Analysez-le, échappez-le, et écrivez le test qui tente d'en sortir. Mon premier motif de lien autorisait les URL relatives au protocole. C'est le test qui l'a attrapé, pas ma relecture du code.

04
Fixer chaque fait qu'on ne peut pas laisser inventer

L'ancrage réduit les endroits où un modèle comble les trous, il ne l'en empêche pas. L'invention dangereuse n'est jamais l'absurde, c'est la plausible, taillée exactement comme la vérité. Nommez ces faits explicitement et testez-les à chaque exécution.

Toutes les autres études de cas ici portent sur la conception de quelque chose pour quelqu'un d'autre. Celle-ci applique la même discipline à mon propre site : un vrai choix d'architecture, un coût que j'ai dû justifier, une promesse de confidentialité écrite dans le code plutôt que dans un paragraphe, et un bug qu'un test a attrapé avant un visiteur. Il tourne en ce moment, en bas à droite de cette page. Posez-lui une question à laquelle il ne peut pas répondre. Il est plutôt bon pour l'admettre.

Interroger les archives

Fondé sur les études de cas et le journal de ce site. Il dit quand il ne sait pas. Les questions sont enregistrées pour que Loïc voie ce que le site n’explique pas. Rien d’autre n’est conservé.

À propos de cet assistant ↗