This commit is contained in:
2026-04-27 19:20:01 +02:00
parent 09f095dc56
commit 03158e226b
2 changed files with 102 additions and 0 deletions

View File

@@ -262,3 +262,88 @@ Attention cache mobile:
- `index.html` charge `/app.js?v=7`. - `index.html` charge `/app.js?v=7`.
- Service worker: `opensquared-assistant-v7`. - Service worker: `opensquared-assistant-v7`.
- Si Android garde l'ancien JS, fermer/rouvrir Chrome ou reinstaller la PWA. - Si Android garde l'ancien JS, fermer/rouvrir Chrome ou reinstaller la PWA.
## Session memoire professionnelle et routeur SQL - 2026-04-27
Objectif:
- Construire une memoire professionnelle utilisable par l'assistant vocal.
- Stocker clients, projets, taches, notes et repos associes.
- Permettre des questions naturelles du type:
- `Quels sont mes clients ?`
- `Que dois-je faire pour ICT ?`
- `Pour quel client ai-je le plus de taches ?`
- `Note que pour FAIRCOT je dois tester le lien vers le PDF.`
Problemes observes pendant les tests:
- Les premieres versions etaient trop basees sur des regex et des actions en dur.
- Les formulations vocales variables, les typos et les phrases de suivi rendaient cette approche fragile.
- Exemple: `note le comme une tache pour FAIRCOT` devait comprendre que `le` faisait reference au message precedent, pas a une regle specifique.
- Les actions de lecture specialisees se multipliaient trop vite: liste clients, liste taches, taches par client, client avec le plus de taches, etc.
- Risque identifie: creer une action rigide pour chaque question probable au lieu de laisser le modele raisonner sur le schema.
Architecture retenue:
- SQLite reste le stockage principal.
- Le modele recoit:
- le schema de la base,
- un extrait de memoire actuelle,
- l'historique recent de conversation,
- le dernier message utilisateur.
- Un routeur LLM decide entre trois sorties:
- `action`: ecriture controlee, par exemple ajouter client, ajouter tache, terminer tache, ajouter repo.
- `interroger_base`: lecture SQL readonly generee par le modele.
- `clarification`: question a Laurent si la cible ou l'intention est ambigue.
- Les lectures globales ne doivent plus devenir une explosion d'actions codees en dur.
- Pour une question analytique, le modele genere un `SELECT`, puis l'app execute uniquement ce SQL en lecture seule.
Pourquoi ce choix:
- Les questions metier sont ouvertes et evoluent vite.
- Le modele est meilleur pour mapper une demande naturelle vers une intention ou une requete SQL que des regex fragiles.
- Le dernier message reste prioritaire, mais le modele doit raisonner avec l'historique recent pour comprendre `lui`, `le`, `cette tache`, `ce client`.
- Les ecritures restent controlees par une liste d'actions permises afin d'eviter qu'un SQL genere ne modifie la base.
- Les lectures sont flexibles via SQL readonly, mais protegees par validation.
Securite SQL readonly:
- `memory.execute_read_query()` accepte uniquement une seule requete `SELECT`.
- Les points-virgules, commentaires SQL, `PRAGMA`, `INSERT`, `UPDATE`, `DELETE`, `DROP`, etc. sont rejetes.
- SQLite `set_authorizer` bloque les operations non autorisees.
- Les tables lisibles sont limitees a:
- `clients`
- `projects`
- `tasks`
- `repositories`
- `memories`
- Le resultat est limite pour eviter les sorties trop longues.
Corrections importantes de la session:
- Le routeur utilise maintenant davantage d'historique recent pour les phrases de suivi.
- Le prompt de secours ne demande plus au modele de produire du JSON d'action; cela evite de concurrencer le routeur.
- Les anciennes fonctions regex sont considerees comme heritage/code mort si elles ne sont plus appelees.
- Correction du bug `"'id'"` en rouge:
- cause: des lignes SQL de synthese etaient stockees dans le contexte comme si elles etaient toujours des taches completes avec `id` et `title`;
- fix: le contexte n'assume plus que chaque ligne possede ces champs.
Decision importante:
- Ne pas ajouter de micro-regles specifiques comme `pending_note` pour chaque cas de suivi.
- Preferer un routeur LLM qui evalue l'intention avec toute la conversation recente.
- Si le modele doute, il doit demander une precision plutot que choisir une action au hasard.
Limite actuelle:
- La qualite depend beaucoup du modele Groq utilise pour le routage.
- Si les references implicites continuent a echouer, tester un modele plus fort ou separer en deux appels:
- appel 1: comprendre l'intention et la cible avec l'historique;
- appel 2: generer l'action ou le SQL readonly.
Etat mental a garder pour la suite:
- Pour les ecritures: actions explicites, schema stable, confirmation si doute.
- Pour les lectures: SQL readonly genere par le modele.
- Pour les phrases ambigues: clarification utilisateur.
- Eviter de transformer chaque bug conversationnel en regex supplementaire.

View File

@@ -162,6 +162,23 @@ Qu'est-ce que tu sais sur SAFTCO ?
La memoire peut contenir des clients, projets, taches, notes et depots Git associes a un projet. La memoire peut contenir des clients, projets, taches, notes et depots Git associes a un projet.
### Architecture de la memoire
L'assistant utilise une architecture en deux niveaux :
- les ecritures passent par des actions controlees (`ajouter_client`, `ajouter_tache`, `terminer_tache`, etc.) ;
- les lectures et analyses passent par un routeur LLM qui peut generer une requete SQL readonly sur le schema SQLite.
Ce choix evite de coder une action specifique pour chaque question possible. Par exemple, `quel client a le plus de taches ?`, `quelles sont mes taches a faire ?` ou `cette tache est pour quel client ?` peuvent etre resolus en lisant la base plutot qu'en ajoutant des routes rigides.
Le routeur recoit le dernier message, l'historique recent, le schema de la base et un extrait de la memoire. Il decide entre :
- executer une action d'ecriture autorisee ;
- lancer une lecture SQL readonly ;
- demander une clarification si la cible est ambigue.
Les requetes SQL generees sont limitees a des `SELECT` et passent par une validation readonly dans `memory.py`.
## Notes ## Notes
- Groq Orpheus TTS doit etre accepte dans la console Groq pour fonctionner : - Groq Orpheus TTS doit etre accepte dans la console Groq pour fonctionner :