Photon: Construirea unui motor de regăsire și clasare de la zero

Cum formate de date specializate, citirile în lot și separarea construirii indexului de servirea interogărilor îmbunătățesc căutarea nativă pentru AI.

AutoriPerplexity Engineering

Introducere

Stiva de căutare nativă pentru AI a Perplexity preia și clasează paginile candidate, scoate la suprafață cel mai relevant conținut pentru ca modelul să își fundamenteze răspunsurile. Inițial, această etapă rula pe un motor open-source pe care l-am adaptat la sistemul nostru. Cu toate acestea, pe măsură ce indexul și sarcinile noastre de lucru au crescut, am atins limite stricte legate de costuri, latența la coadă și timpul de recuperare a nodurilor, pe care nu le-am putut rezolva în cadrul platformei terțe existente.

Pentru a depăși aceste provocări, am construit Photon, un nou motor intern de regăsire și clasare. Aceasta continuă abordarea noastră de a construi infrastructură de căutare orientată spre AI de la zero, așa cum am făcut cu CobbleDB, stocarea noastră distribuită de cheie-valoare pentru servirea înregistrărilor de pagini, și API-ul de căutare.

Photon folosește formate de date compacte pentru a citi și decodifica doar ceea ce are nevoie fiecare interogare, cu caching conștient de loturi și citiri asincrone pentru a reduce accesul la disc și a suprapune așteptările. Construirea indexului se execută separat de servirea interogărilor, actualizând un singur grup de servire la un moment dat și încălzindu-i cache-urile înainte de a rura interogări live către acesta.

Photon alimentează acum conductei noastre de căutare și reprezintă, de asemenea, fundația unei noi presetări rapide pentru API-ul nostru de căutare, cu o latență a apelului de căutare unică de 160 ms la p50 și 230 ms la p95. În șase benchmarkuri publice, presetarea rapidă a redus costul estimat model-plus-căutare per sarcină cu 68%, menținând în același timp o calitate agregată a sarcinilor comparabilă cu presetarea implicită. O lansăm astăzi pentru ca dezvoltatorii să poată accesa aceste îmbunătățiri.

Latența auto-raportată a apelului de căutare unică. PPLX Fast raportează o latență p50 de 160 ms și o latență p95 de 230 ms. Exa Instant raportează p90, nu p95, pentru valoarea sa de coadă superioară; valorile de coadă superioară ale lui Parallel nu sunt publicate. Percentilele raportate și configurările de măsurare nu reprezintă o comparație controlată de tipul like-for-like.
Calitatea agregată a sarcinilor în funcție de costul total estimat model-plus-căutare pentru aceleași 3.554 de sarcini selectate. Scorurile sunt ponderate în funcție de numărul de sarcini, iar costurile acoperă întregul set de sarcini. PPLX Fast obține 64,3% la 59,73 USD, față de 64,0% la 187,60 USD pentru presetarea implicită PPLX, reprezentând un cost estimat cu aproximativ 68% mai mic pentru același număr de sarcini.

Ce necesită motorul de regăsire și clasare

Pentru fiecare interogare, motorul de regăsire și clasare caută într-un index mare, distribuit, pentru a selecta și comanda un set mic de pagini relevante în limita bugetului de latență a stivei de căutare. De asemenea, sistemul trebuie să mențină indexul la zi pe măsură ce sosesc pagini noi și cele existente se modifică, fără ca această muncă să încetinească interogările live.

Am evaluat mai multe opțiuni open-source și am ales un motor matur de regăsire și clasare de uz general care a răspuns nevoilor noastre inițiale. Apoi l-am adaptat la arhitectura și sarcinile noastre de lucru, menținând latența și debitul stabile la scară de producție.

Unde a eșuat sistemul nostru anterior

Ne-am menținut propriul fork pentru a adapta motorul la indexul nostru în creștere, dar abordarea limitărilor cheie a impus tot mai mult reproiectarea unor mari părți ale platformei. Mai multe constrângeri s-au dovedit greu de rezolvat fără modificări arhitecturale fundamentale:

