Genovervejelse af søgning som kodegenerering
Udvikling af søgning fra monolitiske tjenester til programmerbare primitiver for agentrammernes tidsalder.
Søgning er en grundlæggende primitiv for AI-systemer. De førende modeller bliver dygtigere måned for måned, men de har stadig brug for adgang til frisk, nøjagtig og velkurateret viden fra den vide verden. Søgning er den primære måde, hvorpå AI-systemer trækker på denne viden, og dermed en fundamentalt vigtig komponent i ethvert produkt, der skal drage konklusioner, udføre handlinger og udføre arbejde i den virkelige verden.
Vi mener, at traditionelle søgnings-pipelines i stigende grad er forældede i agenternes tidsalder. Traditionelle søgninger besvarer forespørgsler, men nutidens agenter fuldfører opgaver, der kan have utallige former. Disse opgaver kræver, at agenter definerer opgavespecifikke hentningsstrategier direkte i deres rammer. I Perplexity Computer har vi set enkelte opgaver igangsætte hundreder eller endda tusindvis af hentningshandlinger på få minutter: en arbejdsproces, der er umulig for mennesker, men helt naturlig for agenter.
I denne verden må selve søgningen blive agentisk, hvor dens byggesten er tilgængelige direkte som SDK'er i agentrammen. Vi introducerer Search as Code (SaC) som Perplexitys nye referencesøgningsarkitektur.
Introduktion
Perplexitys søgestak betjener tusindvis af forespørgsler hvert sekund på tværs af vores applikationer og API-platform. I september 2025 udgav vi den første arkitektoniske oversigt over vores søgesystemer. Konstant innovation inden for disse systemer har understøttet lanceringen af nye tilbud som Search API, Agent API og Computer, hvor selvforbedringsløkker optimerer søgestakken for bedre at betjene brugere for hver dag, der går.
Traditionelt har AI-systemer behandlet søgning som en monolit: en AI-model udsender en forespørgsel, søgemaskinen kører sin prædefinerede pipeline, og modellen forbruger resultaterne som kontekst. For det meste fungerede dette fint til at opfylde behovene hos tidlige AI-brugere. Givet den relative enkelhed af deres anmodninger var der ingen grund til at bekymre sig om præcist, hvordan søgnings-pipelinen var designet, eller om pipelinens arkitektur var optimal for den aktuelle opgave. Standarderne blev antaget at være gode nok, ligesom standardgrænsefladerne (funktionskald og MCP'er) var det.
Alligevel bliver denne tilgang mere forældet for hver måned, der går. Brugere kræver meget mere end enkeltskudsanalyse fra AI. De forventer, at agenter fuldfører opgaver fra ende til anden over timer eller endda dage. Disse opgaver kan være komplekse, åbne og stærkt variable i deres informationsbehov, og monolitagtige arkitekturer bukker under for vægten af disse krav.
Det centrale flaskehals er i sidste ende et spørgsmål om kontrol. Førende modeller er allerede ret gode til at ræsonnere over fast kontekst. De mest kraftfulde AI-systemer vil dog kræve evnen til at styre, hvordan denne kontekst hentes, behandles, aggregeres og præsenteres for modellen.
Traditionelle søgesystemer blev ikke designet med denne grad af kontrollerbarhed for øje. Man kan trods alt ikke forvente, at menneskelige brugere udøver finkornet kontrol over søgnings-pipelinens indmad, selv hvis det blev tilbudt. Tidlige AI-modeller kan kun styre søgning gennem en lineær bane af funktionskald og MCP'er. Men nutidens førende modeller, drevet af kode-kapable agentrammer, kan udøve finkornet kontrol over enhver tænkelig beregningsprimitiv gennem computercode. Vores opgave bliver at levere de rette primitiver.
For at imødekomme dette behov introducerer vi en ny søgearkitektur på tværs af vores produkter: Search as Code (SaC). Denne nye arkitektur gør det muligt for modeller at nå ind i selve søgestakken i stedet for blot at forbruge dens endelige output. Kerneideen er enkel: Vi eksponerer søgestakkens komponenter som primitiver i et SDK. For enhver forespørgsel, der kræver søgning, sammensætter en model disse primitiver efter behov til en hentningspipeline, der er skræddersyet til netop den pågældende forespørgsel.
Samlingen af denne pipeline sker gennem kodegenerering og eksekvering i en sikker sandbox. I modsætning til andre kodegenereringsdrevne tilgange til søgning sætter vi ikke blot et traditionelt søgnings-API ind i en skal eller et sprogkørselsmiljø. I stedet har vi omhyggeligt udviklet et Agentic Search SDK, der eksponerer søgningens individuelle byggesten på det mest atomare niveau muligt.
Bevæbnet med disse byggesten giver SaC modeller direkte kontrol over hvert enkelt søgetrin: hentning, rangering, filtrering, fanouts, gengivelse og mere. Det giver også modellen effektiv adgang til mellemliggende tilstand som kandidatlister og rangeringssignaler. Sammen tillader disse to løftestænger for kontrol og læsbarhed agenter at designe skræddersyede søgnings-pipelines, der spænder over tusindvis af hentningsoperationer, optimere disse pipelines undervejs og kun forbruge de mest nyttige informationer som modelkontekst.
Denne artikel beskriver SaC's motivation, design og implementering sammen med empiriske resultater på både eksisterende og nye benchmarks. SaC etablerer en ny omkostnings-ydeevnegrænse for agentisk søgning, og vi glæder os til at dele den med vores brugere og det bredere AI-fællesskab.
Den traditionelle søgnings rigiditet
Verdens første søgemaskiner blev bygget til menneskelige brugere. Disse brugere kom til at forvente en forudsigelig oplevelse, der typisk bestod af et fast antal relevansrangerede dokumenter. Brugere ønskede ikke at mikrostyre søgeprocessen; de ville indtaste en forespørgsel og finde et nyttigt resultat.
Som et resultat konvergerede menneskevendte søgemaskiner om en almindelig monolitisk arkitektur, gearet mod at producere menneskevenlige søgemaskineresultatsider (SERP'er), der indeholder de øverste n hits for en inputforespørgsel. Dette mønster har drevet årtiers fremskridt inden for Forbrugersøgning. Det er hurtigt, velkendt og yderst effektivt til menneskelig browsing.
Derefter kom LLM'er, og AI-systemer blev også forbrugere af søgning. Perplexity banede vejen for dette skift med lanceringen af vores svarmaskine i 2022. Siden da har vores søgetekniske indsats fokuseret på, hvordan man optimerer værdien af søgeresultater for AI-modeller. For at bygge verdens mest nøjagtige og pålidelige AI var vi nødt til at konstruere et søgesystem med fokus på at gøre hvert enkelt token så informationsmæt som muligt. De resulterende innovationer inden for underdokumenthentning, konteksteffektivitet, semantisk forståelse og andre nøgleområder førte til dramatiske forbedringer i AI-systemers evne til at hente og handle på information.
Selv AI-optimerede systemer har imidlertid i vid udstrækning arvet den samme grundlæggende kontrakt som traditionelle søgemaskiner: accepter en forespørgsel, kør en prædefineret søgnings-pipeline, og returner et fuldt behandlet resultatsæt. For simple anmodninger fungerer denne tilgang fint. Men for mere komplekse anmodninger bliver dette en stadigt mere begrænsende flaskehals, der forringer ydeevne, ventetid og omkostninger.
Fejltilstande fra rigiditet
Traditionelle søgnings-pipelines er designet omkring et enkelt kontrolpunkt: forespørgselsparametrene. Søgemaskinen ejer resten af pipen i henhold til dens prædefinerede logik, og modellen må tilpasse sig den. For modellen er alt, der er downstream fra forespørgselsparametrene, stift – formen på den faktiske beregning er uden for modellens kontrol.
Dette er en fornuftig grænse, når forbrugeren er et menneske, der scanner links. Det er en dårlig grænse, når forbrugeren er en AI-model, der forsøger at løse vidensintensive opgaver i en lukket sløjfe. Efter vores erfaring skaber denne rigiditet tre tilbagevendende fejltilstande:
Grov kontekst. AI-modeller er følsomme over for kontekstens kvalitet og kompakthed. Både kvalitet og kompakthed er stærkt forespørgselsafhængige, og monolitagtige søgnings-pipelines er ikke designet til at fungere optimalt på tværs af alle forespørgsler. For eksempel, hvis en model har brug for et enkelt, yderst kirurgisk stykke information, men kun har adgang til et end-to-end-søgningsendepunkt, der prioriterer genkaldelse, vil brugen af det endepunkt introducere en stor mængde irrelevant information i modelkonteksten. På den anden side, hvis en model har brug for mange stykker information, der hver kræver forskellige søgestrategier, kan den blive tvunget til serielt at påkalde den samme suboptimale pipeline for dem alle, hvilket resulterer i eksploderende omkostninger og støjende kontekst.
Manglende udnyttelse af domæneviden. I mange tilfælde kan modellen have domæneviden (fra sin træning, en Agent Skill, hukommelse eller tidligere tokens i LLM-banen), som bør styre søgestrategien. En rigid søgegrænseflade forhindrer dog modellen i at udnytte den viden. For eksempel kan modellen indse for en specifik anmodning, at den bør blande leksikalske og semantiske signaler på en bestemt måde, prioritere visse kilder eller aggregere resultater efter en specifik nøgle. Medmindre disse indsigter tilfældigvis kan implementeres gennem forespørgselsparametre, kan modellen ikke reelt handle på dem.
Ineffektiv kontrolstrøm og kontekstforurening. Mange søgnings-arbejdsprocesser er ikke naturligt serielle. De kan have brug for fan-out over forespørgselsvarianter, parallel hentning, deduplikering og andre operationer, der kræver ikke-lineær og asynkron kontrolstrøm. At tvinge disse trin igennem gentagne modelsving tilføjer ventetid og gør arbejdsprocessen sværere at optimere. Det forurener også modelkonteksten med støjende mellemliggende tilstand, der muligvis ikke er nyttig for modellens ræsonnement, hvilket resulterer i dårligere ydeevne og hyppigere komprimeringer.
Der var ikke meget, man kunne gøre ved disse udfordringer under funktionskald- og MCP-æraerne for AI. Når hver søgeoperation kræver sin egen tur-retur til LLM-inferens, foretrækker udviklere naturligvis at få så meget fra hånden på den tur-retur. Dette betyder end-to-end-søgnings-pipelines, der returnerer fuldt behandlede resultatsæt til direkte forbrug af en model.
Som et resultat opererer de fleste AI-vendte søgesystemer i dag stadig under denne monolitiske kontrakt. Men med fortsat vækst i modelintelligens og brugerkrav bliver manglerne ved den kontrakt mere udtalte. Nutidens mest avancerede AI-systemer, bygget oven på kode-først-rammer, kan sammensætte opgavespecifikke arbejdsprocesser, der udfører tusindvis af handlinger hvert minut. Søgesystemer har endnu ikke fuldt ud indfriet dette potentiale.
Vi har længe haft mistanke om, at den rette grænse for AI-naturlig søgning ligger længere nede i stakken. Modeller bør ikke blot kalde en søgemaskine. De bør være i stand til at orkestrere de individuelle dele af søgestakken, som den specifikke opgave kræver. Det kræver en fundamentalt anden arkitektur.
Design af en programmerbar søgningsarkitektur
Den næste generation af søgningsarkitekturer vil hænge på et kernepricip: søgning bør være oprindeligt programmerbar af AI-agenter. En agent må ikke være begrænset til et sæt forudbestemte søgnings-pipelines. Snarere skal en agent være i stand til at konstruere den pipeline, som den specifikke opgave kræver, ved hjælp af komponerbare byggesten designet på forskellige abstraktionsniveauer.
Vores nye Search as Code (SaC)-arkitektur indlejrer dette princip. I SaC bliver ikke en eneste hentningsoperation afsendt gennem et funktionskald eller en MCP-grænseflade. Alle operationer orkestreres i stedet via modelgenereret Python-kode. For de enkleste søgebehov kan denne kode bestå af en håndfuld anmodninger til et højtsniveau søgeendepunkt. Men for komplekse opgaver kan koden være så indviklet som nødvendigt, herunder betinget eksekvering, asynkronitet, parallelisme og kald til en bred vifte af lavniveaus-primitiver.
SaC involverer tre tæt koblede lag:
Modeller fungerer som kontrolplanet. De ræsonnerer om brugerens (eller forældreagentens) direktiv, nedbryder direktivet i opgaver, beslutter hvilke hentnings- og behandlingspipelines der er nødvendige for hver opgave, og genererer kode til at implementere disse pipelines.
Beregningssandboxes leverer deterministisk beregning gennem et sikkert kodeeksekveringsmiljø. De leverer et lærred for modeller til at implementere kontrolstrøm, batching, forsøg igen, filtrering, join-operationer, aggregering og andre deterministiske operationer.
Vores Agentic Search SDK eksponerer Perplexitys søgestak som komponerbare primitiver. Det leverer byggesten fra lavniveaus-hentningsoperationer til højtsniveau semantisk parsing. SDK'et er indlejret i sandboxenes eksekveringsmiljøer, hvilket giver modeller mulighed for at orkestrere op til tusindvis af operationer inden for en enkelt inferenstur. Nedenfor diskuterer vi vores designtræf for hvert lag.
Agentic Search SDK'et
Agentic Search SDK'et definerer byggestenene til programmerbar søgning. Vigtigst af alt er vores SDK ikke et præeksisterende søge-API pakket som et bibliotek. I de seneste måneder har vores ingeniørteam rearkitekteret vores søgestak til modulære, komponerbare primitiver. Vi har bygget Agentic Search SDK'et til at levere direkte adgang til disse primitiver, hvilket giver et meget kraftfuldere lærred, hvorpå modellen kan orkestrere opgavespecifikke hentnings-pipelines.
Højniveau, end-to-end søgnings-pipelines er stadig tilgængelige inden for SDK'et, men de er ikke længere den eneste mulighed. De fungerer snarere som en form for stenografi for almindelige søgemønstre. Modellen står frit for at bruge eller omgå dem, efterhånden som opgaven kræver det.
Valg af kørselsmiljø: Vi overvejede Python, Rust, TypeScript og Bash som SDK-kørselsmiljø. Vi havde en mistanke om, at Python ville være det mest naturlige valg i betragtning af dens udbredelse og økosystem af databehandlingsbiblioteker. Intern testning bekræftede, at dette var tilfældet, og den version af SDK'et, der udrulles i dag, er Python-baseret. Vi forventer periodisk at genoverveje valget af kørselsmiljø for at sikre, at det fortsat leverer den bedste agentoplevelse.
Løbende forbedring via autosøgning: Vi har også optimeret SDK'ets forbrugbarhed for førende LLM'er gennem en iterativ autosøgningssløkke. Denne sløkke, der kører kontinuerligt over uger, foreslår og validerer SDK-forbedringer mod metrics, herunder ventetid, kodegenereringskvalitet og samlet opgaveydeevne. Autosøgningssløkken har allerede foretaget adskillige ændringer af både strukturen og æstetikken i SDK'et med væsentlige gevinster på tværs af alle dimensioner. Vi planlægger yderligere at finpudse SDK'et via autosøgning, efterhånden som nye førende modeller og søgekomponenter dukker op.
Sandboxes
Sandboxes leverer sikre miljøer til definition og kørsel af SaC-pipelines. De eksekverer modelgenereret kode og giver adgang til Agentic Search SDK'et for at lette interaktionen med individuelle søgeprimitiver.
Vi har foretaget betydelige investeringer i at optimere og hærde vores sandboxes, og deres overordnede systemdesign fortjener en artikel for sig selv. Her fokuserer vi på det designtagende hensyn, der er mest relevant for SaC: håndtering af mellemliggende tilstande.
SaC giver agenter magt til at orkestrere komplekse pipelines inden for en enkelt inferenstur. Visse mellemliggende tilstande skal dog overføres på tværs af ture. For eksempel kan en model ønske at hente nogle dokumenter i tur 1, inspicere en undervurdering af disse dokumenter i tur 2 for at beslutte, hvad der skal gøres derefter, og derefter udvikle en downstream-søgnings-pipeline for yderligere at undersøge disse dokumenter fra tur 3 og fremefter. Som diskuteret ovenfor er det ikke en effektiv strategi at videregive mellemliggende tilstande gennem tokensum.
Vi overvejede to tilgange til styring af mellemliggende tilstande på tværs af ture:
Vedholdende filsystem + eksplicit serde: Sandboxes kan eksponere vedholdende filsystemer, som modeller kan bruge på tværs af ture. Modeller, der ønsker at fastholde mellemliggende tilstand, kan inkludere et serialiseringstrin inden for den genererede kode for en tur sammen med et deserialiseringstrin inden for en efterfølgende tur (enten til modellernes egen inspektion eller til downstream-brug). Filsystemstilgangen gør det muligt for modeller direkte og eksplicit at styre, hvordan mellemliggende tilstand overføres på tværs af ture. Den sikrer også sporbarhed ved at håndhæve eksplicit identifikation og vedholdenhed af information brugt af modellen. En ulempe er ventetiden og kontekstoverheaden, der pådrages ved generering af serde-koden, selvom veldesignede hjælpefunktioner kan afbøde denne overhead.
REPL: Alternativt kan en sandbox fastholde selve eksekveringsmiljøet på tværs af ture i et REPL-lignende miljø. Dette gør det muligt for modeller at opretholde mellemliggende tilstand in-memory uden overhovedet at skulle serialisere den, da variabler defineret eller modificeret i tidligere ture simpelthen kan refereres ved navn i efterfølgende ture. REPL-tilgangen er mere tokeneffektiv, da den undgår behovet for at generere serde-kode. Manglen på et eksplicit serialiseringstrin kan dog skade downstream-ydeevnen af grunde, der er velkendte for enhver, der har arbejdet med en 100-cellers Jupyter-notebook: efterhånden som variabelnavnerummet bliver rodet, bliver det vanskeligere at holde styr på, hvad der præcist fastholdes på tværs af ture, og hvorfor.
Vi testede begge tilgange og fandt, at selvom de fungerer ens ved almindelig brug, giver filsystembaseret serde bedre pålidelighed på særligt lange baner. Vi indtager derfor filsystembaseret serde som vores løsning. Vi formoder, at det at kræve, at modeller videregiver tilstand deklarativt i stedet for implicit, hjælper dem med at administrere denne tilstand mere effektivt. Dette er et foreløbigt fund, og vi vil fortsætte med at iterere på begge tilgange.
Modeller
Modellerne, der driver agentrammerne, fungerer som SaC's kontrolplan: de samler dynamisk søgnings-pipelines fra Agentic Search SDK'ets byggesten for at opfylde behovene i hver opgave og udsender derefter disse pipelines som kode til sandbox-eksekvering.
Perplexity benytter en række modeller inden for vores agentrammer, og vi har fundet ud af, at de seneste førende modeller er ret effektive over hele linjen til generisk kodegenerering. Hovedudfordringen er at fremprovokere effektiv kodegenerering specifikt til Agentic Search SDK'et. Det vil sige, hvordan kan vi få modeller til effektivt at flette vores SDK's byggesten sammen til opgaveoptimerede pipelines?
I modsætning til et sprogs standardbibliotek er det usandsynligt, at et skræddersyet SDK er repræsenteret i forudtræningsdata. Selv med SDK-forbrugerforbedringerne fra autosøgning er mange modeller stadig trænede til at interagere med søgesystemer gennem funktionskald og direkte MCP-påkaldelse. Det er usandsynligt, at disse modeller kyndigt vil svinge SDK'et med kildekode og autogenererede dokumenter alene.
For at løse denne udfordring har vi udviklet højt afstemte Agent Skills til at lære modeller at udnytte vores SDK effektivt. De første versioner blev udviklet i henhold til Perplexitys designprincipper for Skills og derefter optimeret gennem en dedikeret autosøgningssløkke med fokus på de samme metrics, der blev brugt i SDK-optimering. Vi begrænser også færdighedsstørrelsen for at beskytte mod kontekstsvulmen, og vores endelige versioner har færre end 2000 tokens i deres rod SKILL.md-filer.
De optimerede Skills går ud over at liste SDK'ets tilgængelige byggesten (noget der lige så nemt kan opnås via runtime reflection). Hovedparten af tokens bruges på at levere kortfattet, generaliserbar vejledning og few-shot-eksempler til sammensætning af disse blokke i komplekse mønstre. Bevæbnet med disse Skills observerer vi, at modeller effektivt udnytter SDK'et til at orkestrere søgnings-pipelines, der skalerer til tusindvis af diskrete operationer.
Kode som orkestrator og fyldstof
Ved at kombinere disse lag ændrer SaC forholdet mellem modeller og søgestakken. I fast-pipeline-søgesystemer sidder modellen over søgning og interagerer med den gennem en smal seriel kaldergrænseflade. I SaC bliver modellen en aktiv deltager i orkestreringen af selve søgeprocessen. Alle elementer i søgestakken bliver direkte programmerbare af modellen, hvor sandboxen og Agentic Search SDK'et leverer de nødvendige grænseflader til disse elementer.
Men hvad med funktioner, der ikke findes naturligt? Kode er et kraftfuldt medium til orkestrering af præeksisterende funktioner. Alligevel går kodes magt videre end orkestrering. Den kan også fungere som et fyldstof for funktioner, der ikke er til stede i søgestakken eller SDK'et. Agenter drager fordel af sparsommelighed, og det ville være ineffektivt for SDK'et at dække enhver potentiel operation med en dedikeret funktion. I stedet leverer SDK'et de mest fundamentale primitiver, og modellen kan bygge eventuelle yderligere komponenter on-the-fly med kode.
Overvej for eksempel et komplekst regex, som ikke effektivt kan implementeres via søgesystemets egen forespørgselssyntaks. Uden kadeevner ville modellen være tvunget til at generere sin bedste tilnærmelse, foretage en forespørgsel og udføre tokensumsfiltrering på et meget støjende resultatsæt. Med SaC kan modellen i stedet generere et program, der foretager parallelle SDK-kald for at indsamle et supersæt af det ønskede regex's resultatsæt. Efter deduplikering via SDK'et kan modellen derefter skrive yderligere kode til deterministisk at indsnævre resultaterne til det nøjagtige regex. På denne måde kan agenter implementere tilpassede søgefunktioner uden at svulme SDK'et op med alt for nicherelaterede subrutiner.
Casestudie: CVE-leverandørrådgivninger
Vi præsenterer et casestudie baseret på en opgave i den virkelige verden inden for vores testsite. Denne opgave beder en agent om at identificere og karakterisere over 200 CVE'er med høj alvorlighedsgrad fra 2023-2025. Hver post skal citere den berørte leverandørs egen rådgivning, navngive produktet og rettelsesversionen samt vise, at rettelsesversionen er knyttet til den specifikke CVE.
SaC's svar scorede 100% på nøjagtighed, hvor det samlede tokenforbrug faldt med 85,1% i forhold til ikke-SaC-baseline (fra 288,7K tokens til 42,9K tokens). De testede ikke-Perplexity-systemer, der diskuteres mere detaljeret i afsnit 4, scorede alle lavere end 25%.
Vi præsenterer tre stiliserede kodeblokke fra banen for at illustrere, hvordan SaC's programmerbarhed tillader modellen at implementere effektive strategier.
# 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"])
]Denne første blok er ren orkestrering. Det genererede program starter med at kode kildeklasse-reglen direkte ind i forespørgselsplanen: kun leverandørejede rådgivningsformater er relevante. Ikke-leverandørkilder inklusive NVD, MITRE, CVE Details, nyhedshistorier, CERT-sider og tredjepartsdatabaser er strukturelt uden for rækkevidde. De nøjagtige sætningsbegrænsninger presser også søgning mod sider, hvis indekserede tekst allerede indeholder de præcise CVE-detaljer, der er nødvendige downstream.
# 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,
)Den anden blok bruger en LLM som en mellemliggende planlægningssubrutine. Koden opsummerer, hvilke leverandør-år-par der producerer nok kandidatsider, beder om målrettede forfininger og validerer hver foreslået forespørgsel før eksekvering. Dette bevarer nyttige mønstre fra banen, såsom sitemæssigt afgrænsede nøjagtige sætningsprober og adaptiv tilbagestopning uden at hårdkode en skræddersyet CVE-rådgivnings-crawler ind i SDK'et.
# 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")Den endelige blok er en resultatverifikator, hvis logik udelukkende defineres af agenten via kodegenerering. Mens søgesubrutiner kan finde plausible rådgivningssider, kræver opgaven en strengere relation: rådgivningen skal binde én CVE til ét berørt produkt og én rettelsesversion i leverandørforfattet tekst. Skemaet gør den relation eksplicit, så downstream-kode kan deduplikere efter CVE, afvise aggregator-URL'er, kassere svage versionsbeviser og fortsætte tilbagestopningen, indtil posttællingsgulvet er opfyldt.
Evalueringsresultater
Vi evaluerer SaC's effektivitet på en omfangsrig benchmark-suite med fokus på både absolut ydeevne og omkostnings-ydeevnegrænsen.
Benchmarks og systemer
Vores benchmark-suite omfatter i alt fem benchmarks, designet til at stressteste søgeafhængige AI-arbejdsprocesser på tværs af en række domæner, opgaveformater og kompleksitetsniveauer. Vi bruger fire præeksisterende benchmarks: DeepSearchQA (DSQA), BrowseComp, Humanity's Last Exam (HLE) og WideSearch. For de første tre benchmarks (DSQA, BrowseComp og HLE) rapporterer vi nøjagtighed som toplinjemetric. For WideSearch rapporterer vi F1-score pr. række.
Vi bruger også det nyligt udviklede WANDR-benchmark, som fokuserer på vanskelige “vide forsknings”-opgaver, der kræver omhyggelig orkestrering af søgning, beregning og modelræsonnement. WANDR er inspireret af de vidensintensive professionelle opgaver, som Perplexity Computer håndterer for brugere. Den itererer over WideSearch og lignende benchmarks, men lægger vægt på mere komplekse opgaver og opgavestrukturer. Vi vil offentliggøre WANDR-benchmarken i de kommende uger.
Vi evaluerer fem agentbaserede systemer. Vi overvejer individuelle kørsler i stedet for “bedst-af-N”-scorer for at isolere ydeevnen af den underliggende arkitektur frem for fordelene ved parallelisering. Hvert systems konfiguration er beskrevet nedenfor:
Perplexity (SaC): Vi evaluerer SaC-arkitekturen inden for Perplexitys produktion Agent API. GPT 5.5 (højt ræsonnement) fungerer som den underliggende model.
OpenAI: Vi evaluerer OpenAI Responses API med både søgning (web_search) og Python-kørselsmiljø (code_interpreter) aktiveret. GPT 5.5 (højt ræsonnement) fungerer som den underliggende model.
Anthropic: Vi evaluerer Anthropic Managed Agents med 20260401-agentværktøjssættet og automatisk tilladte kommandoer. Opus 4.7 (højt ræsonnement) fungerer som den underliggende model.
Exa: Vi evaluerer Exa Agent via produktions-API'et, hvor indsatsen er sat til høj.
Parallel: Vi evaluerer Parallel Tasks via produktions-API'et, hvor processoren er sat til ultra4x.
Sammenlignende ydeevne
Tabel 1 rapporterer benchmark-scorer for hvert system. SaC overgår alle andre systemer på fire af de fem benchmarks. På den resterende benchmark (HLE) deler SaC i bund og grund førstepladsen med OpenAI Responses. Figur 2 fra introduktionen visualiserer disse scorer i grafisk form.
Benchmark | 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 |
Tabel 1 | Benchmark-scorer for hvert evalueret system. Bedste score pr. række med fed skrift.
Selvom SaC opnår state-of-the-art ydeevne på tværs af benchmark-suiten, er dens fordel særligt udtalt på WANDR. Figur 5 bryder WANDR-scorerne ned og viser, at Perplexitys SaC-implementering overgår det næstbedste system med en faktor på 2,5×. På trods af denne store margin forbliver WANDR umættet og viser sig udfordrende selv for SaC. Vi mener, at de komplekse, stærkt horisontale søgnings-arbejdsprocesser, der kræves af WANDR's opgaver, vil kræve yderligere fremskridt inden for forskning og søgeteknik for at opnå konsekvent høj ydeevne.
Endelig måler vi de relative gevinster ved SaC i forhold til en mere traditionel søgnings-pipeline, der udnytter den samme Perplexity-søgeinfrastruktur. Figur 6 rapporterer forskellen i scorer mellem SaC- og ikke-SaC-arkitekturerne på tværs af hvert benchmark. Over hele linjen giver SaC et væsentligt boost i ydeevne, med den største absolutte gevinst på DSQA (+19,77 pp, 29%) og den største relative gevinst på WANDR (+12,00 pp, 45%).
Omkostnings-ydeevnegrænse
I praksis bekymrer brugere sig om ydeevne i forhold til omkostninger. Vi evaluerer derfor omkostnings-ydeevnegrænsen på DSQA og WideSearch. Vi måler omkostningerne og ydeevnen af SaC på tværs af lave, mellemstore og høje modelresonneringsniveauer ved siden af de andre systemer. Figur 7 og 8 plotter benchmarkscore mod pris pr. opgave med x-aksen omvendt, så punkter længere mod højre er billigere, og punkter højere oppe repræsenterer bedre ydeevne.
På DSQA ligger alle tre SaC-indstillinger på den øverste højre grænse. Indstillingen for lavt ræsonnement er billigere end alle andre systemer, mens den præsterer bedre end to af dem. Indstillingen for mellemste ræsonnement overgår alle ikke-SaC-systemer til under $1 pr. opgave. Indstillingen for højt ræsonnement opnår topydeevne med en konkurrencedygtig pris.
WideSearch viser en lignende formet grænse. Som med DSQA opnår indstillingen for lavt ræsonnement konkurrencedygtig ydeevne til lavere omkostninger end alle ikke-SaC-systemer, mens både mellemste og høje ræsonnement overgår ikke-SaC-systemer i opgaveydeevne.
Mod en ny beregningsarkitektur
Search as Code afspejler en bredere ændring i softwaredesign. I årtier blev softwaresystemer organiseret omkring deterministiske instruktioner eksekveret af traditionelle kørselsmiljøer på CPU'er. Førende modeller introducerer en ny form for beregning: tokensums-ræsonnement, som både kan følge og generere instruktioner. De mest kapable beregningssystemer vil kombinere disse to former for beregning i stedet for at vælge mellem dem.
Søgning er et naturligt testfelt for denne hybride arkitektur. Modeller er velegnede til at beslutte, hvilken evidens der er nødvendig, og hvordan usikkerhed skal løses. Deterministiske kørselsmiljøer er velegnede til batching, parallelisme, filtrering, rangering og aggregering. Søgeinfrastruktur fungerer som et universelt I/O-lag, der forsyner kørselsmiljøet med nyttige håndtag ind i verdens information, som kan opretholde tusindvis af operationer pr. minut. Når disse dele integreres, er det resulterende system meget kraftfuldere og mere effektivt til at udføre opgaver i den virkelige verden.
Enhver del af denne arkitektur er nødvendig for at frigøre disse funktioner. Uden intelligente modeller kan systemet ikke ræsonnere om søgestrategi. Uden sandboxes tvinges modeller ind i seriel I/O og ineffektiv tokensums-behandling. Og uden en atomiseret søgestak har modellen intet at orkestrere. SaC fungerer, fordi ræsonnement, deterministisk beregning og I/O er designet i fællesskab til at fremhæve hvert lags styrker.
Dette codesign kan tages endnu længere gennem udviklingen af løkker til løbende forbedring. For eksempel kunne Agentic Search SDK og SaC Agent Skills optimeres i fællesskab i en fælles autosøgningssløkke. Mere ambitiøst kan modeller trænes til at udnytte lavniveaus-søgeprimitiver eksponeret som et SDK. Man kan endda forsøge at samudvikle SDK-design under selve modeltræningsprocessen. Vi ser frem til at forfølge mere aggresive codesign-strategier i fremtidigt arbejde.
Vi byggede SaC for at give modeller mulighed for at styre søgeprocessen i stedet for blot at forbruge dens resultater. Vores resultater beviser kraften i denne kontrol: SaC fremmer både absolut ydeevne og omkostnings-ydeevnegrænsen på vidensintensive agent-benchmarks. Vi glæder os til at bringe SaC's funktioner til vores brugere, startende i dag med Perplexity Computer og Agent API. Vi vil fortsætte med at optimere SaC-arkitekturen på tværs af alle lag af stakken for at sikre, at vores brugere (og de agenter, der betjener dem) har de mest kraftfulde og effektive søgefunktioner muligt.
Citation
@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}
}