docs: Remove obsolete documentation files from library_rag

Cleaned up 15 obsolete MD files that were temporary session reports
and outdated documentation, now replaced by the organized docs/ structure
and comprehensive README.md.

Removed files:
- ANALYSE_ARCHITECTURE_WEAVIATE.md (superseded by docs/migration-gpu/)
- ANALYSE_RAG_FINAL.md (session report)
- ANALYSE_RESULTATS_RESUME.md (session report)
- COMPLETE_SESSION_RECAP.md (session report)
- EXPLICATION_SUMMARY_CHUNK.md (old technical docs)
- FIX_HIERARCHICAL.md (session report)
- INTEGRATION_SUMMARY.md (session report)
- PLAN_LLM_SUMMARIZER.md (old planning docs)
- QUICKSTART_SUMMARY_SEARCH.md (superseded by README.md)
- README_SEARCH.md (superseded by README.md)
- REFACTOR_SUMMARY.md (session report)
- SESSION_SUMMARY.md (session report)
- TTS_INSTALLATION_GUIDE.md (not used)
- WEAVIATE_GUIDE_COMPLET.md (superseded by README.md)
- WEAVIATE_SCHEMA.md (superseded by schema.py comments)

Retained documentation:
✓ README.md (main documentation)
✓ docs/ (organized migration and project docs)
✓ docs_techniques/ (technical specifications)
✓ .claude/CLAUDE.md (Claude Code instructions)
✓ examples/ (usage examples)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-09 12:52:32 +01:00
parent 7cbcdeb476
commit c90864e9f7
15 changed files with 0 additions and 6631 deletions

View File

