Photon : Construire un moteur de récupération et de classement à partir de zéro

Comment des formats de données spécialisés, des lectures par lots et la séparation de la construction d'index de la desserte de requêtes améliorent la recherche native par IA.

AuteursPerplexity Engineering

Introduction

La pile de recherche native de l'IA de Perplexity récupère et classe les pages candidates, faisant surface le contenu le plus pertinent pour que le modèle fonde ses réponses. À l'origine, cette étape s'exécutait sur un moteur open-source que nous avons adapté à notre système. Cependant, à mesure que notre index et nos charges de travail augmentaient, nous avons atteint des limites strictes sur les coûts, la latence de queue et le temps de récupération des nœuds que nous ne pouvions pas résoudre au sein de la plateforme tierce existante.

Pour surmonter ces défis, nous avons construit Photon, un nouveau moteur interne de récupération et de classement. Cela s'inscrit dans le droit fil de notre approche consistant à construire une infrastructure de recherche axée sur l'IA à partir de zéro, comme nous l'avons fait avec CobbleDB, notre magasin clé-valeur distribué pour la desserte d'enregistrements de pages, et notre API de recherche.

Photon utilise des formats de données compacts pour lire et décoder uniquement ce dont chaque requête a besoin, avec une mise en cache consciente des lots et des lectures asynchrones pour réduire l'accès au disque et chevaucher les attentes. La construction de l'index s'exécute séparément de la desserte des requêtes, en mettant à jour un groupe de desserte à la fois et en réchauffant ses caches avant d'acheminer les requêtes en direct vers celui-ci.

Photon alimente désormais notre pipeline de recherche et constitue également le fondement d'un nouveau préréglage rapide pour notre API de recherche, avec une latence d'appel de recherche unique de 160 ms à p50 et de 230 ms à p95. Sur six repères publics, le préréglage rapide a réduit le coût estimé du modèle et de la recherche par tâche de 68 % tout en maintenant une qualité de tâche globale comparable au préréglage par défaut. Nous le publions aujourd'hui afin que les développeurs puissent accéder à ces améliorations.

Latence des appels de recherche unique autodéclarée. PPLX Rapide signale une latence p50 de 160 ms et une latence p95 de 230 ms. Exa Instant signale p90, et non p95, pour sa valeur de queue haute; les valeurs de queue haute de Parallel ne sont pas publiées. Les percentiles signalés et les configurations de mesure ne constituent pas une comparaison contrôlée comparable.
Qualité globale des tâches par rapport au coût total estimé du modèle et de la recherche pour les mêmes 3 554 tâches sélectionnées. Les scores sont pondérés par le nombre de tâches, et les coûts couvrent l'ensemble des tâches. PPLX Rapide obtient 64,3 % à 59,73 $, contre 64,0 % à 187,60 $ pour le préréglage PPLX par défaut, soit un coût estimé inférieur d'environ 68 % pour le même nombre de tâches.

Ce que le moteur de récupération et de classement exige

Pour chaque requête, le moteur de récupération et de classement recherche dans un index vaste et distribué pour sélectionner et ordonner un petit ensemble de pages pertinentes dans le budget de latence de la pile de recherche. Le système doit également maintenir l'index à jour à mesure que de nouvelles pages arrivent et que les pages existantes changent, sans laisser ce travail ralentir les requêtes en direct.

Nous avons évalué plusieurs options open-source et choisi un moteur de récupération et de classement généraliste et mature qui répondait à nos besoins initiaux. Nous l'avons ensuite adapté à notre architecture et à nos charges de travail, en maintenant une latence et un débit stables à l'échelle de la production.

Là où notre système précédent a échoué

Nous avons maintenu notre propre fork pour adapter le moteur à notre index en croissance, mais l'adresse des limitations clés exigeait de plus en plus la reconception de grandes parties de la plateforme. Plusieurs contraintes se sont avérées difficiles à résoudre sans changements architecturaux fondamentaux :

1. Coûts de mise à échelle. Le nombre de documents que nous stockons et la quantité de données par document que nous devons récupérer et classer ont augmenté au fil du temps. Cette mise à échelle a exercé une pression sur notre matériel, en particulier sur la quantité de RAM disponible. Pour contrôler les coûts, nous avions besoin de représentations de données plus compactes et d'un contrôle plus fin sur ce qui reste en mémoire et ce qui est lu à partir du disque à la demande.

