Architecture Global Search & Intelligence Artificielle - Phase 1
đŻ DĂ©cision d'Architectureâ
â Recommandation : Backend NestJS (implĂ©mentĂ©)â
Pourquoi NestJS pour la Phase 1 ?
-
Infrastructure existante :
LlmServiceetOpenaiServicedéjà en place- Gestion des clés API OpenAI par utilisateur
- AccĂšs direct Ă la DB via Kysely
- TypeScript partagé avec le frontend
-
Avantages :
- Pas de communication inter-services (plus simple)
- Déploiement et maintenance plus faciles
- Performance suffisante pour la Phase 1
- Cohérence avec l'architecture existante
-
Limites acceptables pour Phase 1 :
- Pas besoin de LangChain intensif
- Pas de traitement batch lourd
- Pas de modĂšles ML complexes
đ Ăvolution future : Service Python sĂ©parĂ© (Phase 2/3)â
Quand envisager un service Python séparé ?
- Si besoin de LangChain de maniĂšre intensive
- Traitement batch lourd (indexation, analyse massive)
- ModÚles ML complexes (embedding, classification avancée)
- Besoin de bibliothÚques Python spécifiques (pandas, scikit-learn, etc.)
Architecture proposée si migration nécessaire :
Frontend â NestJS Backend â Python AI Service (gRPC/REST)
â
OpenAI/LangChain
đ Structure Actuelleâ
backend/src/search/
âââ search.service.ts # Recherche classique (DB + Notion)
âââ search.controller.ts # Endpoints REST
âââ search.module.ts # Module NestJS
âââ ai-search.service.ts # âš NOUVEAU : Service IA pour Phase 1
đ Endpoints APIâ
1. POST /api/search/ai/processâ
Traite une requĂȘte en langage naturel et dĂ©termine l'intention.
Request:
{
"query": "sessions de mariage en juillet 2024 avec montant > 2000âŹ"
}
Response:
{
"intent": "create_view",
"confidence": 0.95,
"parsedQuery": {
"entity": "sessions",
"filters": [
{
"field": "type",
"operator": "equals",
"value": "mariage"
},
{
"field": "date",
"operator": "between",
"value": ["2024-07-01", "2024-07-31"]
},
{
"field": "amount",
"operator": "greater_than",
"value": 2000
}
]
}
}
2. POST /api/search/ai/filtersâ
GĂ©nĂšre des filtres structurĂ©s Ă partir d'une requĂȘte en langage naturel.
Request:
{
"query": "contacts actifs avec au moins 2 sessions cette année",
"entity": "contacts"
}
Response:
{
"filters": [
{
"field": "session_count",
"operator": "greater_than",
"value": 2
},
{
"field": "last_session_date",
"operator": "greater_than",
"value": "2024-01-01"
}
],
"entity": "contacts"
}
3. POST /api/search/ai/answerâ
Répond à une question sur les données.
Request:
{
"question": "Quel est le revenu total du mois dernier ?",
"context": {
"invoices": [...]
}
}
Response:
{
"answer": "Le revenu total du mois dernier est de 15 450âŹ.",
"confidence": 0.92,
"sources": [
{
"type": "invoices",
"id": "invoice-123",
"snippet": "Facture #2024-001 - 2500âŹ"
}
]
}
đïž Architecture du Service IAâ
AiSearchServiceâ
Le service AiSearchService fournit trois méthodes principales :
-
processQuery(): Classification d'intention- Analyse la requĂȘte utilisateur
- Détermine l'intention (search, create_view, execute_action, question)
- Parse la requĂȘte pour extraire les paramĂštres
-
generateFilters(): Génération de filtres- Convertit le langage naturel en filtres DB structurés
- Supporte les opérateurs : equals, contains, greater_than, less_than, between, in
- Valide les champs selon l'entité cible
-
answerQuestion(): Réponse aux questions- Analyse le contexte fourni
- GénÚre une réponse naturelle
- Cite les sources utilisées
Prompts Systemâ
Les prompts sont construits dynamiquement selon :
- L'entité cible (sessions, contacts, quotes, invoices)
- Les champs disponibles pour chaque entité
- Le type de requĂȘte (classification, filtres, question)
Configurationâ
- ModÚle par défaut :
gpt-4o-mini(configurable par utilisateur) - Temperature :
- 0.2 pour la classification d'intention
- 0.1 pour la génération de filtres (précision maximale)
- 0.3 pour les réponses aux questions
- Format de réponse : JSON strict (
response_format: { type: "json_object" })
đ Flux d'Utilisationâ
Exemple 1 : CrĂ©ation d'une vue personnalisĂ©eâ
1. User: "Crée une vue des sessions de mariage du mois de juillet"
â
2. Frontend â POST /api/search/ai/process
â
3. AiSearchService.processQuery()
â Intent: "create_view"
â Entity: "sessions"
â Filters: [type="mariage", date="2024-07"]
â
4. Frontend â POST /api/search/ai/filters (si besoin de plus de prĂ©cision)
â
5. Frontend applique les filtres et affiche la vue
Exemple 2 : Question sur les donnĂ©esâ
1. User: "Quel est le revenu total du mois dernier ?"
â
2. Frontend â POST /api/search/ai/process
â Intent: "question"
â
3. Frontend récupÚre les données nécessaires (invoices du mois dernier)
â
4. Frontend â POST /api/search/ai/answer
â Answer: "Le revenu total est de 15 450âŹ"
â
5. Frontend affiche la réponse
Exemple 3 : Action complexeâ
1. User: "Crée une facture pour toutes les sessions payées du mois dernier"
â
2. Frontend â POST /api/search/ai/process
â Intent: "execute_action"
â Action: "create_invoice"
â Parameters: { sessions: "paid", period: "last_month" }
â
3. Frontend exécute l'action via l'API appropriée
đ SĂ©curitĂ©â
- Authentification : JWT + ActiveUserGuard requis
- Clés API : Chaque utilisateur utilise sa propre clé OpenAI (stockée chiffrée)
- Validation : Tous les filtres générés sont validés avant application
- Rate Limiting : à implémenter si nécessaire (via
RateLimitingModule)
đ Performanceâ
- Latence attendue : 1-3 secondes par requĂȘte IA (selon le modĂšle)
- Cache : Ă implĂ©menter pour les requĂȘtes frĂ©quentes
- Optimisation : Utilisation de
gpt-4o-minipar défaut (plus rapide et moins cher)