1. Costuri de scalare. Atât numărul de documente pe care le stocăm, cât și cantitatea de date per document pe care trebuie să le regăsim și să le clasam au crescut în timp. Această scalare a pus presiune pe hardware-ul nostru, în special pe cantitatea de memorie RAM disponibilă. Pentru a ține sub control costurile, am avut nevoie de reprezentări de date mai compacte și de un control mai fin asupra a ceea ce rămâne în memorie și a ceea ce este citit de pe disc la cerere.

2. Latență slabă la coadă. Pe traficul de producție, timpul de răspuns p99 al vechiului sistem era de aproximativ 800 ms. Setul de date depășea memoria RAM disponibilă, așa că nu am putut folosi mlock pentru a-l menține în întregime în memorie. Accesarea datelor non-rezidente putea declanșa defecte majore de pagină, blocând execuția interogărilor în timp ce sistemul de operare citea de pe disc.

De asemenea, motorul își comasa periodic indexul principal de pe disc cu indexuri mai mici eliminate din memorie. În timpul acestui proces de fuziune a indexului de pe disc, numărul defectelor de pagină a crescut și mai mult, latența p99 ajungând la aproximativ 1,2 s timp de 10-15 minute. Pe măsură ce cache-urile se încălzeau, frecvența defectelor de pagină și a latenței au scăzut ambele, sugerând că citirile reci au reprezentat o contribuție majoră la vârfuri. Preîncărcarea datelor și încălzirea indexului au redus vârfurile, dar nu au abordat în mod adecvat latența mare la coadă.

3. Recuperare și sincronizare de lungă durată. În sistemul anterior, implementarea unui cluster suplimentar și sincronizarea datelor sale putea dura mai mult de o săptămână. Sinkronizarea era, de asemenea, necesară atunci când se adăugau grupuri de noduri pentru a deține copii suplimentare de date sau la recuperarea după eșecuri de nod. În timpul recuperării, o pondere mai mare a răspunsurilor de căutare era parțială, ceea ce scădea scorurile calității răspunsului final.

În cele din urmă, am concluzionat că ar fi mai simplu și mai ieftin să construim de la zero decât să continuăm să adaptăm și să menținem bifurcația noastră. Bazându-ne pe experiența noastră în operarea sistemului anterior, o echipă mică de ingineri a lucrat alături de un roi de agenți de programare persistenți pentru a construi Photon.

Unde se integrează Photon în stiva de căutare

Photon este conceput pentru două fluxuri de lucru principale: servirea cererilor de căutare și preluarea actualizărilor din conducta de procesare.

O cerere de la serviciul de căutare de nivel superior ajunge la brokerul Photon prin intermediul unui echilibrator de sarcină. Brokerul selectează un grup de sharduri și redirecționează cererea către fiecare shard, monitorizând expirările de timp și emițând cereri suplimentare atunci când este necesar.

Fiecare shard efectuează regăsirea, clasarea inițială și clasarea de a doua etapă, apoi își returnează cei mai buni candidați către broker. Brokerul combină acești candidați într-o singură listă clasată și preia câmpurile cheie ale documentelor pentru paginile selectate de la shardurile relevante. Apoi returnează aceste rezultate serviciului de căutare de nivel superior, care colectează conținutul paginii necesar agentului pentru a genera un răspuns fundamentat.

Actualizările indexului urmează o cale separată. Pillar, stratul nostru de publicare, pregătește datele și le stochează în tabele YTsaurus. Indexorii convertesc aceste tabele în structuri de index pe care shardurile le pot încărca pentru căutare. Controlorul coordonează pregătirea datelor, construirea indexului și implementarea noilor versiuni de index în grupurile de servire. Înainte de a procesa traficul live, fiecare shard reia interogările de căutare reale pentru a-și încălzi cache-urile.

O interogare trece de la serviciul de căutare de nivel superior prin intermediul echilibratorului de sarcină și al brokerului către un grup de sharduri selectat. Fiecare shard preia și clasează candidații; brokerul comasează rezultatele, preia câmpurile de documente pentru paginile selectate și le returnează serviciului de căutare de nivel superior. Pașii numerați indică ordinea. Săgețile pline transportă cererile, iar săgețile întrerupte transportă rezultatele înapoi. Etichetele de fază din stânga disting selecția candidaților de citirile de sumar.

Proiectarea Photon pentru fluxurile noastre de lucru

Trei alegeri de design fac ca Photon să se potrivească bine cu fluxul nostru de lucru: reprezentări de date compacte, caching și citiri asincrone de pe disc, și separarea actualizărilor de index de servirea interogărilor.

