Paieškos pergalvojimas kaip kodo generavimas
Paieškos evoliucija nuo monolitinių paslaugų iki programuojamų primityvų agentų mechanizmų eroje.
Paieška yra pagrindinė dirbtinio intelekto sistemų funkcija. Pažangieji modeliai kas mėnesį tampa pajėgesni, tačiau jiems vis tiek reikia prieigos prie naujų, tikslių ir puikiai sutvarkytų žinių iš platesnio pasaulio. Paieška yra pagrindinis būdas, kuriuo dirbtinio intelekto sistemos naudojasi šiomis žinėmis, todėl ji yra pamatinis bet kurio produkto, turinčio daryti išvadas, imtis veiksmų ir atlikti realaus pasaulio darbus, komponentas.
Tikime, kad tradicinės paieškos darbo eigos agentų eroje vis labiau sensta. Tradicinė paieška atsako į užklausas, tačiau šiandieniniai agentai atlieka užduotis, galinčias įgauti nesuskaičiuojamą daugybę pavidalų. Šios užduotys reikalauja, kad agentai tiesiogiai savo mechanizmuose apibrėžtų užduotims specifines paieškos strategijas. „Perplexity Computer“ sistemoje matėme, kaip pavienės užduotys per kelias minutes iškviečia šimtus ar net tūkstančius paieškos operacijų: tai darbo eiga, kuri yra neįmanoma žmonėms, bet visiškai natūrali agentams.
Šiame pasaulyje pati paieška turi tapti orientuota į agentus, o jos statybiniai blokai turi būti priekybje tiesiogiai kaip SDK agento mechanizme. Pristatome „Search as Code“ (SaC) kaip naująją „Perplexity“ etaloninę paieškos architektūrą.
Įvadas
„Perplexity“ paieškos steke kas sekundę apdorojama tūkstančiai užklausų mūsų programėlėse ir API platformoje. 2025 m. rugsėjį paskelbėme pirmąją architektūrinę mūsų paieškos sistemų apžvalgą. Nuolatinės naujovės šiose sistemose padėjo pradėti tokių naujų pasiūlymų kaip „Search API“, „Agent API“ ir Computer paleidimą, o savęs tobulinimo ciklai optimizuoja paieškos steką, kad kasdien vis geriau aptarnautų vartotojus.
Tradiciniuose dirbtinio intelekto sistemose paieška tradiciškai laikyta monolitu: dirbtinio intelekto modelis pateikia užklausą, paieškos variklis vykdo iš anksto apibrėžtą eigą, o modelis suvartoja rezultatus kaip kontekstą. Didžiąja dalimi tai gerai tiko ankstyvųjų dirbtinio intelekto vartotojų poreikiams patenkinti. Atsižvelgiant į santykinį jų užklausų paprastumą, nebuvo priežasties nerimauti dėl to, kaip tiksliai suprojektuota paieškos eiga ar ar eigos architektūra buvo optimali nagrinėtai užduočiai. Buvo manoma, kad numatytieji nustatymai yra pakankamai geri, kaip ir numatytosios sąsajos (funkcijų iškvietimas ir MCP).
Tačiau šiandien šis požiūris su kiekvienu mėnesiu darosi vis labiau pasenęs. Vartotojai iš dirbtinio intelekto reikalauja kur kas daugiau nei vienkartinės analizės. Jie tikisi, kad agentai užduotis atliks nuo pradžios iki galo per kelias valandas ar net dienas. Šios užduotys gali būti sudėtingos, atviro pobūdžio ir labai kintančių informacijos poreikių, o monolitinės architektūros lūžta po šių reikalavimų svoriu.
Pagrindinė kliūtis galiausiai yra valdymas. Pažangieji modeliai jau dabar gana gerai geba mąstyti remdamiesi fiksuotu kontekstu. Tačiau galingiausioms dirbtinio intelekto sistemoms reikės galimybės valdyti tai, kaip šis kontekstas gaunamas, apdorojamas, agreguojantis ir atvaizduojamas modeliui.
Tradicinės paieškos sistemos nebuvo sukurtos galvojant apie tokį valdomumo laipsnį. Galiausiai, negalima tikėtis, kad žmonės vartotojai vykdys smulkmenišką paieškos eigos vidinių procesų valdymą, net jei tai būtų siūloma. Ankstyvieji dirbtinio intelekto modeliai paiešką gali valdyti tik per linijinę funkcijų iškvietimų ir MCP trajektoriją. Tačiau šių dienų pažangieji modeliai, valdomi kodą palaikančių agentų mechanizmų, gali atlikti smulkmenišką bet kokių įsivaizduojamų skaičiavimo primityvų valdymą pasitelkdami kompiuterinį kodą. Mūsų užduotis tampa pateikti tinkamus primityvus.
Siekdami patenkinti šį poreikį, visuose savo produktuose pristatome naują paieškos architektūrą: „Search as Code“ (SaC). Ši nauja architektūra įgalina modelius patekti į paieškos steką, o ne tik suvartoti jo galutinius rezultatus. Pagrindinė idėja yra nesudėtinga: mes pateikiame paieškos steko komponentus kaip primityvus SDK viduje. Bet kokiai užklausai, kuriai reikia paieškos, modelis pagal poreikį surenka šiuos primityvus į paieškos eigą, pritaikytą tai konkrečiai užklausai.
Ši eiga surenkama generuojant ir vykdant kodą saugioje sandbox aplinkoje. Skirtingai nuo kitų kodų generavimu pagrįstų paieškos būdų, mes tiesiog neįkeliame tradicinės paieškos API į apvalkalą ar kalbos vykdymo aplinką. Vietoj to mes kruopščiai sukūrėme agentinės paieškos SDK, kuri atskirus paieškos statybinius blokus atskleidžia atomiškiausiu įmanomu lygiu.
Apsiginklavęs šiais statybiniais blokais, SaC suteikia modeliams tiesioginį kiekvieno atskiro paieškos žingsnio valdymą: paiešką, rikiavimą, filtravimą, iššakojimą, atvaizdavimą ir kt. Tai taip pat suteikia modeliui veiksmingą prieigą prie tarpinių būsenų, tokių kaip kandidatų sąrašai ir rikiavimo signalai. Kartu šie du valdymo ir skaitomumo svertai leidžia agentams kurti individualias paieškos eigas, apimančias tūkstančius paieškos operacijų, optimizuoti šias eigas jų eigos metu ir suvartoti tik naudingiausią informaciją kaip modelio kontekstą.
Šiame straipsnyje aprašoma SaC motyvacija, dizainas ir diegimas bei empiriniai rezultatai tiek esamuose, tiek naujuose etaloniniuose testuose. SaC nustato naują kainos ir našumo ribą agentinei paieškai, ir mes džiaugiamės galėdami ja pasidalinti su savo vartotojais bei platesne dirbtinio intelekto bendruomene.
Tradicinės paieškos nelankstumas
Pasaulyje pirmieji paieškos varikliai buvo sukurti žmonėms vartotojams. Šie vartotojai įprato gauti nuspėjamą patirtį, paprastai susidedančią iš fiksuoto pagal svarbą suorganizuotų dokumentų skaičiaus. Vartotojai nenorėjo mikromenedžuoti paieškos proceso; jie norėjo įvesti užklausą ir rasti naudingą rezultatą.
Dėl to į žmones orientuoti paieškos varikliai susitelkė ties bendra monolitine architektūra, skirta kurti žmogui patogius paieškos variklio rezultatų puslapius (SERP), kuriuose pateikiami geriausi įvesties užklausos rezultatai. Šis šablonas lemia dešimtmečius trunkantį pažangos vartotojų paieškoje procesą. Jis yra greitas, pažįstamas ir labai veiksmingas naršant žmonėms.
Tada pasirodė didieji kalbos modeliai (LLM), ir dirbtinio intelekto sistemos taip pat tapo paieškos vartotojomis. „Perplexity“ pradininkė šį poslinkį padarė 2022 m., paleisdama mūsų atsakymų variklį. Nuo tada mūsų paieškos inžinerinės pastangos buvo nukreiptos į tai, kaip optimizuoti paieškos rezultatų vertę dirbtinio intelekto modeliams. Kad sukurtume pasaulyje tiksliausią ir patikimiausią dirbtinį intelektą, turėjome suprojektuoti paieškos sistemą, kurioje daugiausia dėmesio skiriama tam, kad kiekvienas žetonas būtų kuo tankesnis informacijos prasme. Dėl to atsiradusios naujovės subdokumentų paieškos, konteksto efektyvumo, semantinio supratimo ir kitose pagrindinėse srityse lėmė didžiulį dirbtinio intelekto sistemų gebėjimo gauti informaciją ir veikti pagal ją pagerėjimą.
Tačiau net ir dirbtinio intelekto optimizuotos sistemos iš esmės paveldėjo tą pačią fundamentalią sutartį kaip ir tradicinės paieškos varikliai: priimti užklausą, paleisti iš anksto apibrėžtą paieškos eigą, grąžinti visiškai apdorotą rezultatų rinkinį. Paprastoms užklausoms šis požiūris veikia puikiai. Tačiau sudėtingesnėms užklausoms tai tampa vis labiau ribojančia kliūtimi, kuri pablogina našumą, delsą ir kainą.
Nelankstumo sukeltos triktys
Tradicinės paieškos eigos sukurtos aplink vieną valdymo tašką: užklausos parametrus. Paieškos variklis valdo likusią eigos dalį pagal savo iš anksto apibrėžtą logicą, o modelis turi prie jos prisitaikyti. Modeliui viskas, kas yra už užklausos parametrų, yra nelanksti – tikrojo skaičiavimo forma yra už modelio kontrolės ribų.
Tai yra suprantama riba, kai vartotojas yra nuorodas skenuojantis žmogus. Tai prasta riba, kai vartotojas yra dirbtinio intelekto modelis, bandantis išspręsti žinių reikalaujančias užduotis uždaroje cikle. Mūsų patirtimi, šis nelankstumas sukelia tris pasikartojančius trikčių režimus:
Stambus kontekstas. Dirbtinio intelekto modeliai yra jautrūs konteksto kokybei ir kompaktiškumui. Tiek kokybė, tiek kompaktiškumas labai priklauso nuo užklausos, o monolitinės paieškos eigos nėra suprojektuotos taip, kad veiktų optimaliai atlikdamos visas užklausas. Pavyzdžiui, jei modeliui reikia vienos, labai tikslios informacijos dalies, bet jis turi prieigą tik prie tiesioginio paieškos galinio punkto, kuriame pirmenybė teikiama informacijos atgavimui, šio galinio punkto naudojimas į modelio kontekstą įtrauks daug nesusijusios informacijos. Kita vertus, jei modeliui reikia daug informacijos dalių, kurių kiekvienai reikia skirtingų paieškos strategijų, jis gali būti priverstas nuosekliai iškviesti tą pačią neoptimalią eigą visoms joms, todėl išlaidos išaugs ir atsiras triukšmingas kontekstas.
Nepavyksta pasinaudoti domeno žiniomis. Daugeliu atvejų modelis gali turėti domeno žinių (iš savo mokymo, Agent Skill, atminties arba ankstesnių žetonų LLM trajektorijoje), kurios turėtų vadovauti paieškos strategijai. Tačiau nelanksti paieškos sąsaja neleidžia modeliui pasinaudoti šiomis žiniomis. Pavyzdžiui, modelis tam tikrai užklausai gali suprasti, kad turėtų tam tikru būdu suderinti leksinius ir semantinius signalus, teikti pirmenybę tam tikriems šaltiniams arba agreguoti rezultatus pagal konkretų raktą. Jei šios įžvalgos nėra įgyvendinamos per užklausos parametrus, modelis negali jomis remtis.
Neveiksmingas valdymo srautas ir konteksto tarša. Daugelis paieškos darbo eigų nėra natūraliai nuoseklios. Joms gali reikėti išsišakojimų per užklausų variantus, lygiagrečio duomenų gavimo, dubliavimo šalinimo ir kitų operacijų, reikalaujančių nelinijinio ir asynchrone valdymo srauto. Šių veiksmų primygtinis atlikimas per pakartotinius modelio žingsnius prideda delsos ir apsunkina darbo eigos optimizavimą. Tai taip pat teršia modelio kontekstą triukšminga tarpine būsena, kuri gali būti naudinga modeliui mąstant, todėl pablogėja našumas ir dažniau atliekami sutankinimai.
Nebuvo daug galima padaryti dėl šių iššūkių funkcijų iškvietimo ir MCP eroje dirbtiniame intelekte. Kai kiekvienai paieškos operacijai reikalingas savarankiškas apsisukimas į LLM išvadą, kūrėjai natūraliai renkasi atlikti kuo daugiau darbų per tą vieną apsisukimą. Tai reiškia paieškos nuo pradžios iki galo eigas, kurios grąžina visiškai apdorotus rezultatų rinkinius, kad juos tiesiogiai vartotų modelis.
Dėl to dauguma į dirbtinį intelektą orientuotų paieškos sistemų šiandien vis dar veikia pagal šią monolitinę sutartį. Tačiau nuolat augant modelio intelektui ir vartotojų poreikiams, šios sutarties trūkumai tampa ryškesni. Šių dienų pažangiausios dirbtinio intelekto sistemos, sukurtos ant pirmiausia kodą naudojančių mechanizmų, gali kurti užduotims specifines darbo eigas, kurios kiekvieną minutę atlieka tūkstančius veiksmų. Paieškos sistemos dar turi visiškai realizuoti šį potencialą.
Jau seniai įtarėme, kad tinkama riba į dirbtinį intelektą orientuotai paieškai yra žemiau steke. Modeliai turėtų ne tik iškviesti paieškos variklį. Jie turėtų gebėti valdyti atskiras paieškos steko dalis taip, kaip to reikalauja konkreti užduotis. Tam reikalinga visiškai kitokia architektūra.
Programuojamos paieškos architektūros kūrimas
Kita paieškos architektūrų karta remsis pagrindiniu principu: paieška turėtų būti iš prigimties programuojama dirbtinio intelekto agentų. Agentas negali apsiriboti iš anksto nustatytais paieškos srautais. Priešingai, agentas privalo sugebėti sukonstruoti konkrečiai užduočiai reikalingą eigą, naudodamas sukomponuojamus statybinius blokus, sukurtus įvairiuose abstrakcijos lygiuose.
Mūsų naujoji „Search as Code“ (SaC) architektūra įkūnija šį principą. Naudojant SaC, nė viena paieškos operacija nėra išsiunčiama per funkcijos iškvietimo ar MCP sąsają. Vietoj to visos operacijos yra orkestruojamos per modelio sugeneruotą „Python“ kodą. Paprasčiausiems paieškos poreikiams šį kodą gali sudaryti keletas užklausų į aukšto lygio paieškos galinį punktą. Tačiau sudėtingoms užduotims kodas gali būti toks sudėtingas, kiek reikia, apimantis sąlyginį vykdymą, asinchroniškumą, lygiagretumą ir iškvietimus į daugybę žemo lygio primityvų.
SaC apima tris glaudžiai susietus sluoksnius:
Modeliai tarnauja kaip valdymo plokštuma. Jie apsvarsto vartotojo (arba pagrindinio agento) nurodymą, suskaido nurodymą į užduotis, nusprendžia, kokių paieškos ir apdorojimo eigų reikia kiekvienai užduočiai, ir sugeneruoja kodą šioms eigoms įgyvendinti.
Skaičiavimo sandbox aplinkos užtikrina deterministinius skaičiavimus per saugią kodo vykdymo aplinką. Jos suteikia pagrindą modeliams įgyvendinti valdymo srautą, pakavimą, pakartotinius bandymus, filtravimą, sujungimą, agregavimą ir kitas deterministines operacijas.
Mūsų agentinės paieškos SDK atskleidžia „Perplexity“ paieškos steką kaip sukomponuojamus primityvus. Ji suteikia statybinių blokų nuo žemo lygio paieškos operacijų iki aukšto lygio semantinio analizavimo. SDK yra įterpta į sandbox aplinkų vykdymo aplinkas, todėl modeliai gali organizuoti iki tūkstančių operacijų vieno išvedimo žingsnio metu. Žemiau aptariame savo dizaino sprendimus kiekvienam sluoksniui.
Agentinės paieškos SDK
Agentinės paieškos SDK apibrėžia programuojamos paieškos statybinius blokus. Svarbu tai, kad mūsų SDK nėra iš anksto egzistuojanti paieškos API, supakuota kaip biblioteka. Per pastaruosius kelis mėnesius mūsų inžinierių komandos pertvarkė mūsų paieškos steką į modulinius, sukomponuojamus primityvus. Sukūrėme agentinės paieškos SDK, kad suteiktume tiesioginę prieigą prie šių primityvų, sukurdami kur kas galingesnę erdvę, kurioje modelis gali organizuoti užduočiai specifines paieškos eigas.
Aukšto lygio paieškos nuo pradžios iki galo eigos vis dar pasiekiamos SDK viduje, tačiau jos nebėra vienintelis pasirinkimas. Vietoj to jos tarnauja kaip tam tikra santrumpa įprastiems paieškos šabloniams. Modelis gali laisvai jas naudoti arba apeiti, kaip to reikalauja užduotis.
Vykdymo aplinkos pasirinkimas: Kaip SDK vykdymo aplinką svarstėme „Python“, „Rust“, „TypeScript“ ir „Bash“. Įtarėme, kad „Python“ bus tinkamiausias pasirinkimas dėl jo paplitimo ir duomenų apdorojimo bibliotekų ekosistemos. Vidiniai bandymai tai patvirtino, o šiandien pristatoma SDK versija yra sukurta „Python“ pagrindu. Tikimės periodiškai iš naujo įvertinti vykdymo aplinkos pasirinkimą, kad užtikrintume, jog ji ir toliau suteikia geriausią agento patirtį.
Nuolatinis tobulinimas naudojant automatinį tyrimą: Taip pat optimizavome SDK pritaikomumą pažangiems LLM per kartotinio automatinio tyrimo ciklą. Šis ciklas, nuolat veikiantis kelias savaites, siūlo ir tikrina SDK patobulinimus pagal metrikas, įskaitant delsą, kodo generavimo kokybę ir bendrą užduoties našumą. Automatinio tyrimo ciklas jau atliko daugybę pakeitimų tiek SDK struktūrai, tiek estetikai, pasiekdamas reikšmingų laimėjimų visose dimensijose. Planuojame ir toliau tobulinti SDK per automatinį tyrimą, kai atsiras nauji pažangieji modeliai ir paieškos komponentai.
Sandbox aplinkos
Sandbox aplinkos užtikrina saugias terpes SaC eigoms apibrėžti ir vykdyti. Jos vykdo modelio sugeneruotą kodą, suteikdamos prieigą prie agentinės paieškos SDK, kad būtų lengviau bendrauti su atskirais paieškos primityvais.
Investavome reikšmingas lėšas į mūsų sandbox aplinkų optimizavimą ir apsaugą, o jų bendra sisteminė architektūra nusipelno atskiro straipsnio. Čia pagrindinį dėmesį skiriame SaC aktualiausiam projektavimo aspektui: tarpinių būsenų valdymui.
SaC įgalina agentus organizuoti sudėtingas eigas vieno išvedimo žingsnio metu. Tačiau tam tikras tarpines būsenas reikia perduoti per skirtingus žingsnius. Pavyzdžiui, modelis gali norėti gauti kai kuriuos dokumentus 1 žingsnyje, patikrinti tų dokumentų dalinę imtį 2 žingsnyje, kad nuspręstų, ką daryti toliau, o tada sukurti tolimesnę paieškos eigą, kad toliau tirtų tuos dokumentus nuo 3 žingsnio. Kaip aptarta aukščiau, tarpinių būsenų perdavimas per žetonų erdvę nėra efektyvi strategija.
Apsvarstėme du tarpinių būsenų valdymui per skirtingus žingsnius skirtus būdus:
Nuolatinė failų sistema + aiškus serde: Sandbox aplinkos gali atskleisti nuolatines failų sistemas, kurias modeliai gali naudoti per skirtingus žingsnius. Modeliai, norintys išsaugoti tarpinę būseną, gali įtraukti serializavimo etapą į generuojamą kodo žingsnį kartu su deserializavimo etapu vėlesniame žingsnyje (arba pačių modelių patikrai, arba tolimesniam naudojimui). Failų sistemos būdas leidžia modeliams tiesiogiai ir aiškiai valdyti, kaip tarpinė būsena perduodama per žingsnius. Tai taip pat užtikrina atsekamumą užtikrinant aiškų informacijos, kurią naudoja modelis, identifikavimą ir išsaugojimą. Vienas trūkumas yra delsa ir konteksto sąnaudos, atsirandančios generuojant serde kodą, nors gerai suprojektuotos pagalbinės funkcijos gali sušvelninti šias sąnaudas.
REPL: Arba sandbox aplinka gali išsaugoti pačią vykdymo aplinką per skirtingus žingsnius REPL stiliaus aplinkoje. Tai leidžia modeliams palaikyti tarpinę būseną atmintyje, visai jos neserializuojant, kadangi ankstesniuose žingsniuose apibrėžti ar pakeisti kintamieji vėlesniuose žingsniuose gali būti tiesiog nurodomi vardu. REPL būdas yra efektyvesnis žetonų atžvilgiu, nes jame nereikia generuoti serde kodo. Tačiau aiškaus serializavimo etapo nebuvimas gali pakenkti tolimesniam našumui dėl priežasčių, kurios pažįstamos visiems, dirbusiems su 100 langelių „Jupyter“ užrašu: kintamųjų vardų sričiai tampant netvarkingai, tampa sunkiau sekti, kas tiksliai yra išsaugoma per žingsnius ir kodėl.
Išbandėme abu būdus ir nustatėme, kad nors įprasto naudojimo metu jų veikimas yra panašus, failų sistema pagrįstas serde užtikrina geresnį patikimumą ypač ilgose trajektorijose. Todėl kaip savo sprendimą priimame failų sistema pagrįstą serde. Darome prielaidą, kad reikalavimas, jog modeliai perduotų būseną deklaratyviai, o ne netiesiogiai, padeda jiems efektyviau valdyti šią būseną. Tai yra preliminari išvada, ir mes ir toliau tobulinsime abu būdus.
Modeliai
Agentų mechanizmus palaikantys modeliai tarnauja kaip SaC valdymo plokštuma: dinamiškai surenka paieškos eigas iš agentinės paieškos SDK statybinių blokų, kad atitiktų kiekvienos užduoties poreikius, o tada išsiunčia šias eigas kaip kodą, skirtą vykdymui sandbox aplinkoje.
„Perplexity“ savo agentų mechanizmuose naudoja įvairius modelius ir nustatėme, kad naujausi pažangieji modeliai yra gana veiksmingi visose srityse, atliekant bendros paskirties kodo generavimą. Pagrindinis iššūkis – paskatinti veiksmingą kodo generavimą būtent agentinės paieškos SDK. Tai yra, kaip galime priversti modelius veiksmingai sujungti mūsų SDK statybinius blokus į užduotiai optimizuotas eigas?
Skirtingai nuo kalbos standartinės bibliotekos, pasirinktinis SDK vargu ar bus atvaizduotas išankstinio mokymo duomenyse. Net ir patobulinus SDK pritaikomumą atliekant automatinį tyrimą, daugelis modelių vis tiek yra apmokyti sąveikauti su paieškos sistemomis per funkcijų iškvietimus ir tiesioginį MCP iškvietimą. Mažai tikėtina, kad šie modeliai eksperto lygiu valdytų SDK naudodami vien tik pirminį kodą ir automatiškai sugeneruotus dokumentus.
Siekdami išspręsti šį iššūkį, sukūrėme puikiai pritaikytus Agent Skills, kad išmokytume modelius veiksmingai išnaudoti mūsų SDK. Pirminės versijos buvo sukurtos pagal „Perplexity“ Skill projektavimo principus, o vėliau optimizuotos per specialų automatinio tyrimo ciklą, orientuotą į tas pačias metrikas, kurios naudojamos SDK optimizavimui. Taip pat apribojame skill dydį, kad apsisaugotume nuo konteksto išpūtimo, o mūsų galutinėse versijose pagrindiniuose SKILL.md failuose yra mažiau nei 2000 žetonų.
Optimizuoti Skills peržengia SDK pasiekiamų statybinių blokų išvardijimo ribas (tai galima lengvai gauti per vykdymo laiko atspindį). Didžioji žetonų dalis skiriama glaustam, apibendrinamam vadovavimui ir kelių pavyzdžių pavyzdžiams pateikti, kaip sudėti šiuos blokus į sudėtingus šablonus. Apsiginklavę šiais Skills, pastebime, kad modeliai veiksmingai išnaudoja SDK, kad organizuotų paieškos eigas, kurios plečiasi iki tūkstančių atskirų operacijų.
Kodas kaip orkestratorius ir spragų užpildytojas
Sujungdamas šiuos sluoksnius, SaC keičia modelių ir paieškos steko santykį. Fiksuotos eigos paieškos sistemose modelis sėdi virš paieškos ir bendrauja su ja per siaurą nuoseklaus iškvietimo sąsają. Naudojant SaC, modelis tampa aktyviu paieškos proceso orkestravimo dalyviu. Visi paieškos steko elementai tampa tiesiogiai programuojami modelio, o sandbox aplinka ir agentinės paieškos SDK teikia reikalingas sąsajas tiems elementams.
O kaip dėl gebėjimų, kurių natūraliai nėra? Kodas yra galinga priemonė egzistuojantiems gebėjimams orkestruoti. Visgi kodo galia peržengia orkestravimo ribas. Jis taip pat gali būti naudojamas kaip spragų užpildytojas gebėjimams, kurių nėra paieškos steke arba SDK. Agentams naudingas taupumas, ir būtų neefektyvu, jei SDK apimtų kiekvieną galimą operaciją su dedikuota funkcija. Vietoj to SDK pateikia pačius pagrindinius primityvus, o modelis gali sukurti bet kokius papildomus komponentus akimirksniu naudodamas kodą.
Apsvarstykite, pavyzdžiui, sudėtingą reguliarųjį reiškinį (regex), kurio neįmanoma efektyviai įgyvendinti naudojant paieškos sistemos savo užklausos sintaksę. Neturėdamas kodavimo gebėjimų, modelis būtų priverstas generuoti savo geriausią apytikslį variantą, atlikti užklausą ir žetonų erdvėje atlikti filtravimą labai triukšmingame rezultatų rinkinyje. Naudodamas SaC, modelis vietoj to gali sugeneruoti programą, kuri atlieka lygiagrečius SDK iškvietimus, kad surinktų pageidaujamo regex rezultatų rinkinio viršinį rinkinį. Atlikęs dubliavimo šalinimą per SDK, modelis gali parašyti papildomą kodą, kad deterministiškai susiaurintų rezultatus iki tikslaus regex. Tokiu būdu agentai gali įgyvendinti pasirinktines paieškos galimybes, neapkraudami SDK pernelyg nišinėmis subrutinomis.
Atvejo analizė: CVE teikėjų rekomendacijos
Pateikiame atvejo analizę, pagrįstą realaus pasaulio užduotimi mūsų bandymų rinkinyje. Ši užduotis reikalauja, kad agentas identifikuotų ir apibūdintų daugiau nei 200 didelio sunkumo CVE iš 2023–2025 m. Kiekviename įraše turi būti nurodyta paveikto teikėjo rekomendacija, įvardytas produktas ir pataisos versija bei parodyta, kad pataisos versija yra susieta su konkrečiu CVE.
SaC atsakymas surinko 100 % tikslumo, o bendras žetonų naudojimas sumažėjo 85,1 %, palyginti su ne SaC bazine line (nuo 288,7 tūkst. žetonų iki 42,9 tūkst. žetonų). Išbandytos ne „Perplexity“ sistemos, aptartos išsamiau 4 skyriuje, visos surinko mažiau nei 25 %.
Pateikiame tris stilizuotus kodo blokus iš trajektorijos, kad parodytume, kaip SaC programuojamumas leidžia modeliui įgyvendinti veiksmingas strategijas.
# Part 1 of 3: fan out over official advisory formats.
templates = [
("Mozilla",
'site:mozilla.org/en-US/security/advisories/mfsa{year} '
'"CVE-{year}-" "Fixed in" "Impact high"'),
("Jenkins",
'site:jenkins.io/security/advisory/{year} '
'"CVE-{year}" "Severity" "High" "Fix"'),
("Chrome",
'site:chromereleases.googleblog.com/{year} '
'"High CVE-{year}" "Stable channel has been updated"'),
("Android",
'source.android.com/docs/security/bulletin/{year}-{month:02d}-01 '
'"High" "CVE-{year}"'),
...
]
queries = [
{"vendor": vendor, "query": pattern.format(year=year, month=month)}
for year in [2023, 2024, 2025]
for vendor, pattern in templates
for month in ([1] if "{month" not in pattern else range(1, 13))
]
seed_hits = sdk.search.web_many(queries, limit_per_query=8, concurrency=12)
pages = [
{"vendor": q["vendor"], "url": h.url, "text": join_result_fields(h)}
for q, hits in zip(queries, seed_hits)
for h in hits
if official_vendor_advisory(h.url, q["vendor"])
]Šis pirmasis blokas yra grynas orkestravimas. Sugeneruota programa prasideda tiesiogiai užklausos plane užkoduojant šaltinio klasės taisyklę: svarbūs tik teikėjui priklausantys rekomendacijų formatai. Ne teikėjo šaltiniai, įskaitant NVD, MITRE, CVE Details, naujienų pranešimus, CERT puslapius ir trečiųjų šalių duomenų bazes, yra struktūriškai už taikymo sribies ribų. Tikslios frazės apribojimai taip pat stumia paiešką į puslapius, kurių indeksuotame tekste jau yra tikslios CVE detalės, reikalingos toliau.
# Part 2 of 3: synthesize refinements for sparse vendor-years.
coverage = summarize(pages, by=["vendor", "year", "url_kind"])
prompt = """
Goal: 230+ high or critical CVEs from official vendor advisories.
Avoid aggregators, CERTs, news, NVD, MITRE, and CVE databases.
Current coverage:
{coverage}
Suggest more site-scoped exact-phrase queries for sparse vendor-years.
Prefer per-advisory pages over archive or month-index pages.
Return JSON lines with vendor and query.
""".format(coverage=coverage)
raw = query_llm(prompt)
expanded_queries = [
row for row in parse_jsonl(raw)
if official_scope(row["query"]) and mentions_cve_year(row["query"])
]
expanded_hits = sdk.search.web_many(
unique(expanded_queries),
limit_per_query=8,
concurrency=12,
)Antrajame bloke kaip tarpinė planavimo subrutina naudojamas LLM. Kode apibendrinama, kurios teikėjo ir metų poros generuoja pakankamai kandidatų puslapių, prašoma tikslinių patobulinimų ir prieš vykdymą patvirtinama kiekviena siūloma užklausa. Tai išsaugo naudingus šablonus iš trajektorijos, tokius kaip svetainės masto tikslios frazės užklausos ir adaptyvus papildymas, be to, SDK nėra įkoduojama specialiai pritaikyta CVE rekomendacijų naršyklė.
# Part 3 of 3: verify CVE-to-version binding.
all_hits = dedupe_by_url(flatten(seed_hits) + flatten(expanded_hits))
items = [
{"url": h.url, "vendor_hint": infer_vendor(h.url),
"text": join_result_fields(h)}
for h in all_hits
if official_vendor_advisory(h.url, infer_vendor(h.url))
]
verified = sdk.llm.extract_many(
items,
instruction=(
"Keep only vendor advisories where the page ties a high or critical "
"CVE to a specific fixed version, build, patch, or security level."
),
schema={
"matches": bool,
"cve": str,
"vendor": str,
"product": str,
"fix_version": str,
"severity": str,
"source_url": str,
"evidence": str,
"version_bound_to_cve": bool,
"confidence": float,
},
)
records = [
to_cve_record(x) for x in verified
if x.matches and x.version_bound_to_cve
if high_or_critical(x.severity) and x.confidence > 0.75
]
records = dedupe_by(records, key="cve")Galutinis blokas yra rezultatų tikrintuokas, kurio logiką agentas visiškai apibrėžia per kodo generavimą. Nors paieškos subrutinos gali rasti tikėtinus rekomendacijų puslapius, užduotis reikalauja griežtesnio ryšio: rekomendacija turi susieti vieną CVE su vienu paveiktu produktu ir viena pataisos versija teikėjo parašytame tekste. Schema padaro šį ryšį aiškų, todėl tolimesnis kodas gali pašalinti dublikatus pagal CVE, atmesti agregatoriaus URL, atmesti silpnius versijos įrodymus ir tęsti pildymą atgal, kol pasiekiamas įrašų skaičiaus minimumas.
Vertinimo rezultatai
Įvertiname SaC veiksmingumą išsamiame etaloninių testų rinkinyje, sutelkdami dėmesį tiek į absoliutų našumą, tiek į kainos ir našumo ribą.
Etaloniniai testai ir sistemos
Mūsų etaloninių testų rinkinį iš viso sudaro penki etaloniniai testai, skirti atlikti paieškos reikalaujančių dirbtinio intelekto darbo eigų testavimą įvairiose srityse, užduočių formatuose ir sudėtingumo lygiuose. Naudojame keturis ankstesnius etaloninius testus: „DeepSearchQA“ (DSQA), „BrowseComp“, „Humanity's Last Exam“ (HLE) ir „WideSearch“. Pirmiems trims etaloniniams testams (DSQA, BrowseComp ir HLE) kaip pagrindinę metriką pranešame tikslumą. „WideSearch“ atveju pranešame F1 įvertinimą pagal eilutę.
Taip pat naudojame naujai suremontuotą WANDR etaloninį testą, kuriame daugiausia dėmesio skiriama sudėtingoms „plačių tyrimų“ užduotims, reikalaujančioms kruopštaus paieškos, skaičiavimų ir modelio samprotavimo orkestravimo. WANDR yra įkvėptas žinių reikalaujančių profesinių užduočių, kurias „Perplexity Computer“ tvarko vartotojams. Jis remiasi „WideSearch“ ir panašiais etaloniniais testais, tačiau akcentuoja sudėtingesnes užduotis ir užduočių struktūras. WANDR etaloninį testą paskelbsime artimiausiomis savaitėmis.
Įvertiname penkias agentais pagrįstas sistemas. Atsižvelgiame į pavienius vykdymus, o ne į „geriausio iš N“ įvertinimus, kad izoliuotume pagrindinės architektūros našumą, o ne lygiagretinimo teikiamą naudą. Kiekvienos sistemos konfigūracija aprašyta žemiau:
„Perplexity“ (SaC): Įvertiname SaC architektūrą „Perplexity“ gamybinėje „Agent API“. Pagrindiniu modeliu tarnauja GPT 5.5 (aukštas mąstymas).
„OpenAI“: Įvertiname „OpenAI Responses API“ su įjungta paieška (web_search) ir „Python“ vykdymo aplinka (code_interpreter). Pagrindiniu modeliu tarnauja GPT 5.5 (aukštas mąstymas).
„Anthropic“: Įvertiname „Anthropic Managed Agents“ su 20260401 agento įrankių rinkiniu ir automatiškai leidžiamomis komandomis. Pagrindiniu modeliu tarnauja „Opus 4.7“ (aukštas mąstymas).
„Exa“: Įvertiname „Exa Agent“ per gamybinę API, nustačius pastangų lygį į aukštą.
„Parallel“: Įvertiname „Parallel Tasks“ per gamybinę API, nustačius procesorių į „ultra4x“.
Lyginamasis našumas
1 lentelėje pateikiami kiekvienos įvertintos sistemos etaloniniai rezultatai. SaC lenkia visas kitas sistemas keturiuose iš penkių etaloninių testų. Likusiame etaloniniame teste (HLE) SaC iš esmės dalijasi pirma vieta su „OpenAI Responses“. 2 pav. iš įvado vizualizuoja šiuos rezultatus grafine forma.
Etaloninis testas | „Perplexity“ (SaC) | „OpenAI“ | „Anthropic“ | „Exa“ | „Parallel“ |
DSQA | 0,871 | 0,733 | 0,815 | 0,530 | 0,810 |
„BrowseComp“ | 0,805 | 0,720 | 0,598 | 0,380 | 0,560 |
HLE | 0,612 | 0,614 | 0,566 | 0,387 | 0,515 |
„WideSearch“ | 0,651 | 0,522 | 0,590 | 0,471 | 0,584 |
WANDR | 0,386 | 0,130 | 0,152 | 0,057 | 0,126 |
1 lentelė | Kiekvienos įvertintos sistemos etaloniniai rezultatai. Geriausias rezultatas eilutėje paryškintas.
Nors SaC pasiekia pažangiausią našumą visame etaloninių testų rinkinyje, jo pranašumas ypač ryškus WANDR atveju. 5 pav. išskiria WANDR rezultatus, parodydamas, kad „Perplexity“ SaC diegimas lenkia kitą geriausią sistemą 2,5 karto. Nepaisant šio didelio skirtumo, WANDR išlieka neužpildytas ir pasirodo esąs sudėtingas net ir SaC. Manome, kad sudėtingos, labai horizontalios paieškos darbo eigos, kurių reikalauja WANDR užduotys, reikalaus papildomų tyrimų ir paieškos inžinerijos laimėjimų, kad būtų pasiektas nuosekliai aukštas našumas.
Galiausiai išmatuojame santykinius SaC laimėjimus, palyginti su tradiciškesne paieškos eiga, kuri naudoja tą pačią „Perplexity“ paieškos infrastruktūrą. 6 pav. pateikia rezultatų skirtumą tarp SaC ir ne SaC architektūrų kiekviename etaloniniame teste. Visose srityse SaC užtikrina didelį našumo pagerėjimą, o didžiausias absoliutus pelnas yra DSQA (+19,77 pp, 29%), o didžiausias santykinis pelnas – WANDR (+12,00 pp, 45%).
Kainos ir našumo riba
Praktikoje vartotojams rūpi našumas, palyginti su kaina. Todėl įvertiname kainos ir našumo ribą DSQA ir „WideSearch“ atveju. Išmatuojame SaC kainą ir našumą esant žemam, vidutiniam ir aukštam modelio samprotavimo lygiams kartu su kitomis sistemomis. 7 ir 8 pav. vaizduoja etaloninį rezultatą, palygintą su kaina už užduotį, o X ašis yra apversta, todėl toliau dešinėje esantys taškai yra pigesni, o aukščiau esantys taškai atvaizduoja geresnį našumą.
DSQA atveju visi trys SaC nustatymai yra viršutinėje dešinėje riboje. Žemo samprotavimo nustatymas yra pigesnis už visas kitas sistemas, o veikia geriau nei dvi iš jų. Vidutinio samprotavimo nustatymas aplenkia visas ne SaC sistemas, kai kaina už užduotį nesiekia 1 USD. Aukšto samprotavimo nustatymas pasiekia geriausią našumą už konkurencingą kainą.
„WideSearch“ rodo panašios formos ribą. Kaip ir DSQA atveju, žemo samprotavimo nustatymas pasiekia konkurencingą našumą mažesne kaina nei visos ne SaC sistemos, o tiek vidutinio, tiek aukšto samprotavimo nustatymai aplenkia ne SaC sistemas pagal užduoties našumą.
Link naujos skaičiavimo architektūros
„Search as Code“ atspindi platesnį programinės įrangos dizaino pokytį. Dešimtmečius programinės įrangos sistemos buvo organizuojamos aplink deterministines instrukcijas, vykdomas tradicinių vykdymo aplinkų CPU. Pažangieji modeliai pristato naują skaičiavimo formą: žetonų erdvės mąstymą, kuris gali tiek vykdyti, tiek generuoti instrukcijas. Galingiausios skaičiavimo sistemos sujungs šias dvi skaičiavimo formas, o nesirinks tarp jų.
Paieška yra natūrali šios hibridinės architektūros bandymų aikštelė. Modeliai puikiai tinka nuspręsti, kokių įrodymų reikia ir kaip turėtų būti išspręstas neapibrėžtumas. Deterministinės vykdymo aplinkos puikiai tinka pakavimui, lygiagretumui, filtravimui, rikiavimui ir agregavimui. Paieškos infrastruktūra tarnauja kaip universali įvesties / išvesties (I/O) sluoksnis, suteikiantis vykdymo aplinkai naudingų valdiklių prie prieigų prie pasaulio informacijos, galinčių palaikyti tūkstančius operacijų per minutę. Kai šie elementai integruojami, gaunama sistema yra kur kas galingesnė ir efektyvesnė atliekant realaus pasaulio užduotis.
Kiekviena šios architektūros dalis yra būtina šioms galimybėms atskleisti. Be išmaniųjų modelių sistema negali mąstyti apie paieškos strategiją. Be sandbox aplinkų modeliai yra priversti atlikti nuoseklią įvestį / išvestį ir neefektyvų žetonų erdvės apdorojimą. Ir be atomizuoto paieškos steko modelis neturi ko orkestruoti. SaC veikia todėl, kad mąstymas, deterministiniai skaičiavimai ir įvestis / išvestis yra bendrai suprojektuoti taip, kad pabrėžtų kiekvieno sluoksnio stipriąsias puses.
Šis bendras projektavimas gali būti perkeltas dar toliau kuriant nuolatinio tobulinimo ciklus. Pavyzdžiui, agentinės paieškos SDK ir SaC Agent Skills galėtų būti bendrai optimizuoti bendrame automatinio tyrimo cikle. Dar ambicingiau, modeliai gali būti apmokyti pasinaudoti žemo lygio paieškos primityvais, atskleistais kaip SDK. Galima net pabandyti kartu vystyti SDK dizainą paties modelio mokymo proceso metu. Tikimės ateityje taikyti agresyvesnes bendro projektavimo strategijas.
Sukūrėme SaC tam, kad leistume modeliams valdyti paieškos procesą, o ne tik suvartoti jo rezultatus. Mūsų rezultatai įrodo šio valdymo galią: SaC pagerina tiek absoliutinį našumą, tiek kainos ir našumo ribą žinių reikalaujančiuose agentų etaloniniuose testuose. Džiaugiamės galėdami pritaikyti SaC galimybes savo vartotojams, pradedant nuo šiandien su „Perplexity Computer“ ir „Agent API“. Mes ir toliau optimizuosime SaC architektūrą visuose steko sluoksniuose, kad užtikrintume, jog mūsų vartotojai (ir jiems tarnaujantys agentai) turėtų galingiausias ir efektyviausias įmanomas paieškos galimybes.
Citata
@online{perplexity2026RethinkingSearchAsCodeGeneration,
author = {{Perplexity} and Denis Bykov and Aleksandr Nikolenko and Artur Zayats and Maksim Gaiduk and Vitalii Polshkov and Akshay Nair and James Liounis and Kirill Priemko and Ryan Buchmayer and Phi Hoang and Jerry Ma},
title = {{Rethinking search as code generation}},
date = {2026-06-01},
url = {https://perplexity.coolkeypoint.com/hub/blog/rethinking-search-as-code-generation}
}