Преосмисляне на търсенето като генериране на код

Развиване на търсенето от монолитни услуги до програмируеми примитиви за ерата на агентните инструменти.

АвториPerplexity Research

Търсенето е основен примитив за AI системите. Фронтиър моделите стават все по-способни с всеки изминал месец, но те все още се нуждаят от достъп до свежи, точни и добре курирани знания от широкия свят. Търсенето е основният начин, по който AI системите се свързват с тези знания, и следователно е основополагащ компонент на всеки продукт, който трябва да прави изводи, да предприема действия и да извършва реална работа.

Вярваме, че традиционните конвейери за търсене стават все по-остарели в ерата на агентите. Традиционното търсене отговаря на заявки, но днешните агенти изпълняват задачи, които могат да приемат безброй форми. Тези задачи изискват агентите да дефинират специфични за задачата стратегии за извличане директно в рамките на техните работни инструменти (harnesses). В рамките на Perplexity Computer сме виждали как отделни задачи извикват стотици или дори хиляди операции по извличане за няколко минути: работен процес, който е невъзможен за хората, но напълно естествен за агентите.

В този свят самото търсене трябва да стане агентно, като неговите градивни елементи са достъпни директно като SDK в рамките на агентния работен инструмент. Представяме Search as Code (SaC) като новата референтна архитектура за търсене на Perplexity.

Въведение

Системата за търсене на Perplexity обслужва хиляди заявки всяка секунда в нашите приложения и API платформата. През септември 2025 г. публикувахме първия архитектурен преглед на нашите системи за търсене. Постоянните иновации в рамките на тези системи подпомогнаха пускането на нови предложения като Search API, Agent API и Computer, като циклите за самоусъвършенстване оптимизират стека за търсене, за да обслужват по-добре потребителите с всеки изминал ден.

Традиционно AI системите третират търсенето като монолит: AI модел подава заявка, търсачката изпълнява предварително дефинирания си конвейер, а моделът консумира резултатите като контекст. В най-общия случай това работи добре за задоволяване на нуждите на ранните AI потребители. Предвид относителната опростеност на техните заявки, нямаше причина да се притесняват точно как е проектиран конвейерът за търсене или дали архитектурата на конвейера е оптимална за конкретната задача. Предполагаше се, че стандартните настройки са достатъчно добри, както и стандартните интерфейси (извикване на функции и MCP).

Традиционните архитектури за търсене представят една единствена фиксирана система, която моделите извикват серийно, докато Search as Code представя атомизирани примитиви за търсене, които агентите комбинират чрез генериран код.

И все пак днес този подход става все по-остарял с всеки изминал месец. Потребителите изискват много повече от еднократен анализ от страна на AI. Те очакват агентите да изпълняват задачи от край до край за часове или дори дни. Тези задачи могат да бъдат сложни, с отворен край и силно променливи по отношение на нуждите си от информация, а монолитните архитектури се огъват под тежестта на тези изисквания.

Основното тесногръдие в крайна сметка е свързано с контрола. Фронтиър моделите вече са доста добри в разсъжденията върху фиксиран контекст. Въпреки това най-мощните AI системи ще изискват способността да насочват как този контекст се извлича, обработва, агрегира и представя на модела.

Традиционните системи за търсене не са проектирани с мисъл за тази степен на управляемост. В края на краищата от човешките потребители не може да се очаква да упражняват фина настройка и контрол върху вътрешните работи на конвейера за търсене, дори и да им се предлагаше такава възможност. Ранните AI модели могат да управляват търсенето само чрез линейна траектория от извиквания на функции и MCP. Но днешните фронтиър модели, задвижвани от агентни инструменти с възможности за генериране на код, могат да упражняват финан контрол върху всякакви изчислителни примитиви, които могат да се ситуират чрез компютърен код. Нашата задача става да предоставим правилните примитиви.

За да отговорим на тази нужда, представяме нова архитектура за търсене в нашите продукти: Search as Code (SaC). Тази нова архитектура дава възможност на моделите да достигнат вътре в самите основи на търсенето, вместо просто да консумират крайните му резултати. Основната идея е проста: излагаме компонентите на стека за търсене като примитиви в рамките на SDK. За всяка заявка, която се нуждае от търсене, моделът сглобява тези примитиви при поискване в конвейер за извличане, адаптиран към тази конкретна заявка.

