From f9ecf6cd1a1917f537a0253657cabf3ea0ef106e Mon Sep 17 00:00:00 2001 From: Ladebeze66 Date: Thu, 23 Apr 2026 18:31:06 +0200 Subject: [PATCH] ajout_section_ia --- CONFIGURATION_SITE.md | 9 ++++++++- docs-site-interne/02-frontend-next.md | 18 ++++++++++++------ docs-site-interne/04-api-llm-et-chatbot.md | 16 ++++++++++++++-- docs-site-interne/etat-actuel.md | 8 +++++--- docs-site-interne/feuille-de-route.md | 3 ++- 5 files changed, 41 insertions(+), 13 deletions(-) diff --git a/CONFIGURATION_SITE.md b/CONFIGURATION_SITE.md index 1019d8e..22dc521 100644 --- a/CONFIGURATION_SITE.md +++ b/CONFIGURATION_SITE.md @@ -24,6 +24,13 @@ my-next-site/ **Observabilité** : le chatbot GrasBot est tracé dans une instance **Langfuse self-hosted** (`langfuse.fernandgrascalvet.com`). Chaque question déclenche une trace `ask` avec spans `retrieval` / `prompt_build` / `ollama-chat`, plus des scores auto (`grounded`, `retrieval_relevance`) et des tags. Voir `docs-site-interne/langfuse-observability.md` pour le détail. +## Contenu : compétences, réalisations IA et ordre d’affichage + +- **Ordre** de la liste `/competences` : champ `order` sur le content-type compétence. Selon la version de Strapi, l’API renvoie `attributes.order` (v4) ou `order` (v5) — le front unifie cela (voir `getOrder()` dans `app/competences/page.jsx`). +- **Fiche** `/competences/[slug]` : affiche des **vignettes** (projets de type `realisation-ia` liés à la compétence) dès qu’il en existe ; sinon, rendu de la fiche richtext « classique ». +- **Détail** d’une réalisation : route `/competences/[slug]/[realisation]` (même gabarit de contenu qu’une fiche portfolio). +- **Documentation détaillée** (tableau des routes, champs Strapi, lien avec GrasBot) : `docs-site-interne/02-frontend-next.md` et, côté API chatbot, `docs-site-interne/04-api-llm-et-chatbot.md` (section *Parcours public*). + ## 🚀 Démarrage Rapide ### Script Automatique (Recommandé) @@ -287,6 +294,6 @@ Pensez à sauvegarder régulièrement : --- -**Dernière mise à jour** : $(Get-Date -Format "dd/MM/yyyy HH:mm") +**Dernière mise à jour** : 2026-04-24 **Version Cursor** : 2.0.77 **OS** : Windows Server 2025 diff --git a/docs-site-interne/02-frontend-next.md b/docs-site-interne/02-frontend-next.md index d8223ec..cc1c6db 100644 --- a/docs-site-interne/02-frontend-next.md +++ b/docs-site-interne/02-frontend-next.md @@ -1,6 +1,6 @@ # Frontend Next.js -**Dernière mise à jour :** 2026-04-01 +**Dernière mise à jour :** 2026-04-24 ## Stack @@ -14,13 +14,20 @@ |--------|---------|--------| | `/` | `app/page.tsx` | Accueil : `GET /api/homepages?populate=*` | | `/portfolio` | `app/portfolio/page.jsx` | Liste projets | -| `/portfolio/[slug]` | `app/portfolio/[slug]/page.tsx` | Détail projet (`fetchData('projects', slug)`) | -| `/competences` | `app/competences/page.jsx` | Liste compétences | -| `/competences/[slug]` | `app/competences/[slug]/page.tsx` | Détail (`fetchData('competences', slug)`) | +| `/portfolio/[slug]` | `app/portfolio/[slug]/page.tsx` | Détail projet : `ContentSection` + `fetchData('projects', slug)` | +| `/competences` | `app/competences/page.jsx` | Liste compétences — tri par champ Strapi `order` (v4 : `attributes.order`, v5 : `order` à la racine) | +| `/competences/[slug]` | `app/competences/[slug]/page.tsx` | **Rendu conditionnel** : si au moins une entrée `realisation-ia` est liée à la compétence (filtre API sur le slug), **grille de vignettes** (même rythme visuel que le portfolio) ; sinon fiche richtext historique via `ContentSectionCompetencesContainer` | +| `/competences/[slug]/[realisation]` | `app/competences/[slug]/[realisation]/page.tsx` | Fiche d'une **réalisation** (collection Strapi `realisation-ia`) : réutilise `ContentSection` comme les projets (carousel, Markdown `resum` ou `Resum`, CTA `link` externe) | | `/contact` | `app/contact/page.js` | Formulaire → `/api/contact` (Brevo, voir `contact-flow.md`) | | `/api/contact` | `app/api/contact/route.ts` | Endpoint serveur : envoie un email via Brevo, honeypot + rate-limit | | `/api/proxy` | `app/api/proxy/route.js` | Proxy GET vers API LLM distante | +**Strapi — content-types concernés :** + +- `competence` : `name`, `content` (richtext), `picture`, `slug`, `order` +- `realisation-ia` : `name`, `description`, `picture`, `slug`, `resum` (richtext, alias accepté côté front : `Resum` pour les `project` uniquement), `link`, `order`, relation `competences` (plusieurs) +- Vignette → toujours navigation vers la **fiche détail** interne ; le champ `link` sert de bouton *Voir plus* en bas de fiche (comme sur les fiches `project`). + ## Layout - `app/layout.tsx` — **Client Component** (`"use client"`). Header fixe, menu burger mobile, fond décoratif, **Footer**, compteur de visites **localStorage** (`visitCount`). @@ -43,8 +50,7 @@ - Carrousels : `Carousel.tsx`, `CarouselCompetences.tsx` (swiper / react-responsive-carousel). - Sections : `ContentSection.tsx`, `ContentSectionCompetences*.tsx`. - `ContactForm.tsx` → `POST /api/contact` → Brevo API (voir `docs-site-interne/contact-flow.md`). -- `ChatBot.js` → `askAI.js` → `/api/proxy` → FastAPI `/ask` avec `session_id` + `user_id` (UUID anonymes via `app/utils/grasbotIds.js`, voir `docs-site-interne/langfuse-observability.md`). -- `ChatBot.js` → `askAI.js` → `/api/proxy`. +- `GrasBotFab` + `ChatBot.js` → `askAI.js` → `/api/proxy` → FastAPI `/ask` avec `session_id` + `user_id` (UUID anonymes via `app/utils/grasbotIds.js`, voir `docs-site-interne/langfuse-observability.md`). - `ModalGlossaire.tsx` — glossaire (données Strapi selon usage dans les pages). ## Fichiers clés (liste courte) diff --git a/docs-site-interne/04-api-llm-et-chatbot.md b/docs-site-interne/04-api-llm-et-chatbot.md index ce13b24..ffc25fe 100644 --- a/docs-site-interne/04-api-llm-et-chatbot.md +++ b/docs-site-interne/04-api-llm-et-chatbot.md @@ -1,6 +1,6 @@ # API LLM et chatbot (GrasBot) -**Dernière mise à jour :** 2026-04-22 (v3 — bascule graph + BM25) +**Dernière mise à jour :** 2026-04-24 (v3 + alignement parcours site) ## Vue d'ensemble @@ -31,13 +31,25 @@ par la refonte (`sources`, `grounded`, `model`, `vault_size`) passent dans la réponse JSON et pourront être affichés dans une itération suivante (voir [pistes d'évolution](#pistes-dévolution)). +## Parcours public (hors moteur Python) — cohérence contenu + +Le visiteur découvre les **projets** sur `/portfolio/[slug]` et, pour la +compétence **IA** (et toute compétence à laquelle on lie des +**`realisation-ia`** dans Strapi), un **parallèle** sur `/competences/[slug]` +(vignettes) puis `/competences/[slug]/[realisation]` (fiche identique en +gabarit à une fiche projet). Rien n'est servi ici par FastAPI : c'est +du **Strapi + Next** uniquement. Le chatbot, lui, interroge toujours +**`vault-grasbot/`** via `llm-api/search.py` — mettre à jour le vault +(ou l'extraction Strapi → vault) quand on veut que GrasBot **reflète** des +faits nouveaux présentés sur le site. Détail des routes : [`02-frontend-next.md`](./02-frontend-next.md). + ## FastAPI — `llm-api/` | Fichier | Rôle | |---------|------| | `api.py` | Endpoints `GET /ask?q=...`, `GET /health`, `POST /reload-vault`. | | `search.py` | `load_vault`, `tokenize_fr`, `score_note`, `expand_by_graph`, `search`, `build_prompt`, `generate`, `answer`. | -| `requirements.txt` | `fastapi`, `uvicorn`, `requests`, `pyyaml`. **Plus besoin** de `chromadb` / `chroma-hnswlib` (supprimés v3). | +| `requirements.txt` | `fastapi`, `uvicorn`, `requests`, `pyyaml` ; + `langfuse` (SDK 3.x, plafond strict inférieur à la v4) + `python-dotenv` pour l'observabilité optionnelle. Voir `llm-api/requirements.txt`. **Plus besoin** de `chromadb` / `chroma-hnswlib` (supprimés v3). | Modules supprimés en v3 : diff --git a/docs-site-interne/etat-actuel.md b/docs-site-interne/etat-actuel.md index 15fca58..6d5501b 100644 --- a/docs-site-interne/etat-actuel.md +++ b/docs-site-interne/etat-actuel.md @@ -1,19 +1,21 @@ # État actuel du site -**Dernière mise à jour :** 2026-04-23 (post-tuning GrasBot + observabilité Langfuse) +**Dernière mise à jour :** 2026-04-24 (doc compétences / realisation-ia + CONFIGURATION) ## Ce qui est en place - **Next.js 15** avec App Router, Tailwind, pages accueil / portfolio / compétences / contact, layout responsive avec menu burger. Design system "Digital Atelier" (Manrope + Newsreader, palette primary indigo-ardoise, vellum cards). -- **Strapi** avec content-types : homepage, projects, competences, messages, glossaire ; médias et texte riche. +- **Strapi** avec content-types : homepage, projects, competences, **realisation-ia** (rattachées aux compétences), messages, glossaire ; médias et texte riche. +- **Compétences côté Next** : liste `/competences` (tri `order`) ; fiche `/competences/[slug]` (vignettes des `realisation-ia` liées quand il y en a, sinon fiche richtext) ; détail `/competences/[slug]/[realisation]`. Même logique d’enrichissement que le portfolio (Markdown, galerie, CTA) pour les fiches liées. - **Formulaire contact** : POST vers Strapi `messages`. - **Chatbot GrasBot v3** : FAB global (`GrasBotFab.tsx`) → proxy Next → API LLM hébergée (`llmapi.fernandgrascalvet.com`). - **FastAPI + Ollama** dans `llm-api/` : modèle `qwen3:8b`, pipeline `search.py` (graph + BM25 sur vault Obsidian `vault-grasbot/`, sans embeddings). - **Vault de connaissance `vault-grasbot/`** : 42 notes enrichies (aliases, answers, priority) — source de vérité du chatbot, régénéré depuis Strapi par `strapi_extraction/build-vault.py`. Inclut une note `bio-fernand` courte (priority 10) dédiée aux questions biographiques et un CV complet complémentaire. - **Observabilité Langfuse** : instance self-hosted `langfuse.fernandgrascalvet.com`, instrumentation Python (`llm-api/observability.py`) traçant chaque requête `/ask` (retrieval / prompt_build / ollama-chat) avec session/user IDs anonymes côté front. Mode no-op automatique si les clés sont absentes. Voir [`langfuse-observability.md`](./langfuse-observability.md). - **Scripts** d'extraction et de doc dans `strapi_extraction/`. -- Documentation opérationnelle : `CONFIGURATION_SITE.md`. +- Documentation opérationnelle : `CONFIGURATION_SITE.md` (incl. ordre des compétences et routes dédiées, renvoi vers `docs-site-interne/02-frontend-next.md`). - **Captures d'écran** de référence (WebP) : `docs-site-interne/captures/` — voir `captures/INDEX.md`. +- **Décision produit** : une **rubrique homelab / serveur** (souvent évoquée en « phase 3 ») n’est **pas retenue** — pas d’évolution planifiée sur ce thème ; le parcours public reste portfolio, compétences (dont IA + réalisations) et contact. ## Dette technique / incohérences connues diff --git a/docs-site-interne/feuille-de-route.md b/docs-site-interne/feuille-de-route.md index ee3c240..cb109af 100644 --- a/docs-site-interne/feuille-de-route.md +++ b/docs-site-interne/feuille-de-route.md @@ -1,6 +1,6 @@ # Feuille de route -**Dernière mise à jour :** 2026-04-23 +**Dernière mise à jour :** 2026-04-24 Document vivant : ajuster les statuts et dates au fil du travail. @@ -58,3 +58,4 @@ Document vivant : ajuster les statuts et dates au fil du travail. | 2026-04-22 | Refonte visuelle — **étape 6 : listes portfolio + compétences**. `app/portfolio/page.jsx` et `app/competences/page.jsx` entièrement réécrits. En-tête éditorial (kicker + titre Manrope extrabold + pitch Newsreader) cohérent avec le hero de la home. Grille **asymétrique 2/3 + 1/3** alternée (`md:grid-cols-6` + pattern de `col-span-4`/`col-span-2` sur modulo 4, `sm:grid-cols-2`, `grid-cols-1` mobile) — conforme DESIGN.md §6 "No-Grid-Lock". Cartes « feuillet vellum » alignées home : `rounded-sheet bg-surface-container-lowest/85 backdrop-blur-vellum shadow-ambient`, image `aspect-[4/3]` fixe avec `group-hover:scale-[1.03]`, titre `text-primary`, description `line-clamp-3` en Newsreader, CTA tertiaire « Découvrir → » / « Explorer → » avec Material Symbol `arrow_forward` qui se décale au hover (`translate="no"` appliqué). Hover : `hover:-translate-y-0.5 hover:shadow-jewel` (remplace le `scale-105` qui débordait). **`Swiper` retiré des vignettes de liste** (arbitrage acté § 2 : carousel réservé aux galeries intra-fiche) — une seule image par carte, `loading="lazy"`. États ajoutés : skeletons animés respectant la grille + état vide avec Material Symbol. Régressions corrigées au passage : largeur fixe `w-80` qui débordait sur S25 Ultra, `hover:scale-105` qui tapait sous le header, classes `bg-white/80 rounded-lg` remplacées par les tokens Stitch. Les composants `Carousel.tsx` et `CarouselCompetences.tsx` restent en place pour les fiches détail (étape 7). Détail dans `REFONTE-VISUELLE.md` §6. | | 2026-04-23 | **GrasBot — tuning pipeline LLM + anti-hallucinations**. Audit des premières traces Langfuse : questions biographiques hallucinées (âge erroné, statut inventé), réponses longues tronquées. Quatre ajustements : (1) `llm-api/search.py` · `generate()` — `num_ctx=8192` explicite (stoppe la troncature silencieuse du prompt par le défaut Ollama 2048/4096 quand plusieurs notes entières sont injectées), `num_predict` 512 → 1024 (réponses longues complètes), `think: false` top-level (désactive le *thinking mode* de qwen3 qui consommait du budget de sortie). (2) `llm-api/search.py` · `build_prompt()` — troncature conditionnelle des sources rank 2+ via `_truncate_body()` + nouvelles variables `SEARCH_SECONDARY_MAX_CHARS` (1500) / `SEARCH_SECONDARY_KEEP_RATIO` (0.8). Aucune source n'est supprimée, seules celles dont le score est < 0.8 × score(#1) ET dont le body dépasse 1500 chars sont résumées. Loggé dans `prompt_build.metadata.truncation`. (3) Vault — nouvelle note `vault-grasbot/30-Parcours/bio-fernand.md` courte et factuelle (priority 10, aliases biographiques courts), canonique pour les questions du type *« qui est Fernand »*. Renvoie vers le CV complet pour le détail. Correction incohérence d'âge dans le CV (46 → 47 ans dans la section Présentation) qui alimentait les hallucinations. (4) `SYSTEM_PROMPT` — nouveau bloc *Règles de fidélité aux sources* : priorité `type=parcours` pour questions bio, interdiction d'inventer des faits factuels, gestion explicite des contradictions, signalement des notes tronquées. **Bascule Langfuse v4 → v3 dans `requirements.txt`** (`langfuse>=3.0,<4`) : le SDK v4 a supprimé `start_as_current_span`, la v3 reste compatible avec l'instrumentation existante. Dépendances Python ajoutées : `langfuse`, `python-dotenv`. Secrets Langfuse déplacés de `.env.local` Next vers `llm-api/.env` (non committé). Doc mise à jour : [`langfuse-observability.md`](./langfuse-observability.md) (nouvelle section *Tuning du pipeline — 2026-04-23*), `CONFIGURATION_SITE.md` (endpoints `/health` + `/reload-vault`), `etat-actuel.md` (42 notes + mention Langfuse). | | 2026-04-22 | **GrasBot v3 — bascule RAG vectoriel → retrieval graph + BM25**. Essais d'installation Windows bloqués par `chroma-hnswlib` (compilation C++ requise) et freezes RDP à chaque chargement de `qwen3:8b` + `nomic-embed-text` simultanément. Arbitrage : pour un vault de 40 notes, la RAG vectorielle sur-dimensionne ; on exploite directement la structure Obsidian (frontmatter, wikilinks, MOCs). **Nouveau pipeline** dans `llm-api/search.py` (scoring multi-signaux : aliases / titre-slug / answers / domains / tags / BM25 ; expansion par graphe via `linked`/`related`/wikilinks ; tokenizer FR avec normalisations `c++` → `cpp`, split `-`/`_`). **Déterministe, traçable (champ `reasons` dans les sources), 50 ms de retrieval**. Scoring calibré sur 12 cas (IA, push-swap, LLMs pluriel, hors-sujet clafoutis → `(aucun)`, etc.). **Dépendances allégées** : fini `chromadb`, `chroma-hnswlib`, `nomic-embed-text`. `requirements.txt` = fastapi + uvicorn + requests + pyyaml uniquement. Fichiers supprimés : `llm-api/rag.py`, `llm-api/index_vault.py`, `chroma-index/` (marqué pour suppression, verrouillé par Cursor au moment du cleanup — sera supprimé au reboot). **Vault enrichi** : `build-vault.py` étendu pour générer automatiquement `aliases` (à partir du slug/titre + `DOMAIN_ALIASES`), `answers` (questions-types adaptées au type de note), `priority` (heuristique CV=10, MOCs=7, compétences=7, projets=5). Note CV curatée (`source: manual`) enrichie manuellement avec 12 aliases et 7 answers. Nouvelle `vault-grasbot/TAXONOMIE.md` qui documente le vocabulaire contrôlé. Réécriture de `vault-grasbot/50-Technique/grasbot-rag.md` → `grasbot-retrieval.md` (nouveau pipeline), + `architecture-site.md` + `vault-structure.md` + `MOC-Technique.md`. Nouveau endpoint `POST /reload-vault` pour recharger sans redémarrer uvicorn. Documentation interne refaite : [`04-api-llm-et-chatbot.md`](./04-api-llm-et-chatbot.md), [`06-strapi-extraction.md`](./06-strapi-extraction.md), nouveau [`08-vault-obsidian-retrieval.md`](./08-vault-obsidian-retrieval.md) (remplace `08-vault-obsidian-rag.md`). | +| 2026-04-24 | **Doc + configuration** : routes `/competences/[slug]/[realisation]`, entité Strapi `realisation-ia`, tri `order` et comportement vignettes/richtext documentés dans `02-frontend-next.md`, `04-api-llm-et-chatbot.md` (parcours public), `etat-actuel.md` ; `CONFIGURATION_SITE.md` : section *Contenu : compétences, réalisations IA et ordre d’affichage*. Décision : **pas de « phase 3 » homelab** sur le site (consignée dans l’état actuel). |