2026-05-10 11:36:52 +02:00

148 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
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"
route_parent: ia
# Slug public Strapi (realisation-ia, UID depuis le titre) — dernier segment de lURL site.
site_slug: gras-bot-chatbot-ia-du-portfolio
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