Photon : Construction d'un moteur de recherche et de classement de zéro

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

AuteursPerplexity Engineering

Introduction

La pile de recherche native pour l'IA de Perplexity récupère et classe les pages candidates, faisant surface le contenu le plus pertinent pour que le modèle puisse fonder 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 en matière de coûts, de latence de queue et de 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 recherche et de classement. Cela poursuit 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 servir les 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 d'index s'exécute séparément de la desserte des requêtes, mettant à jour un groupe de service à la fois et réchauffant ses caches avant d'y acheminer les requêtes en direct.

Photon alimente désormais notre pipeline de recherche et constitue également la base d'un nouveau préréglage rapide pour notre API de recherche, avec une latence d'appel de recherche unique de 160 ms au p50 et 230 ms au p95. Sur six benchmarks publics, le préréglage rapide a réduit le coût estimé du modèle plus 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 d'appel de recherche unique auto-déclarée. PPLX Fast 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 de type équivalent.
Qualité globale des tâches par rapport au coût total estimé du modèle et de la recherche pour les 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 Fast obtient 64,3 % pour 59,73 $, contre 64,0 % pour 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 recherche et de classement requiert

Pour chaque requête, le moteur de recherche et de classement parcourt un index volumineux 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 recherche et de classement mature et polyvalent qui répondait à nos besoins initiaux. Nous l'avons ensuite adapté à notre architecture et à nos charges de travail, 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 croissant, mais résoudre les limitations clés nécessitait de plus en plus de concevoir de grandes parties de la plateforme. Plusieurs contraintes se sont avérées difficiles à résoudre sans modifications architecturales fondamentales :

1. Coûts de mise à l'échelle. Le nombre de documents que nous stockons et la quantité de données par document que nous devons récupérer et classer n'ont cessé de croître au fil du temps. Cette mise à l'échelle a exercé une pression sur notre matériel, en particulier sur la quantité de RAM disponible. Pour maîtriser 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 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. Le jeu 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 à des 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 depuis le disque.

Le moteur fusionnait également périodiquement son index de disque principal avec des index plus petits vidés de la mémoire. Au cours de 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. Au fur et à 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 à froid contribuaient largement aux pics. Le préchargement des données et le réchauffement de l'index ont réduit les pics mais n'ont pas résolu adéquatement la latence de queue élevée.

3. Récupération et synchronisation longues. 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 nécessaire 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 part des réponses de recherche était partielle, ce qui 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. S'appuyant sur notre expérience de l'exploitation du système précédent, une petite équipe d'ingénieurs 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 le biais 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 recherche, 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 auprès des partitions pertinentes. Il renvoie ensuite ces résultats au service de recherche de niveau supérieur, qui rassemble le contenu des pages nécessaire pour que l'agent génère une réponse fondée.

Les mises à jour de l'index suivent un chemin distinct. Pillar, notre couche de publication, prépare les données et les stocke dans les 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 des index et le déploiement de nouvelles versions d'index vers les groupes de service. Avant de traiter le trafic en direct, chaque shard relit les requêtes de recherche réelles pour réchauffer ses caches.

Une requête passe du service de recherche de niveau supérieur via 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 recherche et le classement

La recherche et le classement accèdent aux données des documents différemment. La recherche 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 séparés 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 entièrement, 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 toutes les listes. Photon choisit le format en fonction du nombre de documents contenant le terme.

Les listes courtes utilisent une représentation en ligne qui tient dans une seule page et ne nécessite aucune table de blocs. Les listes plus longues qui ne tiennent 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 creux stockent des tableaux triés de décalages d'ID de documents, tandis que les blocs denses utilisent des bitmaps. Les blocs creux utilisent une recherche par galop, qui avance par pas de plus en plus grands pour sauter 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 des requêtes 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, concentrant les données chaudes dans une région de stockage plus petite. Au sein de 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'ID de documents fixes, avec des tableaux de décalages triés pour les blocs creux 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. Analyser exhaustivement chaque liste est coûteux, c'est pourquoi 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 la traversée 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 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 borner le score maximum 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 se déroule ensuite en trois étapes :

  • Traversée : 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 maintenus dans un ensemble borné en utilisant un score qui combine la couverture et la fréquence. À mesure que les meilleurs 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 illustrative de candidats bornés. Les listes directrices proposent des documents, tandis que les bornes supérieures permettent aux candidats situés sous le seuil d'admission actuel d'être élagués 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 à des fins d'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 nécessite les fréquences des termes, la couverture des champs, ainsi que les emplacements et 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, classer un candidat ne nécessite qu'une seule recherche 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 où un terme est apparu, un compteur 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 des termes qui ont réellement correspondu sont décodés, tandis que tout le reste de l'enregistrement reste au 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. L'augmentation de la taille de l'enregistrement ne force pas plus de travail par recherche, car le classement ne touche jamais que les parties pertinentes pour les termes correspondants plutôt que l'enregistrement entier.

Un docblob regroupe les données de classement dans un enregistrement compact par document. Les termes de la 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 position fournissent les données nécessaires pour les termes correspondants tandis que les termes non apparentés restent compressés. Les ID de termes et les positions 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 afin d'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 du cache sont copiés dans un tampon préparé ; les échecs sont soumis via io_uring afin que les attentes du 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 du 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 l'intermédiaire de pointeurs mémoire. Cependant, l'accès à une page absente de la mémoire nécessitait toujours une lecture de disque. Le fil devait attendre les données avant de poursuivre le calcul, et ce temps d'attente s'accumulait lorsque le processus devait lire séquentiellement des enregistrements froids.