Reprezentări de date pentru regăsire și clasare

Regăsirea și clasarea accesează datele documentelor în mod diferit. Regăsirea lexicală începe cu termenii de interogare și găsește documentele care îi conțin. Clasarea necesită apoi informații detaliate despre fiecare document selectat, inclusiv frecvențele și pozițiile termenilor.

Photon folosește două reprezentări complementare pentru a accepta aceste modele de acces. Un index inversat stochează o listă de documente potrivite pentru fiecare termen, numită listă de postări, pentru a susține selecția candidaților. Înregistrări separate per document furnizează datele necesare pentru clasare. De asemenea, optimizăm modul în care listele de postări sunt stocate și traversate pentru a îmbunătăți selecția sub un buget de lucru fix.

Reprezentările de date specializate ne permit să stocăm date cheie mai eficient. Un index inversat mai compact reduce cantitatea de date citite sau mutate per interogare, îmbunătățind latența prin eliminarea operațiunilor de I/O inutile. Aceste formate fac, de asemenea, posibilă verificarea dacă un document apare într-o listă fără a-l decodifica complet, o proprietate pe care se bazează logica noastră de traversare pentru a controla volumul de muncă al unei interogări sub un buget fix. Optimizarea înregistrărilor per document ne permite să stocăm mai multe date per document pentru clasare, reducând în același timp și costurile de scalare asociate sistemului nostru anterior.

Indexul inversat

Pentru fiecare termen, indexul inversat stochează o listă de postări. Aceste liste pot varia de la câteva documente până la milioane, astfel încât niciun format unic nu funcționează bine pentru fiecare listă. Photon alege formatul în funcție de numărul de documente care conțin termenul.

Listele scurte utilizează o reprezentare în linie care se încadrează într-o singură pagină și nu necesită un tabel de blocuri. Listele mai lungi care nu se încadrează în formatul în linie sunt împărțite în blocuri care acoperă intervale fixe de identificatori de documente. Reprezentarea fiecărui bloc depinde de densitatea sa: blocurile sparse stochează tablouri sortate de offseturi de ID-uri de documente, în timp ce blocurile dense folosesc hărți de biți (bitmaps). Blocurile sparse utilizează căutarea prin salturi (galloping search), care avansează în pași din ce în ce mai mari pentru a sări peste regiuni ale listei. Blocurile dense permit verificări de membru prin căutarea bitului corespunzător unui document.

Frecvența de interogare a unui termen determină locul unde este plasată lista sa de postări pe disc. Listele interogate frecvent sunt stocate aproape una de cealaltă, concentrând datele fierbinți într-o regiune de stocare mai mică. În cadrul fiecărei liste, documentele sunt ordonate după un semnal separat de utilitate, astfel încât candidații mai promițători să fie întâlniți mai devreme.

Photon alege o reprezentare a listei de postări în funcție de lungime și densitatea blocului. Listele scurte se încadrează în linie în cadrul unei pagini. Listele mai lungi sunt împărțite în intervale fixe de ID-uri de documente, cu tablouri de offseturi sortate pentru blocurile sparse și hărți de biți pentru blocurile dense.

Traversarea listelor într-un buget de lucru

Selecția candidaților necesită traversarea listelor de postări pentru a găsi documente potențial relevante. Scanarea exhaustivă a fiecărei liste este costisitoare, așa că Photon utilizează un algoritm de tip WAND care traversează doar unele liste, luând totuși în considerare potrivirile din celelalte.

Algoritmul împarte listele în două grupuri. Listele motoare avansează traversarea și propun documente candidate. Listele de sondă contribuie la scorurile acilor candidați, dar nu generează ele însele candidați.

Scorarea candidaților combină acoperirea ponderată a termenilor de interogare și o contribuție a frecvenței, cu normalizarea lungimii documentului și o limită a câștigurilor din termenii repetați. Photon verifică mai întâi prezența termenilor în tablouri și hărți de biți pentru a limita scorul maxim posibil al fiecărui fișier candidat. Citește frecvențele exacte ale termenilor doar pentru candidații care încă ar putea îndeplini pragul de selecție.