Сглобяването на този конвейер става чрез генериране и изпълнение на код в сигурна Sandbox среда. За разлика от други ориентирани към кодиране подходи за търсене, ние не просто поставяме традиционен Search API в обвивка или езиков изпълним модул. Вместо това сме проектирали внимателно SDK за агентно търсене (Agentic Search SDK), което излага отделните градивни елементи на търсенето на възможно най-атомно ниво.

Search as Code (SaC) подобрява границите на производителността на агентното търсене в разнообразен набор от бенчмаркове.

Въоръжен с тези градивни елементи, SaC дава на моделите директен контрол върху всяка отделна стъпка на търсене: извличане, класиране (рейтинг), филтриране, разклоняване (fanouts), изобразяване и др. Той също така дава на модела ефективен достъп до междинно състояние, като списъци с кандидати и сигнали за класиране. Заедно тези два лоста за контрол и четимост позволяват на агентите да проектират персонализирани конвейери за търсене, обхващащи хиляди операции по извличане, да оптимизират тези конвейери в движение и да консумират само най-полезната информация като контекст на модела.

Тази статия описва мотивацията, дизайна и изпълнението на SaC, наред с емпиричните резултати както по съществуващи, така и по нови бенчмаркове. SaC установява нова граница между разходи и производителност за агентното търсене и се радваме да я споделим с нашите потребители и по-широката AI общност.

Негъвкавостта на традиционното търсене

Първите търсачки в света бяха създадени за човешки потребители. Тези потребители очакваха предвидимо изживяване, обикновено състоящо се от фиксиран брой класирани по релевантност документи. Потребителите не искаха да микроуправляват процеса на търсене; те искаха да въведат заявка и да намерят полезен резултат.

В резултат на това ориентираните към хората търсачки се обединиха около обща монолитна архитектура, насочена към създаване на удобни за човека страници с резултати от търсачката (SERP), съдържащи първите n попадения за входяща заявка. Този модел е захранвал десетилетия напредък в потребителското търсене. Той е бърз, познат и силно ефективен за човешкото сърфиране.

След това се появиха LLM и AI системите също станаха потребители на търсенето. Perplexity беше пионер в тази промяна с пускането на нашия двигател за отговори през 2022 г. Оттогава насам нашите усилия в областта на инженерното търсене са насочени към това как да оптимизираме стойността на резултатите от търсенето за AI моделите. За да изградим най-точния и надежден AI в света, трябваше да проектираме система за търсене, фокусирана върху това да направим всеки токен максимално информационно наситен. Получените иновации в областта на извличането на поддокументи, ефективността на контекста, семантичното разбиране и други ключови области доведе до драстични подобрения в способността на AI системите да извличат информация и да действат въз основа на нея.

Въпреки това, дори оптимизираните за AI системи до голяма степен са наследили същия фундаментален договор като традиционните търсачки: приемат заявка, изпълняват предварително дефиниран конвейер за търсене, връщат напълно обработен набор от резултати. За прости заявки този подход работи добре. Но за по-сложни заявки това се превръща във все по-ограничаващо тесногръдие, което влошава производителността, латентността и разходите.

Традиционните системи за търсене принуждават агентните работни процеси да подреждат търсенето в последователност чрез видими за модела ходове (turns). Моделите трябва многократно да извикват едни и същи конвейери за търсене през различни параметри на заявката и да въвеждат всички резултати в контекста на модела.

Режими на неизправност поради негъвкавост

Традиционните конвейери за търсене са проектирани около една точка на контрол: параметрите на заявката. Търсачката притежава останалата част от конвейера според предварително дефинираната си логика и моделът трябва да се адаптира към нея. За модела всичко след параметрите на заявката е негъвкаво – формата на действителното изчисление е извън контрола на модела.

Това е разумна граница, когато потребителят е човек, който сканира връзки. Това е лоша граница, когато потребителят е AI модел, който се опитва да решава интензивни на знания задачи в затворен цикъл. В нашия опит тази негъвкавост създава три повтарящи се режима на неизправност:

Груб контекст. AI моделите са чувствителни към качеството и компактността на контекста. Както качеството, така и компактността зависят силно от заявката, а монолитните конвейери за търсене не са проектирани да работят оптимално при всички заявки. Например, ако моделът се нуждае от една единствена, силно прецизна част от информацията, но има достъп само до крайна точка за търсене от край до край, която дава приоритет на изземването (recall), използването на тази крайна точка ще въведе голямо количество нерелевантна информация в контекста на модела. От друга страна, ако моделът се нуждае от много части информация, всяка от които изисква различни стратегии за търсене, той може да бъде принуден да извиква серийно един и същ субоптимален конвейер за всички тях, което води до нарастващи разходи и шумен контекст.

Неуспех при използването на домейн знания. В много случаи моделът може да разполага с домейн знания (от своето обучение, умение на агент (Agent Skill), памет или по-ранни токени в траекторията на LLM), които трябва да ръководят стратегията за търсене. Негъвкавият интерфейс за търсене обаче пречи на модела да се възползва от тези знания. Например моделът може да осъзнае за конкретна заявка, че трябва да смеси лексикални и семантични сигнали по определен начин, да даде приоритет на определени източници или да агрегира резултатите по конкретен ключ. Освен ако тези прозрения не се окажат приложими чрез параметри на заявката, моделът не може реално да действа въз основа на тях.

Неефективен контролен поток и замърсяване на контекста. Много работни процеси за търсене не са естествено серийни. Те може да изискват разклоняване (fan-out) по варианти на заявки, паралелно извличане, дедупликация и други операции, които изискват нелинеен и асинхронен контролен поток. Налагането на тези стъпки чрез повтарящи се ходове на модела добавя латентност и затруднява оптимизирането на работния процес. Това също така замърсява контекста на модела с шумно междинно състояние, което може да не е полезно за разсъжденията на модела, което води до по-лоша производителност и по-чести компакции.

Малко можеше да се направи по отношение на тези предизвикателства по време на епохите на извикване на функции и MCP на AI. Когато всяка операция по търсене изисква собствено двупосочно пътуване (roundtrip) до LLM инференса, разработчиците естествено предпочитат да свършат възможно най-много работа в рамките на това пътуване. Това означава конвейери за търсене от край до край, които връщат напълно обработени набори от резултати за директна консумация от модела.

В резултат на това повечето ориентирани към AI системи за търсене днес все още работят при този монолитен договор. Въпреки това, с продължаващия растеж в интелигентността на моделите и изискванията на потребителите, недостатъците на този договор стават по-изразени. Най-напредналите AI системи днес, изградени върху първични по отношение на кода инструменти, могат да съставят специфични за задачата работни процеси, които изпълняват хиляди действия всяка минута. Системите за търсене все още не са реализирали напълно този потенциал.

Отдавна подозираме, че правилната граница за AI-нативното търсене е по-надолу в стека. Моделите не трябва просто да извикват търсачка. Те трябва да могат да оркестрират отделните части на стека за търсене според изискванията на конкретната задача. Това изисква съкоренно различна архитектура.

Проектиране на програмуруема архитектура за търсене

Следващото поколение архитектури за търсене ще се базира на основен принцип: търсенето трябва да бъде програмно управляемо по рождение от AI агентите. Един агент не трябва да бъде ограничен до набор от предварително установени конвейери за търсене. По-скоро агентът трябва да може да изгради конвейера, който конкретната задача изисква, използвайки компонируеми градивни елементи, проектирани на различни нива на абстракция.

Нашата нова архитектура Search as Code (SaC) олицетворява този принцип. В SaC нито една операция по извличане не се изпраща чрез интерфейс за извикване на функции или MCP. Вместо това всички операции се оркестрират чрез генериран от модела Python код. За най-простите нужди от търсене този код може да се състои от шепа заявки към крайна точка за търсене с високо ниво. Но за сложни задачи кодът може да бъде толкова сложен, колкото е необходимо, включвайки условно изпълнение, асинхронност, паралелизъм и извиквания към широк спектър от ниско ниво примитиви.

Архитектурата Search as Code (SaC) разчита на стек, съдържащ модели, изчислителни sandbox среда и SDK за агентно търсене (Agentic Search SDK), разположени върху инфраструктурата за търсене на Perplexity.

SaC включва три плътно свързани слоя:

Моделите служат като контролен план. Те правят изводи относно директивата на потребителя (или родителския агент), декомпозират директивата на задачи, решават кои конвейери за извличане и обработка са необходими за всяка задача и генерират код за внедряване на тези конвейери.

Изчислителните Sandbox среди осигуряват детерминистични изчисления чрез сигурна среда за изпълнение на код. Те предоставят платно за моделите за внедряване на контролен поток, пакетиране (batching), повторни опити (retries), филтриране, обединяване (joining), агрегиране и други детерминистични операции.

Нашият SDK за агентно търсене (Agentic Search SDK) излага стека за търсене на Perplexity като компонируеми примитиви. Той предоставя градивни елементи от ниско ниво операции по извличане до семантичен анализ с високо ниво. SDK е вграден в средите за изпълнение на Sandbox средите, което позволява на моделите да оркестрират до хиляди операции в рамките на един единствен инференс ход. По-долу обсъждаме нашите решения за проектиране за всеки слой.

SDK за агентно търсене (Agentic Search SDK)

SDK за агентно търсене (Agentic Search SDK) дефинира градивните елементи за програмируемо търсене. Важно е да се отбележи, че нашият SDK не е предварително съществуващ Search API, опакован като библиотека. През последните няколко месеца нашият инженерен екип реархитектурира нашия стек за търсене в модулни, компонируеми примитиви. Изградихме SDK за агентно търсене (Agentic Search SDK), за да осигурим директен достъп до тези примитиви, създавайки много по-мощно платно, върху което моделът може да оркестрира специфични за задачата конвейери за извличане.

Конвейерите за търсене от край до край с високо ниво все още са достъпни в рамките на SDK, но те вече не са единствената опция. По-скоро те служат като форма на съкращение за общи модели на търсене. Моделът е свободен да ги използва или заобикаля според изискванията на задачата.

Избор на среда за изпълнение (runtime): Обмислихме Python, Rust, TypeScript и Bash като среда за изпълнение на SDK. Подозирахме, че Python ще бъде най-естественото съответствие предвид неговата повсеместност и екосистема от библиотеки за обработка на данни. Вътрешното тестване потвърди това и версията на SDK, която се пуска днес, е базирана на Python. Очакваме периодично да преоценяваме избора на среда за изпълнение, за да гарантираме, че тя продължава да предоставя най-доброто изживяване на агента.

Постоянно подобрение чрез автоматично изследване (autoresearch): Също така оптимизирахме консумирането на SDK за фронтиър LLMs чрез итеративен цикъл за автоматично изследване. Този цикъл, работещ непрекъснато в продължение на седмици, предлага и валидира подобрения на SDK спрямо показатели, включително латентност, качество на генерирането на код и обща производителност на задачата. Цикълът за автоматично изследване вече е направил множество промени както в структурата, така и в естетиката на SDK, със значителни печалби във всички измерения. Планираме допълнително да усъвършенстваме SDK чрез автоматично изследване с появата на нови фронтиър модели и компоненти за търсене.

Sandbox среди

Sandbox средите осигуряват сигурни среди за дефиниране и стартиране на SaC конвейери. Те изпълняват генериран от модела код, осигурявайки достъп до SDK за агентно търсене (Agentic Search SDK), за да се улесни взаимодействието с отделните примитиви за търсене.

Направихме значителни инвестиции в оптимизирането и укрепването на нашите Sandbox среди и цялостният дизайн на тяхната система заслужава собствена статия. Тук се фокусираме върху съображението за дизайн, най-релевантно за SaC: управлението на междинни състояния.

SaC дава възможност на агентите да оркестрират сложни конвейери в рамките на един единствен инференс ход. Въпреки това определени междинни състояния трябва да бъдат предадени през ходовете. Например моделът може да пожелае да извлече някои документи в ход 1, да инспектира подизвадка от тези документи в ход 2, за да реши какво да прави по-нататък, и след това да разработи конвейер за търсене надолу по веригата, за да изследва допълнително тези документи от ход 3 нататък. Както бе обсъдено по-горе, предаването на междинни състояния през пространството на токените не е ефективна стратегия.

Обмислихме два подхода за управление на междинните състояния през ходовете:

Постоянна файлова система + изрична сериализация/десериализация (serde): Sandbox средите могат да предоставят постоянни файлови системи, които моделите да използват в различните ходове. Моделите, които желаят да запазят междинно състояние, могат да включат стъпка на сериализация в генерирания код за един ход, заедно със стъпка на десериализация в последващ ход (или за собствена инспекция на моделите, или за последваща употреба). Подходът с файловата система позволява на моделите директно и изрично да контролират как междинното състояние се предава през ходовете. Той също така гарантира проследимост чрез налагане на изрична идентификация и постоянство на информацията, използвана от модела. Един недостатък е латентността и режийните разходи за контекста, произтичащи от генерираването на serde кода, въпреки че добре проектираните спомагателни функции могат да смекчат тези режийни разходи.

REPL: Като алтернатива, Sandbox средата може да запази самата среда за изпълнение в различните ходове в среда в стил REPL. Това позволява на моделите да поддържат междинно състояние в паметта, без да се налага да го сериализират изобщо, тъй като променливите, дефинирани или модифицирани в предишни ходове, могат просто да бъдат реферирани по име в последващи ходове. Подходът REPL е по-ефективен по отношение на токените, тъй като избягва нуждата от генериране на serde код. Липсата на изрична стъпка на сериализация обаче може да навреди на производителността надолу по веригата поради причини, познати на всеки, който е работил със 100-клетъчен Jupyter бележник: с претрупването на пространството от имена на променливите става по-трудно да се проследи какво точно е запазено в различните ходове и защо.

Тествахме и двата подхода и установихме, че макар да се представят сходно при обичайна употреба, базираната на файлова система сериализация (serde) осигурява по-добра надеждност при особено дълги траектории. Затова приемаме базираната на файлова система сериализация (serde) за наше решение. Предполагаме, че изискването към моделите да предават състоянието декларативно, а не имплицитно, им помага да управляват това състояние по-ефективно. Това е предварително откритие и ще продължим да итерираме и по двата подхода.

Модели

Моделите, захранващи агентните инструменти, служат като контролен план на SaC: динамично сглобяващи конвейери за търсене от градивните елементи на SDK за агентно търсене (Agentic Search SDK), за да отговорят на нуждите на всяка задача, след което изпращат тези конвейери като код за изпълнение в Sandbox средата.

Perplexity използва разнообразие от модели в нашите агентни инструменти и установихме, че най-новите фронтиър модели са доста ефективни в целия спектър при генерирането на код с общо предназначение. Основното предизвикателство е да се предизвика ефективно генериране на код специално за SDK за агентно търсене (Agentic Search SDK). Тоест, как можем да накараме моделите ефективно да втъкнат градивните елементи на нашия SDK в оптимизирани за задачи конвейери?

За разлика от стандартната библиотека на езика, е малко вероятно персонализиран SDK да бъде представен в предтренировъчните данни. Дори с подобренията в консумирането на SDK от автоматичното изследване, много модели все пак са обучени да взаимодействат със системите за търсене чрез извиквания на функции и директно извикване на MCP. Малко вероятно е тези модели да боравят експертно със SDK само с изходен код и автогенерирани документи.

За да разрешим това предизвикателство, разработихме силно настроени умения на агента (Agent Skills), които да учат моделите да използват ефективно нашия SDK. Първоначалните версии бяха разработени съгласно принципите на проектиране на Perplexity за умения (Skills) и след това оптимизирани чрез специален цикъл за автоматично изследване, фокусиран върху същите показатели, използвани при оптимизацията на SDK. Също така ограничаваме размера на уменията, за да се предпазим от прекомерно раздуване на контекста, а нашите финални версии имат по-малко от 2000 токена в своите коренни SKILL.md файлове.

Оптимизираните умения (Skills) надхвърлят простото изброяване на наличните градивни елементи на SDK (нещо, което може лесно да се получи чрез отражение в средата за изпълнение). Голяма част от токените се харчат за предоставяне на кратки, обобщаеми насоки и примери с малко примери (few-shot) за комбиниране на тези блокове в сложни модели. Въоръжени с тези умения, наблюдаваме как моделите ефективно се възползват от SDK, за да оркестрират конвейери за търсене, които се мащабират до хиляди дискретни операции.

Кодът като оркестратор и запълнител на пропуски