2. Mauvaise latence de queue. Sur le trafic de production, le temps de réponse p99 de l'ancien système était d'environ 800 ms. L'ensemble de données dépassait la RAM disponible, nous ne pouvions donc pas utiliser mlock pour le conserver entièrement en mémoire. L'accès aux données non résidentes pouvait déclencher des défauts de page majeurs, bloquant l'exécution des requêtes pendant que le système d'exploitation lisait à partir du disque.

Le moteur fusionnait également périodiquement son index de disque principal avec des index plus petits vidés de la mémoire. Pendant ce processus de fusion d'index de disque, le nombre de défauts de page augmentait encore plus, la latence p99 atteignant environ 1,2 s pendant 10 à 15 minutes. À mesure que les caches se réchauffaient, la fréquence des défauts de page et la latence diminuaient toutes deux, ce qui suggère que les lectures froides contribuaient grandement aux pics. Le préchargement des données et le réchauffement de l'index ont réduit les pics mais n'ont pas adéquatement abordé la latence de queue élevée.

3. Récupération et synchronisation fastidieuses. Dans le système précédent, le déploiement d'un cluster supplémentaire et la synchronisation de ses données pouvaient prendre plus d'une semaine. La synchronisation était également requise lors de l'ajout de groupes de nœuds pour contenir des copies de données supplémentaires ou lors de la récupération après des pannes de nœuds. Pendant la récupération, une plus grande proportion des réponses de recherche était partielle, ce the abaissait les scores de qualité des réponses finales.

En fin de compte, nous avons conclu qu'il serait plus simple et moins coûteux de construire à partir de zéro plutôt que de continuer à adapter et à maintenir notre fork. En nous appuyant sur notre expérience de l'exploitation du système précédent, une petite équipe d'ingénierie a travaillé aux côtés d'un essaim d'agents de codage persistants pour construire Photon.

Où Photon s'intègre dans la pile de recherche

Photon est conçu pour deux flux de travail principaux : la desserte des requêtes de recherche et l'ingestion des mises à jour du pipeline de traitement.

Une requête provenant du service de recherche de niveau supérieur atteint le courtier Photon par l'intermédiaire d'un équilibreur de charge. Le courtier sélectionne un groupe de partitions et transmet la requête à chaque partition, surveillant les délais d'attente et émettant des requêtes supplémentaires si nécessaire.

Chaque partition effectue la récupération, le classement initial et le classement de deuxième étape, puis renvoie ses meilleurs candidats au courtier. Le courtier combine ces candidats en une seule liste classée et récupère les champs de documents clés pour les pages sélectionnées à partir des partitions pertinentes. Il renvoie ensuite ces résultats au service de recherche de niveau supérieur, qui rassemble le contenu de page nécessaire pour que l'agent génère une réponse fondée.

Les mises à jour d'index suivent un chemin distinct. Pillar, notre couche de publication, prépare les données et les stocke dans des tables YTsaurus. Les indexeurs convertissent ces tables en structures d'index que les partitions peuvent charger pour la recherche. Le contrôleur coordonne la préparation des données, la construction de l'index et le déploiement de nouvelles versions d'index vers les groupes de desserte. Avant de traiter le trafic en direct, chaque shard rejoue de véritables requêtes de recherche pour réchauffer ses caches.

Une requête passe du service de recherche de niveau supérieur à travers l'équilibreur de charge et le courtier vers un groupe de partitions sélectionné. Chaque partition récupère et classe les candidats; le courtier fusionne les résultats, récupère les champs de documents pour les pages sélectionnées et les renvoie au service de recherche de niveau supérieur. Les étapes numérotées indiquent l'ordre. Les flèches pleines transportent les requêtes, et les flèches en pointillés transportent les résultats en retour. Les étiquettes de phase du côté gauche distinguent la sélection des candidats des lectures de résumés.

Conception de Photon pour nos flux de travail

Trois choix de conception rendent Photon bien adapté à notre charge de travail : des représentations de données compactes, la mise en cache et les lectures de disque asynchrones, et la séparation des mises à jour d'index de la desserte des requêtes.

Représentations de données pour la récupération et le classement

