Recherche/Construire un système qui lit les documents envoyés et permet aux agents d’IA d’y chercher

Construire un système qui lit les documents envoyés et permet aux agents d’IA d’y chercher

Pour créer un service qui reçoit des PDF et autres fichiers pour la recherche par IA. Envoie chaque fichier vers un analyseur adapté, garde titres et tableaux, enregistre les fragments dans un format fixe et cherche dans un budget donné, avec des preuves citées.

Pour utiliser ces règles d'IA
## Nommer les branches clairement et séparer le code de l’API, des workers et le code partagé Rendez les responsabilités visibles avant de modifier le code afin que chaque comportement reste dans la couche capable de le tester et de le maintenir. ### Utiliser des branches traçables - Nommez les branches selon `type/user/description pattern`. - Conservez `type` en minuscules et choisissez une catégorie de changement reconnue, telle que `feat`, `fix`, `refactor`, `chore`, `docs`, `test`, `perf`, `ci`, `build` ou `revert`. - Utilisez dans `user` la personne responsable du travail ; ne la remplacez jamais par le nom générique d’un agent ou d’un outil. - Gardez `description` courte, en minuscules et en notation kebab-case. ### Séparer les responsabilités d’exécution - Maintenez dans des paquets distincts le traitement synchrone de l’API, le travail documentaire asynchrone, les modèles et services partagés ainsi que les aspects liés au déploiement. - Placez l’orchestration des points d’accès, les règles métier, la persistance, l’analyse syntaxique, la récupération et les utilitaires génériques dans des modules aux responsabilités explicites ; traitez les SDK distribués indépendamment comme des produits distincts. - Lorsqu’un comportement traverse plusieurs paquets, définissez d’abord le contrat partagé et testez chaque implémentation responsable. ## Envoyer chaque fichier reçu vers un analyseur adapté à son format Utilisez un pipeline par étapes afin que chaque document suive un parcours visible du téléversement jusqu’aux éléments probants de récupération pouvant être cités. 1. Acceptez le téléversement, créez une tâche, conservez l’objet source et placez le traitement asynchrone dans une file d’attente. 2. Établissez une seule fois le profil du document, puis dirigez-le vers un analyseur selon le type de fichier et les preuves structurelles. 3. Convertissez le résultat de l’analyseur en un contrat tabulaire typé unique. 4. Convertissez les lignes en enregistrements de fragments typés. 5. Publiez l’état du document, des sections, des fragments et du graphe avant la récupération. ### Expliciter l’orientation vers les analyseurs - Utilisez un point d’entrée d’analyseur typé unique pour tous les formats et renvoyez des chemins d’artefacts locaux à la tâche. - Dirigez les entrées PDF, DOCX, PPTX, de tableur, Markdown, texte, image et fragment brut vers des stratégies propres à leur format ; convertissez les anciens formats bureautiques avant d’utiliser l’analyseur moderne. - Pour les PDF, séparez la classification sémantique ouverte des catégories réservées à l’orientation, telles qu’atlas, document numérisé, diapositives et document générique. - Exécutez une seule fois l’analyse structurelle au point d’entrée des documents surdimensionnés, puis transmettez le plan de partitionnement obtenu aux étapes suivantes. - Après l’analyse, retirez les images non référencées et appliquez une compression d’image déterministe. ## Retrouver la hiérarchie des titres et garder tableaux et images à la conversion Déterminez la structure à partir des preuves disponibles les plus solides et conservez les tableaux, les images et les relations entre titres pendant la conversion. ### Résoudre les titres selon l’ordre des preuves 1. Utilisez une table des matières intégrée comme source de vérité lorsqu’elle est disponible. 2. Faites correspondre les modèles de numérotation explicites et les marqueurs de chapitre propres à la langue. 3. N’utilisez un modèle de hiérarchie fondé sur un LLM que pour les titres candidats qui restent non résolus. 4. Pour les PDF riches en mise en page, regroupez la géométrie des polices en un ensemble borné de niveaux de titres. ### Préserver le comportement propre à chaque format - Parcourez les éléments du corps d’un DOCX dans l’ordre de la source, y compris les paragraphes, les tableaux, les images et les zones de table des matières. - Maintenez une pile de titres qui ferme les descendants lorsqu’un nouveau titre revient au niveau parent. - Convertissez les tableaux en HTML avec des valeurs `rowspan` et `colspan` exactes, puis dédupliquez les images au moyen d’un hachage perceptuel. - Dirigez les PDF standard vers l’extraction et l’analyse de Markdown ; dirigez les documents de type atlas ou surdimensionnés vers leurs parcours spécialisés. - Maintenez la synthèse, la reconnaissance de hiérarchie, la description d’image, l’OCR et la classification grossière derrière des clés distinctes de configuration du modèle. ## Enregistrer fragments, navigation et manifeste dans un format fixe Considérez le corpus persistant comme faisant autorité ; les DataFrames intermédiaires sont des détails d’implémentation transitoires. ### Stocker l’état du corpus et des documents - Conservez les métadonnées du graphe à l’échelle du corpus et les statistiques de résultats de récupération à côté d’un répertoire par document ingéré. - Conservez durablement les fragments ordonnés, la navigation hiérarchique, les métadonnées d’analyse, l’arbre complet des titres, les ressources sources archivées, les images et tableaux extraits ainsi que les résultats de diagnostic. - Utilisez exactement trois types principaux de fragments : `text`, `image` et `table`. - Attribuez à chaque fragment un `chunk_id` déterministe, un contenu typé, un chemin hiérarchique et des métadonnées portant sur la longueur, les synthèses, les numéros de page, les jetons, les mots-clés, les chemins de fichiers et les références entre fragments. ### Préserver les références et la navigation - Représentez les relations intégrées au moyen d’entrées `connect_to` contenant `target`, `relation`, `ref` et la `position` exprimée en décalage de caractères. - Utilisez `embeds` pour les ressources intégrées et `related` pour les associations qui ne le sont pas. - Construisez `doc_nav.json` comme un arbre de sections comportant des synthèses, un nombre de fragments, des enfants et des ressources d’image ou de tableau. - Construisez `manifest.json` avec les métadonnées sources, les statistiques et une `HIERARCHY` imbriquée. - Convertissez les lignes transitoires de l’analyseur en charges utiles de fragments typés avant d’écrire `chunks.json`. ## Publier ensemble les enregistrements de la base de données, les index de recherche et les liens du graphe Publiez une révision cohérente afin que les enregistrements relationnels, les canaux de recherche et les arêtes du graphe décrivent le même ensemble de fragments. ### Maintenir la responsabilité des données relationnelles - Stockez au niveau du document son identité, son propriétaire, son espace de noms, son état, sa révision active et le nom du fichier source. - Stockez les liens vers les parents, les chemins, les titres, les niveaux, les synthèses et l’ordre de tri dans un arbre de sections tenant compte de la révision. - Stockez pour chaque fragment les hachages de contenu, les types de fragments, le texte interrogeable, les chemins sources, les chemins de ressources, les métadonnées et l’ordre de tri. - Limitez les nœuds du graphe au document et utilisez des arêtes non orientées lorsqu’elles représentent une relation symétrique. ### Publier selon une séquence fixe 1. Dédupliquez les fragments entre documents au moyen d’un hachage déterministe du contenu. 2. Construisez les sections parentes à partir des chemins des fragments, du sommet vers la base. 3. Générez pour chaque fragment des canaux de recherche distincts pour le contenu, le chemin et les termes bruts. 4. Créez des nœuds de graphe documentaire et des arêtes de chevauchement de mots-clés uniquement lorsqu’au moins 3 mots-clés sont partagés et que le score est au minimum de 0.8. Utilisez le contenu segmenté en jetons avec les synthèses pour la recherche de contenu, les noms de fichiers et chemins de sections segmentés en jetons pour la recherche par chemin, et le contenu brut avec les chemins pour la recherche de sous-chaînes. ## Proposer la recherche classique par classement et la recherche par agent dans un budget Séparez selon les responsabilités la mise en forme des requêtes, la recherche lexicale, l’hydratation, l’accès au graphe, les statistiques de résultats, l’exécution des flux de travail, la navigation et le rendu des preuves. ### Préserver les deux modes de récupération - En mode historique, combinez les canaux de chemin, de contenu et de termes au moyen d’une fusion par rang réciproque. - Utilisez les pondérations de canal par défaut `path=1.0`, `content=2.0` et `term=1.5`, avec `score = weight / (k + rank + 1)` et `k=60`. - En mode agentique, laissez un planificateur décomposer les requêtes complexes en un DAG d’étapes de récupération ; ne planifiez pas d’étapes de synthèse de réponse au sein de la récupération. - Appliquez un budget de jetons unique à l’ensemble du DAG. Lorsqu’il est épuisé, arrêtez-vous en toute sécurité et renvoyez les meilleures preuves recueillies jusque-là. - Exécutez la découverte, la navigation contrainte en largeur dans les sections et le rendu des preuves comme des phases distinctes. - Présentez `evidence_text` comme réponse principale et conservez le champ déprécié `answer_text` uniquement comme champ de compatibilité vide. ### Hydrater et classer avec discernement - Présentez les sections non ouvertes sous forme de plans composés d’un titre et d’une synthèse, et n’hydratez les fragments `text`, `image` et `table` bruts que pour les feuilles sélectionnées. - Résolvez nativement les ressources connectées et intégrez-les en ligne sans marqueurs de substitution de chaînes fragiles. - Classez les résultats de l’agent d’abord par `agent_score`, puis par `discovery_score` ; reléguez les lignes dont `agent_score=0` dans un ensemble de repli. - Avant l’assemblage, excluez les documents et les sections indiqués, puis limitez le résultat aux types de fragments autorisés. - Joignez des citations contenant `document_id`, `chunk_id`, `source_file_name` et `section_path`. ## Garder des ID de fragments stables et ne mettre en cache que les résultats réussis Explicitez les raccourcis, les identifiants, l’ordre des modifications et la télémétrie afin que les optimisations ne changent pas la sémantique de la récupération. ### Maintenir des résultats reproductibles - Dérivez les identifiants de fragments uniquement d’un hachage stable du contenu textuel, sans les références aux images ni aux tableaux, afin que les contenus identiques soient dédupliqués entre les téléversements. - Planifiez d’abord les modifications du DOM, puis appliquez-les dans l’ordre inverse afin d’éviter les décalages d’indices. - Dédupliquez les images identiques dans un document au moyen d’un hachage perceptuel tout en réutilisant les métadonnées mises en cache. - Attribuez aux images répétées à différentes positions des identifiants déterministes mais uniques, et poursuivez l’analyse au-delà des identifiants binaires lorsque vous recherchez le contexte textuel voisin. ### Borner les raccourcis et les caches - Lorsque `total_chunks <= top_k`, renvoyez directement tous les fragments par un parcours explicite réservé aux petits corpus. - Mettez en cache par utilisateur, espace de noms, requête, `top_k` et filtres ; vérifiez la version du cache avant l’exécution et n’écrivez qu’après la réussite. - Enregistrez les résultats par fragment et par document afin d’améliorer le classement sans modifier le contenu source. - Conservez, pour les actions, les entrées, les sorties, la latence et la consommation de jetons de l’agent, des enregistrements d’exécution et d’étapes auxquels seules des entrées peuvent être ajoutées. ## Gérer les particularités de l’API du LLM et vérifier en local avant d’annoncer la fin Explicitez les contraintes des modèles et les commandes de vérification locale afin que les défaillances restent diagnosticables. ### Renforcer les intégrations de modèles - Incluez le mot `json` lorsque vous demandez le mode `json_object` de DeepSeek. - Pendant la diffusion en continu, concaténez `delta.content` uniquement lorsqu’il n’est pas égal à `None`. - Alternez les jetons d’API dans les limites de débit propres à chaque jeton, appliquez des temps de pause et réessayez sur place avec le prochain jeton disponible. - Limitez la récupération aux preuves ; les agents en aval décident si elles sont suffisantes et synthétisent les réponses en dehors du service de récupération. ### Vérifier le système localement - Installez depuis l’espace de travail aux versions épinglées, copiez localement les modèles d’environnement et démarrez les services requis de base de données, de cache, de stockage d’objets, d’API et de traitement. - Fournissez des commandes de débogage de bout en bout ciblées sur l’analyseur, le profileur, la hiérarchie et le traitement agentique ; exécutez ensuite le lint, les corrections automatiques sûres et les vérifications de types dans les paquets d’API, de traitement et de composants partagés. - Vérifiez la documentation de l’API locale et les points d’accès des services sous-jacents avant de diagnostiquer les défaillances de niveau supérieur du pipeline. - Ne déclarez pas le travail terminé tant que l’analyseur concerné, le parcours de publication, le mode de récupération et les contrôles de qualité ne disposent pas de résultats directs.