Чрез комбинирането на тези слоеве SaC променя взаимоотношението между моделите и стека за търсене. В системите за търсене с фиксиран конвейер моделът стои над търсенето и взаимодейства с него чрез тесен сериен интерфейс за извикване. В SaC моделът се превръща в активен участник в оркестрацията на самия процес на търсене. Всички елементи на стека за търсене стават директно програмируеми от модела, като Sandbox средата и SDK за агентно търсене (Agentic Search SDK) осигуряват необходимите интерфейси към тези елементи.

Но какво да кажем за възможностите, които не съществуват по рождение? Кодът е мощен средник за оркестриране на предварително съществуващи възможности. И все пак силата на кода надхвърля оркестрацията. Той може да служи и като запълнител на пропуски за възможности, които не присъстват в стека за търсене или SDK. Агентите се ползват от парсимония (икономичност) и би било неефективно за SDK да покрива всяка потенциална операция със специална функция. Вместо това SDK предоставя най-фундаменталните примитиви и моделът може да изгради всякакви допълнителни компоненти в движение с код.

Помислете например за сложен регулярен израз (regex), който не може да бъде ефективно внедрен чрез собствения синтаксис за заявки на системата за търсене. Без възможности за кодиране моделът би бил принуден да генерира най-доброто си приближение, да направи заявка и да извърши филтриране в пространството на токените върху много шумен набор от резултати. Със SaC моделът може вместо това да генерира програма, която прави паралелни SDK извиквания, за да събере надмножество от набора от резултати на желания регулярен израз. След дедупликация чрез SDK моделът може след това да напише допълнителен код за детерминистично стесняване на резултатите до точния регулярен израз. По този начин агентите могат да внедрят персонализирани възможности за търсене, без да раздуват SDK с прекалено нишови подпрограми.

Казус: Препоръки от доставчици за CVE (CVE Vendor Advisories)

Представяме казус, базиран на реална задача в рамките на нашия тестов пакет. Тази задача изисква от агента да идентифицира и охарактеризира над 200 CVE с висока степен на сериозност от периода 2023–2025 г. Всеки запис трябва да цитира собствената препоръка на засегнатия доставчик, да назове продукта и версията за коригиране (fix version) и да покаже, че версията за коригиране е обвързана с конкретния CVE.

Отговорът на SaC постигна 100% точност, като общото използване на токени спадна с 85.1% спрямо базовата линия без SaC (от 288.7K токена до 42.9K токена). Тестваните системи без Perplexity, обсъдени по-подробно в раздел 4, постигнаха резултат под 25%.

Представяме три стилизирани кодови блока от траекторията, за да илюстрираме как програмируемостта на SaC позволява на модела да внедрява ефективни стратегии.

python
# 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"]) ]

Този първи блок е чисто оркестриране. Генерираната програма започва с кодиране на правилото за изходния клас директно в плана за заявки: само форматите за препоръки, притежавани от доставчика, са релевантни. Източници, които не са от доставчика, включително NVD, MITRE, CVE Details, новинарски статии, страници на CERT и бази данни на трети страни, са структурно извън обхвата. Ограниченията за точна фраза също тласкат търсенето към страници, чийто индексиран текст вече съдържа точните подробности за CVE, необходими надолу по веригата.

python
# 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, )

Вторият блок използва LLM като междинна подпрограма за планиране. Кодът обобщава кои двойки доставчик-година произвеждат достатъчно кандидат-страници, изисква насочени уточнения и валидира всяка предложена заявка преди изпълнение. Това запазва полезните модели от траекторията, като например насочени към конкретен сайт проби с точна фраза и адаптивно запълване назад (backfilling), без да се хардкодва персонализиран CVEcrawler за препоръки в SDK.

python
# 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")

Последният блок е верификатор на резултати, чиято логика е изцяло дефинирана от агента чрез генериране на код (codegen). Въпреки че подпрограмите за търсене могат да намерят правдоподобни страници с препоръки, задачата изисква по-строго отношение: препоръката трябва да обвърже един CVE с един засегнат продукт и една версия за коригиране в текст, създаден от доставчика. Схемата прави тази връзка изрична, така че кодът надолу по веригата да може да прави дедупликация по CVE, да отхвърля URL адреси на агрегатори, да изхвърля слаби доказателства за версията и да продължи да запълва назад, докато се достигне минималният брой записи.