La récupération et le classement accèdent aux données des documents différemment. La récupération lexicale commence par les termes de la requête et trouve les documents qui les contiennent. Le classement a ensuite besoin d'informations détaillées sur chaque document sélectionné, y compris les fréquences des termes et les positions.

Photon utilise deux représentations complémentaires pour prendre en charge ces modèles d'accès. Un index inversé stocke une liste de documents correspondants pour chaque terme, appelée liste d'affichage, pour prendre en charge la sélection des candidats. Des enregistrements par document distincts fournissent les données nécessaires au classement. Nous optimisons également la façon dont les listes d'affichage sont stockées et parcourues pour améliorer la sélection dans le cadre d'un budget de travail fixe.

Des représentations de données spécialisées nous permettent de stocker les données clés plus efficacement. Un index inversé plus compact réduit la quantité de données lues ou déplacées par requête, améliorant la latence en éliminant les opérations d'E/S inutiles. Ces formats permettent également de vérifier si un document apparaît dans une liste sans le décoder complètement, une propriété sur laquelle notre logique de parcours s'appuie pour contrôler la quantité de travail effectuée par une requête sous un budget fixe. L'optimisation des enregistrements par document permet de stocker plus de données par document pour le classement, tout en réduisant les coûts de mise à l'échelle associés à notre système précédent.

L'index inversé

Pour chaque terme, l'index inversé stocke une liste d'affichage. Ces listes peuvent aller d'une poignée de documents à des millions, de sorte qu'aucun format unique ne fonctionne bien pour chaque liste. Photon choisit le format en fonction du nombre de documents contenant le terme.

Les listes courtes utilisent une représentation en ligne qui s'intègre dans une seule page et ne nécessite aucune table de blocs. Les listes plus longues qui ne s'intègrent pas dans le format en ligne sont divisées en blocs couvrant des plages fixes d'identifiants de documents. La représentation de chaque bloc dépend de sa densité : les blocs espacés stockent des tableaux triés de décalages d'identifiants de documents, tandis que les blocs denses utilisent des bitmaps. Les blocs espacés utilisent une recherche par galop, qui avance par pas de plus en plus grands pour ignorer des régions de la liste. Les blocs denses permettent des vérifications d'appartenance en consultant le bit correspondant à un document.

La fréquence de requête d'un terme détermine l'emplacement de sa liste d'affichage sur le disque. Les listes fréquemment interrogées sont stockées à proximité les unes des autres, ce qui concentre les données chaudes dans une région de stockage plus petite. Dans chaque liste, les documents sont ordonnés par un signal d'utilité distinct afin que les candidats les plus prometteurs soient rencontrés plus tôt.

Photon choisit une représentation de liste d'affichage en fonction de la longueur et de la densité des blocs. Les listes courtes s'intègrent en ligne dans une page. Les listes plus longues sont divisées en plages d'identifiants de documents fixes, avec des tableaux de décalages triés pour les blocs espacés et des bitmaps pour les blocs denses.

Traversée de listes dans le cadre d'un budget de travail

La sélection des candidats nécessite de parcourir les listes d'affichage pour trouver des documents potentiellement pertinents. L'analyse exhaustive de chaque liste est coûteuse, de sorte que Photon utilise un algorithme de type WAND qui ne parcourt que certaines listes tout en tenant compte des correspondances dans les autres.

L'algorithme divise les listes en deux groupes. Les listes directrices font avancer le parcours et proposent des documents candidats. Les listes de sondage contribuent aux scores de ces candidats mais ne génèrent pas de candidats elles-mêmes.

Le score des candidats combine la couverture pondérée des termes de la requête et une contribution de la fréquence, avec une normalisation de la longueur du document et un plafond sur les gains des termes répétés. Photon vérifie d'abord la présence des termes dans les tableaux et les bitmaps pour délimiter le score maximal possible de chaque candidat. Il lit les fréquences exactes des termes uniquement pour les candidats qui peuvent encore atteindre le seuil de sélection.

La sélection procède ensuite en trois étapes :

  • Parcours : commencez par une exigence stricte de couverture des requêtes. Si trop peu de candidats sont trouvés, répétez avec une exigence assouplie.
  • Rétention : les candidats sont conservés dans un ensemble délimité en utilisant un score qui combine la couverture et la fréquence. À mesure que les principaux candidats collectés s'améliorent, le seuil d'admission s'élève.
  • Sélection finale : les résultats finaux pour la passe sont choisis parmi l'ensemble retenu sur la base des scores de fréquence. Chaque champ exécute sa propre passe, et les résultats sont fusionnés à l'aide des poids des champs.

