Dans le précédent article, je racontais comment Hermes Agent s’est installé dans mon homelab. La première vraie automatisation que je lui ai confiée, c’est la veille IA. Aujourd’hui, chaque matin, j’ai un article de veille prêt, que je relis avant qu’il parte en ligne. Voici comment c’est monté, dans l’ordre où les besoins sont apparus.

Le besoin de départ

Chaque matin, je faisais ma veille à la main. J’ouvrais Hacker News, Reddit, arXiv, les papiers Hugging Face. Je triais ce qui valait le coup, je notais les liens, puis je rédigeais un billet de synthèse. Trente minutes par jour, une heure les mauvais jours. Et tout ça restait pour moi : je ne publiais rien, aucune de ces lectures n’était partagée.

J’ai donc eu envie d’un pipeline qui fasse tout ça à ma place : collecter, trier, rédiger, préparer la publication. Chaque matin, avec une validation de ma part avant la mise en ligne.

Première étape : la collecte

D’où viennent les sujets ? J’ai listé les sources que je consultais moi-même et je les ai toutes branchées :

  • Hacker News pour les discussions tech et les projets open-source
  • Reddit (r/LocalLLaMA et les subs voisins) via leur flux RSS public
  • arXiv pour les papiers de recherche
  • Hugging Face Daily Papers pour les modèles qui sortent
  • X pour les annonces et les retours d’expérience
  • Des flux RSS pour le reste

Chaque source est un petit module indépendant. Le collecteur les interroge toutes et rassemble les résultats dans un fichier commun. Une quinzaine d’items par source, ce qui fait une centaine de candidats chaque matin. La première fois que j’ai vu ce nombre, j’ai compris que le tri serait le vrai sujet.

Besoin suivant : filtrer le bruit

Une centaine d’items, c’est beaucoup trop pour un billet de veille. J’ai confié le tri à un LLM. Je découpe les items en lots, et pour chaque lot, je demande au modèle de noter chaque item sur 10 avec une justification : intérêt, nouveauté, qualité. Tout ce qui passe sous la barre des 7/10 est écarté, le reste est classé par score.

En pratique, j’ai vite ajouté du post-traitement pour rendre le tri plus juste :

  • La fraîcheur compte. Un item de moins de 24h garde son score. Au-delà, il perd des points. Une veille, c’est censé être récent.
  • Toutes les sources ne se valent pas. Une discussion Hacker News et un post LinkedIn n’ont pas le même poids dans ma veille. J’ai pondéré : Hacker News et arXiv montent, les autres descendent.
  • Pas de doublons. Si un sujet a déjà été couvert dans les sept derniers jours, il est écarté. Les gens ne reviennent pas sur ce qu’ils ont déjà lu.
  • Pas de monotonie. Maximum trois items du même domaine par jour. Sinon, on se retrouve avec quatre articles sur le même modèle et rien d’autre.

Ces règles, je les ai ajoutées une par une, chacune après un matin où la veille m’avait fait râler. C’est le genre de détails qu’on ne voit pas dans le résultat final, mais qui font toute la différence entre un fil d’actualités et une vraie veille.

Résultat : sur une centaine d’items, il en reste cinq à huit, et un classement assez net pour désigner le « top 1 » du billet.

Besoin suivant : rédiger l’article

Les items sont sélectionnés et classés, la rédaction peut démarrer. Le prompt demande au modèle d’écrire un billet de veille en français, avec le top 1 détaillé et le reste de la veille en liste.

C’est l’étape qui m’a donné le plus de fil à retordre. Les modèles qui « réfléchissent » laissent parfois leurs réflexions traîner dans la réponse. J’ai vu des articles publiés avec des bouts de raisonnement noyés dans le texte, du genre « Je dois écrire un billet en français, de 200 à 400 mots ». Ça se voyait comme le nez au milieu de la figure.

La solution a été un nettoyage en plusieurs couches. Le prompt interdit explicitement tout meta-texte. La réponse doit être encapsulée entre des marqueurs, et le script extrait uniquement ce qui se trouve entre eux. En dernier recours, une liste de motifs de raisonnement détecte les lignes suspectes et les retire. J’ai enrichi cette liste à chaque incident, en anglais comme en français, parce que les modèles raisonnent dans les deux langues.