Selecția se desfășoară apoi în trei etape:

  • Traversare: Începeți cu o cerință strictă de acoperire a interogării. Dacă se găsesc prea puțini candidați, repetați cu o cerință relaxată.
  • Retenție: Candidații sunt ținuți într-un set mărginit folosind un scor care combină acoperirea și frecvența. Pe măsură ce primii candidați colectați se îmbunătățesc, pragul de admitere crește.
  • Selecția finală: Rezultatele finale pentru pas sunt alese din setul reținut pe baza scorurilor de frecvență. Fiecare câmp își rulează propriul pas, iar rezultatele sunt comasate folosind ponderile câmpurilor.

Algoritmul produce un set de candidați reprezentând documente relevante care vor fi utilizate în clasarea ulterioară.

Traversare ilustrativă a candidaților mărginiți. Listele motoare propun documente, în timp ce limitele superioare permit ca acești candidați aflati sub pragul curent de admitere să fie tăiați fără a citi liste de sondă sau frecvențe exacte. Pragul crește pe măsură ce setul reținut se îmbunătățește. Scorurile sunt inventate pentru ilustrare, iar candidații reținuți nu reprezintă un top-k exact garantat.

Docblob

După ce paginile candidate sunt selectate, faza de clasare necesită frecvențe ale termenilor, acoperirea câmpurilor și locațiile și proximitatea aparițiilor. Obținerea acestor date prin intermediul indexului inversat ar necesita accesări dispersate în numeroase perechi termen-document. În Photon, stocăm o înregistrare compactă per document numită docblob care conține frecvențele termenilor, câmpurile în care a apărut un termen și unde a apărut în document. Drept urmare, clasarea unui candidat necesită o singură căutare per document.

Formatul este conceput pentru a evita decodificarea mai mult decât este necesar. În cadrul unui docblob, câmpurile sunt grupate după analizorul de text. Fiecare grup stochează o listă de termeni sortată și codificată cu Elias-Fano, astfel încât un termen de interogare să poată fi căutat direct fără a extinde mai întâi întreaga listă. O mască de câmp marchează unde a apărut un termen, un contor de frecvență urmărește frecvența, iar pozițiile reale se află în blocuri separate per pereche termen-câmp, codificate ca diferențe de poziție. Doar blocurile pentru termenii care s-au potrivit efectiv sunt decodificate, în timp ce tot restul înregistrării rămâne în formatul comprimat.

Această decodificare selectivă permite docblob să accepte stocarea mai multor date per document fără o creștere proporțională a costurilor. Creșterea înregistrării nu forțează mai multă muncă per căutare, deoarece clasarea atinge doar piesele relevante pentru termenii potriviți, în loc de întreaga înregistrare.

Un docblob grupează datele de clasare într-o înregistrare compactă per document. Termenii de interogare sunt căutați într-o listă de termeni codificată Elias–Fano; măștile de câmp, frecvențele și blocurile de poziție furnizează datele necesare pentru termenii potriviți, în timp ce termenii irelevanți rămân comprimați. ID-urile termenilor și pozițiile sunt ilustrative.

Citiri în lot și lucrul cu memoria

Chiar și cu reprezentările de date mai eficiente, memoria RAM se epuizează înaintea altor resurse, așa că trebuie să accesăm frecvent datele stocate pe disc. Photon utilizează citiri asincrone de pe disc și un cache optimizat pentru citiri în lot pentru a accelera aceste accesări, reducând timpul de așteptare per cerere. Acest lucru contribuie la o îmbunătățire semnificativă a latenței la coadă în comparație cu sistemul anterior.

Photon verifică un lot de offseturi de înregistrări cunoscute în cache-ul său înainte de a emite citiri de pe disc. Hiturile din cache sunt copiate într-un buffer pregătit; missurile sunt trimise prin io_uring astfel încât așteptările pe disc să se poată suprapune, iar datele returnate populează cache-ul. Înregistrările și cronologiile sunt schematice, nu latențe măsurate.

Suprapunerea așteptărilor pe disc

Clasarea necesită obținerea caracteristicilor a o sută de documente situate în diferite părți ale unui fișier. Sistemul nostru anterior a folosit mmap pentru a mapa fișierul în spațiul de adrese virtual, astfel încât să poată fi citit prin pointeri de memorie. Cu toate acestea, accesarea unei pagini care lipsea din memorie necesita în continuare o citire de pe disc. Firul trebuia să aștepte datele înainte de a continua calculul, iar acest timp de așteptare se aduna atunci când procesul trebuia să citească înregistrări reci în mod secvențial.

