02-ce-que-je-construis/specs/ia-veille.md

Lot 3 — Veille agentique : spécification

Spécification du pipeline de veille automatisée : suivre l'actualité (IA, dev web, qualité, juridique), résumer, classer et alimenter pilotage/veille/ — sous contrôle humain. Rattaché au cadre : specs/ia-vitrine.md. Statut : V1 complète bout-en-bout côté telaria (commits 0e26ea0..e776aca, 25 tests PHPUnit verts). Pipeline planifié actif (Scheduler+Messenger câblés, cadence 15 min) + dashboard /admin/veille + revue propositions (bb77c65). Catalogue des flux V1 et réserve V2+ : ia-veille-sources.md.


1. Objectif et périmètre

C'est la surface « agentic automation » de la vitrine : démontrer une automatisation IA planifiée, utile et encadrée. Le pipeline collecte des sources, les résume, les classe et propose des entrées dans la veille existante.

  • Symfony-natif (Scheduler + Messenger), pas de SaaS no-code (cohĂ©rent avec le cadre).
  • GĂ©nĂ©ration via Claude ; dĂ©duplication et rapprochement thĂ©matique peuvent rĂ©utiliser les embeddings du cĹ“ur (L0).
  • Ce n'est pas un produit : sortie = propositions rĂ©visĂ©es par un humain.

