## Bug Fixes ### Note Card Actions - Fix broken size change functionality (missing state declaration) - Implement React 19 useOptimistic for instant UI feedback - Add startTransition for non-blocking updates - Ensure smooth animations without page refresh - All note actions now work: pin, archive, color, size, checklist ### Markdown LaTeX Rendering - Add remark-math and rehype-katex plugins - Support inline equations with dollar sign syntax - Support block equations with double dollar sign syntax - Import KaTeX CSS for proper styling - Equations now render correctly instead of showing raw LaTeX ## Technical Details - Replace undefined currentNote references with optimistic state - Add optimistic updates before server actions for instant feedback - Use router.refresh() in transitions for smart cache invalidation - Install remark-math, rehype-katex, and katex packages ## Testing - Build passes successfully with no TypeScript errors - Dev server hot-reloads changes correctly
464 lines
19 KiB
Markdown
464 lines
19 KiB
Markdown
# Epic: Amélioration de la Recherche Sémantique - Version 2.0
|
|
|
|
**Epic ID:** EPIC-SEARCH-2.0
|
|
**Status:** Draft
|
|
**Priority:** High
|
|
**Created:** 2026-01-09
|
|
**Owner:** Development Team
|
|
|
|
---
|
|
|
|
## Description du Problème
|
|
|
|
L'actuel système de recherche hybride (mots-clés + sémantique) produit des résultats non pertinents et imprévisibles. Les utilisateurs se plaignent que la recherche "fait n'importe quoi" - les résultats ne correspondent pas à leurs attentes, même quand les notes contiennent les termes recherchés.
|
|
|
|
### Analyse des Causes Racines
|
|
|
|
Après analyse du code dans `keep-notes/app/actions/notes.ts` (lignes 108-212), les problèmes identifiés sont:
|
|
|
|
1. **Seuil de similarité cosine trop bas (0.40)**: Permet des correspondances sémantiques de très faible qualité, créant du bruit dans les résultats
|
|
2. **RRF (Reciprocal Rank Fusion) mal configuré**: Le constant k=60 n'est pas optimal pour le petit nombre de notes typique dans Keep
|
|
3. **Pondération fixe recherche mot-clé/sémantique**: Les poids sont hardcodés (3 pour titre, 1 pour contenu, 2 pour labels) sans adaptation au type de requête
|
|
4. **Absence de validation des embeddings**: Pas de vérification que les embeddings sont correctement générés ou de dimensionnalité cohérente
|
|
5. **Manque de prétraitement des requêtes**: Pas de stemming, lemmatization, ou expansion de requête
|
|
6. **Aucune métrique de qualité**: Impossible de mesurer l'amélioration ou la dégradation des performances
|
|
|
|
### Impact Utilisateur
|
|
|
|
- **Frustration**: Perte de temps à filtrer manuellement les résultats non pertinents
|
|
- **Perte de confiance**: Les utilisateurs désactivent ou évitent la recherche intelligente
|
|
- **Expérience dégradée**: Contredit la promesse d'une recherche "intuitive" du PRD
|
|
|
|
---
|
|
|
|
## Objectifs Mesurables
|
|
|
|
1. **Améliorer la précision de recherche de 40%** (mesurée par tests automatisés)
|
|
2. **Réduire les faux positifs sémantiques de 60%** (seuil plus strict)
|
|
3. **Temps de réponse < 300ms** pour 1000 notes (objectif PRD existant)
|
|
4. **Satisfaction utilisateur > 4/5** (feedback post-déploiement)
|
|
5. **Taux de "serendipity" (résultats sémantiques sans mots-clés) entre 20-40%** (objectif PRD)
|
|
|
|
---
|
|
|
|
## User Stories
|
|
|
|
### Story 1: Validation et Qualité des Embeddings
|
|
|
|
**ID:** SEARCH-2.0-1
|
|
**Title:** Valider la qualité des embeddings générés
|
|
**Priority:** Must Have
|
|
**Estimation:** 3h
|
|
|
|
**En tant que:** développeur
|
|
**Je veux:** valider que les embeddings sont correctement générés et stockés
|
|
**Afin que:** la recherche sémantique fonctionne sur des données de qualité
|
|
|
|
**Critères d'Acceptation:**
|
|
1. **Given** une note avec du contenu texte
|
|
2. **When** l'embedding est généré via `provider.getEmbeddings()`
|
|
3. **Then** le vecteur doit:
|
|
- Avoir une dimensionnalité > 0
|
|
- Contenir des nombres valides (pas de NaN, Infinity)
|
|
- Avoir une norme L2 normale (entre 0.7 et 1.2)
|
|
4. **Given** des embeddings existants en base de données
|
|
5. **When** ils sont chargés via `parseNote()`
|
|
6. **Then** ils doivent être correctement désérialisés et validés
|
|
7. **And** une action admin `/api/debug/embeddings/validate` doit lister les notes problématiques
|
|
|
|
**Fichiers à Modifier:**
|
|
- `keep-notes/app/actions/notes.ts` - Ajouter validation dans `parseNote()`
|
|
- `keep-notes/lib/utils.ts` - Ajouter `validateEmbedding()` et `normalizeEmbedding()`
|
|
- `keep-notes/app/api/admin/embeddings/validate/route.ts` - Nouveau endpoint debug
|
|
|
|
**Tests Nécessaires:**
|
|
- Test unitaire `validateEmbedding()` avec vecteurs valides/invalides
|
|
- Test d'intégration création note → validation embedding
|
|
- Test endpoint API debug
|
|
|
|
**Risques:**
|
|
- Certains embeddings existants invalides nécessiteront un re-indexing
|
|
- Performance impact de la validation à chaque chargement
|
|
|
|
---
|
|
|
|
### Story 2: Optimisation du Seuil de Similarité Sémantique
|
|
|
|
**ID:** SEARCH-2.0-2
|
|
**Title:** Ajuster le seuil de similarité cosine pour éliminer le bruit
|
|
**Priority:** Must Have
|
|
**Estimation:** 4h
|
|
|
|
**En tant que:** utilisateur
|
|
**Je veux:** ne voir que des résultats sémantiquement pertinents
|
|
**Afin que:** la recherche me fasse confiance et me fasse gagner du temps
|
|
|
|
**Critères d'Acceptation:**
|
|
1. **Given** une requête de recherche sémantique
|
|
2. **When** les notes sont classées par similarité cosine
|
|
3. **Then** seules les notes avec similarité >= 0.65 sont considérées (au lieu de 0.40)
|
|
4. **And** le seuil doit être configurable dans `SystemConfig` (`SEARCH_SEMANTIC_THRESHOLD`)
|
|
5. **Given** une recherche avec résultats sémantiques faibles
|
|
6. **When** le seuil est appliqué
|
|
7. **Then** les faux positifs sont réduits d'au moins 50%
|
|
8. **And** un test automatisé mesure la réduction des faux positifs
|
|
|
|
**Fichiers à Modifier:**
|
|
- `keep-notes/app/actions/notes.ts` - Ligne 190, remplacer 0.40 par `config.SEARCH_SEMANTIC_THRESHOLD || 0.65`
|
|
- `keep-notes/lib/config.ts` - Lire la config depuis DB
|
|
- `keep-notes/tests/search-quality.spec.ts` - Ajouter tests de seuil
|
|
|
|
**Tests Nécessaires:**
|
|
- Test Playwright: recherche "coding" ne retourne PAS des notes sur "cuisine" (faux positifs)
|
|
- Test unitaire: vérifier que les scores < seuil sont filtrés
|
|
- Test de non-régression: s'assurer que les vrais positifs ne sont pas perdus
|
|
|
|
**Risques:**
|
|
- Seuil trop élevé peut éliminer des résultats pertinents (faux négatifs)
|
|
- Nécessite A/B testing pour trouver le seuil optimal
|
|
- Différents modèles d'embedding peuvent nécessiter des seuils différents
|
|
|
|
---
|
|
|
|
### Story 3: Reconfiguration de l'Algorithme RRF
|
|
|
|
**ID:** SEARCH-2.0-3
|
|
**Title:** Optimiser le paramètre k du Reciprocal Rank Fusion
|
|
**Priority:** Should Have
|
|
**Estimation:** 3h
|
|
|
|
**En tant que:** système
|
|
**Je veux:** un RRF avec un paramètre k adapté au nombre de notes typique
|
|
**Afin que:** le ranking hybride reflète mieux la pertinence réelle
|
|
|
|
**Critères d'Acceptation:**
|
|
1. **Given** un RRF avec constant k
|
|
2. **When** le nombre moyen de notes par utilisateur est < 500
|
|
3. **Then** k doit être 20 (au lieu de 60) pour mieux pénaliser les bas rangs
|
|
4. **And** k doit être configurable: `k = max(20, nombre_notes / 10)`
|
|
5. **Given** deux listes de ranking (mot-clé + sémantique)
|
|
6. **When** RRF est appliqué
|
|
7. **Then** les résultats bien classés dans les deux listes sont fortement favorisés
|
|
8. **And** la formule RRF est documentée dans le code
|
|
|
|
**Fichiers à Modifier:**
|
|
- `keep-notes/app/actions/notes.ts` - Lignes 182-198, ajuster k et ajouter logique adaptive
|
|
- `keep-notes/lib/utils.ts` - Ajouter `calculateRRFK(totalNotes: number): number`
|
|
|
|
**Tests Nécessaires:**
|
|
- Test unitaire: vérifier la formule RRF avec différents k
|
|
- Test d'intégration: comparer rankings avec k=20 vs k=60
|
|
- Test avec dataset de benchmark (notes + requêtes + résultats attendus)
|
|
|
|
**Risques:**
|
|
- Changer k peut impacter significativement l'ordre des résultats
|
|
- Nécessite validation utilisateur sur de vraies données
|
|
- Peut nécessiter des ajustements itératifs
|
|
|
|
---
|
|
|
|
### Story 4: Pondération Adaptative des Scores de Recherche
|
|
|
|
**ID:** SEARCH-2.0-4
|
|
**Title:** Adapter les poids mot-clé/sémantique selon le type de requête
|
|
**Priority:** Should Have
|
|
**Estimation:** 6h
|
|
|
|
**En tant que:** utilisateur
|
|
**Je veux:** que la recherche privilégie les mots-clés pour les termes exacts
|
|
**Et qu'elle privilégie le sémantique pour les concepts abstraits
|
|
**Afin que:** les résultats soient toujours pertinents
|
|
|
|
**Critères d'Acceptation:**
|
|
1. **Given** une requête avec des guillemets (ex: `"Error 404"`)
|
|
2. **When** la recherche est exécutée
|
|
3. **Then** le poids mot-clé est multiplié par 2 (recherche exacte prioritaire)
|
|
4. **Given** une requête conceptuelle (ex: "comment améliorer...")
|
|
5. **When** la recherche est exécutée
|
|
6. **Then** le poids sémantique est multiplié par 1.5 (concept prioritaire)
|
|
7. **Given** une requête mixte
|
|
8. **When** aucun pattern n'est détecté
|
|
9. **Then** les poids par défaut sont utilisés
|
|
10. **And** la logique de détection est documentée
|
|
|
|
**Fichiers à Modifier:**
|
|
- `keep-notes/app/actions/notes.ts` - Ajouter `detectQueryType()` et ajuster les poids
|
|
- `keep-notes/lib/types.ts` - Ajouter `QueryType: 'exact' | 'conceptual' | 'mixed'`
|
|
- `keep-notes/lib/utils.ts` - Ajouter `detectQueryType(query: string): QueryType`
|
|
|
|
**Tests Nécessaires:**
|
|
- Test unitaire `detectQueryType()` avec différents patterns
|
|
- Test d'intégration: vérifier que `"Error 404"` privilégie les mots-clés
|
|
- Test d'intégration: vérifier que "comment cuisiner" privilégie le sémantique
|
|
- Test Playwright: scénarios de recherche avec guillemets
|
|
|
|
**Risques:**
|
|
- La détection automatique du type de requête peut être imprécise
|
|
- Nécessite des règles bien pensées pour éviter les effets de bord
|
|
- Peut nécessiter du machine learning pour être vraiment efficace
|
|
|
|
---
|
|
|
|
### Story 5: Expansion et Normalisation des Requêtes
|
|
|
|
**ID:** SEARCH-2.0-5
|
|
**Title:** Améliorer les requêtes par expansion et normalisation
|
|
**Priority:** Could Have
|
|
**Estimation:** 5h
|
|
|
|
**En tant que:** utilisateur francophone/anglophone
|
|
**Je veux:** que ma recherche trouve les résultats même avec des variations de mots
|
|
**Afin que:** je n'aie pas à deviner les termes exacts utilisés
|
|
|
|
**Critères d'Acceptation:**
|
|
1. **Given** une requête avec des mots au pluriel (ex: "recettes pizzas")
|
|
2. **When** la recherche est exécutée
|
|
3. **Then** les singuliers sont aussi recherchés ("recette pizza")
|
|
4. **Given** une requête avec des accents (ex: "éléphant")
|
|
5. **When** la recherche est exécutée
|
|
6. **Then** les variantes sans accents sont aussi recherchées ("elephant")
|
|
7. **Given** une requête courte (< 3 mots)
|
|
8. **When** l'expansion est activée
|
|
9. **Then** des synonymes courants sont ajoutés (ex: "bug" → "erreur", "problème")
|
|
10. **And** l'expansion est limitée à 3 termes par mot original
|
|
|
|
**Fichiers à Modifier:**
|
|
- `keep-notes/app/actions/notes.ts` - Ajouter `expandQuery()` avant le calcul des scores
|
|
- `keep-notes/lib/utils.ts` - Implémenter `expandQuery()` et `normalizeText()`
|
|
- `keep-notes/lib/data/synonyms.json` - Créer une liste de synonymes (FR/EN)
|
|
|
|
**Tests Nécessaires:**
|
|
- Test unitaire `expandQuery()` avec différents cas
|
|
- Test d'intégration: recherche "pizzas" trouve notes avec "pizza"
|
|
- Test d'intégration: recherche "bug" trouve notes avec "erreur"
|
|
- Test performance: vérifier que l'expansion ne dégrade pas les performances
|
|
|
|
**Risques:**
|
|
- L'expansion de requête peut augmenter significativement les faux positifs
|
|
- La gestion des synonymes est complexe et contextuelle
|
|
- Nécessite une base de synonymes bien maintenue
|
|
- Peut ne pas être pertinent pour toutes les langues
|
|
|
|
---
|
|
|
|
### Story 6: Interface de Debug et Monitoring de Recherche
|
|
|
|
**ID:** SEARCH-2.0-6
|
|
**Title:** Créer une interface de debug pour analyser la qualité de recherche
|
|
**Priority:** Should Have
|
|
**Estimation:** 8h
|
|
|
|
**En tant que:** développeur/testeur
|
|
**Je veux:** visualiser les détails du calcul de score pour chaque résultat
|
|
**Afin que:** je puisse comprendre et optimiser la recherche
|
|
|
|
**Critères d'Acceptation:**
|
|
1. **Given** une recherche exécutée
|
|
2. **When** le mode debug est activé (`?debug=true`)
|
|
3. **Then** chaque résultat affiche:
|
|
- Score mot-clé brut
|
|
- Score sémantique brut (similarité cosine)
|
|
- Score RRF final
|
|
- Rang dans chaque liste (mot-clé / sémantique)
|
|
4. **Given** la page `/debug-search`
|
|
5. **When** j'accède à la page
|
|
6. **Then** je vois une interface pour:
|
|
- Tester des requêtes avec tous les paramètres
|
|
- Comparer différents seuils de similarité
|
|
- Voir les embeddings des notes
|
|
7. **And** les métriques sont exportables en JSON
|
|
|
|
**Fichiers à Modifier:**
|
|
- `keep-notes/app/actions/notes.ts` - Retourner les scores debug si demandé
|
|
- `keep-notes/app/debug-search/page.tsx` - Créer la page (existante dans git status)
|
|
- `keep-notes/components/search-debug-results.tsx` - Nouveau composant
|
|
- `keep-notes/app/api/debug/search/route.ts` - Nouveau endpoint API
|
|
|
|
**Tests Nécessaires:**
|
|
- Test E2E: accès à la page debug-search
|
|
- Test API: endpoint retourne bien les scores détaillés
|
|
- Test visuel: vérifier l'affichage des scores dans l'UI
|
|
- Test de performance: vérifier que le mode debug n'impacte pas la recherche normale
|
|
|
|
**Risques:**
|
|
- Complexité supplémentaire dans la UI
|
|
- Nécessite de bien sécuriser l'accès (admin uniquement)
|
|
- Informations sensibles (embeddings) visibles
|
|
|
|
---
|
|
|
|
### Story 7: Re-génération et Validation des Embeddings Existants
|
|
|
|
**ID:** SEARCH-2.0-7
|
|
**Title:** Script de re-indexation des embeddings invalides ou manquants
|
|
**Priority:** Must Have
|
|
**Estimation:** 4h
|
|
|
|
**En tant que:** administrateur système
|
|
**Je veux:** un script pour régénérer les embeddings des notes existantes
|
|
**Afin que:** toutes les notes bénéficient de la recherche sémantique
|
|
|
|
**Critères d'Acceptation:**
|
|
1. **Given** des notes avec embeddings manquants ou invalides
|
|
2. **When** je lance le script `npm run reindex-embeddings`
|
|
3. **Then** les embeddings sont régénérés pour toutes les notes
|
|
4. **And** la progression est affichée (X/Y notes traitées)
|
|
5. **Given** des notes avec des embeddings valides
|
|
6. **When** le script est lancé avec `--force`
|
|
7. **Then** tous les embeddings sont régénérés (même les valides)
|
|
8. **And** le script peut être relancé sans erreurs (idempotent)
|
|
9. **And** un rapport final résume les succès/erreurs
|
|
|
|
**Fichiers à Modifier:**
|
|
- `keep-notes/scripts/reindex-embeddings.ts` - Créer le script
|
|
- `keep-notes/app/actions/admin.ts` - Ajouter `reindexAllEmbeddings()`
|
|
- `keep-notes/package.json` - Ajouter le script npm
|
|
|
|
**Tests Nécessaires:**
|
|
- Test du script sur base de données vide
|
|
- Test du script avec des notes sans embeddings
|
|
- Test du script avec des embeddings invalides (NaN, dimension 0)
|
|
- Test du mode `--force`
|
|
- Test d'idempotence (relancer le script deux fois)
|
|
|
|
**Risques:**
|
|
- Temps d'exécution long si beaucoup de notes (plusieurs minutes/heures)
|
|
- Peut saturer le provider IA (Ollama/OpenAI) avec trop de requêtes
|
|
- Nécessite un mécanisme de rate limiting
|
|
- Peut impacter les performances de l'application si lancé pendant l'utilisation
|
|
|
|
---
|
|
|
|
### Story 8: Suite de Tests Automatisés de Qualité de Recherche
|
|
|
|
**ID:** SEARCH-2.0-8
|
|
**Title:** Créer des tests automatisés pour mesurer la qualité de recherche
|
|
**Priority:** Should Have
|
|
**Estimation:** 6h
|
|
|
|
**En tant que:** développeur
|
|
**Je veux:** une suite de tests automatisés pour valider la qualité de recherche
|
|
**Afin que:** les améliorations soient mesurables et les régressions détectées
|
|
|
|
**Critères d'Acceptation:**
|
|
1. **Given** un dataset de test (notes + requêtes + résultats attendus)
|
|
2. **When** les tests sont exécutés
|
|
3. **Then** les métriques suivantes sont calculées:
|
|
- Precision: % de résultats pertinents dans le top 10
|
|
- Recall: % de résultats pertinents trouvés
|
|
- MRR (Mean Reciprocal Rank): rang moyen du premier résultat pertinent
|
|
- Faux positifs sémantiques: résultats sans pertinence
|
|
4. **Given** une modification du code de recherche
|
|
5. **When** les tests sont relancés
|
|
6. **Then** une régression de plus de 5% fait échouer les tests
|
|
7. **And** les tests prennent < 2 minutes à s'exécuter
|
|
8. **And** un rapport HTML est généré pour analyse
|
|
|
|
**Fichiers à Modifier:**
|
|
- `keep-notes/tests/search-benchmark.spec.ts` - Créer le benchmark
|
|
- `keep-notes/tests/fixtures/search-dataset.json` - Dataset de test
|
|
- `keep-notes/tests/utils/search-metrics.ts` - Utilitaires de calcul de métriques
|
|
- `keep-notes/playwright.config.ts` - Configuration pour générer le rapport HTML
|
|
|
|
**Tests Nécessaires:**
|
|
- Test du test (métatest) avec un dataset trivial
|
|
- Test avec dataset réel (notes sur tech, cuisine, voyage, etc.)
|
|
- Test de régression: introduire un bug et vérifier que les tests le détectent
|
|
- Test de performance: temps d'exécution des tests
|
|
|
|
**Risques:**
|
|
- Création du dataset manuelle et longue
|
|
- Subjectivité de la "pertinence" (qui décide quoi est pertinent?)
|
|
- Maintenance du dataset à chaque nouvelle feature
|
|
- Tests peuvent être "flaky" si les embeddings changent
|
|
|
|
---
|
|
|
|
## Dépendances Entre Stories
|
|
|
|
```
|
|
SEARCH-2.0-1 (Validation Embeddings)
|
|
↓
|
|
SEARCH-2.0-7 (Re-génération) ← dépend de 1 pour détecter les invalides
|
|
↓
|
|
SEARCH-2.0-2 (Seuil Similarité) ← dépend de 1 pour des embeddings valides
|
|
↓
|
|
SEARCH-2.0-3 (RRF Config)
|
|
↓
|
|
SEARCH-2.0-4 (Pondération Adaptative)
|
|
↓
|
|
SEARCH-2.0-8 (Tests Automatisés) ← dépend de 2,3,4 pour mesurer les améliorations
|
|
↓
|
|
SEARCH-2.0-6 (Debug Interface) ← utile pendant le développement de toutes les autres
|
|
↓
|
|
SEARCH-2.0-5 (Expansion Requêtes) ← amélioration optionnelle à la fin
|
|
```
|
|
|
|
**Ordre recommandé:**
|
|
1. **Sprint 1:** SEARCH-2.0-1, SEARCH-2.0-7 (Base solide avec embeddings valides)
|
|
2. **Sprint 2:** SEARCH-2.0-2, SEARCH-2.0-3 (Corrections critiques du ranking)
|
|
3. **Sprint 3:** SEARCH-2.0-4, SEARCH-2.0-6 (Améliorations + tooling)
|
|
4. **Sprint 4:** SEARCH-2.0-8, SEARCH-2.0-5 (Tests + optimisations optionnelles)
|
|
|
|
---
|
|
|
|
## Métriques de Succès
|
|
|
|
### Avant/Après (Objectifs)
|
|
|
|
| Métrique | Avant | Après (Objectif) | Comment Mesurer |
|
|
|----------|-------|------------------|-----------------|
|
|
| Précision Top-10 | ~50% (estimé) | 70%+ | Tests automatisés Story 8 |
|
|
| Faux positifs sémantiques | ~30% | <10% | Tests Playwright |
|
|
| Temps de réponse (1000 notes) | 200ms | <300ms | Tests performance |
|
|
| Taux de serendipité | N/A | 20-40% | Tests dataset |
|
|
| Satisfaction utilisateur | 2/5 (subjectif) | 4/5+ | Sondage post-déploiement |
|
|
|
|
---
|
|
|
|
## Configuration Système Proposée
|
|
|
|
Nouveaux paramètres dans `SystemConfig`:
|
|
|
|
```typescript
|
|
interface SearchConfig {
|
|
// Seuil de similarité cosine minimum (0-1)
|
|
SEARCH_SEMANTIC_THRESHOLD: number; // défaut: 0.65
|
|
|
|
// Constante k pour RRF (adaptive)
|
|
SEARCH_RRF_K_BASE: number; // défaut: 20
|
|
SEARCH_RRF_K_ADAPTIVE: boolean; // défaut: true
|
|
|
|
// Pondération mot-clé vs sémantique
|
|
SEARCH_KEYWORD_BOOST_EXACT: number; // défaut: 2.0 (guillemets)
|
|
SEARCH_KEYWORD_BOOST_CONCEPTUAL: number; // défaut: 0.7
|
|
SEARCH_SEMANTIC_BOOST_EXACT: number; // défaut: 0.7
|
|
SEARCH_SEMANTIC_BOOST_CONCEPTUAL: number; // défaut: 1.5
|
|
|
|
// Expansion de requête
|
|
SEARCH_QUERY_EXPANSION_ENABLED: boolean; // défaut: true
|
|
SEARCH_QUERY_EXPANSION_MAX_SYNONYMS: number; // défaut: 3
|
|
|
|
// Debug
|
|
SEARCH_DEBUG_MODE: boolean; // défaut: false
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Fichers Critiques pour l'Implémentation
|
|
|
|
Les 5 fichiers les plus importants à modifier:
|
|
|
|
1. **keep-notes/app/actions/notes.ts** - Logique de recherche principale (RRF, seuils, ranking)
|
|
2. **keep-notes/lib/utils.ts** - Fonctions de similarité cosine et nouvelles utilités
|
|
3. **keep-notes/lib/ai/providers/ollama.ts** - Génération des embeddings avec validation
|
|
4. **keep-notes/tests/search-quality.spec.ts** - Tests de qualité de recherche
|
|
5. **keep-notes/lib/config.ts** - Configuration des nouveaux paramètres
|
|
|
|
---
|
|
|
|
**Document Version:** 1.0
|
|
**Last Updated:** 2026-01-09
|
|
**Agent:** Plan (a551c9b)
|