@@ -1,613 +0,0 @@
# Analyse Architecture Weaviate - Library RAG
**Date**: 2026-01-03
**Dernier commit**: `b76e56e` - refactor: Suppression tous fonds beiges header section
**Status**: Production (13,829 vecteurs indexés)
---
## 📋 Table des Matières
1. [Vue d'Ensemble de la Base Weaviate](#1-vue-densemble-de-la-base-weaviate)
2. [Collections et leurs Relations](#2-collections-et-leurs-relations)
3. [Focus: Œuvre, Document, Chunk - La Hiérarchie Centrale](#3-focus-œuvre-document-chunk---la-hiérarchie-centrale)
4. [Stratégie de Recherche: Résumés → Chunks](#4-stratégie-de-recherche-résumés--chunks)
5. [Outils Weaviate: Utilisés vs Non-Utilisés](#5-outils-weaviate-utilisés-vs-non-utilisés)
6. [Recommandations pour Exploiter Weaviate à 100%](#6-recommandations-pour-exploiter-weaviate-à-100)
7. [Annexes Techniques](#7-annexes-techniques)
---
## 1. Vue d'Ensemble de la Base Weaviate
### 1.1 Architecture Générale
Library RAG utilise **Weaviate 1.34.4** comme base vectorielle pour indexer et rechercher des textes philosophiques. L'architecture suit un modèle **normalisé avec dénormalisation stratégique** via nested objects.
```
┌─────────────────────────────────────────────────────────────┐
│ WEAVIATE DATABASE │
├─────────────────────────────────────────────────────────────┤
│ │
│ Work (0 objets) Document (16 objets) │
│ └─ Métadonnées œuvre └─ Métadonnées édition │
│ (vectorisé) (non vectorisé) │
│ │
│ Chunk (5,404 objets) ⭐ Summary (8,425 objets) │
│ └─ Fragments vectorisés └─ Résumés vectorisés │
│ COLLECTION PRINCIPALE (recherche hiérarchique) │
│ │
└─────────────────────────────────────────────────────────────┘
```
### 1.2 Statistiques Clés
| Collection | Objets | Vectorisé | Taille estimée | Utilisation |
|------------|--------|-----------|----------------|-------------|
| **Chunk** | **5,404** | ✅ Oui (text + keywords) | ~3 MB | **Recherche sémantique principale** |
| **Summary** | **8,425** | ✅ Oui (text + concepts) | ~5 MB | Recherche hiérarchique par chapitres |
| **Document** | **16** | ❌ Non | ~10 KB | Métadonnées éditions |
| **Work** | **0** | ✅ Oui (title + author)* | 0 B | Prêt pour migration |
**Total vecteurs**: 13,829 (5,404 chunks + 8,425 summaries)
**Ratio Summary/Chunk**: 1.56 (1.6 résumés par chunk, excellent pour recherche hiérarchique)
\* *Work est configuré avec vectorisation depuis migration 2026-01 mais actuellement vide*
### 1.3 Modèle de Vectorisation
**Modèle**: BAAI/bge-m3
**Dimensions**: 1024
**Contexte**: 8192 tokens
**Langues supportées**: Grec ancien, Latin, Français, Anglais
**Migration Dec 2024**: MiniLM-L6 (384-dim) → BGE-M3 (1024-dim)
- **Gain**: 2.7x plus riche en représentation sémantique
- **Performance**: Meilleure sur textes philosophiques/académiques
- **Multilingue**: Support natif grec/latin
---
## 2. Collections et leurs Relations
### 2.1 Architecture des Collections
```
Work (Œuvre philosophique)
│ Nested in Document.work: {title, author}
│ Nested in Chunk.work: {title, author}
Document (Édition/traduction spécifique)
│ Nested in Chunk.document: {sourceId, edition}
│ Nested in Summary.document: {sourceId}
├─► Chunk (Fragments de texte, 200-800 chars)
│ └─ Vectorisé: text, keywords
│ └─ Filtres: sectionPath, unitType, orderIndex
└─► Summary (Résumés de chapitres/sections)
└─ Vectorisé: text, concepts
└─ Hiérarchie: level (1=chapitre, 2=section, 3=subsection)
```
### 2.2 Collection Work (Œuvre)
**Rôle**: Représente une œuvre philosophique canonique (ex: Ménon de Platon)
**Propriétés**:
```python
title: TEXT (VECTORISÉ) # "Ménon", "République"
author: TEXT (VECTORISÉ) # "Platon", "Peirce"
originalTitle: TEXT [skip_vec] # "Μένων" (grec)
year: INT # -380 (avant J.-C.)
language: TEXT [skip_vec] # "gr", "la", "fr"
genre: TEXT [skip_vec] # "dialogue", "traité"
```
**Vectorisation**: Activée depuis 2026-01
-`title` vectorisé → recherche "dialogues socratiques" trouve Ménon
-`author` vectorisé → recherche "philosophie analytique" trouve Haugeland
**Status actuel**: Vide (0 objets), prêt pour migration
### 2.3 Collection Document (Édition)
**Rôle**: Représente une édition ou traduction spécifique d'une œuvre
**Propriétés**:
```python
sourceId: TEXT # "platon_menon_cousin"
edition: TEXT # "trad. Cousin, 1844"
language: TEXT # "fr" (langue de cette édition)
pages: INT # 120
chunksCount: INT # 338 (nombre de chunks extraits)
toc: TEXT (JSON) # Table des matières structurée
hierarchy: TEXT (JSON) # Hiérarchie complète des sections
createdAt: DATE # 2025-12-09T09:20:30
# Nested object
work: {
title: TEXT # "Ménon"
author: TEXT # "Platon"
}
```
**Vectorisation**: ❌ Non (métadonnées uniquement)
### 2.4 Collection Chunk ⭐ (PRINCIPALE)
**Rôle**: Fragments de texte optimisés pour recherche sémantique (200-800 caractères)
**Propriétés vectorisées**:
```python
text: TEXT (VECTORISÉ) # Contenu du fragment
keywords: TEXT_ARRAY (VECTORISÉ) # ["justice", "vertu", "connaissance"]
```
**Propriétés de filtrage** (non vectorisées):
```python
sectionPath: TEXT [skip_vec] # "Présentation > Qu'est-ce que la vertu?"
sectionLevel: INT # 2 (profondeur hiérarchique)
chapterTitle: TEXT [skip_vec] # "Présentation"
canonicalReference: TEXT [skip_vec] # "Ménon 80a" ou "CP 5.628"
unitType: TEXT [skip_vec] # "argument", "définition", "exposition"
orderIndex: INT # 42 (position séquentielle 0-based)
language: TEXT [skip_vec] # "fr", "en", "gr"
```
**Nested objects** (dénormalisation):
```python
work: {
title: TEXT # "Ménon"
author: TEXT # "Platon"
}
document: {
sourceId: TEXT # "platon_menon_cousin"
edition: TEXT # "trad. Cousin"
}
```
**Exemple d'objet**:
```json
{
"text": "SOCRATE. - Peux-tu me dire, Ménon, si la vertu peut s'enseigner?",
"keywords": ["vertu", "enseignement", "question socratique"],
"sectionPath": "Présentation > Qu'est-ce que la vertu?",
"sectionLevel": 2,
"chapterTitle": "Présentation",
"canonicalReference": "Ménon 70a",
"unitType": "argument",
"orderIndex": 0,
"language": "fr",
"work": {
"title": "Ménon ou de la vertu",
"author": "Platon"
},
"document": {
"sourceId": "platon_menon_cousin",
"edition": "trad. Cousin"
}
}
```
### 2.5 Collection Summary (Résumés)
**Rôle**: Résumés LLM de chapitres/sections pour recherche hiérarchique
**Propriétés vectorisées**:
```python
text: TEXT (VECTORISÉ) # Résumé généré par LLM
concepts: TEXT_ARRAY (VECTORISÉ) # ["réminiscence", "anamnèse", "connaissance innée"]
```
**Propriétés de filtrage**:
```python
sectionPath: TEXT [skip_vec] # "Livre I > Chapitre 2"
title: TEXT [skip_vec] # "La réminiscence et la connaissance"
level: INT # 1=chapitre, 2=section, 3=subsection
chunksCount: INT # 15 (nombre de chunks dans cette section)
```
---
## 3. Focus: Œuvre, Document, Chunk - La Hiérarchie Centrale
### 3.1 Modèle de Données
L'architecture suit un modèle **normalisé avec dénormalisation stratégique** :
```
┌──────────────────────────────────────────────────────────────┐
│ MODÈLE NORMALISÉ │
├──────────────────────────────────────────────────────────────┤
│ │
│ Work (Source de vérité unique) │
│ title: "Ménon ou de la vertu" │
│ author: "Platon" │
│ year: -380 │
│ language: "gr" │
│ genre: "dialogue" │
│ │
│ ├─► Document 1 (trad. Cousin) │
│ │ sourceId: "platon_menon_cousin" │
│ │ edition: "trad. Cousin, 1844" │
│ │ language: "fr" │
│ │ pages: 120 │
│ │ chunksCount: 338 │
│ │ work: {title, author} ← DÉNORMALISÉ │
│ │ │
│ │ ├─► Chunk 1 │
│ │ │ text: "Peux-tu me dire, Ménon..." │
│ │ │ work: {title, author} ← DÉNORMALISÉ │
│ │ │ document: {sourceId, edition} ← DÉNORMALISÉ │
│ │ │ │
│ │ ├─► Chunk 2... │
│ │ └─► Chunk 338 │
│ │ │
│ │ ├─► Summary 1 (chapitre 1) │
│ │ │ text: "Cette section explore..." │
│ │ │ level: 1 │
│ │ │ document: {sourceId} ← DÉNORMALISÉ │
│ │ │ │
│ │ └─► Summary N... │
│ │ │
│ └─► Document 2 (Loeb Classical Library) │
│ sourceId: "plato_meno_loeb" │
│ edition: "Loeb Classical Library" │
│ language: "en" │
│ ... (même structure) │
│ │
└──────────────────────────────────────────────────────────────┘
```
### 3.2 Pourquoi Nested Objects au lieu de Cross-References ?
**Avantages**:
1.**Requête unique** - Récupération en une seule requête sans joins
2.**Performance** - Pas de jointures complexes côté application
3.**Simplicité** - Logique de requête plus simple
4.**Cache-friendly** - Toutes les métadonnées dans un seul objet
**Trade-off**:
- Pour 5,404 chunks: ~200 KB de duplication
- Économie de temps: ~50-100ms par requête (évite 2 roundtrips Weaviate)
---
## 4. Stratégie de Recherche: Résumés → Chunks
### 4.1 Pourquoi Deux Collections Vectorisées ?
**Problème**: Chercher directement dans 5,404 chunks peut manquer le contexte global
**Solution**: Architecture à deux niveaux
```
┌─────────────────────────────────────────────────────────────┐
│ RECHERCHE À DEUX NIVEAUX │
├─────────────────────────────────────────────────────────────┤
│ │
│ Niveau 1: MACRO (Summary - 8,425 objets) │
│ "Quels chapitres parlent de la réminiscence?" │
│ └─► Identifie: Chapitre 2, Section 3 │
│ │
│ Niveau 2: MICRO (Chunk - 5,404 objets) │
│ "Quelle est la définition exacte de l'anamnèse?" │
│ └─► Trouve: Chunk #42 dans la section identifiée │
│ │
└─────────────────────────────────────────────────────────────┘
```
**Avantages**:
1. ✅ Meilleure précision (contexte chapitres + détails chunks)
2. ✅ Performance optimale (filtrer chunks par section identifiée)
3. ✅ Hiérarchie exploitée (level 1=chapitre, 2=section, 3=subsection)
### 4.2 Stratégies de Recherche Implémentables
#### Stratégie 1: Sequential Search (Résumés puis Chunks)
**Cas d'usage**: Recherche approfondie avec contexte
```python
# 1. Chercher dans Summary (macro)
summaries = client.collections.get("Summary")
summary_results = summaries.query.near_text(
query="théorie de la réminiscence",
limit=5,
filters=Filter.by_property("level").equal(1) # Chapitres uniquement
)
# 2. Extraire sections pertinentes
relevant_sections = [
s.properties['sectionPath']
for s in summary_results.objects
]
# 3. Chercher chunks dans ces sections (micro)
chunks = client.collections.get("Chunk")
chunk_results = chunks.query.near_text(
query="qu'est-ce que l'anamnèse?",
limit=10,
filters=Filter.by_property("sectionPath").like(f"{relevant_sections[0]}*")
)
```
**Performance**: 2 requêtes (~50ms chacune) = 100ms total
#### Stratégie 2: Hybrid Two-Stage avec Score Boosting
**Algorithme recommandé pour production**:
```python
def hybrid_search(query: str, limit: int = 10) -> List[ChunkResult]:
"""Recherche hybride résumés → chunks avec boosting."""
# Stage 1: Summary search (macro)
summaries = client.collections.get("Summary")
summary_results = summaries.query.near_text(
query=query,
limit=3, # Top 3 chapitres
filters=Filter.by_property("level").less_or_equal(2),
return_metadata=wvq.MetadataQuery(distance=True)
)
# Stage 2: Chunk search avec boost par section
chunks = client.collections.get("Chunk")
all_chunks = []
for summary in summary_results.objects:
section_path = summary.properties['sectionPath']
summary_score = 1 - summary.metadata.distance
# Chercher chunks dans cette section
chunk_results = chunks.query.near_text(
query=query,
limit=5,
filters=Filter.by_property("sectionPath").like(f"{section_path}*"),
return_metadata=wvq.MetadataQuery(distance=True)
)
# Booster le score des chunks
for chunk in chunk_results.objects:
chunk_score = 1 - chunk.metadata.distance
boosted_score = (chunk_score * 0.7) + (summary_score * 0.3)
all_chunks.append({
'chunk': chunk,
'score': boosted_score,
'context_chapter': section_path
})
# Trier par score boosted
all_chunks.sort(key=lambda x: x['score'], reverse=True)
return all_chunks[:limit]
```
**Impact**: +15-20% précision, ~120ms latence
---
## 5. Outils Weaviate: Utilisés vs Non-Utilisés
### 5.1 Outils Actuellement Utilisés ✅
1. **Semantic Search (near_text)** - Recherche sémantique principale
2. **Filters (Nested Objects)** - Filtrage par author, work, language
3. **Fetch Objects** - Récupération par ID
4. **Batch Insertion** - Insertion groupée adaptative (10-100 objets)
5. **Delete Many** - Suppression en masse
### 5.2 Outils Weaviate NON Utilisés ❌
#### 1. Hybrid Search (Sémantique + BM25) ⚠️ **HAUTE PRIORITÉ**
**Qu'est-ce que c'est?**
Combine recherche vectorielle (sémantique) + BM25 (mots-clés exacts)
**Exemple d'implémentation**:
```python
result = chunks.query.hybrid(
query="qu'est-ce que la vertu?",
alpha=0.75, # 75% vectoriel, 25% BM25
limit=10,
filters=filters,
)
```
**Impact attendu**: +10-15% précision sur requêtes factuelles
#### 2. Generative Search (RAG natif) 🚨 **HAUTE PRIORITÉ**
**Qu'est-ce que c'est?**
Weaviate génère directement une réponse synthétique à partir des chunks
**Exemple**:
```python
result = chunks.generate.near_text(
query="qu'est-ce que la réminiscence chez Platon?",
limit=5,
grouped_task="Réponds à la question en utilisant ces 5 passages",
)
# Résultat contient:
# - result.objects: chunks trouvés
# - result.generated: réponse LLM générée
```
**Impact**: Réduction 50% latence end-to-end (RAG complet en une requête)
#### 3. Reranking (Cohere, Voyage AI) ⚠️ **MOYENNE PRIORITÉ**
Re-score les résultats avec un modèle spécialisé
**Impact**: +15-20% précision top-3, +50-100ms latence
#### 4. RAG Fusion (Multi-Query Search) ⚠️ **MOYENNE PRIORITÉ**
Génère N variantes de la requête et fusionne les résultats
**Impact**: +20-25% recall
### 5.3 Matrice Priorités
| Outil | Priorité | Difficulté | Impact Précision | Impact Latence | Coût |
|-------|----------|------------|------------------|----------------|------|
| **Hybrid Search** | 🔴 Haute | Faible (1h) | +10-15% | +5ms | Gratuit |
| **Generative Search** | 🔴 Haute | Moyenne (3h) | +30% (RAG E2E) | -50% E2E | LLM API |
| **Reranking** | 🟡 Moyenne | Faible (2h) | +15-20% top-3 | +50-100ms | $0.001/req |
| **RAG Fusion** | 🟡 Moyenne | Moyenne (4h) | +20-25% recall | x3 requêtes | Gratuit |
---
## 6. Recommandations pour Exploiter Weaviate à 100%
### 6.1 Quick Wins (1-2 jours d'implémentation)
#### Quick Win #1: Activer Hybrid Search
**Fichier à modifier**: `schema.py`
```python
# Ajouter index BM25
wvc.Property(
name="text",
data_type=wvc.DataType.TEXT,
index_searchable=True, # ← Active BM25
)
```
**Fichier à modifier**: `mcp_tools/retrieval_tools.py`
```python
# Remplacer near_text par hybrid
result = chunks.query.hybrid(
query=input_data.query,
alpha=0.75, # 75% vectoriel, 25% BM25
limit=input_data.limit,
filters=filters,
)
```
**Impact**: +10% précision, <5ms surcoût
#### Quick Win #2: Implémenter Two-Stage Search
Créer `utils/two_stage_search.py` avec l'algorithme hybrid boosting (voir section 4.2)
**Impact**: +15-20% précision, ~120ms latence
### 6.2 High-Impact Features (1 semaine d'implémentation)
#### Feature #1: Generative Search (RAG Natif)
**Étape 1**: Activer module dans docker-compose.yml
```yaml
services:
weaviate:
environment:
GENERATIVE_ANTHROPIC_APIKEY: ${ANTHROPIC_API_KEY}
```
**Étape 2**: Endpoint Flask
```python
@app.route("/search/generative", methods=["GET"])
def search_generative():
query = request.args.get("q", "")
chunks = client.collections.get("Chunk")
result = chunks.generate.near_text(
query=query,
limit=5,
grouped_task=f"Réponds à: {query}. Utilise les passages fournis.",
)
return jsonify({
"answer": result.generated,
"sources": [...]
})
```
**Impact**: RAG complet en une requête, -50% latence E2E
---
## 7. Annexes Techniques
### 7.1 Exemple de Requête Complète
```python
import weaviate
from weaviate.classes.query import Filter
client = weaviate.connect_to_local()
chunks = client.collections.get("Chunk")
# Recherche: "vertu" chez Platon en français
result = chunks.query.near_text(
query="qu'est-ce que la vertu?",
limit=10,
filters=(
Filter.by_property("work").by_property("author").equal("Platon") &
Filter.by_property("language").equal("fr")
),
return_metadata=wvq.MetadataQuery(distance=True)
)
for obj in result.objects:
props = obj.properties
similarity = 1 - obj.metadata.distance
print(f"Similarité: {similarity:.3f}")
print(f"Texte: {props['text'][:100]}...")
print(f"Œuvre: {props['work']['title']}")
print(f"Référence: {props['canonicalReference']}")
print("---")
client.close()
```
### 7.2 Glossaire Weaviate
| Terme | Définition |
|-------|------------|
| **Collection** | Équivalent d'une "table" en SQL |
| **Object** | Une entrée dans une collection |
| **Vector** | Représentation numérique (1024-dim pour BGE-M3) |
| **near_text** | Recherche sémantique par similarité |
| **hybrid** | Recherche combinée (vectorielle + BM25) |
| **Nested Object** | Objet imbriqué (ex: `work: {title, author}`) |
| **HNSW** | Index vectoriel performant |
| **RQ** | Rotational Quantization (-75% RAM) |
---
## Conclusion
### Points Clés
1. **Architecture solide** - 4 collections avec nested objects
2. **13,829 vecteurs** - Base de production opérationnelle
3. **Ratio 1.56 Summary/Chunk** - Excellent pour recherche hiérarchique
4. **Utilisation 30%** - Beaucoup de potentiel non exploité
### Roadmap Recommandée
**Q1 2026** (Quick Wins):
1. Hybrid Search (1 jour)
2. Two-Stage Search (3 jours)
3. Métriques/monitoring (2 jours)
**Q2 2026** (High Impact):
1. Generative Search (1 semaine)
2. Reranking (3 jours)
3. Semantic caching (3 jours)
---
**Dernière mise à jour**: 2026-01-03
**Version**: 1.0

View File

@@ -1,206 +0,0 @@
# Analyse Finale du Système RAG Library - État au 2026-01-03
## Résumé Exécutif
Le système RAG a été considérablement amélioré grâce à la génération de résumés LLM de haute qualité. La recherche dans la collection **Summary** fonctionne excellemment (90% de visibilité des documents riches). Cependant, la recherche dans la collection **Chunk** souffre d'une domination écrasante des chunks Peirce (97% de la base), rendant les autres documents pratiquement introuvables.
## État de la Base de Données
### Collection Summary
- **Total**: 114 résumés
- **Riches** (>100 chars): 106 résumés
- **Vides** (titres): 8 résumés
**Répartition par document:**
- Tiercelin: 51 résumés (43 riches)
- Haugeland: 50 résumés
- Platon: 12 résumés
- La logique de la science: 1 résumé
**Performance de recherche**: 90% de visibilité (54/60 résultats sur 15 requêtes réelles)
### Collection Chunk
- **Total**: 5,230 chunks
- **Peirce**: 5,068 chunks (97%)
- **Haugeland**: 50 chunks (1%)
- **Platon**: 50 chunks (1%)
- **Tiercelin**: 36 chunks (0.7%)
- **Autres**: 26 chunks (0.5%)
**Ratio problématique**: 97:3 (Peirce:Autres)
## Travaux Réalisés
### Phase 1: Génération des Résumés
| Document | Résumés | Coût | Statut |
|----------|---------|------|--------|
| Tiercelin | 43 | $0.63 | ✅ Complet |
| Platon | 12 | $0.14 | ✅ Complet |
| La logique de la science | 1 | $0.02 | ✅ Complet |
| Haugeland | 50 | $0.44 | ✅ Complet |
| **TOTAL** | **106** | **$1.23** | **✅ Complet** |
### Phase 2: Nettoyage de la Base
1. **Suppression de 7 doublons vides** (Tiercelin)
2. **Suppression de 8,313 résumés vides Peirce**
- Avant: 10% de visibilité
- Après: 63% → 90% (avec Haugeland)
## Performance par Type de Recherche
### ✅ Recherche dans Summary (EXCELLENT)
**15 requêtes réelles testées** couvrant 5 domaines:
- Pragmatisme/Peirce (3 requêtes)
- Platon/Vertu (3 requêtes)
- IA/Philosophie de l'esprit (3 requêtes)
- Sémiotique (3 requêtes)
- Épistémologie (3 requêtes)
**Résultat**: 90% de visibilité des résumés riches (54/60 résultats)
**Exemple de qualité**:
- Query: "Can virtue be taught according to Plato?"
- Top 3: Tous Platon, similarité 71-72%
- Résumés pertinents et informatifs
### ❌ Recherche dans Chunks (PROBLÉMATIQUE)
#### Test 1: Questions génériques sur l'IA (domaine de Haugeland)
**10 requêtes AI-spécifiques**:
- "What is the Turing test?"
- "Can machines think?"
- "What is a physical symbol system?"
- "How do connectionist networks work?"
- etc.
**Résultats (50 total)**:
- 🔴 Peirce: 44/50 (88%)
- 🟣 Haugeland: 5/50 (10%)
- 🟢 Platon: 1/50 (2%)
**Conclusion**: Même sur son domaine propre, Haugeland est écrasé.
#### Test 2: Recherche hiérarchique (Summary → Chunks)
**Stratégie**:
1. Identifier documents pertinents via Summary (fonctionne bien)
2. Filtrer chunks de ces documents (échoue - Peirce domine toujours)
**Exemple**:
- Query: "How do connectionist networks work?"
- Summary identifie correctement: Haugeland "Connectionist networks"
- Mais Chunk search retourne: 5/5 chunks Peirce (0/5 Haugeland)
**Limitation technique**: Weaviate v4 ne permet pas de filtrer par nested objects dans les requêtes → filtrage en Python après récupération.
## Problème Central
### Domination des Chunks Peirce
**Cause**: 5,068 chunks Peirce sur 5,230 total (97%)
**Impact**:
- Les chunks Peirce ont des similarités sémantiques élevées (73-77%) sur presque toutes les requêtes
- Ratio trop déséquilibré pour laisser apparaître d'autres documents
- Même la recherche hiérarchique ne résout pas le problème
**Contrainte utilisateur**:
> "NE SUPPRIME PAS LES CHUNKLS D EPEIRCE BORDEL"
Pas de suppression des chunks Peirce permise.
## Solutions Proposées
### Option A: Summary comme Interface Principale (RECOMMANDÉ)
**Statut**: Prouvé et fonctionnel (90% de visibilité)
**Avantages**:
- ✅ Fonctionne immédiatement (déjà testé)
- ✅ Coût: $0 (déjà implémenté)
- ✅ Performance excellente démontrée
- ✅ Interface utilisateur claire
**Mise en œuvre**:
```python
# Recherche primaire dans Summary
summary_results = summaries.query.near_text(
query=user_query,
limit=10,
return_metadata=wvq.MetadataQuery(distance=True)
)
# Afficher résumés avec contexte
for result in summary_results:
print(f"Document: {result.properties['document']['sourceId']}")
print(f"Section: {result.properties['title']}")
print(f"Résumé: {result.properties['text']}")
print(f"Concepts: {', '.join(result.properties['concepts'])}")
```
**Flux utilisateur**:
1. User pose une question
2. Système retourne résumés pertinents (comme Google Scholar)
3. User peut cliquer pour voir les chunks détaillés d'une section
### Option B: Système Hybride
**Statut**: Nécessite développement
**Fonctionnalités**:
- Toggle "Recherche par résumés" / "Recherche détaillée"
- Mode résumés par défaut (pour découverte)
- Mode chunks pour requêtes très précises
**Coût**: ~2-3 jours de développement UI
### Option C: Régénération Résumés Peirce
**Statut**: Non implémenté
**Estimation**:
- 5,068 chunks → ~500-600 sections
- Regroupement intelligent nécessaire
- Coût: $45-50
- Temps: 15-20 heures (génération + ingestion)
**Risque**: Peut ne pas résoudre le problème si les résumés Peirce restent sémantiquement proches de toutes les requêtes.
## Tests Disponibles
Tous les scripts de test sont dans `generations/library_rag/`:
1. **test_summaries_validation.py** - Validation complète des résumés
2. **test_real_queries.py** - 15 requêtes réelles sur Summary
3. **test_hierarchical_search.py** - Test Summary → Chunks
4. **test_haugeland_ai.py** - Test spécifique IA (domaine Haugeland)
## Recommandation Finale
**Implémenter Option A immédiatement**:
1. Interface de recherche principale sur Summary
2. 90% de visibilité déjà prouvée
3. Coût $0, temps < 1 jour
4. Respecte la contrainte (pas de suppression chunks Peirce)
**Future améliorations** (optionnel):
- Option B: Ajouter mode hybride si demandé
- Option C: Considérer seulement si vraiment nécessaire
## Statistiques Finales
### Coûts Totaux
- Génération résumés: $1.23
- Suppression données vides: $0
- **Total projet**: $1.23
### Résultats
- 106 résumés riches de haute qualité
- 90% de visibilité en recherche Summary
- Base de données propre et optimisée
- Interface de recherche fonctionnelle
### Performance
- Summary search: 90% pertinence ✅
- Chunk search: 10% pertinence ❌ (mais solution identifiée)
---
**Date**: 2026-01-03
**Système**: Weaviate 1.34.4 + BGE-M3 (1024-dim)
**LLM**: Claude Sonnet 4.5 (résumés) + text2vec-transformers (vectorisation)

View File

@@ -1,436 +0,0 @@
# Analyse des Résultats de Recherche - Collection Summary
**Date**: 2026-01-03
**Requête**: "Peirce et la sémiose"
**Collection**: Summary (8,425 objets)
**Résultats retournés**: 20
---
## 📊 Statistiques Globales
| Métrique | Valeur | Évaluation |
|----------|--------|------------|
| **Total résultats** | 20 | ✅ Bon |
| **Similarité moyenne** | 0.716 | ⚠️ Moyenne (< 0.75) |
| **Meilleur score** | 0.723 | ⚠️ Faible pour top-1 |
| **Plus mauvais score** | 0.713 | ⚠️ Très faible |
| **Niveau hiérarchique** | 100% Level 1 | ❌ Pas de diversité |
| **Documents sources** | 1 seul | ❌ Pas de diversité |
---
## 🚨 Problèmes Critiques Identifiés
### 1. Résumés Vides (CRITIQUE)
**Observation**: Tous les 20 résumés ont un champ `text` vide ou minimal.
**Exemple**:
```
Résumé: Peirce: CP 3.592
```
**Attendu**:
```
Résumé: Ce passage explore la théorie peircéenne de la sémiose comme processus
triadique impliquant le signe (representamen), l'objet et l'interprétant.
Peirce développe l'idée que la signification n'est jamais binaire mais
nécessite toujours cette relation ternaire irréductible...
```
**Impact**:
- ❌ La recherche ne peut pas matcher le contenu sémantique réel
- ❌ Les résumés ne servent à rien (pas de contexte)
- ❌ Impossible d'identifier les sections pertinentes
**Cause probable**:
- Les Summary n'ont jamais été remplis avec de vrais résumés LLM
- Le pipeline d'ingestion a sauté l'étape de génération de résumés
- OU les résumés ont été générés mais pas insérés dans Weaviate
### 2. Concepts Vides (CRITIQUE)
**Observation**: Le champ `concepts` est vide pour tous les résumés.
**Exemple**:
```
Concepts:
```
**Attendu**:
```
Concepts: sémiose, triade, signe, interprétant, représentamen, objet, signification
```
**Impact**:
- ❌ Impossible de filtrer par concepts philosophiques
- ❌ Perte d'une dimension sémantique clé
- ❌ Les résumés ne peuvent pas booster la recherche
### 3. Pas de Chunks Associés (CRITIQUE)
**Observation**: Tous les résumés ont `chunksCount: 0`.
**Exemple**:
```
Chunks dans cette section: 0
```
**Attendu**:
```
Chunks dans cette section: 15-50
```
**Impact**:
- ❌ Les résumés ne sont pas liés aux chunks
- ❌ Impossible de faire une recherche hiérarchique (Summary → Chunk)
- ❌ La stratégie two-stage est cassée
**Cause probable**:
- Les Summary ont été créés mais sans lien avec les Chunks
- Le champ `document.sourceId` dans Summary ne match pas avec `document.sourceId` dans Chunk
- OU les Summary ont été créés pour des sections qui n'ont pas de chunks
### 4. Similarité Faible (ALERTE)
**Observation**: Scores entre 0.713 et 0.723.
**Analyse**:
| Score | Interprétation |
|-------|----------------|
| > 0.90 | Excellent match |
| 0.80-0.90 | Bon match |
| 0.70-0.80 | Match moyen |
| **0.71-0.72** | **Match faible** ⚠️ |
| < 0.70 | Pas pertinent |
**Pourquoi c'est faible ?**
- Le modèle BGE-M3 match uniquement sur "Peirce: CP X.XXX" (titre)
- Pas de contenu sémantique à matcher
- La requête "Peirce et la sémiose" ne trouve que "Peirce" dans le titre
**Comparaison attendue**:
- Avec vrais résumés: scores 0.85-0.95
- Avec concepts remplis: boost de +0.05-0.10
### 5. Pas de Diversité Hiérarchique (ALERTE)
**Observation**: 100% des résultats sont Level 1 (chapitres).
**Distribution**:
```
Chapitre (Level 1): 20 résultats (100%)
Section (Level 2): 0 résultats (0%)
Subsection (Level 3): 0 résultats (0%)
```
**Impact**:
- ❌ Pas de navigation hiérarchique
- ❌ Tous les résultats au même niveau de granularité
- ❌ Impossible de drill-down dans les sous-sections
**Cause probable**:
- Les Summary ont été créés uniquement pour les Level 1
- Le pipeline n'a pas généré de résumés pour Level 2/3
### 6. Un Seul Document Source (ALERTE)
**Observation**: 100% des résultats viennent de `peirce_collected_papers_fixed`.
**Impact**:
- ⚠️ Pas de diversité (autres auteurs sur la sémiose ignorés)
- ⚠️ Biais vers Peirce (normal pour la requête, mais limite les perspectives)
**Note**: Ceci peut être acceptable car la requête contient "Peirce", mais d'autres documents comme "Tiercelin - La pensée-signe" devraient aussi matcher.
---
## 🔍 Analyse Détaillée des Résultats
### Top 5 Résultats
#### [1] CP 3.592 - Similarité: 0.723
**Référence Peirce**: CP 3.592 (Collected Papers, Volume 3, §592)
**Contenu actuel**: VIDE (juste "Peirce: CP 3.592")
**Ce que CP 3.592 devrait contenir** (selon index Peirce):
- Volume 3 = Exact Logic
- Section probable: Théorie des signes ou logique des relations
- Contenu attendu: Discussion sur la triplicité du signe
**Action requise**: Vérifier le JSON source `peirce_collected_papers_fixed_chunks.json` pour voir si le résumé existe.
#### [2] CP 2.439 - Similarité: 0.719
**Référence**: CP 2.439 (Volume 2 = Elements of Logic)
**Contenu attendu**: Probablement sur la classification des signes ou la sémiotique.
#### [3] CP 2.657 - Similarité: 0.718
**Référence**: CP 2.657 (Volume 2)
**Contenu attendu**: Classification des arguments ou inférence.
#### [4] CP 5.594 - Similarité: 0.717
**Référence**: CP 5.594 (Volume 5 = Pragmatism and Pragmaticism)
**Contenu attendu**: Relation entre pragmatisme et théorie des signes.
#### [5] CP 4.656 - Similarité: 0.717
**Référence**: CP 4.656 (Volume 4 = The Simplest Mathematics)
**Contenu attendu**: Logique mathématique ou théorie des relations.
### Distribution par Volume Peirce
| Volume | Résultats | Thématique principale |
|--------|-----------|----------------------|
| **CP 2** | 7 | Elements of Logic (forte pertinence) |
| **CP 3** | 3 | Exact Logic (pertinence moyenne) |
| **CP 4** | 2 | Mathematics (faible pertinence) |
| **CP 5** | 4 | Pragmatism (pertinence moyenne) |
| **CP 7** | 4 | Science and Philosophy (faible pertinence) |
**Analyse**: Les résultats du Volume 2 (Elements of Logic) sont les plus pertinents pour "sémiose", ce qui est cohérent.
---
## 🛠️ Diagnostic Technique
### Vérification 1: Les Summary existent-ils dans Weaviate ?
```python
import weaviate
client = weaviate.connect_to_local()
summaries = client.collections.get("Summary")
# Compter objets
count = summaries.aggregate.over_all(total_count=True)
print(f"Total Summary: {count.total_count}") # Attendu: 8,425
# Vérifier un objet au hasard
result = summaries.query.fetch_objects(limit=1)
obj = result.objects[0].properties
print(f"Exemple Summary:")
print(f" text: '{obj.get('text', 'VIDE')}'")
print(f" concepts: {obj.get('concepts', [])}")
print(f" chunksCount: {obj.get('chunksCount', 0)}")
```
**Résultat attendu**: 8,425 objets existent, mais avec champs vides.
### Vérification 2: Comparer avec les Chunks
```python
chunks = client.collections.get("Chunk")
# Chercher chunks sur "sémiose"
result = chunks.query.near_text(
query="Peirce et la sémiose",
limit=10
)
for obj in result.objects:
props = obj.properties
similarity = 1 - obj.metadata.distance
print(f"Similarité: {similarity:.3f}")
print(f"Texte: {props['text'][:100]}...")
print(f"Section: {props['sectionPath']}")
print("---")
```
**Hypothèse**: Les Chunks devraient avoir de meilleurs scores (0.85-0.95) car ils contiennent le vrai contenu.
### Vérification 3: Inspecter le JSON source
```bash
# Vérifier si les résumés existent dans le JSON
jq '.summaries | length' output/peirce_collected_papers_fixed/peirce_collected_papers_fixed_chunks.json
# Afficher un résumé
jq '.summaries[0]' output/peirce_collected_papers_fixed/peirce_collected_papers_fixed_chunks.json
```
**Hypothèses possibles**:
1. ✅ Les résumés existent dans le JSON mais n'ont pas été insérés dans Weaviate
2. ✅ Les résumés ont été insérés mais avec des champs vides
3. ❌ Les résumés n'ont jamais été générés (pipeline incomplet)
---
## 📋 Plan d'Action Recommandé
### Phase 1: Diagnostic Approfondi (30 min)
1. **Vérifier le JSON source**:
```bash
cd output/peirce_collected_papers_fixed
cat peirce_collected_papers_fixed_chunks.json | jq '.summaries[0:3]'
```
2. **Vérifier un Summary dans Weaviate**:
```python
# Dans test_resume.py, ajouter après la recherche:
print("\n=== INSPECTION DÉTAILLÉE ===")
summaries = client.collections.get("Summary")
result = summaries.query.fetch_objects(
filters=Filter.by_property("document").by_property("sourceId").equal("peirce_collected_papers_fixed"),
limit=5
)
for obj in result.objects:
print(f"UUID: {obj.uuid}")
print(f"Text length: {len(obj.properties.get('text', ''))}")
print(f"Concepts count: {len(obj.properties.get('concepts', []))}")
print(f"ChunksCount: {obj.properties.get('chunksCount', 0)}")
print("---")
```
3. **Comparer avec Chunk**:
- Chercher "sémiose" dans Chunk
- Comparer les scores de similarité
### Phase 2: Correction selon Diagnostic (1-4h)
**Scénario A**: Les résumés existent dans le JSON mais pas dans Weaviate
```bash
# Ré-injecter uniquement les Summary
python utils/weaviate_ingest.py --reingest-summaries --doc peirce_collected_papers_fixed
```
**Scénario B**: Les résumés dans Weaviate sont corrompus
```python
# Supprimer et recréer les Summary pour ce document
from utils.weaviate_ingest import delete_summaries, ingest_summaries
delete_summaries("peirce_collected_papers_fixed")
ingest_summaries("peirce_collected_papers_fixed")
```
**Scénario C**: Les résumés n'ont jamais été générés
```bash
# Régénérer les résumés avec LLM
python utils/llm_summarizer.py --doc peirce_collected_papers_fixed --force
python utils/weaviate_ingest.py --doc peirce_collected_papers_fixed --summaries-only
```
### Phase 3: Validation (30 min)
1. **Ré-exécuter test_resume.py**:
```bash
python test_resume.py
```
2. **Vérifier les améliorations**:
- Scores de similarité: 0.85-0.95 attendu
- Texte résumé: 100-500 caractères attendu
- Concepts: 5-15 mots-clés attendus
- ChunksCount: > 0 attendu
3. **Tester la recherche two-stage**:
```python
# Créer test_two_stage.py
from utils.two_stage_search import hybrid_search
results = hybrid_search("Peirce et la sémiose", limit=10)
# Vérifier que ça fonctionne maintenant
```
---
## 🎯 Résultats Attendus Après Correction
### Exemple de Résultat Idéal
```
[1] Similarité: 0.942 | Level: 2
Titre: La sémiose et les catégories phanéroscopiques
Section: Peirce: CP 5.314 > La sémiose et les catégories
Document: peirce_collected_papers_fixed
Concepts: sémiose, triade, signe, interprétant, représentamen, objet, priméité, secondéité, tiercéité
Résumé:
Ce passage fondamental expose la théorie peircéenne de la sémiose comme
processus triadique irréductible. Peirce articule la relation entre signe
(representamen), objet et interprétant avec ses trois catégories universelles:
la Priméité (qualité pure), la Secondéité (réaction) et la Tiercéité (médiation).
La sémiose est définie comme un processus potentiellement infini où chaque
interprétant devient à son tour un nouveau signe, créant une chaîne sémiotique
sans fin. Cette conception s'oppose radicalement aux théories binaires du signe
(signifiant/signifié) et fonde l'épistémologie pragmatiste de Peirce.
Chunks dans cette section: 23
```
**Améliorations**:
- ✅ Similarité: 0.723 → 0.942 (+30%)
- ✅ Texte: 13 chars → 600 chars
- ✅ Concepts: 0 → 9
- ✅ ChunksCount: 0 → 23
- ✅ Niveau: Toujours 1 mais avec vrais sous-niveaux possibles
---
## 📊 Comparaison Avant/Après (Projeté)
| Métrique | Avant | Après | Gain |
|----------|-------|-------|------|
| **Similarité moyenne** | 0.716 | 0.88 | +23% |
| **Texte moyen** | 13 chars | 350 chars | +2600% |
| **Concepts moyens** | 0 | 7 | +∞ |
| **ChunksCount moyen** | 0 | 18 | +∞ |
| **Utilité recherche** | 10% | 95% | +850% |
---
## 🔗 Documents Liés
- `ANALYSE_ARCHITECTURE_WEAVIATE.md` - Architecture complète de la base
- `WEAVIATE_GUIDE_COMPLET.md` - Guide d'utilisation Weaviate
- `test_resume.py` - Script de test (ce fichier a généré l'analyse)
- `resultats_resume.txt` - Résultats bruts de la recherche
---
## 🎓 Conclusion
### État Actuel: ❌ COLLECTION SUMMARY NON FONCTIONNELLE
La collection Summary existe (8,425 objets) mais est **inutilisable** pour la recherche car:
1. Les résumés sont vides (juste des titres)
2. Les concepts sont absents
3. Pas de lien avec les Chunks (chunksCount=0)
4. Scores de similarité très faibles (0.71-0.72)
### Impact sur l'Architecture RAG
**Stratégie Two-Stage cassée**:
- ❌ Impossible de faire Summary → Chunk
- ❌ Pas de recherche hiérarchique
- ✅ Chunk search seul fonctionne (mais perd le contexte)
**Solution de contournement actuelle**:
- Utiliser uniquement la recherche directe dans Chunk
- Ignorer complètement Summary
- Perdre 8,425 vecteurs (~60% de la base)
### Priorité: 🔴 HAUTE
Cette correction est **critique** pour exploiter l'architecture à deux niveaux de Library RAG.
**ROI attendu**: +30% précision, recherche hiérarchique fonctionnelle, 60% de la base vectorielle activée.
---
**Dernière mise à jour**: 2026-01-03
**Auteur**: Analyse automatisée
**Version**: 1.0

View File

@@ -1,445 +0,0 @@
# Session Complète - RAG Library Optimization
**Date**: 2026-01-03
**Durée**: Session complète
**Objectif**: Résoudre le problème de dominance des chunks Peirce et intégrer une solution dans Flask
---
## 📋 Table des Matières
1. [Problème Initial](#problème-initial)
2. [Travaux Préliminaires](#travaux-préliminaires)
3. [Solution Développée](#solution-développée)
4. [Intégration Flask](#intégration-flask)
5. [Livrables](#livrables)
6. [Résultats](#résultats)
---
## Problème Initial
### État de la Base de Données
- **Chunk Collection**: 5,230 chunks total
- Peirce: 5,068 chunks (97%)
- Autres: 162 chunks (3%)
### Impact
- Recherche directe dans Chunks: **10% de visibilité** pour documents riches
- Même sur requêtes ultra-spécifiques (ex: "What is the Turing test?"), Peirce domine 88% des résultats
- Haugeland n'apparaît que dans 10% des résultats sur son propre domaine (IA)
### Contrainte Utilisateur
> **"NE SUPPRIME PAS LES CHUNKLS D EPEIRCE BORDEL"**
❌ Pas de suppression des chunks Peirce permise
---
## Travaux Préliminaires
### Phase 1: Génération des Résumés (Déjà Effectué)
| Document | Résumés | Coût | Statut |
|----------|---------|------|--------|
| Tiercelin | 43 | $0.63 | ✅ |
| Platon | 12 | $0.14 | ✅ |
| La logique de la science | 1 | $0.02 | ✅ |
| Haugeland | 50 | $0.44 | ✅ |
| **TOTAL** | **106** | **$1.23** | ✅ |
### Phase 2: Nettoyage de la Base
1. ✅ Suppression de 7 doublons vides (Tiercelin)
2. ✅ Suppression de 8,313 résumés vides Peirce
- Avant: 10% de visibilité
- Après: 63% → 90% (avec Haugeland)
### Phase 3: Tests de Validation
**Scripts créés**:
- `test_summaries_validation.py` - Validation complète
- `test_real_queries.py` - 15 requêtes réelles
- `test_hierarchical_search.py` - Test Summary → Chunks
- `test_haugeland_ai.py` - Test domaine IA spécifique
**Résultats**:
- Summary search: **90% de visibilité**
- Chunk search: **10% de visibilité**
---
## Solution Développée
### Option A: Summary-First Interface (Sélectionnée)
**Principe**: Utiliser la collection Summary (équilibrée, haute qualité) comme point d'entrée principal.
**Avantages**:
- ✅ 90% de visibilité démontrée
- ✅ Coût: $0 (réutilise résumés existants)
- ✅ Respecte la contrainte (pas de suppression)
- ✅ Performance immédiate
**Alternatives Considérées**:
- Option B: Système hybride (nécessite développement UI)
- Option C: Régénération résumés Peirce (~$45-50, 15-20h)
### Architecture Summary Collection
```
Summary Collection (114 résumés)
├─ Tiercelin: 51 résumés (LLM-generated)
├─ Haugeland: 50 résumés (LLM-generated)
├─ Platon: 12 résumés (LLM-generated)
└─ Logique: 1 résumé (LLM-generated)
Vectorisation: BAAI/bge-m3
- Dimensions: 1024
- Context window: 8192 tokens
- Multilingual: EN, FR, Latin, Greek
```
---
## Intégration Flask
### Fichiers Créés/Modifiés
#### 1. Backend (`flask_app.py`)
**Ajouts**:
- `search_summaries_backend()` - Fonction de recherche
- `@app.route("/search/summary")` - Route Flask
- Logique d'icônes par document (🟣🟢🟡🔵⚪)
**Lignes**: 2907-3046 (~140 lignes)
#### 2. Template (`templates/search_summary.html`)
**Caractéristiques**:
- Interface cohérente avec design existant
- Bannière d'info sur performance (90% vs 10%)
- Cartes de résumés avec animations
- Badges de concepts
- Suggestions pré-remplies
- Bouton bascule vers recherche classique
**Taille**: ~320 lignes HTML/CSS/Jinja2
#### 3. Navigation (`templates/base.html`)
**Modification**:
- Ajout lien "📚 Recherche Résumés" dans sidebar
- Badge "90%" de performance
- Active state highlighting
**Lignes modifiées**: 709-713
### Tests d'Intégration
**Script**: `test_flask_integration.py`
**Résultats**: ✅ 100% de réussite (12/12 checks)
```
Test 1: What is the Turing test?
✅ Found Haugeland icon 🟣
✅ Results displayed
✅ Similarity scores displayed
✅ Concepts displayed
Test 2: Can virtue be taught?
✅ Found Platon icon 🟢
✅ Results displayed
✅ Similarity scores displayed
✅ Concepts displayed
Test 3: What is pragmatism?
✅ Found Tiercelin icon 🟡
✅ Results displayed
✅ Similarity scores displayed
✅ Concepts displayed
Test 4: Navigation link
✅ Link present
✅ Label found
```
---
## Livrables
### Documentation (7 fichiers)
1. **ANALYSE_RAG_FINAL.md** (15 KB)
- Analyse complète du système
- État de la base de données
- Performance par type de recherche
- Solutions proposées
2. **search_summary_interface.py** (8 KB)
- Script standalone pour ligne de commande
- Mode interactif + single query
- Fonction `search_summaries()`
3. **README_SEARCH.md** (7 KB)
- Guide d'utilisation complet
- Exemples d'utilisation
- Architecture technique
- Prochaines étapes
4. **SESSION_SUMMARY.md** (5 KB)
- Résumé exécutif de la session
- Métriques de performance
- Recommandation finale
5. **INTEGRATION_SUMMARY.md** (10 KB)
- Détails de l'intégration Flask
- Tests de validation
- Architecture technique
- Support et débogage
6. **QUICKSTART_SUMMARY_SEARCH.md** (6 KB)
- Guide de démarrage rapide
- Exemples de recherche
- Troubleshooting
- Conseils d'utilisation
7. **COMPLETE_SESSION_RECAP.md** (ce fichier)
- Vue d'ensemble complète
- Chronologie des travaux
- Tous les résultats
### Code (3 fichiers)
1. **flask_app.py** (modifié)
- +140 lignes de code
- Fonction backend + route
2. **templates/search_summary.html** (nouveau)
- ~320 lignes HTML/CSS/Jinja2
- Interface complète
3. **templates/base.html** (modifié)
- Navigation mise à jour
- Badge performance
### Tests (2 fichiers)
1. **test_flask_integration.py** (nouveau)
- 4 tests automatisés
- Validation complète
2. **search_summary_interface.py** (réutilisable)
- CLI pour tests manuels
- Peut être importé
---
## Résultats
### Métriques de Performance
| Métrique | Avant (Chunk) | Après (Summary) | Amélioration |
|----------|---------------|-----------------|--------------|
| Visibilité documents riches | 10% | 90% | **+800%** |
| Haugeland sur requêtes IA | 10% | 100% | **+900%** |
| Platon sur requêtes Vertu | 20% | 100% | **+400%** |
| Tiercelin sur Pragmatisme | 0% | 100% | **∞** |
| Temps de réponse | ~300ms | ~300ms | = |
### Tests de Précision
**15 requêtes réelles testées** (5 domaines):
1. **Pragmatisme/Peirce**: 3/3 ✅
2. **Platon/Vertu**: 3/3 ✅
3. **IA/Esprit**: 3/3 ✅
4. **Sémiotique**: 3/3 ✅
5. **Épistémologie**: 3/3 ✅
**Résultat Global**: 100% de précision sur tous les tests
### Coûts
| Poste | Montant | Détail |
|-------|---------|--------|
| Génération résumés (déjà fait) | $1.23 | 106 résumés LLM |
| Développement interface | $0 | Temps de développement |
| Infrastructure | $0 | Weaviate existant |
| **Total projet** | **$1.23** | Coût total |
### Accessibilité
**URL**: `http://localhost:5000/search/summary`
**Navigation**: Menu ☰ → "📚 Recherche Résumés"
**Paramètres**:
- Nombre de résultats: 5, 10, 15, 20
- Seuil de similarité: 60%, 65%, 70%, 75%
---
## Impact Utilisateur
### Avant (Recherche Chunk)
**Expérience**:
```
Query: "What is the Turing test?"
Résultats:
1. ⚪ Peirce CP 4.162 - 73.5%
"This idea of discrete quantity..."
2. ⚪ Peirce CP 5.520 - 73.5%
"Doctor X. Yours seemed marked..."
3. ⚪ Peirce CP 2.143 - 73.5%
"All these tests, however..."
4. ⚪ Peirce CP 5.187 - 73.3%
"We thus come to the test..."
5. ⚪ Peirce CP 7.206 - 73.2%
"Having, then, by means of..."
❌ 0/5 résultats pertinents
```
### Après (Recherche Summary)
**Expérience**:
```
Query: "What is the Turing test?"
Résultats:
1. 🟣 Haugeland - 69.5%
Computers and intelligence
"This section examines Turing's 1950 prediction..."
Concepts: Turing test, AI, computation...
📄 1 passage détaillé
2. 🟣 Haugeland - 68.8%
Computer Science as Empirical Inquiry
"Newell and Simon present computer science..."
Concepts: empirical inquiry, symbolic system...
📄 1 passage détaillé
3. 🟣 Haugeland - 66.6%
The Turing test
"This section explores two foundational..."
Concepts: Turing test, intentionality...
📄 1 passage détaillé
✅ 3/3 résultats pertinents (100%)
```
---
## Recommandations
### Court Terme ✅
1. **Promouvoir la Recherche Summary** comme interface principale
- Mettre en avant dans la navigation (déjà fait)
- Badge "90%" de performance (déjà fait)
2. **Former les utilisateurs**
- Guide QUICKSTART disponible
- Suggestions de recherche intégrées
3. **Monitorer l'usage**
- Logs Flask pour analytics
- Feedback utilisateurs
### Moyen Terme (Optionnel)
1. **Améliorer l'interface**
- Bouton "Voir chunks détaillés" sur chaque résumé
- Route `/summary/<uuid>/chunks` pour expansion
2. **Ajouter des fonctionnalités**
- Filtres par auteur/document
- Historique de recherche
- Export résultats
3. **Mode hybride**
- Toggle Summary/Chunk
- Comparaison côte-à-côte
### Long Terme (Si Besoin)
1. **Régénération Peirce** (~$45-50)
- Seulement si nécessaire
- Améliorerait aussi la recherche Chunk
2. **Analytics avancés**
- Graphe de concepts
- Suggestions intelligentes
- Recherches liées
---
## Conclusion
### Objectifs Atteints ✅
1. ✅ Problème de visibilité résolu (10% → 90%)
2. ✅ Contrainte respectée (pas de suppression Peirce)
3. ✅ Solution production-ready implémentée
4. ✅ Documentation complète fournie
5. ✅ Tests validés (100% de précision)
6. ✅ Intégration Flask fonctionnelle
### État Final
**Base de Données**:
- Summary: 114 résumés (106 riches)
- Chunk: 5,230 chunks (intacts)
- Performance Summary: 90% ✅
- Performance Chunk: 10% ❌ (mais toujours disponible)
**Application Flask**:
- Route `/search/summary` opérationnelle
- Navigation intégrée avec badge "90%"
- Interface moderne et responsive
- Tests automatisés passants
**Documentation**:
- 7 fichiers de documentation
- Guides utilisateur complets
- Documentation technique détaillée
### Recommandation Finale
**Utiliser `/search/summary` comme interface de recherche principale.**
La recherche Summary offre:
- 📊 **90% de visibilité** vs 10% en recherche directe
- 🎯 **100% de précision** sur tests
-**Performance identique** (~300ms)
- 📚 **Métadonnées riches** (concepts, auteur, résumés)
- 🚀 **Meilleure UX** pour découverte de documents
La recherche Chunk reste disponible via `/search` pour les cas d'usage spécifiques nécessitant des citations exactes.
---
## Fichiers de Référence Rapide
| Besoin | Fichier |
|--------|---------|
| Démarrage rapide | `QUICKSTART_SUMMARY_SEARCH.md` |
| Intégration technique | `INTEGRATION_SUMMARY.md` |
| Analyse complète | `ANALYSE_RAG_FINAL.md` |
| Guide utilisateur | `README_SEARCH.md` |
| Vue d'ensemble | Ce fichier |
---
**Auteur**: Claude Sonnet 4.5
**Date**: 2026-01-03
**Durée**: Session complète
**Statut**: ✅ Projet Complet et Fonctionnel
**ROI**: +800% de visibilité pour $1.23 d'investissement initial
---
*Fin du rapport de session*

View File

@@ -1,739 +0,0 @@
# Lien entre Summary et Chunk - Explication Complète
**Date**: 2026-01-03
**Fichiers analysés**: `utils/weaviate_ingest.py`, `schema.py`, `pdf_pipeline.py`
---
## 📋 Table des Matières
1. [Vue d'Ensemble](#1-vue-densemble)
2. [Lien Théorique entre Summary et Chunk](#2-lien-théorique-entre-summary-et-chunk)
3. [Comment les Summary sont Créés](#3-comment-les-summary-sont-créés)
4. [Pourquoi les Summary sont Vides](#4-pourquoi-les-summary-sont-vides)
5. [Comment Corriger le Problème](#5-comment-corriger-le-problème)
---
## 1. Vue d'Ensemble
### Architecture Hiérarchique
```
Document (ex: Peirce Collected Papers)
├─► TOC (Table des Matières)
│ └─ Structure hiérarchique des sections
├─► Summary (8,425 objets) - MACRO
│ └─ Un résumé pour chaque section de la TOC
│ └─ Vectorisé pour recherche sémantique chapitres
└─► Chunk (5,404 objets) - MICRO
└─ Fragments de texte (200-800 chars)
└─ Vectorisé pour recherche sémantique fine
```
### Lien entre Summary et Chunk
Le lien devrait être **par sectionPath** :
```python
Summary:
sectionPath: "Peirce: CP 5.314 > La sémiose et les catégories"
chunksCount: 23 # ← Nombre de chunks dans cette section
text: "Ce passage explore la théorie de la sémiose..."
Chunk 1:
sectionPath: "Peirce: CP 5.314 > La sémiose et les catégories"
text: "Un signe, ou representamen, est quelque chose..."
Chunk 2:
sectionPath: "Peirce: CP 5.314 > La sémiose et les catégories"
text: "La sémiose est l'action du signe..."
... (21 autres chunks)
Chunk 23:
sectionPath: "Peirce: CP 5.314 > La sémiose et les catégories"
text: "Ainsi la relation triadique est irréductible..."
```
**Principe**: Tous les Chunks avec le même `sectionPath` appartiennent au Summary correspondant.
---
## 2. Lien Théorique entre Summary et Chunk
### 2.1 Modèle de Données
#### Summary (Résumé de Section)
**Fichier**: `utils/weaviate_ingest.py:86-100`
```python
class SummaryObject(TypedDict):
"""Structure d'un Summary dans Weaviate."""
sectionPath: str # "Peirce: CP 5.314 > La sémiose"
title: str # "La sémiose et les catégories"
level: int # 2 (profondeur hiérarchique)
text: str # "Ce passage explore..." (RÉSUMÉ LLM)
concepts: List[str] # ["sémiose", "triade", "signe"]
chunksCount: int # 23 (nombre de chunks dans cette section)
document: {
sourceId: str # "peirce_collected_papers_fixed"
}
```
**Champs vectorisés**:
-`text` → Vectorisé avec BGE-M3 (1024-dim)
-`concepts` → Vectorisé avec BGE-M3
**Champs de filtrage**:
- `sectionPath` → Pour lier avec Chunks
- `level` → Pour hiérarchie (1=chapitre, 2=section, 3=subsection)
- `chunksCount` → Pour navigation
#### Chunk (Fragment de Texte)
**Fichier**: `schema.py:216-280`
```python
{
"text": str, # Contenu du fragment (200-800 chars)
"keywords": List[str], # ["sémiose", "triade"]
"sectionPath": str, # "Peirce: CP 5.314 > La sémiose" (LIEN AVEC SUMMARY)
"sectionLevel": int, # 2
"chapterTitle": str, # "La sémiose et les catégories"
"orderIndex": int, # 42 (position dans le document)
"unitType": str, # "argument", "définition", etc.
"work": {
"title": str, # "Collected Papers"
"author": str, # "Peirce"
},
"document": {
"sourceId": str, # "peirce_collected_papers_fixed"
"edition": str, # "Hartshorne & Weiss"
}
}
```
### 2.2 Comment le Lien Fonctionne
**Lien par sectionPath** (chaîne de caractères):
```python
# Recherche dans Summary
summary_result = summaries.query.near_text(query="sémiose", limit=3)
top_section = summary_result.objects[0].properties['sectionPath']
# → "Peirce: CP 5.314 > La sémiose et les catégories"
# Récupérer tous les Chunks de cette section
chunks = client.collections.get("Chunk")
chunk_result = chunks.query.fetch_objects(
filters=Filter.by_property("sectionPath").like(f"{top_section}*"),
limit=100
)
# → Retourne les 23 chunks appartenant à cette section
```
**Avantages de ce design** (vs cross-references):
- ✅ Pas besoin de UUID references
- ✅ Requête unique (pas de jointures)
- ✅ Filtrage simple avec LIKE ou EQUAL
- ✅ Lisible et debuggable
**Inconvénients**:
- ⚠️ Sensible aux typos dans sectionPath
- ⚠️ Pas de validation d'intégrité référentielle
---
## 3. Comment les Summary sont Créés
### 3.1 Fonction d'Ingestion
**Fichier**: `utils/weaviate_ingest.py:632-731`
```python
def ingest_summaries(
client: WeaviateClient,
doc_name: str,
toc: List[Dict[str, Any]], # Table des matières
summaries_content: Dict[str, str], # ← RÉSUMÉS LLM (actuellement vide !)
) -> int:
"""Insert section summaries into the Summary collection."""
summaries_to_insert: List[SummaryObject] = []
def process_toc(items: List[Dict[str, Any]], parent_path: str = "") -> None:
"""Parcourt récursivement la TOC pour créer des Summary."""
for item in items:
title: str = item.get("title", "")
level: int = item.get("level", 1)
path: str = f"{parent_path} > {title}" if parent_path else title
summary_obj: SummaryObject = {
"sectionPath": path,
"title": title,
"level": level,
# ⚠️ PROBLÈME ICI : Si summaries_content est vide,
# on utilise juste le titre comme texte !
"text": summaries_content.get(title, title),
"concepts": item.get("concepts", []),
# ⚠️ PROBLÈME : Toujours 0, jamais calculé !
"chunksCount": 0,
"document": {
"sourceId": doc_name,
},
}
summaries_to_insert.append(summary_obj)
# Traiter les sous-sections récursivement
if "children" in item:
process_toc(item["children"], path)
process_toc(toc)
# Insertion batch dans Weaviate
summary_collection.data.insert_many(summaries_to_insert)
return len(summaries_to_insert)
```
### 3.2 Appel dans le Pipeline
**Fichier**: `utils/weaviate_ingest.py:844-845`
```python
# Dans la fonction ingest_document()
if ingest_summary_collection and toc:
ingest_summaries(client, doc_name, toc, {}) # ← {} = VIDE !
```
**PROBLÈME** : Le dictionnaire `summaries_content` passé est **VIDE** (`{}`).
**Résultat** : Ligne 686 → `summaries_content.get(title, title)` retourne juste `title` !
**Exemple**:
```python
title = "Peirce: CP 5.314"
summaries_content = {} # VIDE
text = summaries_content.get(title, title)
# → text = "Peirce: CP 5.314" (car title pas dans dict vide)
# Attendu:
# text = "Ce passage explore la théorie de la sémiose comme processus triadique..."
```
### 3.3 Source de la TOC
La TOC vient de l'extraction LLM :
**Fichier**: `utils/llm_toc.py` (étape 5 du pipeline)
```python
def extract_toc_from_markdown(markdown_text: str, ...) -> List[TOCEntry]:
"""Extrait la TOC via LLM (Ollama ou Mistral).
Résultat:
[
{
"title": "Peirce: CP 5.314",
"level": 1,
"page": null,
"children": [
{
"title": "La sémiose et les catégories",
"level": 2,
"page": null
}
]
},
...
]
"""
```
**Note**: La TOC contient **seulement les titres**, pas les résumés.
---
## 4. Pourquoi les Summary sont Vides
### 4.1 Problème #1 : Pas de Génération de Résumés LLM
**Constat**: Le pipeline PDF ne génère **jamais** de résumés pour les sections.
**Étapes du pipeline actuel** (`utils/pdf_pipeline.py`):
```
[1] OCR → Texte brut
[2] Markdown → Markdown structuré
[3] Images → Extraction images
[4] Metadata → Titre, auteur, année
[5] TOC → Table des matières (TITRES SEULEMENT)
[6] Classify → Classification sections
[7] Chunking → Découpage en chunks
[8] Cleaning → Nettoyage chunks
[9] Validation → Validation + concepts
[10] Ingestion → Insertion Weaviate
```
**Manque** : Étape de génération de résumés par section !
**Ce qui devrait exister** :
```
[5.5] Summarization → Générer résumé LLM pour chaque section TOC
Input: Section text (tous les chunks d'une section)
Output: {"Peirce: CP 5.314": "Ce passage explore..."}
```
### 4.2 Problème #2 : chunksCount Toujours à 0
**Constat**: Le champ `chunksCount` est hardcodé à 0.
**Fichier**: `utils/weaviate_ingest.py:688`
```python
"chunksCount": 0, # ← Hardcodé, jamais calculé !
```
**Ce qui devrait être fait** :
```python
def calculate_chunks_count(chunks: List[Dict], section_path: str) -> int:
"""Compte combien de chunks appartiennent à cette section."""
count = 0
for chunk in chunks:
if chunk.get("sectionPath", "").startswith(section_path):
count += 1
return count
# Dans process_toc():
chunks_count = calculate_chunks_count(all_chunks, path)
summary_obj: SummaryObject = {
...
"chunksCount": chunks_count, # ← Calculé dynamiquement
...
}
```
**Pourquoi ce n'est pas fait** :
- La fonction `ingest_summaries()` n'a pas accès à la liste des chunks
- Les chunks sont insérés APRÈS les summaries dans le pipeline
- Ordre incorrect : devrait être Chunks → Summaries (pour compter)
### 4.3 Problème #3 : Concepts Vides
**Constat**: Le champ `concepts` est toujours vide.
**Fichier**: `utils/weaviate_ingest.py:687`
```python
"concepts": item.get("concepts", []), # ← TOC n'a jamais de concepts
```
**Explication**: La TOC extraite par LLM ne contient que `{title, level, page}`, pas de concepts.
**Ce qui devrait être fait** :
Les concepts devraient être extraits lors de la génération du résumé :
```python
# Étape 5.5 - Summarization (à créer)
def generate_section_summary(section_text: str) -> Dict[str, Any]:
"""Génère résumé + concepts via LLM."""
prompt = f"""Résume cette section et extrais les concepts clés.
Section:
{section_text}
Réponds en JSON:
{{
"summary": "Résumé en 100-200 mots...",
"concepts": ["concept1", "concept2", ...]
}}
"""
response = llm.generate(prompt)
return json.loads(response)
# Résultat:
{
"summary": "Ce passage explore la théorie de la sémiose...",
"concepts": ["sémiose", "triade", "signe", "interprétant", "représentamen"]
}
```
---
## 5. Comment Corriger le Problème
### 5.1 Solution Complète : Ajouter Étape de Summarization
**Créer nouveau module** : `utils/llm_summarizer.py`
```python
"""LLM-based section summarization for Library RAG.
Generates summaries and extracts concepts for each section in the TOC.
"""
from typing import Dict, List, Any
from utils.llm_structurer import get_llm_client
import json
def generate_summaries_for_toc(
toc: List[Dict[str, Any]],
chunks: List[Dict[str, Any]],
llm_provider: str = "ollama"
) -> Dict[str, Dict[str, Any]]:
"""Generate LLM summaries for each section in the TOC.
Args:
toc: Table of contents with hierarchical structure.
chunks: All document chunks with sectionPath.
llm_provider: "ollama" or "mistral".
Returns:
Dict mapping section title to {summary, concepts}.
Example:
>>> summaries = generate_summaries_for_toc(toc, chunks)
>>> summaries["Peirce: CP 5.314"]
{
"summary": "Ce passage explore la sémiose...",
"concepts": ["sémiose", "triade", "signe"]
}
"""
llm = get_llm_client(llm_provider)
summaries_content: Dict[str, Dict[str, Any]] = {}
def process_section(item: Dict[str, Any], parent_path: str = "") -> None:
title = item.get("title", "")
path = f"{parent_path} > {title}" if parent_path else title
# Collecter tous les chunks de cette section
section_chunks = [
chunk for chunk in chunks
if chunk.get("sectionPath", "").startswith(path)
]
if not section_chunks:
# Pas de chunks, utiliser juste le titre
summaries_content[title] = {
"summary": title,
"concepts": []
}
else:
# Générer résumé via LLM
section_text = "\n\n".join([c.get("text", "") for c in section_chunks[:10]]) # Max 10 chunks
prompt = f"""Résume cette section philosophique en 100-200 mots et extrais les 5-10 concepts clés.
Section: {title}
Texte:
{section_text}
Réponds en JSON:
{{
"summary": "Résumé de la section...",
"concepts": ["concept1", "concept2", ...]
}}
"""
try:
response = llm.generate(prompt, max_tokens=500)
result = json.loads(response)
summaries_content[title] = result
except Exception as e:
print(f"Erreur génération résumé pour {title}: {e}")
summaries_content[title] = {
"summary": title,
"concepts": []
}
# Traiter sous-sections récursivement
if "children" in item:
for child in item["children"]:
process_section(child, path)
for item in toc:
process_section(item)
return summaries_content
```
**Modifier le pipeline** : `utils/weaviate_ingest.py`
```python
def ingest_document(
doc_name: str,
chunks: List[Dict[str, Any]],
metadata: Dict[str, Any],
...,
ingest_summary_collection: bool = False,
) -> IngestResult:
# ... (code existant pour chunks)
# NOUVEAU : Générer résumés APRÈS avoir les chunks
if ingest_summary_collection and toc:
from utils.llm_summarizer import generate_summaries_for_toc
# Générer résumés LLM pour chaque section
summaries_content = generate_summaries_for_toc(toc, chunks, llm_provider="ollama")
# Transformer en format pour ingest_summaries
summaries_text = {
title: content["summary"]
for title, content in summaries_content.items()
}
# Ajouter concepts dans la TOC
def enrich_toc_with_concepts(items: List[Dict]) -> None:
for item in items:
title = item.get("title", "")
if title in summaries_content:
item["concepts"] = summaries_content[title]["concepts"]
if "children" in item:
enrich_toc_with_concepts(item["children"])
enrich_toc_with_concepts(toc)
# Insérer avec vrais résumés
ingest_summaries(client, doc_name, toc, summaries_text)
```
### 5.2 Solution Rapide : Calculer chunksCount Dynamiquement
**Modifier** : `utils/weaviate_ingest.py:ingest_summaries()`
```python
def ingest_summaries(
client: WeaviateClient,
doc_name: str,
toc: List[Dict[str, Any]],
summaries_content: Dict[str, str],
chunks: List[Dict[str, Any]] = [], # ← NOUVEAU paramètre
) -> int:
summaries_to_insert: List[SummaryObject] = []
def count_chunks_for_section(section_path: str) -> int:
"""Compte chunks appartenant à cette section."""
count = 0
for chunk in chunks:
if chunk.get("sectionPath", "").startswith(section_path):
count += 1
return count
def process_toc(items: List[Dict[str, Any]], parent_path: str = "") -> None:
for item in items:
title: str = item.get("title", "")
level: int = item.get("level", 1)
path: str = f"{parent_path} > {title}" if parent_path else title
summary_obj: SummaryObject = {
"sectionPath": path,
"title": title,
"level": level,
"text": summaries_content.get(title, title),
"concepts": item.get("concepts", []),
# ✅ CORRECTIF : Calculer dynamiquement
"chunksCount": count_chunks_for_section(path),
"document": {
"sourceId": doc_name,
},
}
summaries_to_insert.append(summary_obj)
if "children" in item:
process_toc(item["children"], path)
process_toc(toc)
# ... (reste du code)
```
**Modifier appel** : `utils/weaviate_ingest.py:844-845`
```python
if ingest_summary_collection and toc:
# ✅ Passer les chunks pour calcul de chunksCount
ingest_summaries(client, doc_name, toc, {}, chunks)
```
### 5.3 Solution Minimale : Ré-injecter avec Vraies Données
Si vous avez déjà les résumés dans les JSON :
```python
# Script de correction rapide
import json
import weaviate
from pathlib import Path
# Charger le JSON avec les résumés
chunks_file = Path("output/peirce_collected_papers_fixed/peirce_collected_papers_fixed_chunks.json")
with open(chunks_file, 'r', encoding='utf-8') as f:
data = json.load(f)
# Vérifier s'il y a des résumés
if 'summaries' in data:
print(f"Trouvé {len(data['summaries'])} résumés dans le JSON")
# Connecter à Weaviate
client = weaviate.connect_to_local()
# Supprimer anciens Summary
summaries = client.collections.get("Summary")
summaries.data.delete_many(
where=Filter.by_property("document").by_property("sourceId").equal("peirce_collected_papers_fixed")
)
# Réinsérer avec vrais résumés
from utils.weaviate_ingest import ingest_summaries
toc = data['metadata']['toc']
chunks = data['chunks']
# Extraire résumés du JSON
summaries_content = {
s['title']: s['text']
for s in data['summaries']
}
# Réinjecter
count = ingest_summaries(client, "peirce_collected_papers_fixed", toc, summaries_content, chunks)
print(f"Réinséré {count} résumés")
client.close()
else:
print("❌ Pas de résumés dans le JSON - il faut les générer avec LLM")
```
---
## 6. Résumé Visual
```
┌─────────────────────────────────────────────────────────────────┐
│ PIPELINE ACTUEL (CASSÉ) │
└─────────────────────────────────────────────────────────────────┘
PDF → OCR → Markdown → TOC Extraction (LLM)
└─► toc = [
{"title": "Peirce: CP 5.314", "level": 1},
{"title": "La sémiose", "level": 2}
]
Chunking (LLM) → chunks = [
{"text": "Un signe...", "sectionPath": "Peirce: CP 5.314 > La sémiose"},
{"text": "La sémiose...", "sectionPath": "Peirce: CP 5.314 > La sémiose"},
...
]
Ingestion → ingest_summaries(client, doc_name, toc, {}) ← VIDE !
└─► Summary créés avec:
- text: "Peirce: CP 5.314" (juste le titre)
- concepts: []
- chunksCount: 0
┌─────────────────────────────────────────────────────────────────┐
│ PIPELINE CORRIGÉ (ATTENDU) │
└─────────────────────────────────────────────────────────────────┘
PDF → OCR → Markdown → TOC Extraction → Chunking
Summarization (LLM) ← NOUVEAU !
└─► summaries_content = {
"Peirce: CP 5.314": {
"summary": "Ce passage explore...",
"concepts": ["sémiose", "triade"]
}
}
Ingestion → ingest_summaries(client, doc_name, toc, summaries_content, chunks)
└─► Summary créés avec:
- text: "Ce passage explore la théorie de la sémiose..." ✅
- concepts: ["sémiose", "triade", "signe"] ✅
- chunksCount: 23 ✅
```
---
## 7. Conclusion
### État Actuel
**Summary → Chunk** : ❌ LIEN CASSÉ
| Aspect | Actuel | Attendu | Status |
|--------|--------|---------|--------|
| **text** | "Peirce: CP 5.314" | "Ce passage explore..." | ❌ Vide |
| **concepts** | `[]` | `["sémiose", "triade"]` | ❌ Vide |
| **chunksCount** | 0 | 23 | ❌ Faux |
| **sectionPath** | ✅ Correct | ✅ Correct | ✅ OK |
### Lien Théorique vs Réel
**Théorique** (design prévu):
```
Summary.sectionPath = "Peirce: CP 5.314 > La sémiose"
↓ LIEN
Chunk.sectionPath = "Peirce: CP 5.314 > La sémiose"
Chunk.sectionPath = "Peirce: CP 5.314 > La sémiose"
... (23 chunks)
```
**Réel** (implémentation actuelle):
```
Summary.sectionPath = "Peirce: CP 5.314" ✅ OK
Summary.chunksCount = 0 ❌ FAUX
Summary.text = "Peirce: CP 5.314" ❌ VIDE
Chunk.sectionPath = "Peirce: CP 5.314" ✅ OK
Chunk.text = "Un signe, ou representamen..." ✅ OK
```
**LIEN** : ⚠️ Existe techniquement (sectionPath identique) mais inutilisable car Summary vides.
### Actions Requises
**Priorité 1** : Générer résumés LLM (créer `llm_summarizer.py`)
**Priorité 2** : Calculer `chunksCount` dynamiquement
**Priorité 3** : Extraire concepts pour Summary
**ROI** : Activer recherche hiérarchique Summary → Chunk (+30% précision)
---
**Dernière mise à jour**: 2026-01-03
**Auteur**: Analyse du code source
**Version**: 1.0

View File

@@ -1,280 +0,0 @@
# Fix - Recherche Hiérarchique
**Date**: 2026-01-03
**Problème**: Mode hiérarchique n'affichait aucun résultat
**Statut**: ✅ Résolu et testé
---
## Problème Identifié
Le mode hiérarchique retournait **0 résultats** pour toutes les requêtes.
**Symptôme**:
```
Mode: 🌳 Hiérarchique
Résultat: "Aucun résultat trouvé"
```
## Cause Racine
**Fichier**: `flask_app.py`
**Fonction**: `hierarchical_search()`
**Lignes**: 338-344
### Code Problématique
```python
summaries_result = summary_collection.query.near_text(
query=query,
limit=sections_limit,
return_metadata=wvq.MetadataQuery(distance=True),
return_properties=[
"sectionPath", "title", "text", "level", "concepts"
], # ❌ N'inclut PAS "document" (nested object)
)
```
**Problème**: Le paramètre `return_properties` **excluait** le nested object `"document"`.
### Conséquence
```python
# Ligne 363-366
doc_obj = props.get("document") # ← Retourne None ou {}
source_id = ""
if doc_obj and isinstance(doc_obj, dict):
source_id = doc_obj.get("sourceId", "") # ← source_id reste vide
# Ligne 374
"document_source_id": source_id, # ← Vide!
# Ligne 385-387
for section in sections_data:
source_id = section["document_source_id"]
if not source_id:
continue # ← Toutes les sections sont SKIPPÉES!
# Ligne 410-421
if not sections_data:
return {
"mode": "hierarchical",
"sections": [],
"results": [],
"total_chunks": 0, # ← 0 résultats!
}
```
**Résultat**: Toutes les sections étaient filtrées → 0 résultats
---
## Solution Appliquée
**Suppression de `return_properties`** pour laisser Weaviate retourner **tous** les properties automatiquement, y compris les nested objects.
### Code Corrigé
```python
summaries_result = summary_collection.query.near_text(
query=query,
limit=sections_limit,
return_metadata=wvq.MetadataQuery(distance=True),
# Note: Don't specify return_properties - let Weaviate return all properties
# including nested objects like "document" which we need for source_id
)
```
**Changement**: Ligne 342-344 - Suppression du paramètre `return_properties`
### Pourquoi ça fonctionne?
En **Weaviate v4**, quand on ne spécifie pas `return_properties`:
- ✅ Weaviate retourne **automatiquement** tous les properties
- ✅ Les **nested objects** comme `document` sont inclus
- ✅ Le `source_id` est correctement récupéré
- ✅ Les sections ne sont plus filtrées
- ✅ Les résultats s'affichent
---
## Tests de Validation
### ✅ Test Automatisé
**Script**: `test_hierarchical_fix.py`
```python
query = "What is the Turing test?"
mode = "hierarchical"
```
**Résultat**:
```
✅ Mode hiérarchique détecté
✅ 13 cartes de passage trouvées
✅ 4 groupes de sections
✅ Headers de section présents
✅ Textes de résumé présents
✅ Concepts affichés
RÉSULTAT: Mode hiérarchique fonctionne!
```
### ✅ Test Manuel
**URL**: `http://localhost:5000/search?q=What+is+the+Turing+test&mode=hierarchical`
**Résultat attendu**:
- Badge "🌳 Recherche hiérarchique (N sections)"
- Groupes de sections avec résumés
- Chunks regroupés par section
- Concepts affichés
- Metadata complète
---
## Comparaison Avant/Après
### Avant (Bugué)
```
Query: "What is the Turing test?"
Mode: Hiérarchique
Étape 1 (Summary): 3 sections trouvées ✓
Étape 2 (Filter): 0 sections après filtrage ✗
(source_id vide → toutes skippées)
Résultat: "Aucun résultat trouvé" ❌
```
### Après (Corrigé)
```
Query: "What is the Turing test?"
Mode: Hiérarchique
Étape 1 (Summary): 3 sections trouvées ✓
Étape 2 (Filter): 3 sections valides ✓
(source_id récupéré → sections conservées)
Étape 3 (Chunks): 13 chunks trouvés ✓
Résultat: 4 sections avec 13 passages ✅
```
---
## Impact
### Code
- **1 ligne modifiée** (flask_app.py:342-344)
- **0 régression** (autres modes inchangés)
- **0 effet secondaire**
### Fonctionnalité
- ✅ Mode hiérarchique opérationnel
- ✅ Summary → Chunks fonctionnel
- ✅ Sections regroupées correctement
- ✅ Metadata complète affichée
### Performance
- **Temps de réponse**: Identique (~500ms)
- **Qualité résultats**: Excellente
- **Visibilité**: Variable (dépend de la requête)
---
## Modes Disponibles (État Final)
| Mode | Collection | Étapes | Statut | Performance |
|------|------------|--------|--------|-------------|
| **Auto** | Détection | 1-2 | ✅ OK | Variable |
| **Simple** | Chunk | 1 | ✅ OK | 10% visibilité |
| **Hiérarchique** | Summary → Chunk | 2 | ✅ **CORRIGÉ** | Variable |
| **Summary** | Summary | 1 | ✅ OK | 90% visibilité |
---
## Leçon Apprise
### ❌ Erreur Commune
**NE PAS** spécifier `return_properties` quand on a besoin de nested objects:
```python
# MAUVAIS
results = collection.query.near_text(
query=query,
return_properties=["field1", "field2"] # ❌ Exclut nested objects
)
```
### ✅ Bonne Pratique
**LAISSER** Weaviate retourner automatiquement tous les properties:
```python
# BON
results = collection.query.near_text(
query=query,
# Pas de return_properties → tous les properties retournés ✓
)
```
**Alternative** (si vraiment nécessaire):
```python
# ACCEPTABLE
results = collection.query.near_text(
query=query,
return_properties=["field1", "field2", "nested_object"] # ✓ Inclure nested
)
```
Mais la **meilleure approche** reste de **ne pas spécifier** `return_properties` quand on utilise des nested objects, pour éviter ce genre de bug.
---
## Vérification Finale
### Checklist de Test
- [x] Mode auto-détection fonctionne
- [x] Mode simple fonctionne
- [x] Mode hiérarchique fonctionne ✅ **CORRIGÉ**
- [x] Mode summary fonctionne
- [x] Filtres auteur/work fonctionnent
- [x] Affichage correct pour tous modes
- [x] Pas de régression
### Commande de Test
```bash
# Démarrer Flask
python flask_app.py
# Tester mode hiérarchique
curl "http://localhost:5000/search?q=What+is+the+Turing+test&mode=hierarchical"
# Ou avec script
python test_hierarchical_fix.py
```
---
## Conclusion
**Le mode hiérarchique est maintenant complètement fonctionnel.**
Le bug était subtil mais critique : l'exclusion du nested object `document` par `return_properties` rendait impossible la récupération du `source_id`, ce qui causait le filtrage de toutes les sections.
La solution simple (supprimer `return_properties`) résout le problème sans effets secondaires.
**Tous les modes de recherche fonctionnent désormais correctement!**
---
**Fichier modifié**: `flask_app.py` (ligne 342-344)
**Tests**: `test_hierarchical_fix.py`
**Statut**: ✅ Résolu et validé

View File

@@ -1,297 +0,0 @@
# Intégration Recherche Summary - Résumé
**Date**: 2026-01-03
**Statut**: ✅ Intégration complète et testée
---
## Fichiers Modifiés/Créés
### 1. Backend (flask_app.py)
**Modifications**:
- ✅ Ajout de la fonction `search_summaries_backend()` (lignes 2907-2999)
- ✅ Ajout de la route `@app.route("/search/summary")` (lignes 3002-3046)
**Fonctionnalités**:
- Recherche sémantique dans la collection Summary
- Filtrage par seuil de similarité configurable
- Icônes de documents automatiques (🟣🟢🟡🔵⚪)
- Métadonnées riches (auteur, année, concepts, résumé)
### 2. Template (templates/search_summary.html)
**Statut**: ✅ Créé (nouveau fichier)
**Caractéristiques**:
- Interface cohérente avec le design existant
- Bannière d'information sur la performance (90% vs 10%)
- Cartes de résumés avec dégradés et animations
- Badges de concepts clés
- Suggestions de recherche pré-remplies
- Bouton de bascule vers recherche classique
### 3. Navigation (templates/base.html)
**Modifications**:
- ✅ Ajout du lien "Recherche Résumés" dans la sidebar (lignes 709-713)
- ✅ Badge "90%" pour indiquer la performance
- ✅ Icône 📚 distincte
---
## Tests de Validation
### ✅ Tests Fonctionnels (4/4 PASS)
#### Test 1: Requête IA (Haugeland)
```
Query: "What is the Turing test?"
✅ PASS - Found Haugeland icon 🟣
✅ PASS - Results displayed
✅ PASS - Similarity scores displayed
✅ PASS - Concepts displayed
```
#### Test 2: Requête Vertu (Platon)
```
Query: "Can virtue be taught?"
✅ PASS - Found Platon icon 🟢
✅ PASS - Results displayed
✅ PASS - Similarity scores displayed
✅ PASS - Concepts displayed
```
#### Test 3: Requête Pragmatisme (Tiercelin)
```
Query: "What is pragmatism according to Peirce?"
✅ PASS - Found Tiercelin icon 🟡
✅ PASS - Results displayed
✅ PASS - Similarity scores displayed
✅ PASS - Concepts displayed
```
#### Test 4: Navigation
```
✅ PASS - Navigation link present
✅ PASS - Summary search label found
```
**Résultat Global**: 100% de réussite (12/12 checks passés)
---
## Accès à la Fonctionnalité
### URL Directe
```
http://localhost:5000/search/summary
```
### Via Navigation
1. Cliquer sur le menu hamburger (☰) en haut à gauche
2. Cliquer sur "📚 Recherche Résumés" (badge 90%)
3. Entrer une question et rechercher
### Paramètres URL
```
/search/summary?q=votre+question&limit=10&min_similarity=0.65
```
**Paramètres disponibles**:
- `q` (string): Question de recherche
- `limit` (int): Nombre de résultats (5, 10, 15, 20)
- `min_similarity` (float): Seuil 0-1 (0.60, 0.65, 0.70, 0.75)
---
## Performance Démontrée
### Recherche Summary (Nouvelle Interface)
- ✅ 90% de visibilité des documents riches
- ✅ 100% de précision sur tests (3/3)
- ✅ Temps de réponse: ~200-500ms
- ✅ Métadonnées riches affichées
### Recherche Chunk (Ancienne Interface)
- ❌ 10% de visibilité des documents riches
- ⚠️ Dominée par chunks Peirce (97%)
- ✅ Toujours disponible via `/search`
---
## Comparaison Visuelle
### Nouvelle Interface (Summary)
```
┌─────────────────────────────────────────┐
│ 📚 Recherche par Résumés │
│ │
│ ┌─────────────────────────────────────┐ │
│ │ 🟣 Haugeland - 69.5% similaire │ │
│ │ Computers and intelligence │ │
│ │ │ │
│ │ This section examines Turing's... │ │
│ │ │ │
│ │ Concepts: Turing test, AI, ... │ │
│ │ 📄 1 passage détaillé │ │
│ └─────────────────────────────────────┘ │
└─────────────────────────────────────────┘
```
### Ancienne Interface (Chunk)
```
┌─────────────────────────────────────────┐
│ 🔍 Recherche sémantique │
│ │
│ ┌─────────────────────────────────────┐ │
│ │ ⚪ Peirce - 73.5% similaire │ │
│ │ "This idea of discrete quantity..." │ │
│ │ │ │
│ │ Section: CP 4.162 │ │
│ └─────────────────────────────────────┘ │
│ [4 autres résultats Peirce...] │
└─────────────────────────────────────────┘
```
---
## Architecture Technique
### Backend Flow
```
User Query
@app.route("/search/summary")
search_summaries_backend()
Weaviate Summary.query.near_text()
Format results (icons, metadata)
render_template("search_summary.html")
HTML Response to Browser
```
### Collection Summary
- **Total**: 114 résumés
- **Riches**: 106 résumés (>100 chars)
- **Vecteurs**: BAAI/bge-m3 (1024-dim)
- **Documents**: Tiercelin (51), Haugeland (50), Platon (12), Logique (1)
---
## Utilisation Recommandée
### Cas d'Usage Summary (Recommandé)
- ✅ Questions générales sur un sujet
- ✅ Découverte exploratoire
- ✅ Vue d'ensemble d'un document/section
- ✅ Identification de sections pertinentes
**Exemples**:
- "What is the Turing test?"
- "Can virtue be taught?"
- "What is pragmatism?"
### Cas d'Usage Chunk (Ancienne)
- Citations précises nécessaires
- Recherche très spécifique dans le texte
- Analyse détaillée d'un passage
**Exemples**:
- "Exact quote about X"
- Requêtes avec mots-clés très précis
---
## Prochaines Étapes (Optionnel)
### Court Terme
- [ ] Ajouter bouton "Voir chunks détaillés" sur chaque résumé
- [ ] Route `/summary/<uuid>/chunks` pour expansion
- [ ] Export résultats (JSON/CSV)
### Moyen Terme
- [ ] Mode hybride avec toggle Summary/Chunk
- [ ] Filtres par auteur/document
- [ ] Historique de recherche
- [ ] Sauvegarde de recherches favorites
### Long Terme
- [ ] Suggestions de recherche basées sur l'historique
- [ ] Graphe de relations entre concepts
- [ ] Visualisation des sections les plus consultées
---
## Maintenance
### Dépendances
- Flask 3.0+
- Weaviate Python client v4
- Jinja2 (inclus avec Flask)
### Monitoring
- Logs Flask: Recherches effectuées dans stdout
- Weaviate: Métriques via `http://localhost:8080/v1/meta`
### Mise à Jour
Si nouveaux résumés générés:
1. Les résumés sont automatiquement vectorisés dans Summary
2. Aucune modification de code nécessaire
3. Nouveaux résumés apparaissent immédiatement dans recherche
---
## Support et Débogage
### Vérifier que Weaviate tourne
```bash
docker ps | grep weaviate
# Devrait montrer: Up X hours
```
### Vérifier les résumés en base
```bash
python -c "
import weaviate
client = weaviate.connect_to_local()
summaries = client.collections.get('Summary')
print(f'Total summaries: {len(list(summaries.iterator()))}')
client.close()
"
```
### Logs Flask
```bash
# Le serveur affiche les requêtes dans stdout
127.0.0.1 - - [DATE] "GET /search/summary?q=... HTTP/1.1" 200 -
```
### Test Manuel
```bash
# Test rapide
curl "http://localhost:5000/search/summary?q=test&limit=5"
# Devrait retourner HTML avec résultats
```
---
## Conclusion
**Intégration complète et fonctionnelle**
- Backend: Fonction + Route
- Frontend: Template + Navigation
- Tests: 100% de réussite
- Performance: 90% de visibilité démontrée
La nouvelle interface de recherche Summary est maintenant disponible dans l'application Flask et offre une expérience utilisateur nettement supérieure pour la découverte de documents philosophiques.
**Recommandation**: Promouvoir la recherche Summary comme interface principale et garder la recherche Chunk pour les cas d'usage spécifiques.
---
**Auteur**: Claude Sonnet 4.5
**Date**: 2026-01-03
**Version**: 1.0
**Status**: ✅ Production Ready

File diff suppressed because it is too large Load Diff

View File

@@ -1,239 +0,0 @@
# Quickstart - Recherche Summary
Guide rapide pour utiliser la nouvelle interface de recherche optimisée.
---
## 🚀 Démarrage Rapide
### 1. Démarrer Weaviate (si pas déjà lancé)
```bash
docker compose up -d
```
### 2. Démarrer l'application Flask
```bash
cd generations/library_rag
python flask_app.py
```
### 3. Accéder à l'interface
Ouvrir dans le navigateur: **http://localhost:5000**
### 4. Utiliser la Recherche Summary
1. Cliquer sur le menu ☰ (hamburger) en haut à gauche
2. Cliquer sur **"📚 Recherche Résumés"** (badge 90%)
3. Entrer une question et cliquer sur **"🔍 Rechercher"**
---
## 💡 Exemples de Recherche
### IA et Philosophie de l'Esprit (Haugeland 🟣)
```
What is the Turing test?
Can machines think?
What is a physical symbol system?
How do connectionist networks work?
```
**Résultat attendu**: Résumés de Haugeland avec icône 🟣
### Vertu et Connaissance (Platon 🟢)
```
Can virtue be taught?
What is the theory of recollection?
How does Socrates define virtue?
```
**Résultat attendu**: Résumés de Platon (Ménon) avec icône 🟢
### Pragmatisme et Sémiotique (Tiercelin 🟡)
```
What is pragmatism according to Peirce?
How does thought work as a sign?
What is the relationship between doubt and inquiry?
```
**Résultat attendu**: Résumés de Tiercelin avec icône 🟡
---
## 🎨 Interface Visuelle
### Ce que vous verrez:
```
┌──────────────────────────────────────────────────────────┐
│ 📚 Recherche par Résumés │
│ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ ✨ Nouvelle interface de recherche optimisée │ │
│ │ Performance: [📊 90% de visibilité] vs [📉 10%] │ │
│ └────────────────────────────────────────────────────┘ │
│ │
│ ┌─ Formulaire de recherche ─────────────────────────┐ │
│ │ Votre question: [What is the Turing test?] │ │
│ │ Nombre: [10 résumés ▼] Seuil: [65% ▼] │ │
│ │ [🔍 Rechercher] [Réinitialiser] [🔄 Classique] │ │
│ └───────────────────────────────────────────────────┘ │
│ │
│ 3 résumés trouvés [📚 Recherche par Résumés] │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 🟣 [Haugeland] John Haugeland (2023) ⚡ 69.5% │ │
│ │ Computers and intelligence │ │
│ │ │ │
│ │ "This section examines Turing's 1950 prediction... │ │
│ │ analyzing the theoretical foundations..." │ │
│ │ │ │
│ │ Concepts: Turing test | AI | formal function |... │ │
│ │ 📄 1 passage détaillé Section: 2.2.3... │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ [Plus de résultats...] │
└──────────────────────────────────────────────────────────┘
```
---
## 📊 Comparaison des Modes
| Fonctionnalité | Summary (Nouveau) | Chunk (Ancien) |
|----------------|-------------------|----------------|
| **Visibilité documents riches** | 90% ✅ | 10% ❌ |
| **Vue d'ensemble** | Résumés de sections | Passages courts |
| **Métadonnées** | Riches (concepts, auteur) | Basiques |
| **Exploration** | Excellente | Difficile |
| **Précision citations** | Moyenne | Excellente |
| **Temps de réponse** | Rapide (~300ms) | Rapide (~300ms) |
### Quand utiliser Summary? ✅
- Questions générales
- Découverte de sujets
- Vue d'ensemble d'un document
- Identification de sections pertinentes
### Quand utiliser Chunk? 🔍
- Besoin de citations exactes
- Recherche très précise
- Analyse détaillée d'un passage
---
## 🎯 Paramètres Recommandés
### Exploration Large
```
Résultats: 15-20 résumés
Seuil: 60-65% (plus large)
```
**Utilisation**: Découverte de sujets, brainstorming
### Recherche Précise
```
Résultats: 5-10 résumés
Seuil: 70-75% (très précis)
```
**Utilisation**: Questions spécifiques, confirmation d'informations
### Par Défaut (Recommandé)
```
Résultats: 10 résumés
Seuil: 65% (équilibré)
```
**Utilisation**: Usage général, meilleur compromis
---
## 🔧 Troubleshooting
### "Aucun résumé trouvé"
**Solutions**:
1. Réduire le seuil de similarité (essayer 60%)
2. Reformuler la question en anglais/français
3. Utiliser des termes plus généraux
4. Vérifier que la question porte sur les documents disponibles
### Page ne charge pas
**Solutions**:
1. Vérifier que Flask tourne: `http://localhost:5000`
2. Vérifier que Weaviate tourne: `docker ps | grep weaviate`
3. Consulter les logs Flask dans le terminal
### Résultats non pertinents
**Solutions**:
1. Augmenter le seuil de similarité (essayer 70-75%)
2. Réduire le nombre de résultats
3. Être plus spécifique dans la question
---
## 📚 Documents Disponibles
### 🟣 Haugeland - Mind Design III
**Sujets**: IA, philosophie de l'esprit, Turing test, réseaux de neurones, computation
**Résumés**: 50 sections
### 🟢 Platon - Ménon
**Sujets**: Vertu, connaissance, réminiscence, Socrate, enseignement
**Résumés**: 12 sections
### 🟡 Tiercelin - La Pensée-Signe
**Sujets**: Pragmatisme, Peirce, sémiotique, pensée, signes
**Résumés**: 51 sections
### 🔵 Peirce - La Logique de la Science
**Sujets**: Croyance, doute, méthode scientifique, fixation des croyances
**Résumés**: 1 section
**Total**: 114 résumés (106 riches) indexés et searchables
---
## 🎓 Conseils d'Utilisation
### 1. Formuler de Bonnes Questions
**Bon**: "What is the Turing test and what does it tell us about intelligence?"
**Mauvais**: "turing"
**Bon**: "Can virtue be taught according to Plato?"
**Mauvais**: "plato virtue"
### 2. Explorer les Concepts
Cliquer sur les concepts affichés pour voir les thèmes principaux d'une section.
### 3. Ajuster le Seuil
- Trop de résultats non pertinents? → Augmenter le seuil
- Pas assez de résultats? → Réduire le seuil
### 4. Basculer entre Modes
Utiliser le bouton "🔄 Recherche classique" pour comparer les résultats entre Summary et Chunk.
---
## 🚀 Prochaines Fonctionnalités
Améliorations prévues:
- [ ] Bouton "Voir les passages détaillés" sur chaque résumé
- [ ] Filtres par auteur/document
- [ ] Historique de recherche
- [ ] Export des résultats (JSON/PDF)
- [ ] Suggestions de recherches liées
---
## 📞 Support
- **Documentation complète**: `INTEGRATION_SUMMARY.md`
- **Analyse technique**: `ANALYSE_RAG_FINAL.md`
- **Guide d'utilisation**: `README_SEARCH.md`
- **Tests**: `test_flask_integration.py`
---
**Version**: 1.0
**Date**: 2026-01-03
**Statut**: ✅ Production Ready
Bon usage de la recherche optimisée! 🚀

View File

@@ -1,188 +0,0 @@
# Guide d'Utilisation - Interface de Recherche Optimisée
## Vue d'Ensemble
L'interface de recherche optimisée utilise la collection **Summary** comme point d'entrée principal, offrant **90% de visibilité** des documents riches vs 10% pour la recherche directe dans Chunks.
## Performance Démontrée
### ✅ Tests Réussis
#### 1. Requêtes sur l'IA (domaine Haugeland)
```bash
python search_summary_interface.py "What is the Turing test?"
```
**Résultat**: 7/7 résultats Haugeland (100%)
#### 2. Requêtes sur la vertu (domaine Platon)
```bash
python search_summary_interface.py "Can virtue be taught?"
```
**Résultat**: 6/6 résultats Platon (100%)
#### 3. Requêtes sur le pragmatisme (domaine Peirce/Tiercelin)
```bash
python search_summary_interface.py "What is pragmatism according to Peirce?"
```
**Résultat**: 5/5 résultats Tiercelin (100%)
### Comparaison avec Recherche Chunk Directe
| Approche | Visibilité Documents Riches | Performance |
|----------|----------------------------|-------------|
| **Summary-first** (ce script) | **90%** | ✅ Excellent |
| Chunk directe | 10% | ❌ Dominé par Peirce |
## Utilisation
### Mode Requête Unique
```bash
# Requête simple
python search_summary_interface.py "Votre question ici"
# Avec limite de résultats
python search_summary_interface.py "What is intelligence?" -n 5
# Avec seuil de similarité personnalisé
python search_summary_interface.py "Can machines think?" -s 0.7
```
### Mode Interactif
```bash
# Lancer sans arguments
python search_summary_interface.py
# Interface interactive
INTERFACE DE RECHERCHE RAG - Collection Summary
================================================
Mode: Summary-first (90% de visibilité démontrée)
Tapez 'quit' pour quitter
Votre question: What is the Chinese Room argument?
[résultats affichés]
Votre question: Can virtue be taught?
[résultats affichés]
Votre question: quit
Au revoir!
```
## Options
| Option | Court | Défaut | Description |
|--------|-------|--------|-------------|
| `query` | - | - | Question de recherche (optionnel) |
| `--limit` | `-n` | 10 | Nombre maximum de résultats |
| `--min-similarity` | `-s` | 0.65 | Seuil de similarité (0-1) |
## Format des Résultats
Chaque résultat affiche:
- **Icône + Document**: 🟣 Haugeland, 🟢 Platon, 🟡 Tiercelin, 🔵 Logique, ⚪ Peirce
- **Similarité**: Score 0-1 et pourcentage
- **Titre**: Titre de la section
- **Auteur/Année**: Si disponible
- **Concepts**: Top 5 concepts clés
- **Résumé**: Résumé de la section (max 300 chars)
- **Chunks**: Nombre de chunks disponibles pour lecture détaillée
### Exemple de Sortie
```
[1] 🟣 Haugeland - Similarité: 0.695 (69.5%)
Titre: 2.2.3 Computers and intelligence
Auteur: John Haugeland, Carl F. Craver, and Colin Klein (2023.0)
Concepts: Turing test, artificial intelligence, formal input/output function, universal machine, computability (+5 autres)
Résumé: This section examines Turing's 1950 prediction that computers would achieve human-level intelligence by 2000, analyzing the theoretical foundations underlying this forecast...
📄 1 chunk(s) disponible(s) pour lecture détaillée
```
## Fonctionnalités Avancées
### Récupération des Chunks Détaillés
Le script inclut la fonction `get_chunks_for_section()` pour récupérer le contenu détaillé:
```python
from search_summary_interface import get_chunks_for_section
# Après avoir identifié une section intéressante
chunks = get_chunks_for_section(
document_id="Haugeland_J._Mind_Design_III...",
section_path="2.2.3 Computers and intelligence",
limit=5
)
for chunk in chunks:
print(chunk["text"])
```
## Architecture
### Collection Summary
- 114 résumés total
- 106 résumés riches (>100 chars)
- Documents: Tiercelin (51), Haugeland (50), Platon (12), Logique (1)
### Vecteurs
- Modèle: BAAI/bge-m3 (1024 dimensions)
- Contexte: 8192 tokens
- Multilingual: Anglais, Français, Latin, Grec
### Recherche Sémantique
- Méthode: `near_text` (Weaviate)
- Distance: Cosine
- Métrique: Similarité = 1 - distance
## Pourquoi Summary-First?
### Problème des Chunks
- 5,068 chunks Peirce sur 5,230 total (97%)
- Domination écrasante même sur requêtes spécialisées
- Exemple: "What is the Turing test?" → 5/5 chunks Peirce (0/5 Haugeland)
### Solution Summary
- Résumés équilibrés par document
- Haute qualité (générés par Claude Sonnet 4.5)
- 90% de visibilité prouvée
- Concepts et keywords riches
## Coût et Performance
### Coût de Génération
- Total: $1.23 pour 106 résumés riches
- Tiercelin: $0.63 (43 résumés)
- Haugeland: $0.44 (50 résumés)
- Platon: $0.14 (12 résumés)
- Logique: $0.02 (1 résumé)
### Performance Requêtes
- Temps moyen: ~200-500ms par requête
- Précision: 90% (documents pertinents dans top 5)
- Couverture: Tous les documents riches indexés
## Prochaines Étapes Possibles
1. **Interface Web**: Intégrer dans Flask app existante
2. **Mode Hybride**: Toggle Summary/Chunk au choix
3. **Expansion Chunks**: Fonction "Voir plus" pour lire chunks détaillés
4. **Filtres**: Par document, auteur, année, concepts
5. **Historique**: Sauvegarde des recherches récentes
## Fichiers Associés
- `search_summary_interface.py` - Script principal
- `ANALYSE_RAG_FINAL.md` - Analyse complète du système
- `test_real_queries.py` - Tests de validation (15 requêtes)
- `test_haugeland_ai.py` - Tests spécifiques IA
- `test_hierarchical_search.py` - Tests Summary → Chunks
## Support
Pour questions ou améliorations, voir `ANALYSE_RAG_FINAL.md` pour le contexte complet.
---
**Date**: 2026-01-03
**Version**: 1.0
**Status**: ✅ Production-ready

View File

@@ -1,372 +0,0 @@
# Refactorisation - Intégration Summary dans Dropdown
**Date**: 2026-01-03
**Type**: Refactorisation (Option 1)
**Statut**: ✅ Complète et testée
---
## Contexte
Initialement, j'avais créé une **page séparée** (`/search/summary`) pour la recherche par résumés.
L'utilisateur a correctement identifié que c'était redondant puisque le mode **hiérarchique** existant fait déjà une recherche en 2 étapes (Summary → Chunks).
**Solution**: Intégrer "Résumés uniquement" comme option dans le dropdown "Mode de recherche" existant.
---
## Ce qui a été Refactorisé
### ✅ Backend (`flask_app.py`)
#### 1. Nouvelle fonction `summary_only_search()`
**Emplacement**: Lignes 553-654
**Rôle**: Recherche sémantique dans la collection Summary uniquement
```python
def summary_only_search(
query: str,
limit: int = 10,
author_filter: Optional[str] = None,
work_filter: Optional[str] = None,
) -> List[Dict[str, Any]]:
"""Summary-only semantic search (90% visibility)."""
```
**Caractéristiques**:
- Recherche dans Summary collection
- Filtre par auteur/work (Python-side)
- Icônes par document (🟣🟢🟡🔵⚪)
- Format compatible avec template existant
#### 2. Modification `search_passages()`
**Ajout**: Support du mode `force_mode="summary"`
```python
if force_mode == "summary":
results = summary_only_search(query, limit, author_filter, work_filter)
return {
"mode": "summary",
"results": results,
"total_chunks": len(results),
}
```
#### 3. Suppression
- ❌ Route `/search/summary` supprimée
- ❌ Fonction `search_summaries_backend()` supprimée
- ❌ ~150 lignes de code dupliqué éliminées
### ✅ Frontend (`templates/search.html`)
#### 1. Dropdown "Mode de recherche"
**Ajout**: Option "Résumés uniquement"
```html
<option value="summary">📚 Résumés uniquement (90% visibilité)</option>
```
**Options disponibles**:
- 🤖 Auto-détection (défaut)
- 📄 Simple (Chunks)
- 🌳 Hiérarchique (Summary → Chunks)
- 📚 Résumés uniquement (90% visibilité) ⭐ **NOUVEAU**
#### 2. Badge de mode
**Ajout**: Badge pour mode summary
```jinja2
{% elif results_data.mode == "summary" %}
<span class="badge">📚 Résumés uniquement (90% visibilité)</span>
```
#### 3. Affichage des résultats Summary
**Ajout**: Bloc spécial pour affichage Summary (lignes 264-316)
**Caractéristiques**:
- Icône de document (🟣🟢🟡🔵⚪)
- Titre de section
- Résumé du contenu
- Concepts clés (top 8)
- Nombre de chunks disponibles
- Badges auteur/année
### ✅ Navigation (`templates/base.html`)
#### Suppression
- ❌ Lien "📚 Recherche Résumés" supprimé de la sidebar
- ❌ Badge "90%" séparé supprimé
**Raison**: Tout est maintenant dans le dropdown de `/search`
### ✅ Templates
#### Suppression
-`templates/search_summary.html` supprimé (~320 lignes)
**Raison**: Utilise désormais `templates/search.html` avec mode conditionnel
---
## Comparaison Avant/Après
### Avant (Page Séparée)
**Navigation**:
```
Sidebar:
├── Recherche (/search)
└── Recherche Résumés (/search/summary) ← Page séparée
```
**Code**:
- Route séparée `/search/summary`
- Template séparé `search_summary.html`
- Fonction séparée `search_summaries_backend()`
- Total: ~470 lignes de code dupliqué
**UX**:
- 2 pages différentes
- Navigation confuse
- Duplication de fonctionnalités
### Après (Dropdown Intégré)
**Navigation**:
```
Sidebar:
└── Recherche (/search)
└── Mode: Résumés uniquement (dropdown)
```
**Code**:
- 1 seule route `/search`
- 1 seul template `search.html`
- Fonction `summary_only_search()` intégrée
- Réduction: ~470 → ~100 lignes
**UX**:
- 1 seule page
- Dropdown clair et intuitif
- Cohérence avec architecture existante
---
## Tests de Validation
### ✅ Tests Automatisés
**Script**: `test_summary_dropdown.py`
```
Test 1: What is the Turing test? (mode=summary)
✅ Found Haugeland icon 🟣
✅ Summary mode badge displayed
✅ Results displayed
✅ Concepts displayed
Test 2: Can virtue be taught? (mode=summary)
✅ Found Platon icon 🟢
✅ Summary mode badge displayed
✅ Results displayed
✅ Concepts displayed
Test 3: What is pragmatism? (mode=summary)
✅ Found Tiercelin icon 🟡
✅ Summary mode badge displayed
✅ Results displayed
✅ Concepts displayed
Test 4: Summary option in dropdown
✅ Summary option present
✅ Summary option label correct
```
**Résultat**: 14/14 tests passés (100%)
---
## Utilisation
### Via Interface Web
1. Ouvrir http://localhost:5000/search
2. Entrer une question
3. **Sélectionner** "📚 Résumés uniquement (90% visibilité)" dans le dropdown
4. Cliquer "Rechercher"
### Via URL
```
http://localhost:5000/search?q=What+is+the+Turing+test&mode=summary&limit=10
```
**Paramètres**:
- `q`: Question
- `mode=summary`: Force le mode Résumés
- `limit`: Nombre de résultats (défaut: 10)
- `author`: Filtre par auteur (optionnel)
- `work`: Filtre par œuvre (optionnel)
---
## Avantages de la Refactorisation
### ✅ Code
- **-370 lignes** de code dupliqué
- Architecture plus propre
- Maintenance simplifiée
- Cohérence avec modes existants
### ✅ UX
- Interface unifiée
- Dropdown intuitif
- Moins de confusion
- Cohérence visuelle
### ✅ Performance
- Aucun impact (même vitesse)
- Même fonctionnalité
- 90% de visibilité maintenue
### ✅ Architecture
- Respect du pattern existant
- Hiérarchie logique: Auto → Simple → Hiérarchique → Summary
- Extensible pour futurs modes
---
## Fichiers Modifiés
### Backend
```
flask_app.py
├── [+] summary_only_search() (lignes 553-654)
├── [~] search_passages() (support mode="summary")
└── [-] Route /search/summary supprimée
```
### Frontend
```
templates/search.html
├── [~] Dropdown: +1 option "summary"
├── [~] Badge mode: +1 cas "summary"
└── [+] Affichage Summary (lignes 264-316)
templates/base.html
└── [-] Lien "Recherche Résumés" supprimé
templates/search_summary.html
└── [❌] Fichier supprimé
```
### Tests
```
test_summary_dropdown.py
└── [+] Nouveau script de tests (14 checks)
test_flask_integration.py
└── [~] Maintenu pour référence (ancien test)
```
---
## Migration
### Pour les utilisateurs
**Aucune action requise**. L'ancienne URL `/search/summary` n'est plus disponible, mais la fonctionnalité existe dans `/search` avec `mode=summary`.
**Migration automatique des URLs**:
```
Avant: /search/summary?q=test
Après: /search?q=test&mode=summary
```
### Pour le code
**Aucune migration nécessaire**. La fonction backend `search_passages()` reste identique, seul le paramètre `force_mode` accepte maintenant `"summary"`.
---
## Prochaines Étapes (Optionnel)
### Court Terme
1. ✅ Ajouter tooltips sur les options du dropdown
2. ✅ Badge "Nouveau" temporaire sur option Summary
3. ✅ Analytics pour suivre l'usage par mode
### Moyen Terme
1. Intégrer filtres auteur/work dans mode Summary
2. Permettre expansion "Voir chunks" depuis un résumé
3. Mode hybride "Auto-Summary" (détection intelligente)
### Long Terme
1. Apprentissage: mémoriser préférence mode par utilisateur
2. Mode "Mixed" (Summary + Chunks dans même résultat)
3. Recherche fédérée (Summary || Chunks en parallèle)
---
## Comparaison des Modes
| Mode | Collection | Étapes | Visibilité | Usage |
|------|------------|---------|-----------|-------|
| **Simple** | Chunk | 1 | 10% ❌ | Citations précises |
| **Hiérarchique** | Summary → Chunk | 2 | Variable | Exploration contextuelle |
| **Summary** | Summary | 1 | 90% ✅ | Vue d'ensemble |
| **Auto** | Détection | 1-2 | Variable | Défaut recommandé |
### Quand utiliser Summary?
✅ Questions générales ("What is X?")
✅ Découverte de sujets
✅ Vue d'ensemble d'un document
✅ Identification de sections pertinentes
❌ Citations exactes nécessaires
❌ Analyse très précise d'un passage
---
## Conclusion
### ✅ Objectifs Atteints
1. ✅ Intégration propre dans dropdown existant
2. ✅ Suppression de la page séparée redondante
3. ✅ Code plus maintenable (-370 lignes)
4. ✅ Tests passants (14/14 - 100%)
5. ✅ UX améliorée (interface unifiée)
6. ✅ Performance identique (90% visibilité)
### 📊 Métriques
- **Lignes de code**: -370 (réduction 79%)
- **Fichiers supprimés**: 1 (search_summary.html)
- **Tests**: 14/14 passés (100%)
- **Routes**: 2 → 1 (simplification)
- **Templates**: 2 → 1 (consolidation)
### 🎯 Résultat
L'option "Résumés uniquement" est maintenant **parfaitement intégrée** dans le dropdown "Mode de recherche", offrant:
- Architecture cohérente avec modes existants
- Code plus propre et maintenable
- UX simplifiée et intuitive
- Performance optimale (90% visibilité)
---
**Auteur**: Claude Sonnet 4.5
**Date**: 2026-01-03
**Type**: Refactorisation Option 1
**Statut**: ✅ Complète et Production-Ready

View File

@@ -1,238 +0,0 @@
# Résumé de Session - Amélioration RAG Library
**Date**: 2026-01-03
**Objectif**: Résoudre le problème de dominance des chunks Peirce sans suppression
**Statut**: ✅ Résolu avec implémentation production-ready
---
## Problème Identifié
### État Initial
- **Collection Chunk**: 5,230 chunks total
- Peirce: 5,068 chunks (97%)
- Autres: 162 chunks (3%)
- **Impact**:
- Recherche chunk directe: 10% de visibilité pour documents riches
- Même sur requêtes ultra-spécifiques (ex: "What is the Turing test?"), Peirce domine 88% des résultats
- Haugeland n'apparaît que dans 10% des résultats sur son propre domaine (IA)
### Contrainte Utilisateur
> "NE SUPPRIME PAS LES CHUNKLS D EPEIRCE BORDEL"
❌ Pas de suppression des chunks Peirce permise
---
## Solution Implémentée
### Option A: Summary-First Search Interface ✅
**Principe**: Utiliser la collection Summary (équilibrée, haute qualité) comme point d'entrée principal au lieu des Chunks.
**Résultats Prouvés**:
- ✅ 90% de visibilité des documents riches
- ✅ 100% de précision sur requêtes testées
- ✅ Coût additionnel: $0
- ✅ Respecte la contrainte (pas de suppression)
---
## Livrables
### 1. Documentation Complète
#### `ANALYSE_RAG_FINAL.md`
Analyse exhaustive comprenant:
- État de la base de données (Summary + Chunk)
- Historique complet des travaux ($1.23, 106 résumés)
- Tests de performance (15 requêtes réelles)
- Comparaison Summary vs Chunk (90% vs 10%)
- 3 options de solution détaillées
#### `README_SEARCH.md`
Guide d'utilisation complet:
- Exemples d'utilisation (modes unique et interactif)
- Options et paramètres
- Format des résultats
- Architecture technique
- Prochaines étapes possibles
### 2. Implémentation Fonctionnelle
#### `search_summary_interface.py`
Script Python production-ready avec:
**Fonctionnalités**:
- ✅ Mode requête unique: `python search_summary_interface.py "question"`
- ✅ Mode interactif: `python search_summary_interface.py`
- ✅ Paramètres configurables: `-n` (limit), `-s` (min-similarity)
- ✅ Affichage riche: icônes, auteurs, concepts, résumés
- ✅ Support multilingue (FR/EN)
- ✅ Fonction bonus: récupération chunks détaillés
**Qualité Code**:
- Type hints complets
- Docstrings Google-style
- Gestion d'erreurs
- Encodage Windows UTF-8
- Code propre et maintenable
### 3. Tests de Validation
#### Tests Exécutés et Validés ✅
**Test 1 - IA/Haugeland**:
```bash
python search_summary_interface.py "What is the Turing test?"
```
Résultat: 7/7 résultats Haugeland (100%)
**Test 2 - Vertu/Platon**:
```bash
python search_summary_interface.py "Can virtue be taught?"
```
Résultat: 6/6 résultats Platon (100%)
**Test 3 - Pragmatisme/Tiercelin**:
```bash
python search_summary_interface.py "What is pragmatism according to Peirce?"
```
Résultat: 5/5 résultats Tiercelin (100%)
**Conclusion**: ✅ 100% de précision sur tous les domaines testés
---
## Métriques de Performance
### Avant (Recherche Chunk Directe)
- Visibilité documents riches: 10%
- Haugeland sur requêtes IA: 10%
- Peirce dominance: 88%
- Utilisabilité: ❌ Mauvaise
### Après (Recherche Summary)
- Visibilité documents riches: 90%
- Haugeland sur requêtes IA: 100%
- Distribution équilibrée: ✅
- Utilisabilité: ✅ Excellente
**Amélioration**: +800% de visibilité
---
## Architecture de la Solution
### Base de Données
```
Summary Collection (114 résumés)
├─ Tiercelin: 51 résumés (générés LLM)
├─ Haugeland: 50 résumés (générés LLM)
├─ Platon: 12 résumés (générés LLM)
└─ Logique: 1 résumé (généré LLM)
Vectorisation: BAAI/bge-m3 (1024-dim, 8192 tokens)
```
### Flux de Recherche
```
User Query
Summary Search (near_text)
Top N résumés pertinents
Affichage: titre, auteur, concepts, résumé
[Optionnel] Récupération chunks détaillés
```
### Avantages Techniques
- ✅ Aucune modification base de données
- ✅ Aucune suppression de données
- ✅ Utilise infrastructure existante
- ✅ Extensible (peut ajouter mode hybride)
- ✅ Maintenable (code simple et clair)
---
## Coûts
### Coûts de Développement
- Génération résumés (déjà effectuée): $1.23
- Développement script: $0
- Tests et validation: $0
- **Total**: $1.23
### Performance
- Temps par requête: ~200-500ms
- Charge serveur: Faible
- Scalabilité: Excellente
---
## Fichiers Créés/Modifiés
### Nouveaux Fichiers ✨
1. `ANALYSE_RAG_FINAL.md` - Documentation complète (15 KB)
2. `search_summary_interface.py` - Script de recherche (8 KB)
3. `README_SEARCH.md` - Guide utilisateur (7 KB)
4. `SESSION_SUMMARY.md` - Ce fichier (5 KB)
### Tests Exécutés ✅
1. `test_haugeland_ai.py` - Validation domaine IA
2. `test_hierarchical_search.py` - Test Summary → Chunks
3. `test_real_queries.py` - 15 requêtes réelles
**Total**: 4 documents + 1 script + 3 tests validés
---
## Prochaines Étapes Recommandées
### Court Terme (Optionnel)
1. Intégrer `search_summary_interface.py` dans Flask app
2. Ajouter route `/search/summary` avec interface web
3. Ajouter bouton "Voir chunks détaillés" pour expansion
### Moyen Terme (Si Besoin)
1. Mode hybride: toggle Summary/Chunk au choix utilisateur
2. Filtres avancés: par auteur, année, concepts
3. Historique de recherche
4. Export résultats (JSON, CSV)
### Long Terme (Si Nécessaire)
1. Régénération résumés Peirce (~$45-50)
2. Amélioration recherche hierarchique (si nouvelle version Weaviate)
3. Multi-modal: recherche par images de diagrammes
---
## Conclusion
### Objectifs Atteints ✅
- ✅ Problème de visibilité résolu (10% → 90%)
- ✅ Contrainte respectée (pas de suppression Peirce)
- ✅ Solution production-ready implémentée
- ✅ Documentation complète fournie
- ✅ Tests validés sur tous domaines
### État Final
- **Fonctionnel**: ✅ Prêt à l'emploi
- **Documenté**: ✅ 4 documents complets
- **Testé**: ✅ 100% de précision démontrée
- **Maintenable**: ✅ Code propre et clair
- **Extensible**: ✅ Facile d'ajouter features
### Recommandation
**Utiliser `search_summary_interface.py` comme interface de recherche principale.**
La recherche dans Summary offre une expérience utilisateur nettement supérieure avec 90% de visibilité vs 10% pour la recherche chunk directe, tout en respectant l'intégrité des données (pas de suppression).
---
**Signature**: Claude Sonnet 4.5
**Date**: 2026-01-03
**Status**: ✅ Mission Accomplie

View File

@@ -1,133 +0,0 @@
# Guide d'Installation TTS - Après Redémarrage Windows
## 📋 Contexte
Vous avez installé **Microsoft Visual Studio Build Tools avec composants C++**.
Après redémarrage de Windows, ces outils seront actifs et permettront la compilation de TTS.
---
## 🔄 Étapes Après Redémarrage
### 1. Vérifier que Visual Studio Build Tools est actif
Ouvrir un **nouveau** terminal et tester :
```bash
# Vérifier que le compilateur C++ est disponible
where cl
# Devrait afficher un chemin comme :
# C:\Program Files\Microsoft Visual Studio\...\cl.exe
```
### 2. Installer TTS (Coqui XTTS v2)
```bash
# Aller dans le dossier du projet
cd C:\GitHub\linear_coding_library_rag\generations\library_rag
# Installer TTS (cela prendra 5-10 minutes)
pip install TTS==0.22.0
```
**Attendu** : Compilation réussie avec "Successfully installed TTS-0.22.0"
### 3. Vérifier l'installation
```bash
# Test d'import
python -c "import TTS; print(f'TTS version: {TTS.__version__}')"
# Devrait afficher : TTS version: 0.22.0
```
### 4. Redémarrer Flask et Tester
```bash
# Lancer Flask
python flask_app.py
# Aller sur http://localhost:5000/chat
# Poser une question
# Cliquer sur le bouton "Audio"
```
**Premier lancement** : Le modèle XTTS v2 (~2GB) sera téléchargé automatiquement (5-10 min).
---
## ⚠️ Si TTS échoue encore après redémarrage
### Solution Alternative : edge-tts (Déjà installé ✅)
**edge-tts** est déjà installé et fonctionne immédiatement. C'est une excellente alternative avec :
- ✅ Voix Microsoft Edge haute qualité
- ✅ Support français excellent
- ✅ Pas de compilation nécessaire
- ✅ Pas besoin de GPU
**Pour utiliser edge-tts**, il faudra modifier `utils/tts_generator.py`.
---
## 📊 Comparaison des Options
| Critère | TTS (XTTS v2) | edge-tts |
|---------|---------------|----------|
| Installation | ⚠️ Complexe (compilation) | ✅ Simple (pip install) |
| Qualité | ⭐⭐⭐⭐⭐ Excellente | ⭐⭐⭐⭐⭐ Excellente |
| GPU | ✅ Oui (4-6 GB VRAM) | ❌ Non (CPU uniquement) |
| Vitesse (100 mots) | 2-5 secondes (GPU) | 3-8 secondes (CPU) |
| Offline | ✅ Oui (après download) | ⚠️ Requiert Internet |
| Taille modèle | ~2 GB | Aucun téléchargement |
| Voix françaises | Oui, naturelles | Oui, Microsoft Azure |
---
## 🎯 Recommandation
1. **Essayer TTS après redémarrage** (pour profiter du GPU)
2. **Si échec** : Utiliser edge-tts (déjà installé, fonctionne immédiatement)
---
## 📝 Commandes de Diagnostic
Si TTS échoue encore :
```bash
# Vérifier Python
python --version
# Vérifier pip
pip --version
# Vérifier torch (déjà installé)
python -c "import torch; print(f'CUDA: {torch.cuda.is_available()}')"
# Vérifier Visual Studio
where cl
```
---
## 🔧 Fichiers Modifiés
-`requirements.txt` - TTS>=0.22.0 ajouté
-`utils/tts_generator.py` - Module TTS créé (pour XTTS v2)
-`flask_app.py` - Route /chat/export-audio ajoutée
-`templates/chat.html` - Bouton Audio ajouté
**Commit** : `d91abd3` - "Ajout de la fonctionnalité TTS"
---
## 📞 Contact après redémarrage
Après redémarrage, exécutez simplement :
```bash
pip install TTS==0.22.0
```
Et dites-moi le résultat (succès ou erreur).

File diff suppressed because it is too large Load Diff

View File

@@ -1,323 +0,0 @@
# Schéma Weaviate - Library RAG
## Architecture globale
Le schéma suit une architecture normalisée avec des objets imbriqués (nested objects) pour un accès efficace aux données.
```
Work (métadonnées uniquement)
└── Document (instance d'édition/traduction)
├── Chunk (fragments de texte vectorisés)
└── Summary (résumés de chapitres vectorisés)
```
---
## Collections
### 1. Work (Œuvre)
**Description** : Représente une œuvre philosophique ou académique (ex: Ménon de Platon)
**Vectorisation** : ✅ **text2vec-transformers** (depuis migration 2026-01)
**Champs vectorisés** :
-`title` (TEXT) - Titre de l'œuvre (permet recherche sémantique "dialogues socratiques" → Ménon)
-`author` (TEXT) - Auteur (permet recherche "philosophie analytique" → Haugeland)
**Champs NON vectorisés** :
- `originalTitle` (TEXT) [skip_vec] - Titre original dans la langue source (optionnel)
- `year` (INT) - Année de composition/publication (négatif pour avant J.-C.)
- `language` (TEXT) [skip_vec] - Code ISO de langue originale (ex: 'gr', 'la', 'fr')
- `genre` (TEXT) [skip_vec] - Genre ou type (ex: 'dialogue', 'traité', 'commentaire')
**Note** : Collection actuellement vide (0 objets) mais prête pour migration. Voir `migrate_add_work_collection.py` pour ajouter la vectorisation sans perdre les 5,404 chunks existants.
---
### 2. Document (Édition)
**Description** : Instance spécifique d'une œuvre (édition, traduction)
**Vectorisation** : AUCUNE (métadonnées uniquement)
**Propriétés** :
- `sourceId` (TEXT) - Identifiant unique (nom de fichier sans extension)
- `edition` (TEXT) - Édition ou traducteur (ex: 'trad. Cousin')
- `language` (TEXT) - Langue de cette édition
- `pages` (INT) - Nombre de pages du PDF/document
- `chunksCount` (INT) - Nombre total de chunks extraits
- `toc` (TEXT) - Table des matières en JSON `[{title, level, page}, ...]`
- `hierarchy` (TEXT) - Structure hiérarchique complète en JSON
- `createdAt` (DATE) - Timestamp d'ingestion
**Objets imbriqués** :
- `work` (OBJECT)
- `title` (TEXT)
- `author` (TEXT)
---
### 3. Chunk (Fragment de texte) ⭐ **PRINCIPAL**
**Description** : Fragments de texte optimisés pour la recherche sémantique (200-800 caractères)
**Vectorisation** : `text2vec-transformers` (BAAI/bge-m3, 1024 dimensions)
**Champs vectorisés** :
-`text` (TEXT) - Contenu textuel du chunk
-`keywords` (TEXT_ARRAY) - Concepts clés extraits
**Champs NON vectorisés** (filtrage uniquement) :
- `sectionPath` (TEXT) [skip_vec] - Chemin hiérarchique complet
- `sectionLevel` (INT) - Profondeur dans la hiérarchie (1=niveau supérieur)
- `chapterTitle` (TEXT) [skip_vec] - Titre du chapitre parent
- `canonicalReference` (TEXT) [skip_vec] - Référence académique (ex: 'CP 1.628', 'Ménon 80a')
- `unitType` (TEXT) [skip_vec] - Type d'unité logique (main_content, argument, exposition, etc.)
- `orderIndex` (INT) - Position séquentielle dans le document (base 0)
- `language` (TEXT) [skip_vec] - Langue du chunk
**Objets imbriqués** :
- `document` (OBJECT)
- `sourceId` (TEXT)
- `edition` (TEXT)
- `work` (OBJECT)
- `title` (TEXT)
- `author` (TEXT)
---
### 4. Summary (Résumé de section)
**Description** : Résumés LLM de chapitres/sections pour recherche de haut niveau
**Vectorisation** : `text2vec-transformers` (BAAI/bge-m3, 1024 dimensions)
**Champs vectorisés** :
-`text` (TEXT) - Résumé généré par LLM
-`concepts` (TEXT_ARRAY) - Concepts philosophiques clés
**Champs NON vectorisés** :
- `sectionPath` (TEXT) [skip_vec] - Chemin hiérarchique
- `title` (TEXT) [skip_vec] - Titre de la section
- `level` (INT) - Profondeur (1=chapitre, 2=section, 3=sous-section)
- `chunksCount` (INT) - Nombre de chunks dans cette section
**Objets imbriqués** :
- `document` (OBJECT)
- `sourceId` (TEXT)
---
## Stratégie de vectorisation
### Modèle utilisé
- **Nom** : BAAI/bge-m3
- **Dimensions** : 1024
- **Contexte** : 8192 tokens
- **Support multilingue** : Grec, Latin, Français, Anglais
### Migration (Décembre 2024)
- **Ancien modèle** : MiniLM-L6 (384 dimensions, 512 tokens)
- **Nouveau modèle** : BAAI/bge-m3 (1024 dimensions, 8192 tokens)
- **Gains** :
- 2.7x plus riche en représentation sémantique
- Meilleur support multilingue
- Meilleure performance sur textes philosophiques/académiques
### Champs vectorisés
Seuls ces champs sont vectorisés pour la recherche sémantique :
- `Chunk.text`
- `Chunk.keywords`
- `Summary.text`
- `Summary.concepts`
### Champs de filtrage uniquement
Tous les autres champs utilisent `skip_vectorization=True` pour optimiser les performances de filtrage sans gaspiller la capacité vectorielle.
---
## Objets imbriqués (Nested Objects)
Au lieu d'utiliser des cross-references Weaviate, le schéma utilise des **objets imbriqués** pour :
1. **Éviter les jointures** - Récupération en une seule requête
2. **Dénormaliser les données** - Performance de lecture optimale
3. **Simplifier les requêtes** - Logique de requête plus simple
### Exemple de structure Chunk
```json
{
"text": "La justice est une vertu...",
"keywords": ["justice", "vertu", "cité"],
"sectionPath": "Livre I > Chapitre 2",
"work": {
"title": "La République",
"author": "Platon"
},
"document": {
"sourceId": "platon_republique",
"edition": "trad. Cousin"
}
}
```
### Trade-off
-**Avantage** : Requêtes rapides, pas de jointures
- ⚠️ **Inconvénient** : Petite duplication de données (acceptable pour métadonnées)
---
## Contenu actuel (au 01/01/2026)
**Dernière vérification** : 1er janvier 2026 via `verify_vector_index.py`
### Statistiques par collection
| Collection | Objets | Vectorisé | Utilisation |
|------------|--------|-----------|-------------|
| **Chunk** | **5,404** | ✅ Oui | Recherche sémantique principale |
| **Summary** | **8,425** | ✅ Oui | Recherche hiérarchique (chapitres/sections) |
| **Document** | **16** | ❌ Non | Métadonnées d'éditions |
| **Work** | **0** | ✅ Oui* | Métadonnées d'œuvres (vide, prêt pour migration) |
**Total vecteurs** : 13,829 (5,404 chunks + 8,425 summaries)
**Ratio Summary/Chunk** : 1.56 (plus de summaries que de chunks, bon pour recherche hiérarchique)
\* *Work est configuré avec vectorisation (depuis migration 2026-01) mais n'a pas encore d'objets*
### Documents indexés
Les 16 documents incluent probablement :
- Collected Papers of Charles Sanders Peirce (édition Harvard)
- Platon - Ménon (trad. Cousin)
- Haugeland - Mind Design III
- Claudine Tiercelin - La pensée-signe
- Peirce - La logique de la science
- Peirce - On a New List of Categories
- Arendt - Between Past and Future
- AI: The Very Idea (Haugeland)
- ... et 8 autres documents
**Note** : Pour obtenir la liste exacte et les statistiques par document :
```bash
python verify_vector_index.py
```
---
## Configuration Docker
Le schéma est déployé via `docker-compose.yml` avec :
- **Weaviate** : localhost:8080 (HTTP), localhost:50051 (gRPC)
- **text2vec-transformers** : Module de vectorisation avec BAAI/bge-m3
- **GPU support** : Optionnel pour accélérer la vectorisation
### Commandes utiles
```bash
# Démarrer Weaviate
docker compose up -d
# Vérifier l'état
curl http://localhost:8080/v1/.well-known/ready
# Voir les logs
docker compose logs weaviate
# Recréer le schéma
python schema.py
```
---
## Optimisations 2026 (Production-Ready)
### 🚀 **1. Batch Size Dynamique**
**Implémentation** : `utils/weaviate_ingest.py` (lignes 198-330)
L'ingestion ajuste automatiquement la taille des lots selon la longueur moyenne des chunks :
| Taille moyenne chunk | Batch size | Rationale |
|---------------------|------------|-----------|
| < 3k chars | 100 chunks | Courts → vectorisation rapide |
| 3k - 10k chars | 50 chunks | Moyens → standard académique |
| 10k - 50k chars | 25 chunks | Longs → arguments complexes |
| > 50k chars | 10 chunks | Très longs → Peirce CP 8.388 (218k) |
**Bénéfice** : Évite les timeouts sur textes longs tout en maximisant le throughput sur textes courts.
```python
# Détection automatique
batch_size = calculate_batch_size(chunks) # 10, 25, 50 ou 100
```
### 🎯 **2. Index Vectoriel Optimisé (Dynamic + RQ)**
**Implémentation** : `schema.py` (lignes 242-255 pour Chunk, 355-367 pour Summary)
- **Dynamic Index** : Passe de FLAT à HNSW automatiquement
- Chunk : seuil à 50,000 vecteurs
- Summary : seuil à 10,000 vecteurs
- **Rotational Quantization (RQ)** : Réduit la RAM de ~75%
- **Distance Metric** : COSINE (compatible BGE-M3)
**Impact actuel** :
- Collections < seuil → Index FLAT (rapide, faible RAM)
- **Économie RAM projetée à 100k chunks** : 40 GB → 10 GB (-75%)
- **Coût infrastructure annuel** : Économie de ~840€
Voir `VECTOR_INDEX_OPTIMIZATION.md` pour détails.
### ✅ **3. Validation Stricte des Métadonnées**
**Implémentation** : `utils/weaviate_ingest.py` (lignes 272-421)
Validation en 2 étapes avant ingestion :
1. **Métadonnées document** : `validate_document_metadata()`
- Vérifie `doc_name`, `title`, `author`, `language` non-vides
- Détecte `None`, `""`, whitespace-only
2. **Nested objects chunks** : `validate_chunk_nested_objects()`
- Vérifie `work.title`, `work.author`, `document.sourceId` non-vides
- Validation chunk par chunk avec index pour debugging
**Impact** :
- Corruption silencieuse : **5-10% → 0%**
- Temps debugging : **~2h → ~5min** par erreur
- **28 tests unitaires** : `tests/test_validation_stricte.py`
Voir `VALIDATION_STRICTE.md` pour détails.
---
## Notes d'implémentation
1. **Timeout augmenté** : Les chunks très longs (ex: Peirce CP 3.403, CP 8.388: 218k chars) nécessitent 600s (10 min) pour la vectorisation
2. **Batch insertion dynamique** : L'ingestion utilise `insert_many()` avec batch size adaptatif (10-100 selon longueur)
3. **Type safety** : Tous les types sont définis dans `utils/types.py` avec TypedDict
4. **mypy strict** : Le code passe la vérification stricte mypy
5. **Validation stricte** : Métadonnées et nested objects validés avant insertion (0% corruption)
---
## Voir aussi
### Fichiers principaux
- `schema.py` - Définitions et création du schéma
- `utils/weaviate_ingest.py` - Fonctions d'ingestion avec validation stricte
- `utils/types.py` - TypedDict correspondant au schéma
- `docker-compose.yml` - Configuration des conteneurs
### Scripts utiles
- `verify_vector_index.py` - Vérifier la configuration des index vectoriels
- `migrate_add_work_collection.py` - Ajouter Work vectorisé (migration sûre)
- `test_weaviate_connection.py` - Tester la connexion Weaviate
### Documentation des optimisations
- `VECTOR_INDEX_OPTIMIZATION.md` - Index Dynamic + RQ (économie RAM 75%)
- `VALIDATION_STRICTE.md` - Validation métadonnées (0% corruption)
### Tests
- `tests/test_validation_stricte.py` - 28 tests unitaires pour validation