Moteur intelligent de gestion des compétences — guide technique
Ce guide trace la recherche multi-référentiels et les suggestions personnalisées, du profil à la résolution du catalogue et à l’attribution. Il s’adresse aux équipes d’implémentation et de support. Les utilisateurs métier peuvent consulter le guide fonctionnel, les administrateurs le guide de configuration.
Sauf mention contraire, les affirmations sont vérifiées dans le code local. La concordance avec la révision déployée et les services effectifs de PS Testing restent non vérifiées.
Architecture et responsabilités
| Responsable | Rôle |
|---|---|
SkillLibraryController historique et Twig skillsLibrary/ | Recherche, regroupement par source, sélection/évaluation et attribution en masse. |
SkillSearcher historique | Sources éligibles, contrat de recherche, ordre et résolution locale. |
ObservatorySkillPersister historique | Copies d’observatoires appartenant à l’entreprise et traductions. |
SkillSuggestionService / SkillSuggestionRepository | Suggestions anciennes persistées, éligibilité, décisions et synchronisation. |
SkillSuggestionV2Service / ExpToSkillAdapter | Inférence récente du profil, priorités et exclusions. |
SkillStorageService / IgnoredSkillManager | File en session et compétences ignorées du chemin récent. |
AIHub skills_library | Contrats, orchestration et récupération par mot-clé. |
AIHub talent_intelligence | Inférence expériences/diplômes/intérêts et correspondance avec les identifiants éligibles. |
Requêtes et flux de la bibliothèque
- La route du profil fournit le collaborateur cible.
SkillLibraryController::indexActionchoisit les modèles collaborateur/entreprise et calcule les permissions. - La recherche envoie
textetcustomeràmain_config_skill_suggestion, déclarémain/config/skill/suggestion, en POST XHR. La réponse est un fragment HTML, pas le contrat JSON AIHub. SkillSearcher::buildApiInputrésoutskillLibraryObservatoriesen identifiants et les combine aux référentiels disponibles de l’entreprise. Les référentiels explicites de certains appels remplacent la liste entreprise par défaut, tout en conservant les observatoires configurés.SkillLibraryUrlManagerchoisit l’URL par défaut ou récente viaskill_library_api_url_skills_qdrant_single.- Les identifiants renvoyés sont résolus en
Skilllocaux par score. Les compétences d’observatoires sont copiées au besoin ; celles appartenant encore à une autre entreprise sont exclues. - Le contrôleur regroupe par groupe/type et sépare les référentiels Neobrain en externes (
out) des autres (in). Les en-têtes décrivent ces familles, pas chaque catalogue d’origine. - La sélection reste dans le navigateur jusqu’à sauvegarde.
main_config_add_skills, déclaré/addSkills, reçoit en POST XHRcustomeretdataavecskillId,level,motivationet champs optionnels pris en charge. Les associations existantes sont ignorées ; les nouvelles sont attribuées et des événements émis.
Observé : gestion de projet présentait des candidats internes et externes ; MS Project révélait les évaluations. L’attribution finale n’avait pas été testée lors de cette inspection initiale.
Contrat du service de recherche
Structure envoyée par l’appelant historique ; identifiants fictifs :
{
"search_query": "project management",
"repositories_id": [101, 202],
"language": "en",
"results_number": 40,
"collection_name": "<configured collection>",
"repositories_id_prio": [101],
"threshold_deduplicate": 0.95
}
Les priorités sont conditionnelles. Le mode récent priorise les référentiels clients disponibles (type === null), principal en premier puis identifiant, et envoie threshold_deduplicate: 0.95. La limite de l’appelant vaut 40. Ces paramètres de recherche ne sont pas des seuils de maîtrise.
Le routeur local AIHub expose POST /api/v1/skills-library/skills_single avec dépendance de clé API et la compatibilité POST /skills-library/skills_single sans cette dépendance au niveau route. Les protections réseau de compatibilité ne sont pas établies. SkillInputSolo définit 10 résultats et 0.98 par défaut ; ces défauts n’écrasent pas les valeurs explicites de l’appelant. Le résolveur consomme notamment skill_id et score. La correspondance exacte URL déployée/routeur n’est pas vérifiée.
query_service.find_single utilise PostgreSQL si les ressources d’exécution correspondantes sont présentes, sinon MongoDB. Le chemin MongoDB examiné normalise et traduit les recherches via traductions mises en cache et configuration IA. Ne le décrivez pas comme une simple recherche de sous-chaîne et ne déduisez pas le stockage vectoriel déployé du nom d’un commutateur.
Modes de suggestions personnalisées
suggestion_skills_v2_ds_api sélectionne le mode dans le même DefaultController historique, indépendamment du commutateur d’URL de bibliothèque.
Ancien mode persisté
SkillSuggestionRepository::getSkillSuggestions sélectionne pour l’utilisateur courant les décisions non résolues, userHasSkill = false, sans Userskill correspondant, avec référentiel disponible (public = 1). Il limite les compétences à l’entreprise, avec une branche d’observatoires si configurée. checkSuggestions exclut aussi les sources externes déjà représentées.
SkillSuggestionService::getSuggestion choisit aléatoirement un candidat éligible et date sa proposition. Sans candidat, il exige une expérience, tente une synchronisation puis une nouvelle sélection, une seule fois chacune. La synchronisation est éligible sans date antérieure ou après plus d’un mois. Les intitulés d’expérience sont envoyés à CustomerProfileApiSkillsSuggestion, jusqu’à 16 compétences par intitulé par défaut. Aucun ordonnanceur mensuel n’est établi.
L’ancien contrat utilise jobs, language, max_skills, job_referentiel_ids et consomme notamment sm_skill_ids. Il diffère du contrat récent en camelCase : ne les intervertissez pas.
| Décision | Effet persisté ancien |
|---|---|
Acceptation, état 1 | approved vrai/refused faux ; attribution avec maîtrise et motivation si pas déjà détenue. |
Refus, état 0 | approved faux/refused vrai. |
Réinitialisation, état 3 | Efface les décisions ; si précédemment acceptée, peut retirer l’association et effacer userHasSkill. |
Les décisions émettent UserSkillSuggestedInfoEvent. Le voter exige l’accès au module et, pour modifier, la propriété de la suggestion. Une condition de compatibilité liée à l’ancienne page d’accueil peut accorder le voter malgré le panneau désactivé ; le modèle vérifie séparément module_suggestion_skill pour l’affichage.
Inférence récente du profil
SkillSuggestionV2Service collecte expériences, diplômes, intérêts, référentiels disponibles et skillSuggestionObservatories. Les référentiels entreprise servent aussi de priorités. UserSkillManager réunit les compétences existantes et ignorées dans les exclusions.
ExpToSkillAdapter appelle talent-intelligence/experience : jusqu’à 15 compétences, seuil 0.9, language: "en", collection selon l’environnement et champs principaux suivants :
{
"jobs": [{"title": "Project coordinator", "description": "Coordinate delivery", "startDate": "2024-01-01", "endDate": "2026-10-23"}],
"diplomas": [],
"interests": [],
"maxSkills": 15,
"referentielIds": [101, 202],
"referentielIdsPrio": [101],
"userSkills": [303],
"language": "en",
"threshold": 0.9,
"debug": false,
"collection": "<configured collection>"
}
Exemple fictif. L’adaptateur renvoie une liste vide sans requête si les trois familles d’informations sont vides ou sans référentiel. Les erreurs API/décodage émettent PostCatchEvent et renvoient une liste vide. SkillService résout les identifiants reçus.
AIHub expose POST /api/v1/talent-intelligence/experience avec clé API et POST /talent-intelligence/experience de compatibilité. ExperienceInput utilise par défaut 10 compétences et l’anglais, et rejette un maxSkills explicite non positif. L’appelant historique envoie 15. Le service choisit PostgreSQL ou MongoDB selon les ressources, puis associe le contenu inféré aux compétences des référentiels demandés. Il est distinct de l’enrichissement du catalogue d’emplois Lexi.
Les candidats sont conservés dans suggestedSkills en session. Le premier s’affiche ; l’acceptation l’attribue et le retire de la file. Le refus l’enregistre via IgnoredSkillManager et le retire. Les changements persistés d’expérience/diplôme/intérêt vident la file via SkillSuggestionRefreshEventListener après flush.
Limite d’annulation : la branche récente de réinitialisation renvoie un succès sans annuler la compétence attribuée ou ignorée. Le retour à la suggestion précédente ne doit pas être décrit comme l’équivalent de l’ancienne réinitialisation persistée.
Contrats navigateur des suggestions continues
Déclarations dans Customer/ProfileBundle/Resources/config/routing.yml ; les préfixes de déploiement s’appliquent. Toutes exigent XHR.
| Méthode et chemin | Entrée / résultat |
|---|---|
GET skills/suggestions | Vérifie le quota puis le mode. Succès : response, suggestion ; l’ancien mode peut renvoyer experience_not_found ou suggestion_not_found. |
POST skills/suggestion/accept | skill_suggestion_id, level, motivation ; résolution d’identifiant selon le mode. |
POST skills/suggestion/refuse | skill_suggestion_id ; refus selon le mode. |
POST skills/suggestion/reset | skill_suggestion_id ; effet selon le mode décrit plus haut. |
Identifiant de décision absent : 403. La récupération convertit forbidden en 403 et les autres échecs de service en 404. Le quota logique renvoie 422 avec response: quota_exceeded ; une erreur inattendue du quota renvoie 500. Un succès du mode récent peut contenir un tableau vide. Les états vides des deux modes n’ont donc pas la même sémantique HTTP.
Données, permissions et confidentialité
Setting porte les deux listes ; Referentiel la disponibilité/le type ; Skill l’entrée catalogue ; Userskill l’association et l’évaluation. Les anciens SkillSuggestion conservent utilisateur, compétence et décisions ; SkillSuggestionLog suit la synchronisation.
ObservatorySkillPersister trouve ou crée un référentiel Neobrain d’entreprise non principal et non public. Il réutilise les copies externes, conserve externalSource: observatory et l’identifiant original, copie traductions et libellés d’évaluation et rend la copie non modifiable. La recherche peut elle-même persister des données catalogue, sans sauvegarde de sélection. Cela reste distinct de l’attribution au profil.
L’ajout en masse exige l’authentification, rejette une autre entreprise et autorise le collaborateur lui-même, son manager direct ou la branche master-school examinée. La page contrôle aussi add_skills_collab pour certains accès tiers et calcule allow_modifying_manager_skill_rating. Les gestionnaires de recherche résolvent le customer cible ; ces vérifications ne constituent pas un audit exhaustif de tous les points d’entrée.
SkillQuotaService compare max_skill_outside_job aux compétences hors emploi. Il s’applique à partir de 1 et si un emploi est attribué. L’ajout bibliothèque valide le nombre d’éléments soumis ; la récupération d’une suggestion valide un ajout potentiel. Emplacements et statuts de contrôle diffèrent.
Expériences, diplômes, intérêts et identifiants sont des données personnelles envoyées au service d’inférence configuré. Les journaux peuvent contenir requêtes et réponses. Limitez leur accès ; n’incluez pas de données réelles, hashes de compte, secrets ou adresses de service dans les tickets/exemples.
Erreurs, dépendances et observabilité
| Échec / symptôme | Trace |
|---|---|
| URL absente / configuration invalide | SkillLibraryUrlManager valide les URL ; SkillSearcher renvoie aussi zéro résultat sans URL résolue. |
| Erreur de transport de recherche | Journalisation du contexte puis exception d’exécution par SkillSearcher. |
| JSON ancien fournisseur invalide | CustomerProfileApiSkillsSuggestion émet PostCatchEvent, renvoie une liste vide. |
| Inférence récente en échec | ExpToSkillAdapter intercepte, émet PostCatchEvent, renvoie une liste vide. |
| Suggestions anciennes en session | File, événements de profil et mode ; modification des sources seule non établie comme invalidation. |
| Ancienne synchronisation absente | Date et enregistrements éligibles non résolus. |
| Doublons / pertinence insuffisante | Sources, priorités, exclusions, scores et correspondances de copies externes. |
| Ajout refusé | Entreprise/relation, quota, évaluations et statut de réponse. |
Dépendances : session Symfony authentifiée, catalogues/profils Doctrine, clients configurés, traductions et ressources AIHub si sélectionnées. Les schémas ne prouvent ni fournisseur de production ni topologie. Journaux d’appels, logs et événements d’exception existent ; aucune métrique dédiée, garantie de reprise ou surveillance en direct établie.
Interfaces et extensions
Observé : la navigation PS Testing hébergeait les écrans historiques. Vérifié dans le code : les recherches nextgen ciblées dans smartmobility-nextgen-front/src et smartmobility-nextgen-back/src n’ont pas établi de remplacement ; DTO et rendus de suggestions de plan de développement sont un autre contexte. Services récents et ancienne UI peuvent coexister.
Pour une source : disponibilité → paramètres d’observatoire → identifiants de requête → indexation → résolution locale → regroupement. Pour une inférence, distinguez classement, exclusions, persistance des propositions et attribution. Validez les deux modes et documentez réinitialisation, quota et actualisation. La visibilité d’un contrôle ne prouve pas l’autorisation serveur.
Sources et limites
- Observé : Chrome, PS Testing 2026, Jim Carter, 23 octobre 2026 : profil/bibliothèque, résultats internes/externes, sélection, évaluations et retrait temporaire. Voir les captures fonctionnelles. Carte continue absente.
- Vérifié — historique :
src/Main/ConfigBundle/{Controller/SkillLibraryController.php,Resources/config/routing/skillslibrary.yml,Resources/views/skillsLibrary/};src/Customer/ProfileBundle/{Controller/DefaultController.php,Resources/config/routing.yml,Services/SkillSearcher.php,Services/ObservatorySkillPersister.php,Services/ApiSkills/CustomerProfileApiSkillsSuggestion.php};src/Service/{SkillLibraryUrlManager.php,Skills/,PartnerAPI/TalentIntelligence/ExpToSkill/ExpToSkillAdapter.php};src/Repository/SkillSuggestionRepository.php;src/Main/ConfigBundle/Security/Skills/SuggestionSkillVoter.php;src/EventListener/SkillSuggestionRefreshEventListener.php. - Vérifié — AIHub :
src/skills_library/{api/search_router.py,schemas/search.py,services/query_service.py};src/talent_intelligence/{api/experience_router.py,schemas/experience.py,services/experience_to_skills.py}etsrc/common/utils/constants.py. - Déduit : ordre des diagnostics et extensions issus des appels tracés.
- Non vérifié lors de l’examen initial : charges réseau, modes actifs exacts, révisions, sauvegardes administrateur, attribution finale, décisions de carte continue, sécurité exhaustive et topologie. Aucun code applicatif modifié. Le contrôle d’attribution ultérieur est décrit ci-dessous.
Sources du guide fonctionnel
Ces références soutiennent le guide fonctionnel. Le code local ne prouve ni la révision déployée ni les options actives ; observations et documents restent distincts.
- Observé : Chrome, PS Testing 2026, Jim Carter, 23 octobre 2026 : sélecteur d’espaces, profil, bibliothèque vide, recherche gestion de projet, en-têtes internes/externes, sélection, évaluation et retrait temporaire. Captures de fenêtre complète.
- Vérifié dans le code :
smartmobility-legacy/src/Main/ConfigBundle/Controller/SkillLibraryController.php, ses modèlesResources/views/skillsLibrary/,Customer/ProfileBundle/Services/{SkillSearcher,ObservatorySkillPersister}.php,Service/Skills/{SkillSuggestionService,SkillSuggestionV2Service,SkillQuotaService}.php. - Déduit : dépannage fondé sur sélection des sources et validation.
- Non vérifié : carte continue, commutateurs déployés, noms des observatoires, concordance des versions et tous les rôles. Aucune compétence sauvegardée le 23 octobre ; le contrôle du 26 suit. La recherche peut créer des copies catalogue.
Vérification du parcours — 26 octobre 2026
Observé : PS Testing 2026, Jim Carter. MS Project ajouté via la bibliothèque historique avec maîtrise et motivation à 2/4, sauvegardé puis contrôlé après rechargement. Sur cette nouvelle ligne de test uniquement, les deux valeurs ont été portées à 3/4 et retrouvées après recharge. L’ajout a été retiré via sa confirmation nominative ; la liste complète rendue a été vérifiée après recharge. Ni actualisation des suggestions personnalisées ni sauvegarde de configuration exercée.
Dernière mise à jour : 3 novembre 2026