Photon tire parti du fait que les décalages d'enregistrements sont connus à l'avance, ce qui nous permet de soumettre plusieurs lectures en une seule fois. Cette gestion est assurée par le réacteur : des fils de travail dédiés soumettent des lots via io_uring et transmettent les données lues au code appelant. Chaque fil 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 pools de tampons réduisent la surcharge des lectures répétées. Cette exécution asynchrone permet aux attentes de plusieurs opérations de se chevaucher, réduisant ainsi la latence de queue.

Réduction du nombre d'accès au lecteur

Avant de soumettre des lectures, Photon vérifie l'ensemble du 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 des 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 d'exiger des mises à jour d'une liste LRU partagée à chaque lecture.
  • Il utilise la prélecture du cache CPU, où les métadonnées et les données des enregistrements à venir sont demandées à l'avance.

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

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

Dans Photon, la construction des 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 service les lisent et effectuent la recherche et le classement. Par conséquent, la construction des 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 résout les goulots d'étranglement de récupération et de synchronisation présents dans l'implémentation précédente. Comme la construction des index s'exécutait dans le 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 sous forme de tâches distribuées qui produisent des structures d'index versionnées et prêtes à servir indépendamment des nœuds de service, de sorte que la construction de la version suivante de l'index ne concurrence plus le trafic en direct.

La construction des 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 à servir dans le stockage d'objets. Les nœuds de service chargent ces structures pour la recherche 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 tâches 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 s'exécutant simultanément sont configurés indépendamment, de sorte qu'une construction peut s'exécuter en plusieurs vagues, ou 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 service, le contrôleur les met à jour un par un. Il supprime d'abord un groupe du routage du courtier et le démarre sur la nouvelle version de l'index. Avant de servir les requêtes, les partitions passent par une étape de réchauffement distincte basée sur les journaux de recherche, ce qui pré-remplit 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 au routage. Les autres groupes continuent de servir les requêtes pendant ce temps. L'état des opérations étant 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 secteurs verticaux de recherche. Pour les secteurs verticaux ayant des exigences de fraîcheur élevées, la livraison des 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 service à la fois. Un groupe quitte le routage du courtier, charge la nouvelle version, réchauffe ses caches avec les requêtes des journaux de recherche et réussit les contrôles de disponibilité avant de retourner au trafic. Les autres groupes continuent de servir, 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 les fonctionnalités et la qualité de la 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 recherche et le classement dans notre pile de recherche de production, avec des temps de réponse sensiblement inférieurs à ceux de l'ancien système.

Tests de charge et évaluations

Pour les tests de performance, nous avons créé un outil de test de charge qui relit 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 performances observées sont cohérentes. Par ailleurs, nous avons évalué Photon et l'ancien système sur les mêmes jeux de données dans nos systèmes d'évaluation hors ligne internes pour vérifier s'il y avait des 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 miroir. Cela nous a permis de comparer leurs performances et leurs résultats sur les charges de travail de production avant de changer le moteur desservant les utilisateurs. Nous avons ensuite activé Photon pour de petits sous-ensembles d'utilisateurs et élargi progressivement le déploiement, en surveillant la qualité et les performances tout au long du processus. La première version a passé les tests d'acceptation sans régression de qualité, et nous avons poursuivi le déploiement jusqu'à ce que Photon serve 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 suivantes 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 version d'index.

Photon utilise environ 20 % de machines de service é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. Épingler le même jeu 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 rapide de l'API de recherche

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 au p50 et de 230 ms au p95, inférieure ou comparable aux chiffres auto-déclarés par 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 benchmarks agentiques : WideSearch, BrowseComp, DSQA, FRAMES, SEAL-0 et SEAL-Hard. Parmi ces évaluations, il présentait le coût total estimé du modèle plus 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 agentiques, offrant des performances comparables au préréglage par défaut à un coût nettement inférieur. Cependant, cela implique un compromis sur la 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 benchmarks internes couvrant les requêtes de longue traîne, la couverture large et la diversité des résultats, il obtient 0,24 point de moins sur la pertinence et environ 3 points de pourcentage de moins sur la disponibilité des réponses. Nous pensons qu'il s'agit d'un compromis judicieux pour les flux de travail agentiques, car le propre 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 Fast. 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 bases d'axe différentes et non nulles, de sorte que les hauteurs de barres mettent l'accent sur les écarts plutôt que sur les différences proportionnelles.

Nous recommandons le préréglage rapide pour les tâches agentiques quotidiennes. Pour des questions plus complexes ou ambiguës qui sont moins sensibles au temps, le préréglage par défaut offre une qualité plus robuste, justifiant sa latence et son coût plus élevés.

Conclusion

Nous transférons régulièrement notre pile de recherche sur une infrastructure interne basée sur Rust. Le remplacement du moteur open-source par Photon, notre moteur personnalisé de recherche et de classement, est la dernière étape en date. Photon nous offre un contrôle total sur les représentations des données, la manière dont les lectures sont organisées et la manière dont les nouveaux index sont déployés, nous permettant 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 de récupération et de classement p99 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, donnant à la recherche 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 au p50 et de 230 ms au p95. Sur les six benchmarks agentiques évalués, il a réduit le coût estimé du modèle plus 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 d'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 document plus riches sur le même matériel tout en maintenant une 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://perplexity.coolkeypoint.com/hub/blog/photon}
}