L'algorithme produit un ensemble de candidats de documents pertinents à utiliser dans un classement ultérieur.

Traversée de candidats délimités illustrative. Les listes directrices proposent des documents, tandis que les bornes supérieures permettent d'élaguer les candidats inférieurs au seuil d'admission actuel sans lire les listes de sondage ou les fréquences exactes. Le seuil s'élève à mesure que l'ensemble retenu s'améliore. Les scores sont inventés pour l'illustration, et les candidats retenus ne constituent pas un top-k exact garanti.

Docblob

Une fois les pages candidates sélectionnées, la phase de classement a besoin des fréquences des termes, de la couverture des champs, ainsi que des emplacements et de la proximité des occurrences. Obtenir ces données par le biais de l'index inversé nécessiterait des accès dispersés à travers de nombreuses paires terme-document. Dans Photon, nous stockons un enregistrement compact par document appelé docblob qui contient les fréquences des termes, les champs dans lesquels un terme est apparu et l'endroit où il s'est produit dans le document. Par conséquent, le classement d'un candidat ne nécessite qu'une seule consultation par document.

Le format est conçu pour éviter de décoder plus que nécessaire. Dans un docblob, les champs sont regroupés par analyseur de texte. Chaque groupe stocke une liste de termes triée encodée avec Elias-Fano, de sorte qu'un terme de requête peut être recherché directement sans développer toute la liste au préalable. Un masque de champ indique l'endroit où un terme est apparu, un décompte de fréquence suit la fréquence et les positions réelles résident dans des blocs séparés par paire terme-champ encodés sous forme de différences de position. Seuls les blocs pour les termes qui ont réellement correspondu sont décodés, tandis que tout le reste de l'enregistrement reste dans le format compressé.

Ce décodage sélectif permet à docblob de prendre en charge le stockage de plus de données par document sans augmentation proportionnelle des coûts. La croissance de l'enregistrement ne force pas plus de travail par consultation, car le classement ne touche jamais que les éléments pertinents pour les termes correspondants plutôt que l'ensemble de l'enregistrement.

Un docblob regroupe les données de classement dans un enregistrement compact par document. Les termes de requête sont recherchés dans une liste de termes encodée en Elias-Fano; les masques de champs, les fréquences et les blocs de positions fournissent les données nécessaires pour les termes correspondants tandis que les termes non reliés restent compressés. Les identifiants et les positions des termes sont illustratifs.

Lectures par lots et travail avec la mémoire

Même avec des représentations de données plus efficaces, la RAM s'épuise toujours avant les autres ressources, de sorte que nous devons fréquemment accéder aux données stockées sur le disque. Photon utilise des lectures de disque asynchrones et un cache optimisé pour les lectures par lots pour accélérer ces accès, réduisant ainsi le temps d'attente par requête. Cela contribue à une amélioration significative de la latence de queue par rapport au système précédent.

Photon vérifie un lot de décalages d'enregistrements connus dans son cache avant d'émettre des lectures de disque. Les succès de cache sont copiés dans un tampon préparé; les échecs sont soumis par l'intermédiaire de io_uring afin que les attentes de disque puissent se chevaucher, et les données renvoyées peuplent le cache. Les enregistrements et les chronologies sont schématiques, et non des latences mesurées.

Chevauchement des attentes sur disque

Le classement nécessite l'obtention des caractéristiques d'une centaine de documents situés dans différentes parties d'un fichier. Notre système précédent utilisait mmap pour mapper le fichier dans l'espace d'adressage virtuel afin qu'il puisse être lu par le biais de pointeurs de mémoire. Cependant, l'accès à une page absente de la mémoire nécessitait toujours une lecture de disque. Le thread devait attendre les données avant de poursuivre le calcul, et ce temps d'attente s'accumulait lorsque le processus avait besoin de lire des enregistrements froids séquentiellement.

