Si tu as compris, c'est qu'on t'a mal expliqué
Pièce 1 — le robot se présente sous son vrai nom
Un robot qui se déguise en navigateur finit bloqué, et il le mérite. Le nôtre annonce qui il est et où l'on peut se renseigner. Une seule ligne, envoyée à chaque site visité :
code-nomi-nomi-veille/1.0 (+https://matourdecontrole.fr ; robot de veille)Un nom, une adresse pour se renseigner. Rien d'autre. Pas d'e-mail criée à tous les sites, pas de faux « Mozilla ».
Pas d'adresse e-mail criée à tous les sites, pas de faux « Mozilla ». Un robot identifié est accepté ; un robot masqué est banni. C'est aussi simple que ça.
Pièce 2 — le portier de sujet
Le titre d'un article est gratuit : on l'a déjà après avoir lu le fil de nouvelles. On décide donc avant d'aller chercher le texte complet. Deux listes de mots à l'intérieur, et une règle.
La règle tient en une phrase : on garde un titre qui touche un sujet suivi, on jette celui qui n'en touche aucun, et on écrit toujours le motif de la décision dans le carnet. Les listes de mots, elles, restent à l'intérieur : les publier reviendrait à donner le mode d'emploi pour fabriquer un titre qui trompe le tri.
Le détail qui compte : la décision rend toujours un motif. Jamais de rejet muet. Le carnet du robot garde la trace : « IGNORE — aucun sujet qui intéresse dans le titre — TITRE: … ». On peut donc contester une décision, et corriger la liste.
Pièce 3 — la file d'attente qui n'oublie pas
Un site qui répond mal une fois répondra peut-être bien demain. La première version rayait l'article raté : il ne repartait jamais. C'était marquer un colis perdu comme livré. Maintenant, un échec est une fiche : trois tentatives, puis « abandonné », et cet abandon est écrit noir sur blanc dans le carnet.
Pièce 4 — la page privée
Le résultat vit dans une page interne. En Odoo, la porte tient en un mot dans la déclaration de l'adresse :
@http.route("/tour/cockpit/veille", type="http", auth="user")
def page(self, **kw):
...
auth="user" veut dire : personne d'autre qu'un utilisateur
connecté. Mieux : notre tour ne dit pas « connecte-toi », elle répond
« cette page n'existe pas ». Un inconnu n'apprend même pas que la page
existe. Le contrôle qui le prouve compare avec une page déjà en
service : les deux doivent répondre pareil.
Pièce 5 — la page se laisse lire par un agent
C'est la partie neuve. Depuis 2026, un navigateur permet à une page de poser ses fonctions sur la table, sous forme d'outils nommés. L'agent ne devine plus où cliquer : il demande.
modelContext.registerTool({
name: "nouvelles_ia",
description: "Renvoie les articles retenus par le robot de veille…",
inputSchema: {
type: "object",
properties: {
sujet: { type: "string" },
source: { type: "string" },
combien: { type: "integer" },
},
},
execute: async ({ sujet, source, combien }) => ({ … }),
});
Trois choses le rendent utile. Chaque article rendu porte son adresse, donc l'agent peut vérifier. Un mot introuvable rend une liste vide — jamais une réponse bricolée. Et la logique est pure : elle travaille sur une liste passée en paramètre, sans toucher au disque ni à l'écran, donc elle se teste hors du navigateur.
Le piège qui a coûté une demi-heure
Après la mise en ligne, la page marchait une fois sur huit. Le fichier d'habillage répondait « connais pas », puis « le voilà », sans logique apparente. La cause : le serveur fait tourner quatre ouvriers, quatre copies qui se partagent les visiteurs. Chacun garde en mémoire la liste des fichiers connus au démarrage. Un module posé après coup n'existe que pour ceux qui ont rechargé.
Le diagnostic ne vient pas d'une intuition : on a demandé le même fichier huit fois de suite. Sept refus, une réussite. Un chiffre tranche là où un avis hésite.