Périmètre V1 : un thème pilote (IA), bout-en-bout (collecte → résumé → classification → proposition d'écriture). Hors V1 : tous les thèmes, tableau de bord, publication automatique, alerting.


2. Flux

Sources (RSS/Atom, gérées en base via /admin/veille/sources)
        │  (planifié : Scheduler — câblage reporté)
        â–Ľ
   Collecte ──▶ Déduplication ──▶ Fetch article ──▶ Résumé (Claude Haiku) ──▶ Classification ──▶ Écriture proposition
   (Messenger)   (URL ou hash)     (DOM lazy)       (+ source/lien)            (mots-clés V1)      var/veille/proposals/*.md
                                                                                                   │
                                                                                          Revue humaine ──▶ bascule vers pilotage/veille/

Le fetch article est nécessaire en pratique car la quasi-totalité des RSS ne fournissent que titre + lien (HN, HuggingFace, blogs Markdown) — sans contenu, le résumeur Claude refuse de halluciner.


3. Composants (Symfony-natif, domaine in-app src/Veille/)

Le domaine veille vit dans l'application telaria (src/Veille/), pas dans un bundle. C'est une surface app, pas un socle réutilisable. Extraction (telaria/veille-bundle) si un autre projet en a besoin un jour — pas avant.

3.1 Sources (entité Doctrine VeilleSource)

  • Flux RSS/Atom uniquement en V1 (couvrent 95 % du besoin pour un pipeline Symfony en pull). Pas de JSON Feed, pas de webhook, pas de scraping de pages sans flux.
  • Thèmes visĂ©s : IA, dev web, qualitĂ©, juridique (CNIL, AI Act / EUR-Lex).
  • V1 = thème IA uniquement, 10 flux sĂ©lectionnĂ©s (4 constructeurs majeurs, 1 souverainetĂ© FR, 1 recherche source arXiv, 2 synthèses anglo, 1 source FR pro, 1 pulse Hacker News filtrĂ©).
  • Stockage : entitĂ© Doctrine VeilleSource (pas de config-as-code, pas de doc-as-code). Justification : maintenance opĂ©rationnelle continue (ajout/retrait d'un flux sans redĂ©ploiement), sĂ©paration des responsabilitĂ©s IA (consommateur) / humain (Ă©diteur).
  • Administration : CRUD /admin/veille/sources cĂ´tĂ© telaria.
  • Champ type obligatoire : native (RSS officiel exposĂ© par l'Ă©diteur), community (flux maintenu par un tiers via GitHub Actions), html (rĂ©servĂ© V2). Plusieurs labos IA majeurs (Anthropic, OpenAI, Mistral, Meta, xAI) n'exposent plus de RSS natif depuis leurs refontes rĂ©centes — on dĂ©pend de flux communautaires (Olshansk/rss-feeds, 0xSMW/rss-feeds), Ă  monitorer.
  • Charge estimĂ©e V1 : ~30-50 items/jour après dĂ©dup.
  • Liste exacte des URL, justifications et catalogue de rĂ©serve : ia-veille-sources.md.

3.2 Collecte planifiée

  • Symfony Scheduler : Schedule "veille" Ă  cadence globale 15 min en V1 (champ VeilleSource.schedule ISO 8601 reste informatif — la cadence per-source sera prise en compte en V2).
  • Symfony Messenger : traitement asynchrone via deux workers — messenger:consume scheduler_veille (dĂ©clencheur) et messenger:consume async (handlers de cycle).
  • CâblĂ© en V1 (e776aca), validĂ© sur le pipeline complet.

3.3 Fetch d'article (ArticleFetcher)

  • Étape ajoutĂ©e en pratique : la quasi-totalitĂ© des RSS ne fournissent que titre + lien. Sans contenu, le rĂ©sumeur Claude refuse de halluciner (comportement attendu).
  • Fetch lazy de l'URL puis extraction DOM (article > main > body, strip <script>/<style>).
  • Contenu enrichi conservĂ© dans VeilleItem::raw_content (TEXT NULL — RSS si fourni, sinon rĂ©sultat du fetcher).

3.4 Déduplication (entité Doctrine VeilleItem)

  • Stockage : entitĂ© Doctrine VeilleItem (pas un simple journal de hash). Justification : observabilitĂ© (queries SQL stats/source/jour), cycle de vie (pending → proposed → accepted | rejected | failed), traçabilitĂ© (model_used, tokens_in, tokens_out, error_message).
  • DĂ©dup par URL OU content_hash SHA-256 (le hash couvre les variantes avec params de tracking).

3.5 Résumé (port LLM Claude)

  • Modèle V1 : claude-haiku-4-5. CoĂ»t observĂ© ~$0.003 / article. TempĂ©rature basse.
  • RĂ©sumĂ© court + points clĂ©s, conservant systĂ©matiquement la source et le lien.
  • PersistĂ© sur VeilleItem : summary, status, model_used, tokens_in, tokens_out.
  • Pas de prompt caching en V1 : le system prompt est < 4096 tokens, sous le seuil minimum de Haiku.

3.6 Classification (ClassifierInterface)

  • V1 : règles par mots-clĂ©s derrière l'interface ClassifierInterface. Pour le thème pilote IA : ~30 mots-clĂ©s (claude, anthropic, llm, rag, agent, …), scoring proportionnel au nombre de matches (word-boundary, fallback default_theme de la source si aucun match).
  • V2 : bascule vers embeddings du cĹ“ur (L0) lorsque dev web / juridique / qualitĂ© s'ajouteront — l'interface est lĂ  pour ça.

3.7 Écriture (proposition locale)

  • Sortie : fichier Markdown var/veille/proposals/<source>-<date>-<id>.md cĂ´tĂ© telaria (pas d'Ă©criture directe dans telaria-doc/pilotage/veille/).
  • Frontmatter YAML : type, title, url, source, theme, status: proposed, date, model, tokens_in, tokens_out.
  • Surface humaine : dashboard /admin/veille + revue des propositions /admin/veille/proposals (actions accept / reject / reopen).
  • Workflow de bascule vers pilotage/veille/ reste manuel en V1 (revue puis copie). Auto-push cross-repo = sujet V2 (cf. §9).

4. Périmètre V1 / hors V1

Aspect V1 Hors V1
Thèmes 1 pilote (IA) dev web, qualité, juridique
Collecte planifiée ✅ (Scheduler + Messenger, cadence globale 15 min) Cadence per-source
Fetch article ✅ (ArticleFetcher, fetch DOM lazy) —
Déduplication ✅ (entité VeilleItem, url ou content_hash) —
Résumé ✅ (Claude Haiku 4.5) Prompt caching, scoring de pertinence avancé
Classification ✅ (règles mots-clés via ClassifierInterface) Embeddings L0 (V2 multi-thèmes)
Sortie proposition Markdown + revue humaine publication auto, alerting, dashboard, auto-push cross-repo

5. Gouvernance et garde-fous (critique)

  • Aucune autoritĂ© juridique : une entrĂ©e de veille juridique n'affirme rien ; elle rĂ©sume et pointe vers le texte officiel (CNIL, EUR-Lex). Risque d'hallucination pris au sĂ©rieux (cf. fiche 6.1).
  • Sources systĂ©matiques : chaque proposition cite sa/ses source(s) avec lien (règle AGENTS.md).
  • Humain dans la boucle : la sortie est une proposition, jamais une publication automatique.
  • Respect des sources : conditions d'utilisation / robots, pas de copie intĂ©grale (rĂ©sumĂ© + lien).
  • Pas de donnĂ©es personnelles ingĂ©rĂ©es.

6. Configuration

La configuration est DB-driven : la liste des sources vit en base (entité VeilleSource), administrée via /admin/veille/sources. Seuls les paramètres applicatifs (modèle Claude, chemin de sortie) restent en config Symfony.

6.1 Entité VeilleSource (administrée via CRUD)

Champ Type Usage
slug string unique Clé stable (dédup, tag, nom de fichier proposal)
name string Libellé affiché
url string URL du flux
type enum rss|atom|html Format (html réservé V2)
schedule string ISO 8601 Cadence de collecte (ex. PT1H, PT6H)
default_theme string Thème de repli si la classification ne match rien
is_active bool Permet de couper un flux sans toucher au code
editorial_description text markdown Note de l'éditeur (pourquoi cette source, angle attendu)
created_at / updated_at timestamps Traçabilité

Le champ type=native|community (cf. §3.1) reste pertinent pour le monitoring mais peut être porté par editorial_description ou un sous-champ — à arbitrer à l'implémentation s'il n'est pas déjà présent.

6.2 Config applicative (Symfony)

  • veille.model : modèle Claude pour le rĂ©sumĂ© (V1 : claude-haiku-4-5).
  • veille.output_dir : destination des propositions (V1 : var/veille/proposals/).
  • veille.dedup : stratĂ©gie (V1 : url OU content_hash SHA-256).

7. Tests unitaires (cas concrets)

État V1 telaria : 25 tests PHPUnit verts couvrant les axes ci-dessous (planification incluse depuis e776aca).

Collecte

  • Un flux RSS et un flux Atom de fixture sont parsĂ©s → items normalisĂ©s (titre, lien, date, contenu).
  • Une source injoignable (erreur HTTP) ou un XML invalide est gĂ©rĂ©e proprement (log + skip), sans casser le run.

Fetch d'article

  • Une URL renvoyant une page HTML standard → contenu extrait (article > main > body), scripts/styles strippĂ©s.
  • Une URL en erreur (404, timeout) → item marquĂ© failed, pas de rĂ©sumĂ© tentĂ©.

Déduplication

  • Un item dĂ©jĂ  traitĂ© (mĂŞme url ou mĂŞme content_hash SHA-256) n'est pas re-soumis au rĂ©sumĂ©.
  • Cas tracking params : deux URL avec params de tracking diffĂ©rents mais mĂŞme contenu → dĂ©dup par content_hash.

Résumé (Claude mocké)

  • Le rĂ©sumĂ© conserve la source et le lien ; la longueur est bornĂ©e.
  • status, summary, model_used, tokens_in, tokens_out persistĂ©s sur VeilleItem.

Classification

  • Un item est rangĂ© dans le bon thème via matches mots-clĂ©s (word-boundary).
  • Matches multiples → score proportionnel, thème dominant retenu.
  • Aucun match → fallback default_theme de la VeilleSource.

Écriture

  • La sortie est une proposition (status: proposed en frontmatter), pas une Ă©criture publiĂ©e ; un humain valide.
  • La source est citĂ©e systĂ©matiquement.

Garde-fous

  • Une entrĂ©e juridique contient un lien vers le texte officiel ; aucune affirmation sans source (couvert implicitement par le contrat « source citĂ©e + status proposed »).

Planification

  • La tâche est dĂ©clenchĂ©e Ă  la cadence globale 15 min (Scheduler veille) et traitĂ©e par les workers messenger:consume scheduler_veille + async.

8. Production documentaire d'accompagnement (doctrine)

Concept introduit Forme Emplacement Statut
Veille automatisée (Symfony Scheduler + Messenger) Tuto veille-automatisee-symfony.md ✅ produit
Automatisation IA encadrée (humain dans la boucle) renvoi fiches 4.5 / 10.5 agents/ (existant) —

9. Points tranchés et restant ouverts

9.1 Tranchés (implémentation V1 telaria)

  1. Liste initiale des sources du thème pilote (IA). → 10 flux RSS/Atom, catalogue ia-veille-sources.md §3.
  2. Stockage des items traités. → entité Doctrine VeilleItem (cf. §3.4) ; pas un journal de hash.
  3. Classification : règles vs embeddings. → ClassifierInterface + règles mots-clés V1 ; embeddings reportés V2 (cf. §3.6).
  4. Format de la proposition. → Markdown + frontmatter YAML dans var/veille/proposals/ côté telaria (cf. §3.7) ; bascule manuelle vers pilotage/veille/ en V1.
  5. Gestion des sources. → entité Doctrine VeilleSource + admin CRUD /admin/veille/sources (cf. §6.1), pas de YAML.
  6. Modèle Claude. → claude-haiku-4-5, pas de prompt caching V1 (system prompt sous le seuil 4096 tok de Haiku).
  7. Périmètre code. → in-app src/Veille/, pas bundle.

9.2 Restant ouverts

  1. Cadence per-source : champ VeilleSource.schedule (ISO 8601) actuellement informatif — V1 applique une cadence globale 15 min. À activer en V2.
  2. Workflow cross-repo auto-push : actuellement la bascule des propositions telaria/var/veille/proposals/ → telaria-doc/pilotage/veille/ est manuelle. Auto-push (vers une sous-arbo _inbox/) à étudier en V2 — pour l'instant le rituel manuel est sain.
  3. Monitoring des flux communautaires : seuil d'alerte et procédure de bascule si un repo upstream est abandonné. → couvert par le standby de source (cf. §10.2) : bascule automatique après N échecs consécutifs.
  4. Filtrage arXiv : volume très élevé sur cs.AI brut. En V1 le classifier mots-clés filtre déjà, mais à calibrer (embeddings ciblés en V2).
  5. Calibrage Hacker News : ajuster le seuil points= après quelques jours pour équilibrer signal/bruit.

10. Diagnostic & pilotage (back-office, v0.5.0)

Ajouts post-V1 livrés en prod 2026-06-01 (telaria v0.5.0). Objectif : statuer sur un flux sans fouiller les logs. Source : rétro-doc Lead dev (#28). Détails de schéma (types de colonnes exacts) = implémentation telaria ; cette spec fige le comportement et les contrats.

10.1 Journal par tentative (VeilleAttempt)

Chaque passage du pipeline sur un item est tracé dans une entité dédiée VeilleAttempt (distincte de VeilleItem, qui porte le cycle de vie de l'item). Une tentative enregistre au minimum :

  • l'Ă©tape atteinte du pipeline et sa durĂ©e ;
  • le diagnostic du fetch HTTP (code, erreur rĂ©seau le cas Ă©chĂ©ant) ;
  • la requĂŞte et la rĂ©ponse brutes de Claude (pour rejouer/auditer un rĂ©sumĂ© douteux) ;
  • l'erreur complète en cas d'Ă©chec.

Bénéfice : observabilité par requête SQL (statuer sur un flux, une source, un jour) sans recourir aux logs applicatifs.

10.2 Standby de source

Une source qui échoue N fois consécutivement (seuil configurable VEILLE_SOURCE_STANDBY_THRESHOLD, défaut 3) bascule automatiquement en état standby :

  • standby est un Ă©tat distinct de is_active : is_active = interrupteur humain (l'Ă©diteur a activĂ©/dĂ©sactivĂ© la source) ; standby = mise en retrait automatique sur Ă©checs rĂ©pĂ©tĂ©s. Les deux ne se confondent pas.
  • Une source en standby sort du cycle de collecte et est signalĂ©e « Ă  statuer » au dashboard, avec un bouton « Lever la veille ».
  • PĂ©riode de grâce : lever le standby rĂ©initialise la sĂ©rie d'Ă©checs (le compteur repart de zĂ©ro), Ă©vitant une rebascule immĂ©diate.

10.3 Page de proposition unique

La revue d'une proposition fusionne sur une seule page l'éditorial (résumé + actions accepter/rejeter) et le diagnostic dépliable (tentatives, cf. §10.1). L'ancienne route /detail est supprimée (un clic en moins).

10.4 Composant de pagination réutilisable

Pagination factorisée dans templates/components/_pagination.html.twig (fenêtre glissante : première · précédente · … · ±5 · … · suivante · dernière). Réutilisable par toute liste paginée du back-office.


Documents liés

  • Cadre : specs/ia-vitrine.md
  • Catalogue des sources V1 et rĂ©serve V2+ : ia-veille-sources.md
  • Veille existante (destination) : pilotage/veille/README.md
  • CĹ“ur RAG (embeddings rĂ©utilisables) : specs/ia-coeur.md
  • Fiche agents — agents & automatisation : agents/4-interagir-avec-l-ia/4-5-les-agents-ia-et-l-automatisation-de-taches.md
  • Fiche agents — veille et ressources : agents/10-perspectives-et-tendances/10-5-se-former-en-continu-veille-et-ressources.md

Implémentation

Aspect Localisation
Bundle principal tlr-codexia — domaine src/Veille/ dans telaria-app (in-app, pas bundle séparé)
Entités VeilleSource, VeilleItem, VeilleAttempt, VeilleRead dans tlr-codexia
Scheduleur Symfony Scheduler — Schedule "veille" cadence globale 15 min
Workers Messenger messenger:consume scheduler_veille + messenger:consume async
Composants ArticleFetcher, ClassifierInterface (règles mots-clés V1)
Sortie var/veille/proposals/<source>-<date>-<id>.md côté telaria-app
Dashboard /admin/veille + revue propositions /admin/veille/proposals dans telaria-app
LLM claude-haiku-4-5 (résumé), via port LLM abstrait
Tests 25 tests PHPUnit verts (commits 0e26ea0..e776aca)

Historique des décisions

Version Date Décision
1.0 2026-06-14 Version initiale — première formalisation du versioning des specs.
— 2026-06-01 V1 complète bout-en-bout livré en prod (telaria v0.5.0). Pipeline planifié actif, dashboard /admin/veille, revue propositions.
— 2026-06-01 Diagnostic v0.5.0 ajouté : VeilleAttempt (journal par tentative), standby source (N échecs consécutifs), page proposition unique, pagination réutilisable.
— 2026-06-01 Domaine veille = in-app src/Veille/, pas bundle. Extraction telaria/veille-bundle si un autre projet en a besoin.
— 2026-06-01 Modèle Claude figé : claude-haiku-4-5, pas de prompt caching V1 (system prompt < 4096 tokens, sous le seuil Haiku).

Assistant documentaire

Posez une question sur la documentation. Les réponses citent leurs sources — un clic ouvre le document à gauche.

Loading…
Loading the web debug toolbar…
Attempt #