2026-04-23 19:41:58 +02:00

145 lines
5.5 KiB
Markdown

---
title: "GrasBot — chatbot IA du portfolio"
slug: grasbot
type: projet
source: manual
domains: [ia, web, devops]
tags: [ollama, fastapi, langfuse, chatbot, qwen3]
aliases:
- grasbot
- assistant grasbot
- chatbot du site
- chatbot fernandgrascalvet
- chatbot ia du portfolio
- assistant du site
- assistant ia locale
- ia locale test
- bot du site
- bouton flottant
answers:
- "Qu'est-ce que GrasBot ?"
- "Parle-moi de GrasBot."
- "Quel est l'assistant IA sur le site ?"
- "Comment fonctionne le chatbot du site ?"
- "Sur quelles sources GrasBot s'appuie-t-il ?"
- "GrasBot hallucine-t-il ?"
priority: 7
linked:
- "[[MOC-Projets]]"
- "[[MOC-Ia]]"
related:
- "[[ia]]"
- "[[grasbot-retrieval]]"
- "[[architecture-site]]"
- "[[fernandgrascalvet-com]]"
- "[[newsletter-ia]]"
- "[[transcription-video]]"
link: "https://fernandgrascalvet.com"
updated: 2026-04-23
visibility: public
---
# GrasBot — chatbot IA du portfolio
> [!info] Rôle de cette note
> Fiche **projet** (réalisation IA exposée sur `/competences/ia`). Pour
> l'algorithme de retrieval détaillé voir [[grasbot-retrieval]] ; pour
> l'architecture globale du site voir [[architecture-site]].
## Le défi
Permettre à un visiteur de **poser des questions libres** sur le parcours,
les projets et les compétences de Fernand, **sans qu'il doive naviguer**
dans dix pages, et **sans que le chatbot invente** des informations qui
ne sont pas dans les notes.
## Pipeline technique
GrasBot n'est pas un simple wrapper ChatGPT : c'est un vrai pipeline **RAG
(Retrieval-Augmented Generation)** construit de bout en bout.
### 1. Vault Obsidian comme source de vérité
Un coffre Obsidian structuré (`vault-grasbot/`) contient les notes de
parcours, projets École 42, compétences et glossaires. Chaque note porte
un **frontmatter YAML** avec `aliases`, `answers`, `priority`, `domains`
— autant de **signaux** pour le scoring.
### 2. Retrieval déterministe par graphe + BM25
Contrairement à un RAG classique à **embeddings vectoriels**, GrasBot
exploite directement la **structure du vault** : score multi-signaux
(aliases / titre / answers / domaines / BM25 sur le body), puis
**expansion par graphe** via les wikilinks `[[...]]`. Résultat : retrieval
en **~50 ms**, **100 % traçable**, sans dépendance à ChromaDB ni à des
embeddings. Détail : [[grasbot-retrieval]].
### 3. Génération locale avec Qwen3 + Ollama
Un modèle **Qwen3 8B** (quantization Q4_K_M) tourne **en local** sur le
serveur, servi par **Ollama**. Paramètres tunés après audit des premières
traces :
- `num_ctx = 8192` pour éviter la **troncature silencieuse** du contexte
(défaut Ollama trop bas quand plusieurs notes entières sont injectées).
- `num_predict = 1024` pour les réponses longues complètes.
- `think = false` pour **désactiver** le mode raisonnement interne qui
consommait du budget de sortie.
### 4. Observabilité Langfuse de bout en bout
Chaque conversation déclenche une trace Langfuse avec **3 spans** :
- `retrieval` (notes remontées, scores, *reasons*),
- `prompt_build` (system + user complets, sources tronquées, flag
*grounded*),
- `ollama-chat` (tokens, latence, paramètres).
Scores automatiques `grounded` et `retrieval_relevance` pour suivre la
qualité dans le temps.
### 5. Règles anti-hallucination
System prompt strict : **interdiction** d'inventer un fait absent des
notes, **priorité** aux sources `type=parcours` pour les questions
biographiques, mention explicite *« non précisé dans les notes »* quand
l'info manque. La source canonique [[bio-fernand]] (priority 10) couvre
les *« qui est Fernand ? »*.
## Stack complète
| Couche | Outils |
|--------|--------|
| **Front** | Next.js 15 + composant React `ChatBot.js` ; session / user IDs anonymes (UUID v4 en `sessionStorage` / `localStorage`). |
| **Proxy** | Route API Next qui valide une whitelist de paramètres (`q`, `session_id`, `user_id`) et forward vers l'API Python. |
| **Backend** | FastAPI + Ollama ; pipeline `search.py` (graph + BM25) + `observability.py` (Langfuse). |
| **Infra** | Windows Server 2025 + IIS reverse proxy + HTTPS Let's Encrypt + VPN pour l'admin. |
## Ce que ce projet démontre
- **Chaîne RAG complète** maîtrisée (ingestion, retrieval, génération,
observabilité).
- Choisir la **bonne brique** selon le contexte : un vault de quelques
dizaines de notes ne justifie pas des embeddings vectoriels — **BM25 +
graphe** suffit largement.
- **Tuning des modèles** plutôt que subir leurs défauts (audit via
Langfuse → correctifs ciblés).
- Déploiement en **production** sur une infra maîtrisée **bout en bout**.
## Différentiation avec les notes voisines
| Note | Angle | Quand elle remonte en premier |
|------|-------|-------------------------------|
| `grasbot` (cette note) | Fiche **produit / vignette réalisation** IA | *« Qu'est-ce que GrasBot ? »*, *« Pipeline technique ? »* |
| [[grasbot-retrieval]] | Technique interne (scoring, BM25, graphe) | *« Comment le chatbot trouve-t-il ses réponses ? »* |
| [[architecture-site]] | Stack globale Next + Strapi + FastAPI | *« Comment est fait le site ? »* |
| [[ia]] | Compétence (parcours IA de Fernand) | *« Quelles sont ses compétences en IA ? »* |
## Liens
- [[MOC-Projets]] — hub projets
- [[MOC-Ia]] — hub domaine *ia*
- [[ia]] — compétence IA (fiche) ; GrasBot y apparaît en réalisation
- [[fernandgrascalvet-com]] — le site qui héberge GrasBot
- [[newsletter-ia]] · [[transcription-video]] — autres réalisations IA