Photon profită de faptul că offseturile înregistrărilor sunt cunoscute în avans, astfel încât putem trimite mai multe operațiuni de citire dintr-o dată. Acest proces este gestionat de reactor: fire dedicate trimit loturi prin io_uring și transmit datele citite codului apelant. Fiecare fir își menține propriul io_uring; loturile sunt trimise către reactorul cel mai puțin încărcat. Descriptorii de fișiere preînregistrați și pool-urile de buffere reduc suprasolicitarea citirilor repetate. Această execuție asincronă permite suprapunerea așteptărilor pentru mai multe operațiuni, reducând latența la coadă.

Reducerea numărului de accesări ale unității de disc

Înainte de a trimite citirile, Photon verifică întregul lot în cache-ul din memorie. Doar cererile pentru înregistrările lipsă merg pe disc; datele citite populează apoi cache-ul.

Cache-ul este conceput pentru citiri în lot. Mai exact:

  • Nu există o alocare separată la un hit. În schimb, datele sunt copiate într-un buffer pregătit în avans de codul apelant.
  • Nu există o achiziție de blocare de către cititor. În schimb, acesta verifică versiunea datelor și reîncearcă dacă intră în conflict cu o scriere.
  • Folosește eliminarea CLOCK, în loc să necesite actualizări la o listă LRU partajată la fiecare citire.
  • Folosește preluarea anticipată în cache-ul CPU, unde metadatele și datele pentru înregistrările viitoare sunt solicitate în avans.

Aceste optimizări scad latența fără a afecta performanța pe sarcinile de lucru care ne interesează.

Construirea și actualizarea indexului separat de servire

În Photon, construirea indexului și servirea interogărilor rulează pe noduri diferite. Indexorii transformă datele în structuri de stocare gata de utilizare, în timp ce nodurile de servire le citesc și efectuează regăsirea și clasarea. Drept urmare, construirea indexului nu concurează cu interogările de căutare pentru CPU, iar resursele pentru aceste sarcini pot fi scalate independent.

Această separare abordează blocajele de recuperare și sincronizare prezente în implementarea anterioară. Deoarece construirea indexului rula în același cluster care servea interogări, recuperarea unui nod eșuat sau adăugarea unei noi copii a datelor putea însemna reindexarea documentelor pe loc, un proces care dura zile și creștea răspunsurile parțiale în timpul recuperării. Photon elimină această cuplare; indexorii rulează ca joburi distribuite care produc structuri de index versionate, gata de servit, independent de nodurile de servire, astfel încât construirea următoarei versiuni a indexului nu mai concurează cu traficul live.

Construirea indexului se execută separat de servirea interogărilor live. Pillar exportă datele sursă, YTsaurus pregătește tabele versionate per shard, iar indexorii paraleli scriu structuri de index gata de servit în stocarea de obiecte. Nodurile de servire încarcă acele structuri pentru regăsire și clasare; concurența indexorului și numărul de sharduri sunt configurate independent.

Pregătire și construire distribuită

O compilare începe prin selectarea documentelor pentru indexul activ și producerea exportului sursă. Controlorul înregistrează versiunea sursă, tabelele de intrare și numărul așteptat de sharduri. Joburile MapReduce din YTsaurus pregătesc textul, metadatele, fragmentele, caracteristicile și încorporările precalculate în tabele versionate partiționate pe shard. Fiecare indexor transmite fluxul tabelului pregătit, construiește structurile pentru shardul său și comasează segmentele de text. Indexul pregătit, împreună cu o descriere a componentelor sale, este încărcat în stocarea de obiecte.

Numărul de sharduri și numărul de indexori care rulează concomitent sunt configurate independent, astfel încât o compilare poate rula în mai multe valuri sau se pot aloca mai multe mașini pentru a lucra în paralel. Pregătirea distribuită și indexorii paraleli permit construirea întregului index web într-un număr de ore de o singură cifră, o îmbunătățire semnificativă față de sistemul anterior.

Implementarea unei noi versiuni

