UNPKG

smart-thinking-mcp

Version:

Un serveur MCP avancé pour le raisonnement multi-dimensionnel, adaptatif et collaboratif

320 lines 13.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.QualityEvaluator = void 0; const metrics_calculator_1 = require("./metrics-calculator"); const config_1 = require("./config"); const service_container_1 = require("./services/service-container"); /** * Classe qui évalue la qualité des pensées * Utilise le service de vérification centralisé pour toutes les fonctionnalités de vérification * Version optimisée avec mise en cache et structures de données efficaces */ class QualityEvaluator { verificationService; // L'opérateur ! indique que la propriété sera initialisée après la construction metricsCalculator; // Caches pour les résultats d'évaluation et les détections de biais evaluationCache = new Map(); biasCache = new Map(); suggestionCache = new Map(); // Expressions régulières pré-compilées pour la détection de biais biasPatterns = [ { regex: /\b(comme je l'ai dit|comme je le pensais|tel que mentionné)\b/i, type: "confirmation_bias", score: 0.7, description: "Tend à confirmer des croyances existantes" }, { regex: /\b(récemment|dernièrement|ces derniers temps)\b/i, type: "recency_bias", score: 0.6, description: "Accorde trop d'importance aux événements récents" }, { regex: /\b(tous|toujours|jamais|aucun|systématiquement|sans exception)\b/i, type: "absolutism_bias", score: 0.65, description: "Utilise des généralisations absolues" }, { regex: /\b(évident|évidemment|clairement|bien sûr|naturellement|sans doute)\b/i, type: "certainty_bias", score: 0.6, description: "Présente comme certain ce qui est discutable" } ]; // Mappage pour les suggestions d'amélioration suggestionMappings = [ { condition: (metrics) => metrics.confidence < config_1.VerificationConfig.CONFIDENCE.LOW_CONFIDENCE, suggestions: [ 'Renforcez l\'argumentation avec des preuves ou des références précises.', 'Évitez les modalisateurs d\'incertitude excessive ("peut-être", "probablement").' ] }, { condition: (metrics) => metrics.relevance < config_1.VerificationConfig.CONFIDENCE.LOW_CONFIDENCE, suggestions: [ 'Clarifiez le lien avec le contexte ou le sujet principal.' ] }, { condition: (metrics) => metrics.quality < config_1.VerificationConfig.CONFIDENCE.LOW_CONFIDENCE, suggestions: [ 'Améliorez la structure et la clarté de cette pensée.' ] } ]; // Mappage pour les suggestions spécifiques au type de pensée typeSuggestionMap = { 'hypothesis': [ { condition: (thought) => !thought.content.toLowerCase().includes('si'), suggestion: 'Formulez l\'hypothèse sous forme conditionnelle (si... alors...).' } ], 'conclusion': [ { condition: (thought, connectedThoughts) => connectedThoughts.length < 2, suggestion: 'Une conclusion devrait synthétiser plusieurs pensées précédentes.' } ], 'revision': [ { condition: (thought, connectedThoughts) => !connectedThoughts.some(t => thought.connections.some(conn => conn.targetId === t.id && ['refines', 'contradicts', 'supports'].includes(conn.type))), suggestion: 'Une révision devrait clairement indiquer ce qu\'elle raffine ou corrige.' } ] }; constructor() { this.metricsCalculator = new metrics_calculator_1.MetricsCalculator(); // L'initialisation du verificationService se fera via setVerificationService } /** * Définit le service de vérification à utiliser * * @param verificationService Le service de vérification */ setVerificationService(verificationService) { this.verificationService = verificationService; } /** * Obtient le service de vérification depuis le conteneur si nécessaire * @returns Le service de vérification */ getVerificationService() { if (!this.verificationService) { this.verificationService = service_container_1.ServiceContainer.getInstance().getVerificationService(); } return this.verificationService; } /** * Crée une clé unique pour le cache * * @param thoughtId L'identifiant de la pensée * @param contextId Un identifiant supplémentaire pour le contexte (comme l'ID de graphe) * @returns Une clé unique pour le cache */ createCacheKey(thoughtId, contextId) { return contextId ? `${thoughtId}:${contextId}` : thoughtId; } /** * Évalue la qualité d'une pensée avec mise en cache pour améliorer les performances * * @param thoughtId L'identifiant de la pensée à évaluer * @param thoughtGraph Le graphe de pensées contenant la pensée * @returns Les métriques de qualité évaluées */ evaluate(thoughtId, thoughtGraph) { // Créer une clé de cache unique basée sur l'ID de la pensée et une représentation unique du graphe // Utilisons l'ID de la pensée comme identifiant primaire puisque c'est unique par graphe const cacheKey = this.createCacheKey(thoughtId); // Vérifier si le résultat est déjà en cache const cachedMetrics = this.evaluationCache.get(cacheKey); if (cachedMetrics) { return { ...cachedMetrics }; // Retourner une copie pour éviter la mutation } const thought = thoughtGraph.getThought(thoughtId); if (!thought) { return { confidence: 0.5, relevance: 0.5, quality: 0.5 }; } // Récupérer les pensées connectées pour le contexte const connectedThoughts = thoughtGraph.getConnectedThoughts(thoughtId); // Utiliser le calculateur de métriques pour obtenir des valeurs plus précises const confidence = this.metricsCalculator.calculateConfidence(thought); const relevance = this.metricsCalculator.calculateRelevance(thought, connectedThoughts); const quality = this.metricsCalculator.calculateQuality(thought, connectedThoughts); const metrics = { confidence, relevance, quality }; // Mettre en cache le résultat this.evaluationCache.set(cacheKey, { ...metrics }); return metrics; } /** * Méthode de délégation pour performPreliminaryVerification */ async performPreliminaryVerification(thought, explicitlyRequested = false) { return this.getVerificationService().performPreliminaryVerification(thought, explicitlyRequested); } /** * Méthode de délégation pour checkPreviousVerification */ async checkPreviousVerification(thoughtContent, sessionId = config_1.SystemConfig.DEFAULT_SESSION_ID) { return this.getVerificationService().checkPreviousVerification(thoughtContent, sessionId); } /** * Méthode de délégation pour deepVerify */ async deepVerify(thought, toolIntegrator, containsCalculations = false, forceVerification = false, sessionId = config_1.SystemConfig.DEFAULT_SESSION_ID) { return this.getVerificationService().deepVerify(thought, containsCalculations, forceVerification, sessionId); } /** * Méthode de délégation pour detectAndVerifyCalculations */ async detectAndVerifyCalculations(content) { return this.getVerificationService().detectAndVerifyCalculations(content); } /** * Méthode de délégation pour annotateThoughtWithVerifications */ annotateThoughtWithVerifications(thought, verifications) { return this.getVerificationService().annotateThoughtWithVerifications(thought, verifications); } /** * Détecte les biais potentiels dans une pensée avec mise en cache des résultats * et utilisation d'expressions régulières optimisées * * @param thought La pensée à analyser * @returns Un tableau de biais détectés, vide si aucun */ detectBiases(thought) { // Vérifier d'abord le cache if (this.biasCache.has(thought.id)) { // Retourner une copie pour éviter la mutation des données en cache return [...this.biasCache.get(thought.id)]; } // Si pas en cache, effectuer l'analyse const biases = []; const content = thought.content.toLowerCase(); // Utiliser les expressions régulières pré-compilées for (const pattern of this.biasPatterns) { if (pattern.regex.test(content)) { biases.push({ type: pattern.type, score: pattern.score, description: pattern.description }); } } // Ajouter les biais spécifiques basés sur les métriques si disponibles if (thought.metrics) { // Biais d'excès de confiance if (thought.metrics.confidence > 0.85 && (/\bcertain(ement)?\b|\bsans doute\b|\babsolument\b/i.test(content))) { biases.push({ type: "overconfidence_bias", score: 0.8, description: "Exprime une confiance excessive non justifiée" }); } } // Mettre le résultat en cache this.biasCache.set(thought.id, [...biases]); return biases; } /** * Suggère des améliorations pour une pensée avec mise en cache des résultats * et structure optimisée pour réduire les calculs redondants * * @param thought La pensée à améliorer * @param thoughtGraph Le graphe de pensées * @returns Un tableau de suggestions d'amélioration */ suggestImprovements(thought, thoughtGraph) { // Créer une clé de cache basée sur l'ID de la pensée et une représentation unique du graphe // Utilisons l'ID de la pensée comme identifiant primaire puisque c'est unique par graphe const cacheKey = this.createCacheKey(thought.id); // Vérifier si les suggestions sont déjà en cache if (this.suggestionCache.has(cacheKey)) { return [...this.suggestionCache.get(cacheKey)]; } // Obtenir les métriques et les pensées connectées const metrics = this.evaluate(thought.id, thoughtGraph); const connectedThoughts = thoughtGraph.getConnectedThoughts(thought.id); const suggestions = []; // Appliquer les mappages de suggestions basées sur les métriques for (const mapping of this.suggestionMappings) { if (mapping.condition(metrics)) { suggestions.push(...mapping.suggestions); } } // Analyse du contenu pour des suggestions spécifiques const content = thought.content.toLowerCase(); const wordCount = content.split(/\s+/).length; if (wordCount < 10) { suggestions.push('Développez davantage cette pensée, elle est trop courte pour être complète.'); } else if (wordCount > config_1.SystemConfig.MAX_THOUGHT_LENGTH / 50) { suggestions.push('Considérez diviser cette pensée en plusieurs parties plus ciblées.'); } // Vérifier la présence de biais const biases = this.detectBiases(thought); if (biases.length > 0) { suggestions.push(`Attention aux biais potentiels: ${biases.map(bias => bias.type).join(', ')}.`); } // Appliquer les suggestions spécifiques au type de pensée if (thought.type in this.typeSuggestionMap) { for (const mapping of this.typeSuggestionMap[thought.type]) { if (mapping.condition(thought, connectedThoughts)) { suggestions.push(mapping.suggestion); } } } // Vérifier les contradictions de manière optimisée const hasContradictions = connectedThoughts.some(t => thought.connections.some(conn => conn.targetId === t.id && conn.type === 'contradicts')); if (hasContradictions) { suggestions.push('Résolvez ou clarifiez les contradictions avec d\'autres pensées.'); } // Mettre en cache les suggestions this.suggestionCache.set(cacheKey, [...suggestions]); return suggestions; } /** * Efface les caches pour forcer une réévaluation complète * Utile lorsque des pensées sont modifiées */ clearCaches() { this.evaluationCache.clear(); this.biasCache.clear(); this.suggestionCache.clear(); } /** * Supprime une entrée spécifique des caches * * @param thoughtId L'identifiant de la pensée à supprimer des caches */ invalidateCacheForThought(thoughtId) { // Supprimer toutes les entrées liées à cette pensée for (const key of this.evaluationCache.keys()) { if (key.startsWith(thoughtId)) { this.evaluationCache.delete(key); } } this.biasCache.delete(thoughtId); for (const key of this.suggestionCache.keys()) { if (key.startsWith(thoughtId)) { this.suggestionCache.delete(key); } } } } exports.QualityEvaluator = QualityEvaluator; //# sourceMappingURL=quality-evaluator.js.map