Резултати от оценката

Оценяваме ефективността на SaC върху изчерпателен пакет от бенчмаркове, фокусирайки се както върху абсолютната производителност, така и върху границата между разходи и производителност.

Бенчмаркове и системи

Нашият пакет от бенчмаркове се състои от общо пет бенчмарка, предназначени за стрес тест на зависещи от търсенето AI работни процеси в различни домейни, формати на задачи и нива на сложност. Използваме четири съществуващи бенчмарка: DeepSearchQA (DSQA), BrowseComp, Humanity's Last Exam (HLE) и WideSearch. За първите три бенчмарка (DSQA, BrowseComp и HLE) отчитаме точността като водещ показател (topline metric). За WideSearch отчитаме F1 резултата по ред.

Използваме също и новоразработения бенчмарк WANDR, който се фокусира върху трудни задачи за „широки изследвания“ (wide research), изискващи внимателна оркестрация на търсенето, изчисленията и разсъжденията на модела. WANDR е вдъхновен от интензивните на знания професионални задачи, които Perplexity Computer обработва за потребителите. Той надгражда WideSearch и подобни бенчмаркове, но набляга на по-сложни задачи и структури на задачите. Ще публикуваме бенчмарка WANDR през идните седмици.

Оценяваме пет базирани на агенти системи. Разглеждаме индивидуални изпълнения, а не “best-of-N” резултати, за да изозолираме производителността на основната архитектура, вместо ползите от паралелизацията. Конфигурацията на всяка система е описана по-долу:

Perplexity (SaC): Оценяваме архитектурата SaC в рамките на производствения Agent API на Perplexity. GPT 5.5 (високи разсъждения) служи като основен модел.

OpenAI: Оценяваме Responses API на OpenAI с активирани както търсене (web_search), така и Python среда за изпълнение (code_interpreter). GPT 5.5 (високи разсъждения) служи като основен модел.

Anthropic: Оценяваме управляваните агенти на Anthropic (Anthropic Managed Agents) с набор от агентни инструменти от 20260401 и автоматично разрешени команди. Opus 4.7 (високи разсъждения) служи като основен модел.

Exa: Оценяваме Exa Agent чрез производствения API, с усилие (effort), зададено на високо.

Parallel: Оценяваме Parallel Tasks чрез производствения API, с процесор, зададен на ultra4x.

Сравнителна производителност

Таблица 1 отчита резултатите от бенчмарка за всяка система. SaC превъзхожда всички останали системи на четири от петте бенчмарка. На останалия бенчмарк (HLE) SaC практически е наравно за първото място с OpenAI Responses. Фигура 2 от въведението визуализира тези резултати в графична форма.

Бенчмарк

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 | Резултати от бенчмарк за всяка оценена система. Най-добър резултат по ред в удебелен шрифт.

Въпреки че SaC постига производителност от най-високо ниво (state-of-the-art) в целия бенчмарк пакет, неговото предимство е особено изразено при WANDR. Фигура 5 разбива резултатите от WANDR, показвайки, че SaC реализацията на Perplexity надминава следващата най-добра система с фактор 2.5×. Въпреки тази голяма преднина, WANDR остава ненаситен и се оказва предизвикателство дори за SaC. Вярваме, че сложните, силно хоризонтални работни процеси за търсене, изисквани от задачите на WANDR, ще изискват допълнителен напредък в изследванията и инженерното търсене за постигане на стабилно висока производителност.

Резултати от WANDR за оценените системи. Perplexity Agent API води пред следващата най-добра система с фактор 2.5×.

И накрая, измерваме относителните печалби на SaC спрямо по-традиционен конвейер за търсене, който използва същата инфраструктура за търсене на Perplexity. Фигура 6 отчита разликата в резултатите между SaC и не-SaC архитектурите за всеки бенчмарк. По цялата линия SaC осигурява съществен тласък в производителността, с най-голямата абсолютна печалба при DSQA (+19.77 pp, 29%) и най-голямата относителна печалба при WANDR (+12.00 pp, 45%).

Базова линия на Perplexity спрямо SaC резултат на всеки бенчмарк, с анотирани абсолютни и относителни делта стойности.