Înainte de implementare, controlorul verifică dacă noul index este gata. Dacă datele sunt incomplete, implementarea este blocată automat.

Atunci când există mai multe grupuri de servire, controlorul le actualizează pe rând. Mai întâi elimină un grup din rutarea brokerului și îl pornește pe noua versiune de index. Înainte de a servi cererile, shardurile trec printr-o etapă separată de încălzire bazată pe jurnalele de căutare, care prepopulează starea inițială și face ca tranziția către traficul real să fie mai lină. După încălzire, controlorul verifică starea indexului și disponibilitatea, apoi readuce grupul în rutare. Celelalte grupuri continuă să servească cererile în acest timp. Deoarece starea operațională este persistată, o repornire nu forțează reluarea unei compilări de la zero; controlorul se poate reatașa la o pregătire deja în curs, poate reutiliza un rezultat pregătit sau poate continua o rotație întreruptă de la pasul salvat.

Timpii de actualizare a datelor difere între verticalele de căutare. Pentru verticalele cu cerințe ridicate de prospețime, livrarea documentelor durează un număr de minute de o singură cifră. O copie suplimentară a datelor poate fi implementată în aproximativ o jumătate de oră; indexurile pregătite sunt încărcate și atașate la sharduri fără a reindexa documentele sursă.

Controlorul verifică dacă un nou index este complet, apoi rotește câte un grup de servire pe rând. Un grup părăsește rutarea brokerului, încarcă noua versiune, își încălzește cache-urile cu interogări din jurnalele de căutare și trece de verificările de disponibilitate înainte de a reveni în trafic. Celelalte grupuri continuă să servească, iar starea persistată a controlorului permite reluarea unei rotații întrerupte.

Migrare și validare în cadrul stivei noastre de căutare

Primul nostru obiectiv a fost să înlocuim vechiul sistem cu un motor care a păstrat funcționalitatea și calitatea căutării, reducând în același timp timpii de răspuns. Am validat Photon în etape, începând cu teste de sarcină reproducibile și evaluări de calitate offline înainte de a trece la traficul live. Photon alimentează acum regăsirea și clasarea în stiva noastră de căutare de producție, având timpi de răspuns considerabil mai mici decât vechiul sistem.

Testarea sarcinii și evaluări

Pentru testarea performanței, am construit o unealtă de testare a sarcinii care reia interogări din jurnalele noastre de căutare la rate de sosire configurabile. Aceasta compară rezultatele între rulări și aplică teste statistice pentru a evalua dacă diferențele de performanță observate sunt consistente. Separat, am evaluat Photon și sistemul vechi pe aceleași seturi de date în sistemele noastre interne de evaluare offline pentru a verifica dacă există regrese de calitate.

După aceste verificări, am trimis interogări live către ambele motoare simultan, folosind trafic de umbră. Acest lucru ne-a permis să le comparăm performanța și rezultatele pe sarcinile de lucru de producție înainte de a schimba motorul care deservea utilizatorii. Apoi am activat Photon pentru subseturi mici de utilizatori și am extins treptat implementarea, monitorizând calitatea și performanța pe parcurs. Prima versiune a trecut testarea de acceptare fără regrese de calitate și am continuat implementarea până când Photon a servit tot traficul de producție.

Îmbunătățiri măsurate în producție

În fluxul nostru de lucru de producție, timpul de răspuns p99 a scăzut de la aproximativ 800 ms în sistemul vechi la aproximativ 65 ms în Photon. Această măsurătoare acoperă toate etapele din interiorul Photon, dar exclude etapele ulterioare din stiva de căutare de nivel superior. De asemenea, nu mai observăm vârfurile de latență asociate anterior cu comutarea versiunilor de index.

Photon folosește cu aproximativ 20% mai puține mașini de servire echivalente decât nodurile de conținut ale vechiului sistem, stocând în același timp de aproximativ 2,5 ori mai multe date per document. După migrare, am folosit aceste date suplimentare pentru a îmbunătăți calitatea clasării dincolo de cea a vechiului sistem.

Photon reduce, de asemenea, volumul de date care trebuie să rămână în memorie. Fixarea aceluiași set de date Photon în memoria RAM cu mlock ar necesita aproximativ de 4,6 ori mai multă memorie rezidentă decât utilizează în prezent Photon.