Photon tire parti du fait que les décalages d'enregistrements sont connus à l'avance, ce qui nous permet de soumettre plusieurs lectures en même temps. Cette opération est gérée par le réacteur : des threads de travail dédiés soumettent des lots par l'intermédiaire de io_uring et transmettent les données qu'ils ont lues au code appelant. Chaque thread gère son propre io_uring; les lots sont envoyés au réacteur le moins chargé. Des descripteurs de fichiers préenregistrés et des bassins de mémoire réduisent la surcharge des lectures répétées. Cette exécution asynchrone permet aux attentes de plusieurs opérations de se chevaucher, ce qui réduit la latence de queue.

Réduction du nombre d'accès aux disques

Avant de soumettre des lectures, Photon vérifie tout le lot dans le cache en mémoire. Seules les requêtes pour les enregistrements manquants vont sur le disque; les données lues peuplent ensuite le cache.

Le cache est conçu pour les lectures par lots. Plus précisément :

  • Il n'y a pas d'allocation distincte lors d'un succès. Au lieu de cela, les données sont copiées dans un tampon préparé à l'avance par le code appelant.
  • Il n'y a pas d'acquisition de verrou par le lecteur. Au lieu de cela, il vérifie la version des données et réessaie en cas de conflit avec une écriture.
  • Il utilise l'éviction CLOCK, plutôt que de nécessiter des mises à jour d'une liste LRU partagée à chaque lecture.
  • Il utilise la prélecture du cache processeur, où les métadonnées et les données pour les enregistrements à venir sont demandées à l'avance.

Ces optimisations réduisent la latence sans nuire aux performances sur les charges de travail qui nous importent.

Construction et mise à jour de l'index séparément de la desserte

Dans Photon, la construction de l'index et la desserte des requêtes s'exécutent sur des nœuds différents. Les indexeurs transforment les données en structures de stockage prêtes, tandis que les nœuds de desserte les lisent et effectuent la récupération et le classement. Par conséquent, la construction de l'index ne concurrence pas les requêtes de recherche pour le processeur, et les ressources pour ces tâches peuvent être mises à l'échelle indépendamment.

Cette séparation aborde les goulets d'étranglement de récupération et de synchronisation présents dans l'implémentation précédente. Étant donné que la construction de l'index s'exécutait à l'intérieur du même cluster qui desservait les requêtes, la récupération d'un nœud défaillant ou l'ajout d'une nouvelle copie des données pouvait signifier la réindexation des documents sur place, un processus qui prenait des jours et augmentait les réponses partielles pendant la récupération. Photon supprime ce couplage; les indexeurs s'exécutent en tant que travaux distribués qui produisent des structures d'index versionnées et prêtes à desservir indépendamment des nœuds de desserte, de sorte que la construction de la version suivante de l'index ne concurrence plus le trafic en direct.

La construction de l'index s'exécute séparément de la desserte des requêtes en direct. Pillar exporte les données sources, YTsaurus prépare les tables versionnées par partition, et des indexeurs parallèles écrivent des structures d'index prêtes à desservir dans le stockage d'objets. Les nœuds de desserte chargent ces structures pour la récupération et le classement; la concurrence des indexeurs et le nombre de partitions sont configurés indépendamment.

Préparation et construction distribuée

Une construction commence par la sélection des documents pour l'index actif et la production de l'exportation source. Le contrôleur enregistre la version source, les tables d'entrée et le nombre attendu de partitions. Les travaux MapReduce dans YTsaurus préparent le texte, les métadonnées, les fragments, les caractéristiques et les intégrations précalculées dans des tables versionnées partitionnées par partition. Chaque indexeur diffuse la table préparée, construit les structures pour sa partition et fusionne les segments de texte. L'index prêt, ainsi qu'une description de ses composants, est téléchargé sur le stockage d'objets.

Le nombre de partitions et le nombre d'indexeurs exécutés simultanément sont configurés indépendamment, de sorte qu'une construction peut s'exécuter en plusieurs vagues, ou que plus de machines peuvent être allouées pour travailler en parallèle. La préparation distribuée et les indexeurs parallèles permettent de construire l'index Web complet en un nombre de chiffres uniques d'heures, une amélioration significative par rapport au système précédent.

Déploiement d'une nouvelle version

Avant le déploiement, le contrôleur vérifie que le nouvel index est prêt. Si les données sont incomplètes, le déploiement est bloqué automatiquement.