Граница между разходи и производителност

На практика потребителите се интересуват от производителността спрямо разходите. Следователно оценяваме границата между разходи и производителност при DSQA и WideSearch. Измерваме разходите и производителността на SaC при ниски, средни и високи нива на разсъждения на модела, заедно с останалите системи. Фигури 7 и 8 чертаят резултата от бенчмарка спрямо цената за задача, като оста x е обърната, така че точките по-надясно са по-евтини, а точките по-нагоре представляват по-добра производителност.

Резултат от DSQA спрямо цена за задача. Прекъснатата линия свързва конфигурациите за разсъждения на SaC модела.

При DSQA и трите настройки на SaC лежат на горната дясна граница. Настройката с ниски разсъждения е по-евтина от всички останали системи, като същевременно се представя по-добре от две от тях. Настройката със средни разсъждения надминава всички не-SaC системи при под $1 на задача. Настройката с високи разсъждения постига топ производителност с конкурентна цена.

Резултат от WideSearch спрямо цена за задача. Прекъснатата линия свързва конфигурациите за разсъждения на SaC модела.

WideSearch показва сходно оформена граница. Както при DSQA, настройката с ниски разсъждения постига конкурентна производителност на по-ниска цена от всички не-SaC системи, докато както средните, така и високите разсъждения надминават не-SaC системите по производителност на задачите.

Към нова архитектура на изчисленията

Search as Code отразява по-широка промяна в дизайна на софтуера. Десетилетия наред софтуерните системи бяха организирани около детерминистични инструкции, изпълнявани от традиционни среди за изпълнение на процесори (CPUs). Фронтиър моделите въвеждат нова форма на изчисления: разсъждения в пространството на токените, които могат едновременно да следват и генерират инструкции. Най-способните изчислителни системи ще комбинират тези две форми на изчисления, вместо да избират между тях.

Търсенето е естествен полигон за изпитване на тази хибридна архитектура. Моделите са добре подходящи за определяне какви доказателства са необходими и как трябва да се разреши несигурността. Детерминистичните среди за изпълнение са добре подходящи за пакетиране (batching), паралелизъм, филтриране, класиране и агрегиране. Инфраструктурата за търсене служи като универсален I/O слой, предоставяйки на средата за изпълнение полезни лостове към световната информация, които могат да поддържат хиляди операции в минута. Когато тези парчета са интегрирани, получената система е много по-мощна и ефективна при изпълнението на задачи в реалния свят.

Всяка част от тази архитектура е необходима за отключване на тези възможности. Без интелигентни модели системата не може да разсъждава върху стратегията за търсене. Без Sandbox среди моделите са принудени към сериен I/O и неефективна обработка в пространството на токените. И без атомизиран стек за търсене моделът няма какво да оркестрира. SaC работи, защото разсъжденията, детерминистичните изчисления и I/O са съвместно проектирани да подчертаят силните страни на всеки слой.

Този съвместен дизайн (codesign) може да бъде развит още повече чрез разработването на цикли за постоянно подобрение. Например SDK за агентно търсене (Agentic Search SDK) и SaC агентните умения (Agent Skills) биха могли да бъдат съвместно оптимизирани в общ цикъл за автоматично изследване. По-амбициозно е, че моделите могат да бъдат обучени да се възползват от примитиви за търсене от ниско ниво, изложени като SDK. Човек може дори да опита съвместно еволюиране на дизайна на SDK по време на самия процес на обучение на модела. Очакваме с нетърпение да преследваме по-агресивни стратегии за съвместен дизайн в бъдеща работа.

Създадохме SaC, за да позволим на моделите да контролират процеса на търсене, вместо просто да консумират неговите резултати. Нашите резултати доказват силата на този контрол: SaC напредва както по отношение на абсолютната производителност, така и по границата между разходи и производителност при интензивни на знания агентни бенчмаркове. Радваме се да предоставим възможностите на SaC на нашите потребители, започвайки днес с Perplexity Computer и Agent API. Ще продължим да оптимизираме архитектурата на SaC във всички слоеве на стека, за да гарантираме, че нашите потребители (и агентите, които ги обслужват) разполагат с възможно най-мощните и ефективни възможности за търсене.

Цитиране

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