Besoin suivant : garantir la qualité

Une fois l’article rédigé, il ne part pas tout de suite. Il passe par deux contrôles.

Le validateur d’abord. Un script vérifie qu’aucun artefact n’a survécu : marqueurs de raisonnement, meta-commentaires, auto-évaluations. Si quelque chose cloche, un correctif automatique retire les résidus et l’article est amendé avant publication.

L’humanisation ensuite. Le premier jet d’un LLM a une signature reconnaissable : phrases trop parfaites, tics d’écriture, rythme monotone. J’ai donc ajouté une étape qui note l’article sur cinq critères de naturalité, de 1 à 10 : la directivité, le rythme, la confiance qu’il accorde au lecteur, l’authenticité, la densité. Si le score total passe sous 35 sur 50, le modèle réécrit l’article en appliquant des règles anti-AI : pas de tirets cadratins, pas de règle de trois, pas de ton promotionnel, des phrases de longueurs variées.

Cette étape change tout. Un article généré brut, ça se sent. Après humanisation, ça se lit comme un texte écrit par quelqu’un. C’est ce réglage qui m’a fait passer de « c’est pratique » à « c’est publiable sans relecture ».

Besoin suivant : publier sans y penser

La publication est le morceau le plus simple, parce que le blog est déjà automatisé. Le pipeline commit l’article sur le dépôt git. Le serveur de build (OneDev) détecte le push, compile le site Hugo et synchronise les fichiers sur le VPS avec rsync. Quarante secondes après le commit, l’article est en ligne.

Le tout est orchestré par un job planifié à 5h du matin. À 6h, quand je me lève, le brouillon est prêt. Je le relis, je vérifie que le top 1 est le bon, et je lance la publication. Cinq minutes de validation, au lieu de trente minutes de veille à la main.

Les pièges rencontrés

Ce pipeline paraît simple sur le papier. En vrai, j’ai collectionné les incidents, et chacun a laissé une trace dans le code :

  • Le backend qui rame. Le provider API a des pannes intermittentes, avec des erreurs 500 et même des 402 trompeurs qui ressemblent à des problèmes de solde alors que ce n’est pas ça. J’ai ajouté des retries avec backoff, et le scoring retente trois fois avant d’abandonner un lot.
  • Le raisonnement qui s’invite. Je l’ai dit : les modèles laissent traîner leurs réflexions, parfois en français, parfois en anglais. La liste des motifs à filtrer est devenue un document vivant, enrichi après chaque incident.
  • Le taux de doublons. Deux tweets différents qui rapportent le même incident passaient tous les deux. La déduplication lexicale ne suffit pas toujours. C’est une limite connue, et la prochaine itération devra passer par une vérification sémantique.

Le bilan

Ce pipeline me fait gagner ce que je passais à faire à la main : la collecte, le tri, la rédaction, la mise en forme. Trente minutes par jour minimum, et surtout, une régularité parfaite. Chaque matin, le brouillon est prêt, je le valide, et il part. Je n’ai plus jamais de journée blanche.

Le coût, c’est quelques centimes d’API par jour pour le scoring et la rédaction. Le seul réglage que je touche encore à la main, c’est le seuil de score, quand je veux une veille plus sélective ou au contraire plus large.

Et la suite

Le pipeline tourne depuis plusieurs semaines, et il a préparé des dizaines d’articles, tous validés avant publication. La prochaine étape que je regarde, c’est la limite que j’ai mentionnée : la déduplication sémantique, pour qu’un même sujet rapporté différemment ne passe pas deux fois.

Si tu fais une veille à la main, ce pipeline est reproductible. Les briques sont simples : un collecteur, un scoring par LLM, un prompt de rédaction, deux contrôles qualité, un dépôt git. Le tout tient dans quelques scripts et un job planifié. Et le résultat, c’est de ne plus jamais passer sa matinée à faire ce qu’une machine fait mieux.