Lorsqu'il y a plusieurs groupes de desserte, le contrôleur les met à jour un par un. Il retire d'abord un groupe de l'acheminement du courtier et le démarre sur la nouvelle version d'index. Avant de desservir les requêtes, les partitions passent par une étape de réchauffement distincte basée sur les journaux de recherche, qui prépeuple l'état initial et rend la transition vers le trafic réel plus fluide. Après le réchauffement, le contrôleur vérifie l'état de l'index et la disponibilité, puis renvoie le groupe à l'acheminement. Les autres groupes continuent de desservir les requêtes pendant ce temps. Étant donné que l'état des opérations est persistant, un redémarrage ne force pas une construction à recommencer; le contrôleur peut se rattacher à une préparation déjà en cours, réutiliser un résultat prêt ou continuer une rotation interrompue à partir de l'étape enregistrée.

Les temps de mise à jour des données diffèrent selon les verticales de recherche. Pour les verticales ayant des exigences de fraîcheur élevées, la livraison de documents prend un nombre de minutes à un seul chiffre. Une copie supplémentaire des données peut être déployée en une demi-heure environ; les index prêts sont chargés et attachés aux partitions sans réindexer les documents sources.

Le contrôleur vérifie qu'un nouvel index est complet, puis fait pivoter un groupe de desserte à la fois. Un groupe quitte l'acheminement du courtier, charge la nouvelle version, réchauffe ses caches avec les requêtes des journaux de recherche et réussit les vérifications de disponibilité avant de retourner au trafic. Les autres groupes continuent de desservir, et l'état persistant du contrôleur permet à une rotation interrompue de reprendre.

Migration et validation au sein de notre pile de recherche

Notre premier objectif était de remplacer l'ancien système par un moteur qui préservait la fonctionnalité et la qualité de recherche tout en réduisant les temps de réponse. Nous avons validé Photon par étapes, en commençant par des tests de charge reproductibles et des évaluations de qualité hors ligne avant de passer au trafic en direct. Photon alimente désormais la récupération et le classement dans notre pile de recherche de production, avec des temps de réponse nettement inférieurs à ceux de l'ancien système.

Tests de charge et évaluations

Pour les tests de performance, nous avons construit un outil de test de charge qui rejoue les requêtes de nos journaux de recherche à des taux d'arrivée configurables. Il compare les résultats entre les exécutions et applique des tests statistiques pour évaluer si les différences de performance observées sont cohérentes. Par ailleurs, nous avons évalué Photon et l'ancien système sur les mêmes ensembles de données dans nos systèmes d'évaluation hors ligne internes pour vérifier les régressions de qualité.

Après ces vérifications, nous avons envoyé des requêtes en direct aux deux moteurs simultanément en utilisant le trafic fantôme. Cela nous a permis de comparer leurs performances et leurs résultats sur les charges de travail de production avant de modifier le moteur qui desservait les utilisateurs. Nous avons ensuite activé Photon pour de petits sous-ensembles d'utilisateurs et avons progressivement élargi le déploiement, en surveillant la qualité et les performances tout au long du processus. La première version a réussi les tests d'acceptation sans régression de qualité, et nous avons poursuivi le déploiement jusqu'à ce que Photon desserve tout le trafic de production.

Améliorations mesurées en production

Dans notre flux de travail de production, le temps de réponse p99 est passé d'environ 800 ms dans l'ancien système à environ 65 ms dans Photon. Cette mesure couvre toutes les étapes à l'intérieur de Photon, mais exclut les étapes ultérieures dans la pile de recherche de niveau supérieur. Nous n'observons plus non plus les pics de latence préalablement associés au changement de versions d'index.

Photon utilise environ 20 % de machines de desserte équivalentes en moins que les nœuds de contenu de l'ancien système tout en stockant environ 2,5 fois plus de données par document. Après la migration, nous avons utilisé ces données supplémentaires pour améliorer la qualité du classement au-delà de celle de l'ancien système.

Photon réduit également la quantité de données qui doivent rester en mémoire. L'épinglage du même ensemble de données Photon dans la RAM avec mlock nécessiterait environ 4,6 fois plus de mémoire résidente que Photon n'en utilise actuellement.

Évaluation du préréglage d'API de recherche rapide

