Ompröva sökning som kodgenerering
Utveckla sökning från monolitiska tjänster till programmerbara primitiver för agentramverkets era.
Sökning är en grundläggande primitiv för AI-system. Frontier-modeller blir allt skickligare för varje månad, men de behöver fortfarande tillgång till färsk, korrekt och välkuraterad kunskap från omvärlden. Sökning är det primära sättet på vilket AI-system tar del av denna kunskap, och därmed en grundläggande komponent i alla produkter som behöver dra slutsatser, vidta åtgärder och utföra verkligt arbete.
Vi anser att traditionella sökpipelines i allt högre grad är föråldrade i agenternas era. Traditionella sökningar besvarar frågor, men dagens agenter utför uppgifter som kan anta otaliga former. Dessa uppgifter kräver att agenter definierar uppgiftsspecifika hämtningsstrategier direkt i sina ramverk. Inom Perplexity Computer har vi sett enskilda uppgifter anropa hundratals eller till och med tusentals hämtningsåtgärder på några få minuter: ett arbetsflöde som är omöjligt för människor men helt naturligt för agenter.
I denna värld måste sökningen i sig bli agentisk, med dess byggstenar tillgängliga direkt som SDK:er i agentramverket. Vi introducerar Search as Code (SaC) som Perplexity nya referenssökarkitektur.
Introduktion
Perplexitys sökstack hanterar tusentals sökfrågor varje sekund i våra applikationer och vår API-plattform. I september 2025 publicerade vi den första arkitektoniska översikten av våra söksystem. Ständig innovation inom dessa system har stöttat lanseringen av nya erbjudanden som Search API, Agent API och Computer, med självförbättringssloopar som optimerar sökstacken för att bättre betjäna användarna för varje dag som går.
Traditionellt har AI-system behandlat sökning som en monolit: en AI-modell utfärdar en sökfråga, sökmotorn kör sin fördefinierade pipeline och modellen konsumerar resultaten som kontext. För det mesta fungerade detta utmärkt för att möta behoven hos tidiga AI-användare. Med tanke på den relativa enkelheten i deras förfrågningar fanns det ingen anledning att oroa sig för exakt hur sökpipelinen var utformad, eller om pipelinens arkitektur var optimal för den aktuella uppgiften. Standardvärdena ansågs vara tillräckligt bra, liksom standardgränssnitten (funktionsanrop och MCP:er).
Ändå blir detta tillvägagångssätt mer föråldrat för varje månad som går. Användarna kräver mycket mer än enstaka analyser från AI. De förväntar sig att agenter ska slutföra uppgifter från början till slut under timmar eller till och med dagar. Dessa uppgifter kan vara komplexa, öppna och mycket varierande i sina informationsbehov, och monolitiska arkitekturer sviktar under vikten av dessa krav.
Den centrala flaskhalsen handlar i slutändan om kontroll. Frontier-modeller är redan ganska bra på att resonera kring fast kontext. De mest kraftfulla AI-systemen kommer dock att kräva förmågan att styra hur den kontexten hämtas, bearbetas, aggregeras och presenteras för modellen.
Traditionella söksystem utformades inte med denna grad av styrbarhet i åtanke. Mänskliga användare kan trots allt inte förväntas utöva finkornig kontroll över sökpipelinens interna delar ens om det erbjöds. Tidiga AI-modeller kan endast styra sökningen genom en linjär bana av funktionsanrop och MCP:er. Men dagens frontier-modeller, som drivs av kodkapabla agentramverk, kan utöva finkornig kontroll över vilka beräkningsprimitiver som helst som kan tänkas med datorkod. Vår uppgift blir att tillhandahålla rätt primitiver.
För att möta detta behov introducerar vi en ny sökarkitektur i alla våra produkter: Search as Code (SaC). Denna nya arkitektur ger modeller befogenhet att nå in i själva sökstacken snarare än att enbart konsumera dess slutresultat. Kärnidén är enkel: vi exponerar sökstackens komponenter som primitiver inom ett SDK. För alla förfrågningar som kräver sökning sätter en modell ihop dessa primitiver on-demand till en hämtningspipeline som är skräddarsydd för just den förfrågan.
Sammansättningen av denna pipeline görs genom kodgenerering och exekvering i en säker sandlåda. Till skillnad från andra kodgenereringsdrivna tillvägagångssätt för sökning klistrar vi inte bara in ett traditionellt sök-API i ett skal eller en språkkörningsmiljö. Istället har vi noggrant utformat ett Agentic Search SDK som exponerar sökningens enskilda byggstenar på en så atomär nivå som möjligt.
Beväpnad med dessa byggstenar ger SaC modeller direkt kontroll över varje enskilt söksteg: hämtning, rangordning, filtrering, fanouts, rendering med mera. Det ger också modellen effektiv åtkomst till intermediärt tillstånd som kandidatlistor och rangordningssignaler. Tillsammans gör dessa dubbla hävstänger för kontroll och läsbarhet att agenter kan designa skräddarsydda sökpipelines som spänner över tusentals hämtningsåtgärder, optimera dessa pipelines under pågående körning och endast konsumera den mest användbara informationen som modellkontext.
Denna artikel beskriver motivationen, designen och implementeringen av SaC, tillsammans med empiriska resultat på både befintliga och nya riktmärken. SaC etablerar en ny kostnadskraftsgräns för agentisk sökning, och vi är glada över att dela med oss av den till våra användare och den bredare AI-gemenskapen.
Traditionell söks stela natur
Världens första sökmotorer byggdes för mänskliga användare. Dessa användare kom att förvänta sig en förutsägbar upplevelse, som vanligtvis bestod av ett fast antal relevansrankade dokument. Användarna ville inte mikrostyra sökprocessen; de ville ange en sökfråga och hitta ett användbart resultat.
Som ett resultat konvergerade människoinriktade sökmotorer till en gemensam monolitisk arkitektur, inriktad på att producera människovänliga sökmotorsresultatsidor (SERP) som innehåller de översta n-träffarna för en indatafråga. Detta mönster har drivit decennier av framsteg inom konsumentsökning. Det är snabbt, bekant och mycket effektivt för mänskligsurfning.
Sedan kom LLM:er, och AI-system blev också konsumenter av sökning. Perplexity banade väg för denna förändring med lanseringen av vår svarsmotor 2022. Sedan dess har våra sökoptimeringsansträngningar fokuserat på hur man kan optimera värdet av sökresultat för AI-modeller. För att bygga världens mest exakta och tillförlitliga AI var vi tvungna att konstruera ett söksystem som fokuserade på att göra varje token så informationsdats som möjligt. De resulterande innovationerna inom underdokumentshämtning, kontexteffektivitet, semantisk förståelse och andra nyckelområden ledde till dramatiska förbättringar av AI-systemens förmåga att hämta och agera på information.
Även AI-optimerade system har dock till stor del ärvt samma grundläggande kontrakt som traditionella sökmotorer: acceptera en sökfråga, kör en fördefinierad sökpipeline, returnera ett fullständigt bearbetat resultatset. För enkla förfrågningar fungerar detta tillvägagångssätt bra. Men för mer komplexa förfrågningar blir detta en alltmer begränsande flaskhals som försämrar prestanda, latens och kostnad.
Feltyper orsakade av stelhet
Traditionella sökpipelines är utformade kring en enda kontrollpunkt: frågeparametrarna. Sökmotorn äger resten av pipelinen enligt sin fördefinierade logik, och modellen måste anpassa sig efter den. För modellen är allt nedströms om frågeparametrarna styvt – formen på den faktiska beräkningen ligger utanför modellens kontroll.
Detta är en rimlig gräns när konsumenten är en människa som skannar länkar. Det är en dålig gräns när konsumenten är en AI-modell som försöker lösa kunskapsintensiva uppgifter i en sluten slöja. Enligt vår erfarenhet skapar denna stelhet tre återkommande feltyper:
Grov kontext. AI-modeller är känsliga för kontextens kvalitet och kompakthet. Både kvalitet och kompakthet är starkt frågeberoende, och monolitiska sökpipelines är inte utformade för att fungera optimalt för alla sökfrågor. Om en modell till exempel behöver en enskild, mycket kirurgisk bit information men bara har tillgång till en end-to-end-sökslutpunkt som prioriterar återkallande, kommer användningen av den slutpunkten att introducera en stor mängd irrelevant information i modellkontexten. Å andra sidan, om en modell behöver många informationsbitar som var och en kräver olika sökstrategier, kan den tvingas att i följd anropa samma suboptimatimala pipeline för alla dem, vilket resulterar i skenande kostnader och bullrig kontext.
Underlåtenhet att utnyttja domänkunskap. I många fall kan modellen ha domänkunskap (från sin träning, en Skill, minne eller tidigare tokens i LLM-banan) som bör styra sökstrategin. Ett stelt sökgränssnitt hindrar dock modellen från att utnyttja den kunskapen. Modellen kan till exempel inse för en specifik begäran att den bör blanda lexikala och semantiska signaler på ett visst sätt, prioritera vissa källor eller aggregera resultat med en specifik nyckel. Om inte dessa insikter råkar gå att implementera via frågeparametrar kan modellen inte faktiskt handla efter dem.
Ineffektivt kontrollflöde och kontextförorening. Många sökarbetsflöden är inte naturligt seriella. De kan behöva spridning över frågevarianter, parallell hämtning, deduplicering och andra åtgärder som kräver olinjära och asynkrona kontrollflöden. Att tvinga fram dessa steg genom upprepade modellbyten lägger till latens och gör arbetsflödet svårare att optimera. Det förorenar också modellkontexten med brusigt intermediärt tillstånd som kanske inte är användbart för modellens resonemang, vilket resulterar i sämre prestanda och oftare förekommande kompaktioner.
Inte mycket kunde göras åt dessa utmaningar under funktionanrops- och MCP-eran inom AI. När varje sökåtgärd kräver sin egen tur och retur till LLM-inferens föredrar utvecklare naturligtvis att få så mycket gjort som möjligt under den turen och returen. Detta innebär end-to-end-sökpipelines som returnerar färdigbearbetade resultatset för direkt konsumtion av en modell.
Som ett resultat fungerar de flesta AI-inriktade söksystem idag fortfarande under detta monolitiska kontrakt. Men med fortsatt tillväxt i modellens intelligens och användarkrav blir bristerna i det kontraktet mer uttalade. Dagens mest avancerade AI-system, byggda ovanpå kodförstärkta ramverk, kan komponera uppgiftsspecifika arbetsflöden som utför tusentals åtgärder varje minut. Söksystem har ännu inte till fullo förverkligat denna potential.
Vi har länge misstänkt att rätt gräns för AI-nativ sökning ligger lägre i stacken. Modeller bör inte bara anropa en sökmotor. De bör kunna orkestrera sökstackens enskilda delar i takt med att den specifika uppgiften kräver det. Det kräver en fundamentalt annorlunda arkitektur.
Utformning av en programmerbar sökarkitektur
Nästa generation av sökarkitekturer kommer att vila på en central princip: sökning bör vara inhemskt programmerbar av AI-agenter. En agent får inte begränsas till en uppsättning förutbestämda sökpipelines. Snarare måste en agent kunna konstruera den pipeline som den specifika uppgiften kräver, med hjälp av komponerbara byggstenar utformade på olika abstraktionsnivåer.
Vår nya Search as Code (SaC)-arkitektur förkroppsligar denna princip. I SaC skickas inte en enda hämtningsåtgärd via ett funktionsanrops- eller MCP-gränssnitt. Alla åtgärder orkestreras i stället via modellgenererad Python-kod. För de enklaste sökbehoven kan denna kod bestå av en handfull förfrågningar till en sökslutpunkt på hög nivå. Men för komplexa uppgifter kan koden vara så invecklad som behövs, vilket innefattar villkorad exekvering, asynkronitet, parallellitet och anrop till ett brett utbud av lågnivåprimitiver.
SaC omfattar tre tätt kopplade lager:
Modeller fungerar som kontrollplan. De resonerar kring användarens (eller moderagentens) direktiv, bryter ner direktivet i uppgifter, bestämmer vilka hämtnings- och bearbetningspipelines som behövs för varje uppgift och genererar kod för att implementera dessa pipelines.
Beräkningssandlådor tillhandahåller deterministiska beräkningar genom en säker körningsmiljö för kod. De tillhandahåller en duk för modeller att implementera kontrollflöde, batchning, försök igen, filtrering, sammanslagning, aggregering och andra deterministiska åtgärder.
Vårt Agentic Search SDK exponerar Perplexitys sökstack som komponerbara primitiver. Det tillhandahåller byggstenar från lågnivåhämtningsåtgärder till semantisk parsning på hög nivå. SDK:t är inbäddat i sandlådornas körningsmiljöer, vilket gör att modeller kan orkestrera upp till tusentals åtgärder inom en enda inferenstur. Nedan diskuterar vi våra designbeslut för varje lager.
Agentic Search SDK
Agentic Search SDK definierar byggstenarna för programmerbar sökning. Viktigt är att vårt SDK inte är ett existerande sök-API paketerat som ett bibliotek. Under de senaste månaderna har vårt ingenjörsteam omarbetat vår sökstack till modulära, komponerbara primitiver. Vi har byggt Agentic Search SDK för att ge direkt åtkomst till dessa primitiver, vilket skapar en mycket kraftfullare duk på vilken modellen kan orkestrera uppgiftsspecifika hämtningspipelines.
End-to-end-sökpipelines på hög nivå är fortfarande tillgängliga inom SDK:t, men de är inte längre det enda alternativet. Snarare fungerar de som en form av genväg för vanliga sökmonster. Modellen står fri att använda eller kringgå dem allt eftersom uppgiften kräver.
Val av körningsmiljö: Vi övervägde Python, Rust, TypeScript och Bash som SDK-körningsmiljö. Vi anade att Python skulle passa bäst med tanke på dess allestädes närvaro och ekosystem av databearbetningsbibliotek. Intern testning bekräftade att så var fallet, och den version av SDK som rullas ut idag är Python-baserad. Vi förväntar oss att regelbundet utvärdera valet av körningsmiljö för att säkerställa att det fortsätter att erbjuda den bästa agentupplevelsen.
Ständig förbättring via autoresearch: Vi har också optimerat SDK:ns konsumerbarhet för frontier LLM:er genom en iterativ autoresearch-loop. Denna loop, som körs kontinuerligt under veckor, föreslår och validerar SDK-förbättringar mot mätvärden inklusive latens, kodgenereringskvalitet och övergripande uppgiftsprestanda. Autoresearch-loopen har redan gjort åtskilliga ändringar i både SDK:ts struktur och estetik, med betydande vinster över alla dimensioner. Vi planerar att ytterligare förfina SDK:t via autoresearch i takt med att nya frontier-modeller och sökkomponenter dyker upp.
Sandlådor
Sandlådor tillhandahåller säkra miljöer för att definiera och köra SaC-pipelines. De exekverar modellgenererad kod och ger tillgång till Agentic Search SDK för att underlätta interaktion med enskilda sökprimitiver.
Vi har gjort betydande investeringar i att optimera och härda våra sandlådor, och deras övergripande systemdesign förtjänar en artikel i sin egen rätt. Här fokuserar vi på de designöverväganden som är mest relevanta för SaC: hantering av intermediära tillstånd.
SaC ger agenter befogenhet att orkestrera komplexa pipelines inom en enda inferenstur. Vissa intermediära tillstånd måste dock förmedlas över turer. Till exempel kan en modell vilja hämta vissa dokument i tur 1, inspektera ett urval av dessa dokument i tur 2 för att bestämma vad som ska göras härnäst och sedan utveckla en nedströms sökpipeline för att ytterligare undersöka dessa dokument från tur 3 och framåt. Som diskuterats ovan är det inte en effektiv strategi att skicka intermediära tillstånd genom tokenrymden.
Vi övervägde två tillvägagångssätt för att hantera intermediära tillstånd över turer:
Beständigt filsystem + explicit serde: Sandlådor kan exponera beständiga filsystem som modeller kan använda över turer. Modeller som vill behålla intermediära tillstånd kan inkludera ett serialiseringssteg i den genererade koden för en tur, tillsammans med ett avserialiseringssteg i en efterföljande tur (antingen för modellernas egen inspektion eller för nedströms användning). Filsystemmetoden gör det möjligt för modeller att direkt och explicit styra hur intermediära tillstånd förmedlas över turer. Det säkerställer också spårbarhet genom att tvinga fram explicit identifiering och beständighet för information som används av modellen. En nackdel är den latens och kontextomkostnad som genereras av att skapa serde-koden, även om väl utformade verktygsfunktioner kan mildra denna omkostnad.
REPL: Alternativt kan en sandlåda behålla själva körningsmiljön över turer i en miljö av REPL-typ. Detta gör det möjligt för modeller att underhålla intermediära tillstånd i minnet utan att behöva serialisera dem alls, eftersom variabler som definierats eller modifierats i tidigare turer helt enkelt kan refereras med namn i efterföljande turer. REPL-metoden är mer tokeneffektiv eftersom den slipper behovet av att generera serde-kod. Avsaknaden av ett explicit serialiseringssteg kan dock skada nedströms prestanda av skäl som är bekanta för alla som har arbetat med en anteckningsbok med 100 celler i Jupyter: när variabelnamnrymden blir rörig blir det svårare att hålla reda på vad som exakt bevaras över turer och varför.
Vi testade båda metoderna och fann att även om de presterar likartat vid vanlig användning, erbjuder filsystemsbaserad serde bättre tillförlitlighet vid särskilt långa banor. Vi antar därför filsystemsbaserad serde som vår lösning. Vi antar att kravet på att modeller ska förmedla tillstånd deklarativt snarare än implicit hjälper dem att hantera det tillståndet mer effektivt. Detta är ett preliminärt fynd och vi kommer att fortsätta att iterera på båda metoderna.
Modeller
De modeller som driver agentramverken fungerar som SaC:s kontrollplan: de sätter dynamiskt samman sökpipelines från Agentic Search SDK:s byggstenar för att möta behoven för varje uppgift, och skickar sedan ut dessa pipelines som kod för exekvering i sandlåda.
Perplexity använder en mängd olika modeller inom våra agentramverk, och vi har funnit att de senaste frontier-modellerna är ganska effektiva överlag på allmän kodgenerering. Den stora utmaningen är att framkalla effektiv kodgenerering specifikt för Agentic Search SDK. Det vill säga, hur kan vi få modeller att effektivt väva samman våra SDK-byggstenar till uppgiftsoptimerade pipelines?
Till skillnad från ett språks standardbibliotek är det osannolikt att ett skräddarsytt SDK representeras i förträningsdata. Även med SDK:ns förbättringar av konsumerbarhet från autoresearch tränas många modeller fortfarande till att interagera med söksystem genom funktionsanrop och direkt MCP-anrop. Dessa modeller kommer sannolikt inte att sakkunnigt använda SDK:t enbart med källkod och autogenererad dokumentation.
För att lösa denna utmaning har vi utvecklat finjusterade Agent Skills för att lära modeller att effektivt utnyttja vårt SDK. De ursprungliga versionerna utvecklades i enlighet med Perplexitys designprinciper för Skills och optimerades sedan genom en dedikerad autoresearch-loop fokuserad på samma mätvärden som används vid SDK-optimering. Vi begränsar också storleken på skill för att skydda mot kontextsvullnad, och våra slutgiltiga versioner har färre än 2000 tokens i sina SKILL.md-filer i roten.
De optimerade Skill sträcker sig bortom att räcka upp SDK:ns tillgängliga byggstenar (något som lika gärna kan erhållas via körtidsreflektion). Huvuddelen av tokens ägnas åt att tillhandahålla koncis, generaliserbar vägledning och few-shot-exempel för att komponera dessa block till komplexa mönster. Beväpnade med dessa Skill observerar vi hur modeller effektivt utnyttjar SDK:t för att orkestrera sökpipelines som skalar upp till tusentals diskreta åtgärder.
Kod som orkestrerare och luckfyllare
Genom att kombinera dessa lager förändrar SaC förhållandet mellan modeller och sökstacken. I sökssystem med fasta pipelines sitter modellen ovanför sökningen och interagerar med den via ett smalt seriellt anropsgränssnitt. I SaC blir modellen en aktiv deltagare i att orkestrera själva sökprocessen. Alla delar av sökstacken blir direkt programmerbara av modellen, där sandlådan och Agentic Search SDK tillhandahåller de nödvändiga gränssnitten till dessa element.
Men hur är det med funktioner som inte existerar inbyggt? Kod är ett kraftfullt medium för att orkestrera förhandsexisterande funktioner. Kods kraft går dock utöver orkestrering. Den kan också fungera som en luckfyllare för funktioner som inte finns i sökstacken eller SDK:t. Agenter gynnas av sparsamhet, och det skulle vara ineffektivt för SDK:t att täcka varje potentiell åtgärd med en dedikerad funktion. I stället tillhandahåller SDK:t de mest grundläggande primitiverna, och modellen kan bygga eventuella ytterligare komponenter i farten med kod.
Överväg till exempel ett komplext reguljärt uttryck som inte effektivt kan implementeras via sökcystemets egen frågesyntax. Utan kodningsmöjligheter skulle modellen tvingas generera sin bästa approximation, göra en sökfråga och utföra tokenrymdsfiltrering på ett mycket bullrigt resultatset. Med SaC kan modellen i stället generera ett program som gör parallella SDK-anrop för att samla in en superset av det önskade reguljära uttryckets resultatset. Efter deduplicering via SDK:t kan modellen sedan skriva ytterligare kod för att deterministiskt begränsa resultaten till det exakta reguljära uttrycket. På detta sätt kan agenter implementera anpassade sökfunktioner utan att överbelasta SDK:t med alltför nischade subrutiner.
Fallstudie: CVE-leverantörsråd
Vi presenterar en fallstudie baserad på en verklig uppgift inom vår testsvit. Denna uppgift ber en agent att identifiera och karakterisera över 200 sårbarheter med hög allvarlighetsgrad (CVE:er) från 2023–2025. Varje post måste ange den berörda leverantörens egna råd, namnge produkten och fixversionen och visa att fixversionen är kopplad till den specifika CVE:n.
SaC:s svar fick 100 % i noggrannhet, och den totala tokenanvändningen sjönk med 85,1 % i förhållande till baslinjen utan SaC (från 288,7K tokens till 42,9K tokens). De testade systemen utan Perplexity, som diskuteras mer i detalj i avsnitt 4, fick samtliga lägre poäng än 25 %.
Vi presenterar tre stiliserade kodblock från banan för att illustrera hur SaC:s programmerbarhet tillåter modellen att implementera effektiva 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"])
]Detta första block är ren orkestrering. Det genererade programmet börjar med att koda regeln för källklass direkt i frågeplanen: endast rådformat som ägs av leverantören är relevanta. Icke-leverantörskällor inklusive NVD, MITRE, CVE Details, nyhetsartiklar, CERT-sidor och databaser från tredje part faller strukturellt utanför ramen. De exakta frasbegränsningarna driver också sökningen mot sidor vars indexerade text redan innehåller de exakta CVE-detaljer som behövs längre fram.
# 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,
)Det andra blocket använder en LLM som en intermediär planeringssubrutin. Koden sammanfattar vilka leverantörs-år-par som producerar tillräckligt med kandidatsidor, ber om riktade förbättringar och validerar varje föreslagen sökfråga före exekvering. Detta bevarar användbara mönster från banan, såsom platssökta exaktfrasprober och adaptiv bakfyllnad, utan att hårdkoda en skräddarsydd CVE-rådgivningscrawlers i SDK:t.
# 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")Det sista blocket är en resultatverifierare vars logik definieras helt av agenten via kodgenerering. Även om söksubrutiner kan hitta rimliga rådgivningssidor kräver uppgiften en striktare relation: rådgivningen måste binda en CVE till en berörd produkt och en fixversion i text författad av leverantören. Schemat gör den relationen explicit, så att nedströms kod kan deduplicera per CVE, avvisa aggregator-URL:er, kassera svaga versionsbevis och fortsätta fylla på tills postantalsgolvet uppnås.
Utvärderingsresultat
Vi utvärderar SaC:s effektivitet på en omfatande riktmärkessvit, med fokus på både absolut prestanda och kostnadsprestandagränsen.
Riktmärken och system
Vår riktmärkessvit omfattar totalt fem riktmärken, utformade för att stress testa sökberoende AI-arbetsflöden över en rad domäner, uppgiftsformat och komplexitetsnivåer. Vi använder fyra befintliga riktmärken: DeepSearchQA (DSQA), BrowseComp, Humanity's Last Exam (HLE) och WideSearch. För de första tre riktmärkena (DSQA, BrowseComp och HLE) rapporterar vi noggrannhet som det översta mätvärdet. För WideSearch rapporterar vi F1-poäng per rad.
Vi använder också det nyutvecklade WANDR-riktmärket, som fokuserar på svåra "bred forskning"-uppgifter som kräver noggrann orkestrering av sökning, beräkning och modellresonemang. WANDR är inspirerat av de kunskapsintensiva professionella uppgifter som Perplexity Computer hanterar åt användare. Det bygger vidare på WideSearch och liknande riktmärken, men betonar mer komplexa uppgifter och uppgiftsstrukturer. Vi kommer att publicera WANDR-riktmärket under de kommande veckorna.
Vi utvärderar fem agentbaserade system. Vi betraktar enskilda körningar snarare än "bäst av N"-poäng för att isolera prestandan hos den underliggande arkitekturen snarare än fördelarna med parallellisering. Varje systems konfiguration beskrivs nedan:
Perplexity (SaC): Vi utvärderar SaC-arkitekturen inom Perplexitys produktions-Agent API. GPT 5.5 (högt resonemang) fungerar som den underliggande modellen.
OpenAI: Vi utvärderar OpenAI Responses API med både sökning (web_search) och Python-körningsmiljö (code_interpreter) aktiverade. GPT 5.5 (högt resonemang) fungerar som den underliggande modellen.
Anthropic: Vi utvärderar Anthropic Managed Agents med agentverktygsuppsättningen 20260401 och auto-tillåtna kommandon. Opus 4.7 (högt resonemang) fungerar som den underliggande modellen.
Exa: Vi utvärderar Exa Agent via produktions-API:et, med ansträngning satt till hög.
Parallel: Vi utvärderar Parallel Tasks via produktions-API:et, med processorn satt till ultra4x.
Jämförande prestanda
Tabell 1 rapporterar riktmärkspoäng för varje system. SaC presterar bättre än alla andra system på fyra av de fem riktmärkena. På det återstående riktmärket (HLE) är SaC i princip oavgjort på första plats med OpenAI Responses. Figur 2 från introduktionen visualiserar dessa poäng i grafisk form.
Riktmärke | 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 |
Tabell 1 | Riktmärkspoäng för varje utvärderat system. Bästa poäng per rad i fetstil.
Även om SaC uppnår topprestanda över riktmärkessviten är dess fördel särskilt uttalad på WANDR. Figur 5 bryter ner WANDR-poängen och visar att Perplexitys SaC-implementering presterar bättre än näst bästa system med en faktor på 2,5×. Trots denna breda marginal förblir WANDR omättad och visar sig utmanande även för SaC. Vi anser att de komplexa, mycket horisontella sökarbetsflöden som krävs av WANDR:s uppgifter kommer att kräva ytterligare framsteg inom forskning och sök- och ingenjörskonst för att uppnå konsekvent hög prestanda.
Slutligen mäter vi de relativa vinsterna för SaC jämfört med en mer traditionell sökpipeline som utnyttjar samma Perplexity-sökstruktur. Figur 6 rapporterar skillnaden i poäng mellan SaC- och icke-SaC-arkitekturerna över varje riktmärke. Över hela linjen ger SaC ett väsentligt lyft i prestanda, med den största absoluta vinsten på DSQA (+19,77 pp, 29 %) och den största relativa vinsten på WANDR (+12,00 pp, 45 %).
Kostnadsprestandagräns
I praktiken bryr sig användarna om prestanda i förhållande till kostnad. Vi utvärderar därför kostnadsprestandagränsen på DSQA och WideSearch. Vi mäter kostnaden och prestandan för SaC över låga, medelhöga och höga resonemangsnivåer för modellen, tillsammans med de andra systemen. Figur 7 och 8 plottar riktmärkspoäng mot pris per uppgift, med x-axeln omvänd så att punkter längre till höger är billigare och punkter högre upp representerar bättre prestanda.
På DSQA ligger alla tre SaC-inställningarna på den övre högra gränsen. Inställningen för lågt resonemang är billigare än alla andra system samtidigt som den presterar bättre än två av dem. Inställningen för medelhögt resonemang presterar bättre än alla icke-SaC-system till under 1 $ per uppgift. Inställningen för högt resonemang uppnår topprestanda till en konkurrenskraftig kostnad.
WideSearch visar en liknande formad gräns. Liksom med DSQA uppnår inställningen för lågt resonemang konkurrenskraftig prestanda till lägre kostnad än alla icke-SaC-system, medan både medelhögt och högt resonemang presterar bättre än icke-SaC-system vad gäller uppgiftsprestanda.
Mot en ny datorkraftarkitektur
Search as Code återspeglar en bredare förändring inom mjukvarudesign. Under decennier organiserades mjukvarusystem kring deterministiska instruktioner som exekverades av traditionella körningsmiljöer på CPU:er. Frontier-modeller introducerar en ny form av beräkning: tokenrymdsresonemang som både kan följa och generera instruktioner. De mest kapabla beräkningssystemen kommer att kombinera dessa två former av beräkning snarare än att välja mellan dem.
Sökning är en naturlig provbänk för denna hybridarkitektur. Modeller lämpar sig väl för att besluta vilket bevis som behövs och hur osäkerhet bör lösas. Deterministiska körningsmiljöer lämpar sig väl för batchning, parallellitet, filtrering, rangordning och aggregering. Sökstrukturen fungerar som ett universellt I/O-lager, vilket ger körningsmiljön användbara handtag till världens information som kan upprätthålla tusentals åtgärder per minut. När dessa bitar integreras blir det resulterande systemet mycket kraftfullare och effektivare när det gäller att utföra verkliga uppgifter.
Varje del av denna arkitektur är nödvändig för att låsa upp dessa funktioner. Utan intelligenta modeller kan systemet inte resonera kring sökstrategi. Utan sandlådor tvingas modeller till seriell I/O och ineffektiv tokenrymdsbearbetning. Och utan en atomiserad sökstack har modellen ingenting att orkestrera. SaC fungerar eftersom resonemang, deterministisk beräkning och I/O är gemensamt utformade för att framhäva varje lagers styrkor.
Denna samdesign kan drivas ännu längre genom utveckling av kontinuerliga förbättringssloopar. Exempelvis kan Agentic Search SDK och SaC Agent Skills optimeras gemensamt i en gemensam autoresearch-loop. Mer ambitiöst kan modeller tränas för att dra nytta av lågnivå-sökprimitiver som exponeras som ett SDK. Man kan till och med försöka samevolvera SDK-design under själva modellträningsprocessen. Vi ser fram emot att fullfölja mer aggressiva samdesignstrategier i framtida arbete.
Vi byggde SaC för att låta modeller styra sökprocessen, snarare än att enbart konsumera dess resultat. Våra resultat bevisar kraften i denna kontroll: SaC flyttar fram både absolut prestanda och kostnadsprestandagränsen på kunskapsintensiva agentriktmärken. Vi är glada över att kunna erbjuda SaC:s funktioner till våra användare, med början idag med Perplexity Computer och Agent API. Vi kommer att fortsätta att optimera SaC-arkitekturen över alla lager i stacken för att säkerställa att våra användare (och de agenter som betjänar dem) har de kraftfullaste och effektivaste sökfunktionerna som är möjliga.
Citering
@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}
}