Evaluarea presetării rapide a API-ului de căutare

De asemenea, am folosit Photon ca bază pentru o nouă presetare rapidă pentru API-ul nostru de căutare, concepută pentru sarcini de lucru sensibile la latență. Conform măsurătorilor noastre, latența unui singur apel de căutare pentru presetarea rapidă este de 160 ms la p50 și 230 ms la p95, fiind mai mică sau comparabilă cu cifrele auto-raportate de alți furnizori de API-uri de căutare, deși percentilele de coadă raportate difere.

Am evaluat presetarea rapidă pe șase benchmarkuri bazate pe agenți: WideSearch, BrowseComp, DSQA, FRAMES, SEAL-0 și SEAL-Hard. În cadrul acestor evaluări, a înregistrat cel mai mic cost total estimat model-plus-căutare și cel mai ridicat scor agregat al sarcinilor dintre configurațiile testate.

Presetarea rapidă asociază Photon cu o clasare optimizată pentru fluxurile de lucru de tip agentic, oferind performanțe comparabile cu presetarea implicită la un cost substanțial mai mic. Totuși, aceasta vine cu un compromis în ceea ce privește calitatea generală a căutării. Presetarea rapidă utilizează mai puțină putere de calcul pentru clasare decât presetarea implicită. Pe benchmarkurile interne care acoperă interogări cu coadă lungă, acoperire largă și diversitate a rezultatelor, obține un scor cu 0,24 puncte mai mic la relevanță și cu aproximativ 3 puncte procentuale mai mic la disponibilitatea răspunsurilor. Considerăm că acesta este un compromis rezonabil pentru fluxurile de lucru bazate pe agenți, deoarece propriul raționament și cunoștințele modelului pot ajuta la compensarea diferenței.

Comparație internă a calității regăsirii între presetarea implicită PPLX și PPLX Fast. Relevanța (DCG) scade de la 2,45 la 2,21, o scădere de 0,24 puncte; disponibilitatea răspunsurilor scade de la 0,596 la 0,567, o scădere de 2,9 puncte procentuale. Cele două panouri utilizează linii de bază diferite, nenule, pentru axe, astfel încât înălțimile barelor subliniază decalajele mai degrabă decât diferențele proporționale.

Recomandăm presetarea rapidă pentru sarcinile agentice de zi cu zi. Pentru întrebări mai dificile sau ambigue, care sunt mai puțin sensibile la timp, presetarea implicită oferă o calitate mai robustă, justificând latența și costul mai ridicate.

Concluzie

Ne mutăm constant stiva de căutare pe o infrastructură internă bazată pe Rust. Înlocuirea motorului open-source cu Photon, motorul nostru personalizat de regăsire și clasare, este cel mai recent pas. Photon ne oferă control total asupra reprezentărilor datelor, a modului în care sunt organizate citirile și a modului în care sunt implementate noile indexuri, permițându-ne să optimizăm fiecare strat pentru sarcinile noastre de lucru.

Photon a făcut posibilă o căutare mai rapidă în cadrul produselor Perplexity și oferă fundația pentru noua noastră presetare rapidă din API-ul de căutare. În urma migrării, latența p99 pentru regăsire și clasare a scăzut de la aproximativ 800 ms la 65 ms. Formatele noastre de date compacte ne permit, de asemenea, să stocăm de 2,5 ori mai multe date per document, oferind regăsirii și clasării acces la informații mai bogate despre documente.

Presetarea rapidă oferă o latență de apel de căutare unică de 160 ms la p50 și 230 ms la p95. De-a lungul celor șase benchmarkuri bazate pe agenți evaluate, a redus costul estimat model-plus-căutare per sarcină cu 68% față de presetarea implicită, menținând în același timp o calitate agregată comparabilă a sarcinilor. Aceste rezultate demonstrează beneficiile practice ale infrastructurii proiectate în jurul sarcinilor noastre de căutare, atât pentru produsele Perplexity, cât și pentru dezvoltatorii care construiesc cu API-ul nostru.

Continuăm să îmbunătățim performanța și eficiența stocării pentru Photon. Scopul nostru este să acceptăm un index mai mare și date de documente mai bogate pe același hardware, menținând în același timp o căutare rapidă pe măsură ce sarcinile noastre de lucru cresc.

Citare

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}
}