Nous avons également utilisé Photon comme base pour un nouveau préréglage rapide pour notre API de recherche, conçu pour les charges de travail sensibles à la latence. Selon nos mesures, la latence d'appel de recherche unique pour le préréglage rapide est de 160 ms à p50 et 230 ms à p95, inférieure ou comparable aux chiffres autodéclarés d'autres fournisseurs d'API de recherche, bien que les percentiles de queue signalés diffèrent.

Nous avons évalué le préréglage rapide sur six repères axés sur les agents : WideSearch, BrowseComp, DSQA, FRAMES, SEAL-0 et SEAL-Hard. Parmi ces évaluations, il présentait le coût total estimé du modèle et de la recherche le plus bas et le score de tâche global le plus élevé parmi les configurations testées.

Le préréglage rapide associe Photon à un classement optimisé pour les flux de travail axés sur les agents, offrant des performances comparables au préréglage par défaut à un coût nettement inférieur. Cependant, il comporte un compromis en matière de qualité de recherche globale. Le préréglage rapide utilise moins de calcul pour le classement que le préréglage par défaut. Sur les repères internes couvrant les requêtes à longue traîne, la couverture large et la diversité des résultats, il obtient des scores inférieurs de 0,24 point sur la pertinence et d'environ 3 points de pourcentage sur la disponibilité des réponses. Nous pensons qu'il s'agit d'un compromis judicieux pour les flux de travail axés sur les agents, car le raisonnement et les connaissances du modèle peuvent aider à compenser la différence.

Comparaison interne de la qualité de récupération entre le préréglage PPLX par défaut et PPLX Rapide. La pertinence (DCG) chute de 2,45 à 2,21, soit une diminution de 0,24 point; la disponibilité des réponses chute de 0,596 à 0,567, soit une diminution de 2,9 points de pourcentage. Les deux panneaux utilisent des lignes de base d'axe non nulles différentes, de sorte que les hauteurs de barres soulignent les écarts plutôt que les différences proportionnelles.

Nous recommandons le préréglage rapide pour les tâches axées sur les agents au jour le jour. Pour les questions plus difficiles ou ambiguës qui sont moins sensibles au temps, le préréglage par défaut offre une qualité plus robuste, ce qui justifie sa latence et son coût plus élevés.

Conclusion

Nous déplaçons régulièrement notre pile de recherche vers une infrastructure interne basée sur Rust. Le remplacement du moteur open-source par Photon, notre moteur personnalisé de récupération et de classement, est la dernière étape en date. Photon nous donne un contrôle total sur les représentations de données, la façon dont les lectures sont organisées et la manière dont les nouveaux index sont déployés, ce qui nous permet d'optimiser chaque couche pour nos charges de travail.

Photon a permis une recherche plus rapide dans les produits de Perplexity et constitue la base de notre nouveau préréglage rapide dans l'API de recherche. Suite à la migration, la latence p99 de récupération et de classement est passée d'environ 800 ms à 65 ms. Nos formats de données compacts nous permettent également de stocker 2,5 fois plus de données par document, ce qui donne à la récupération et au classement l'accès à des informations de documents plus riches.

Le préréglage rapide offre une latence d'appel de recherche unique de 160 ms à p50 et de 230 ms à p95. Parmi les six repères axés sur les agents évalués, il a réduit le coût estimé du modèle et de la recherche par tâche de 68 % par rapport au préréglage par défaut tout en maintenant une qualité de tâche globale comparable. Ces résultats démontrent les avantages pratiques d'une infrastructure conçue autour de nos charges de travail de recherche, tant pour les produits de Perplexity que pour les développeurs construisant avec notre API.

Nous continuons à améliorer les performances et l'efficacité du stockage de Photon. Notre objectif est de prendre en charge un index plus grand et des données de documents plus riches sur le même matériel tout en maintenant la recherche rapide à mesure que nos charges de travail augmentent.

Citation

BibTeX
@online{perplexity2026Photon,
  author = {{Perplexity} and Maksim Morozov and Bogdan Savko and Ruslan Kovalev and Aleksei Bykov and Artur Zayats and Denis Bykov and Nikita Kireev and Jarrod Bryan and Claire Beamer and Jeremy Yang},
  title = {{Photon: Building a retrieval and ranking engine from scratch}},
  date = {2026-09-24},
  url = {https://www.perplexity.ai/hub/blog/photon}
}