Переосмысление поиска как генерации кода
Эволюция поиска: от монолитных сервисов к программируемым примитивам для эпохи агентных систем.
Поиск — ключевой фундаментальный элемент систем ИИ. Пограничные модели с каждым месяцем становятся все более способными, но им по-прежнему нужен доступ к свежим, точным и тщательно отобранным знаниям из внешнего мира. Поиск является основным способом получения ИИ-системами таких знаний и, следовательно, базовым компонентом любого продукта, которому необходимо делать выводы, предпринимать действия и выполнять практическую работу в реальном мире.
Мы считаем, что традиционные поисковые конвейеры все больше устаревают в эпоху агентов. Традиционный поиск отвечает на запросы, но современные агенты выполняют задачи, которые могут принимать самые разные формы. Такие задачи требуют от агентов определения специфических стратегий извлечения данных непосредственно в рамках их исполнения. В Perplexity Computer мы наблюдали, как одна задача вызывает сотни или даже тысячи операций извлечения данных за несколько минут: рабочий процесс, невозможный для человека, но абсолютно естественный для агентов.
В этом мире сам поиск должен стать агентным, а его строительные блоки — доступными непосредственно в виде SDK внутри агентной системы. Мы представляем «Поиск как код» (Search as Code, SaC) в качестве новой эталонной архитектуры поиска Perplexity.
Введение
Поисковый стек Perplexity обслуживает тысячи запросов каждую секунду в наших приложениях и API Platform. В сентябре 2025 года мы опубликовали первый архитектурный обзор наших поисковых систем. Постоянные инновации в этих системах способствовали запуску новых предложений, таких как Search API, Agent API и Computer, с циклами самообучения, оптимизирующими поисковый стек для лучшего обслуживания пользователей с каждым днем.
Традиционно системы ИИ рассматривали поиск как нечто монолитное: модель ИИ отправляет запрос, поисковая система запускает предопределенный конвейер, а модель потребляет результаты в качестве контекста. По большей части это хорошо работало для удовлетворения потребностей ранних пользователей ИИ. Учитывая относительную простоту их запросов, не было причин беспокоиться о том, как именно был спроектирован поисковый конвейер или оптимальна ли его архитектура для поставленной задачи. По умолчанию все считалось достаточно хорошим, как и стандартные интерфейсы (вызов функций и MCP).
Однако сегодня этот подход с каждым месяцем становится все более устаревшим. Пользователи требуют от ИИ гораздо большего, чем просто разовый анализ. Они ожидают, что агенты будут выполнять задачи целиком в течение часов или даже дней. Такие задачи могут быть сложными, открытыми и крайне вариативными в своих информационных потребностях, а монолитные архитектуры не справляются с грузом этих требований.
Ключевым «узким местом» в конечном итоге является контроль. Пограничные модели уже довольно хорошо справляются с рассуждениями на основе фиксированного контекста. Однако наиболее мощным ИИ-системам потребуется возможность управлять тем, как этот контекст извлекается, обрабатывается, агрегируется и представляется модели.
Традиционные поисковые системы не были разработаны с учетом такой степени управляемости. В конце концов, от пользователей-людей нельзя ожидать контроля над внутренними механизмами поискового конвейера, даже если бы это было предложено. Ранние модели ИИ могут управлять поиском только через линейную траекторию вызовов функций и MCP. Но современные пограничные модели, работающие на базе агентных систем с поддержкой кода, могут осуществлять детальный контроль над любыми вычислительными примитивами с помощью компьютерного кода. Наша задача — предоставить правильные примитивы.
Для удовлетворения этой потребности мы внедряем новую поисковую архитектуру во всех наших продуктах: «Поиск как код» (SaC). Эта новая архитектура дает моделям возможность проникать внутрь самого поискового стека, а не просто потреблять его конечные результаты. Основная идея проста: мы предоставляем компоненты поискового стека как примитивы внутри SDK. Для любого запроса, требующего поиска, модель по требованию собирает эти примитивы в поисковый конвейер, адаптированный для этого конкретного запроса.
Сборка этого конвейера осуществляется посредством генерации и выполнения кода в безопасной песочнице. В отличие от других подходов к поиску, основанных на генерации кода, мы не просто помещаем традиционный поисковый API в оболочку или среду выполнения языка. Вместо этого мы тщательно спроектировали Agentic Search SDK, который открывает доступ к отдельным строительным блокам поиска на максимально атомарном уровне.
Вооружившись этими строительными блоками, SaC предоставляет моделям прямой контроль над каждым отдельным шагом поиска: извлечением, ранжированием, фильтрацией, веерной рассылкой, рендерингом и многим другим. Это также дает модели эффективный доступ к промежуточным состояниям, таким как списки кандидатов и сигналы ранжирования. В совокупности эти два рычага — контроль и читаемость — позволяют агентам проектировать индивидуальные поисковые конвейеры, охватывающие тысячи операций извлечения данных, оптимизировать эти конвейеры «на лету» и потреблять в качестве контекста модели только самую полезную информацию.
В этой статье описываются мотивация, дизайн и реализация SaC, а также эмпирические результаты по существующим и новым эталонным тестам. SaC устанавливает новый рубеж стоимости и производительности для агентного поиска, и мы рады поделиться им с нашими пользователями и более широким сообществом ИИ.
Жесткость традиционного поиска
Первые в мире поисковые системы создавались для пользователей-людей. Эти пользователи ожидали предсказуемого опыта, обычно состоящего из фиксированного количества документов, отранжированных по релевантности. Пользователи не хотели вмешиваться в процесс поиска; они хотели ввести запрос и получить полезный результат.
В результате поисковые системы, ориентированные на людей, сошлись на общей монолитной архитектуре, направленной на создание удобных для людей страниц результатов поисковой выдачи (SERP), содержащих первые n результатов по входному запросу. Эта модель обеспечила десятилетия прогресса в потребительском поиске. Она быстрая, привычная и высокоэффективная для просмотра пользователем.
Затем появились LLM, и системы ИИ также стали потребителями поиска. Perplexity была пионером этого сдвига с запуском нашего движка ответов в 2022 году. С тех пор наши усилия в области поисковой инженерии были сосредоточены на том, как оптимизировать ценность результатов поиска для моделей ИИ. Чтобы создать самый точный и надежный ИИ в мире, нам пришлось разработать поисковую систему, ориентированную на максимальную информационную плотность каждого токена. Полученные инновации в извлечении на уровне фрагментов документов, эффективности контекста, семантическом понимании и других ключевых областях привели к значительному улучшению способности ИИ-систем находить информацию и действовать на ее основе.
Однако даже оптимизированные для ИИ системы во многом унаследовали тот же фундаментальный договор, что и традиционные поисковые системы: принять запрос, запустить предопределенный поисковый конвейер, вернуть полностью обработанный набор результатов. Для простых запросов этот подход работает нормально. Но для более сложных запросов это становится все более ограничивающим узким местом, которое снижает производительность, увеличивает задержки и стоимость.
Режимы сбоев из-за жесткости
Традиционные поисковые конвейеры спроектированы вокруг единственной точки управления: параметров запроса. Поисковая система владеет остальной частью конвейера в соответствии со своей предопределенной логикой, а модель должна адаптироваться к ней. Для модели все, что находится «ниже по потоку» от параметров запроса, является жестким — форма фактического вычисления находится вне контроля модели.
Это разумная граница, когда потребителем является человек, просматривающий ссылки. Это плохая граница, когда потребителем является модель ИИ, пытающаяся решать интенсивные задачи на основе знаний в замкнутом цикле. По нашему опыту, эта жесткость создает три повторяющихся режима сбоев:
Грубый контекст. Модели ИИ чувствительны к качеству и компактности контекста. И качество, и компактность сильно зависят от запроса, а монолитные поисковые конвейеры не спроектированы так, чтобы работать оптимально для всех запросов. Например, если модели нужна одна конкретная, высокоточная информация, но у нее есть доступ только к сквозной поисковой конечной точке, отдающей приоритет полноте, использование этой конечной точки введет большое количество нерелевантной информации в контекст модели. С другой стороны, если модели нужно много фрагментов информации, каждый из которых требует разных стратегий поиска, она может быть вынуждена последовательно вызывать один и тот же субоптимальный конвейер для всех них, что приведет к росту затрат и зашумлению контекста.
Неспособность использовать доменные знания. Во многих случаях модель может обладать доменными знаниями (из своего обучения, навыка агента, памяти или более ранних токенов в траектории LLM), которые должны определять стратегию поиска. Однако жесткий интерфейс поиска мешает модели использовать эти знания. Например, модель может понять для конкретного запроса, что ей следует определенным образом смешать лексические и семантические сигналы, расставить приоритеты для определенных источников или агрегировать результаты по определенному ключу. Если эти идеи невозможно реализовать с помощью параметров запроса, модель не может действовать на их основе.
Неэффективный поток управления и загрязнение контекста. Многие поисковые рабочие процессы по своей сути не являются последовательными. Им может потребоваться разветвление по вариантам запросов, параллельная выборка, дедупликация и другие операции, требующие нелинейного и асинхронного потока управления. Принудительное выполнение этих шагов через повторяющиеся шаги модели увеличивает задержку и усложняет оптимизацию рабочего процесса. Это также загрязняет контекст модели шумным промежуточным состоянием, которое может быть бесполезным для рассуждений модели, что приводит к снижению производительности и более частым операциям сжатия.
В эпоху вызова функций и MCP в ИИ мало что можно было сделать с этими проблемами. Когда каждая поисковая операция требует своего собственного обмена данными с LLM для вывода, разработчики естественным образом предпочитают выполнять как можно больше действий за один раз. Это означает использование сквозных поисковых конвейеров, которые возвращают полностью обработанные наборы результатов для прямого потребления моделью.
В результате большинство поисковых систем, ориентированных на ИИ, сегодня по-прежнему работают в рамках этого монолитного договора. Однако с продолжающимся ростом интеллекта моделей и требований пользователей недостатки этого договора становятся все более выраженными. Самые современные ИИ-системы, построенные поверх систем с приоритетом кода, могут компоновать специфические рабочие процессы, которые выполняют тысячи действий каждую минуту. Поисковые системы еще не полностью реализовали этот потенциал.
Мы давно подозревали, что правильная граница для поиска, ориентированного на ИИ, находится ниже в стеке. Модели не должны просто вызывать поисковую систему. Они должны иметь возможность оркестровать отдельные части поискового стека по мере того, как того требует конкретная задача. Это требует принципиально иной архитектуры.
Проектирование программируемой архитектуры поиска
Следующее поколение поисковых архитектур будет зависеть от основного принципа: поиск должен быть нативно программируемым агентами ИИ. Агент не должен ограничиваться набором предопределенных поисковых конвейеров. Напротив, агент должен иметь возможность построить конвейер, необходимый для конкретной задачи, используя компонуемые строительные блоки, разработанные на разных уровнях абстракции.
Наша новая архитектура «Поиск как код» (SaC) воплощает этот принцип. В SaC ни одна операция извлечения не отправляется через интерфейс вызова функций или MCP. Все операции вместо этого оркеструются с помощью Python-кода, сгенерированного моделью. Для самых простых потребностей поиска этот код может состоять из нескольких запросов к высокоуровневой поисковой конечной точке. Но для сложных задач код может быть настолько сложным, насколько это необходимо, включая условное выполнение, асинхронность, параллелизм и вызовы широкого спектра низкоуровневых примитивов.
SaC включает в себя три тесно связанных слоя:
Модели служат плоскостью управления. Они рассуждают о директиве пользователя (или родительского агента), декомпозируют директиву на задачи, решают, какие конвейеры извлечения и обработки необходимы для каждой задачи, и генерируют код для реализации этих конвейеров.
Вычислительные песочницы обеспечивают детерминированные вычисления через безопасную среду выполнения кода. Они предоставляют холст для моделей, на котором те могут реализовать поток управления, пакетирование, повторные попытки, фильтрацию, объединение, агрегацию и другие детерминированные операции.
Наш Agentic Search SDK предоставляет поисковый стек Perplexity в виде компонуемых примитивов. Он содержит строительные блоки от низкоуровневых операций извлечения до высокоуровневого семантического анализа. SDK встроен в среды выполнения песочниц, что позволяет моделям оркестровать до тысяч операций за один шаг вывода. Ниже мы обсуждаем наши проектные решения для каждого слоя.
Agentic Search SDK
Agentic Search SDK определяет строительные блоки для программируемого поиска. Важно отметить, что наш SDK — это не существующий поисковый API, упакованный как библиотека. За последние несколько месяцев наши инженерные команды переработали наш поисковый стек в модульные, компонуемые примитивы. Мы создали Agentic Search SDK, чтобы обеспечить прямой доступ к этим примитивам, создавая гораздо более мощный холст, на котором модель может оркестровать специфические поисковые конвейеры.
Высокоуровневые сквозные поисковые конвейеры по-прежнему доступны в SDK, но они больше не являются единственным вариантом. Скорее, они служат формой сокращения для общих поисковых шаблонов. Модель вольна использовать их или обходить, если того требует задача.
Выбор среды выполнения: Мы рассматривали Python, Rust, TypeScript и Bash в качестве среды выполнения SDK. Мы подозревали, что Python будет наиболее естественным выбором, учитывая его повсеместность и экосистему библиотек для обработки данных. Внутреннее тестирование подтвердило это, и версия SDK, которая выпускается сегодня, основана на Python. Мы планируем периодически переоценивать выбор среды выполнения, чтобы гарантировать, что она продолжает обеспечивать лучший опыт для агентов.
Постоянное улучшение через автоисследования: Мы также оптимизировали пригодность SDK для использования пограничными LLM с помощью итеративного цикла автоисследований. Этот цикл, непрерывно работающий неделями, предлагает и проверяет улучшения SDK на основе таких метрик, как задержка, качество генерации кода и общая производительность выполнения задач. Цикл автоисследований уже внес многочисленные изменения как в структуру, так и в эстетику SDK, с существенными достижениями по всем параметрам. Мы планируем и дальше совершенствовать SDK посредством автоисследований по мере появления новых пограничных моделей и компонентов поиска.
Песочницы
Песочницы обеспечивают безопасные среды для определения и запуска SaC-конвейеров. Они выполняют сгенерированный моделью код, предоставляя доступ к Agentic Search SDK для облегчения взаимодействия с отдельными поисковыми примитивами.
Мы вложили значительные средства в оптимизацию и укрепление наших песочниц, и их общая системная архитектура заслуживает отдельной статьи. Здесь мы сосредоточимся на проектном аспекте, наиболее актуальном для SaC: управлении промежуточными состояниями.
SaC позволяет агентам оркестровать сложные конвейеры в рамках одного шага вывода. Однако некоторые промежуточные состояния необходимо передавать между шагами. Например, модель может захотеть получить несколько документов на шаге 1, изучить подвыборку этих документов на шаге 2, чтобы решить, что делать дальше, а затем разработать дальнейший поисковый конвейер для продолжения исследования этих документов начиная с шага 3. Как обсуждалось выше, передача промежуточных состояний через пространство токенов не является эффективной стратегией.
Мы рассмотрели два подхода к управлению промежуточными состояниями между шагами:
Постоянная файловая система + явная сериализация/десериализация (serde): Песочницы могут предоставлять постоянные файловые системы для использования моделями между шагами. Модели, желающие сохранить промежуточное состояние, могут включить шаг сериализации в сгенерированный код для конкретного шага, наряду с шагом десериализации в последующем шаге (либо для собственного анализа модели, либо для последующего использования). Подход с файловой системой позволяет моделям напрямую и явно контролировать, как промежуточное состояние передается между шагами. Это также обеспечивает прослеживаемость за счет принудительной явной идентификации и сохранения информации, используемой моделью. Одним из недостатков являются задержка и накладные расходы на контекст, возникающие при генерации кода сериализации, хотя хорошо спроектированные вспомогательные функции могут смягчить эти накладные расходы.
REPL: Альтернативно песочница может сохранять саму среду выполнения кода между шагами в среде в стиле REPL. Это позволяет моделям поддерживать промежуточное состояние в памяти без необходимости его сериализации, поскольку переменные, определенные или измененные на предыдущих шагах, можно просто использовать по имени на последующих. Подход REPL является более эффективным с точки зрения токенов, поскольку исключает необходимость генерации кода сериализации. Однако отсутствие явного шага сериализации может ухудшить производительность в будущем по причинам, знакомым всем, кто работал со 100-ячеечным ноутбуком Jupyter: по мере того, как пространство имен переменных становится перегруженным, становится все труднее отслеживать, что именно сохраняется между шагами и почему.
Мы протестировали оба подхода и обнаружили, что, хотя они работают аналогично при обычном использовании, файловая сериализация обеспечивает лучшую надежность на особенно длинных траекториях. Поэтому мы приняли сериализацию на основе файловой системы в качестве нашего решения. Мы полагаем, что требование к моделям передавать состояние декларативно, а не неявно, помогает им более эффективно управлять этим состоянием. Это предварительный вывод, и мы продолжим итерировать оба подхода.
Модели
Модели, обеспечивающие работу агентных систем, служат плоскостью управления SaC: динамически собирая поисковые конвейеры из строительных блоков Agentic Search SDK для удовлетворения потребностей каждой задачи, а затем отправляя эти конвейеры в виде кода для выполнения в песочнице.
Perplexity использует множество моделей в своих агентных системах, и мы обнаружили, что последние пограничные модели довольно эффективны во всех отношениях при генерации кода общего назначения. Главная задача — добиться эффективной генерации кода специально для Agentic Search SDK. То есть, как мы можем заставить модели эффективно сплетать строительные блоки нашего SDK в конвейеры, оптимизированные под задачу?
В отличие от стандартной библиотеки языка, маловероятно, что специально созданный SDK будет представлен в данных предварительного обучения. Даже с учетом улучшений пригодности SDK благодаря автоисследованиям, многие модели все еще обучены взаимодействовать с поисковыми системами через вызовы функций и прямой вызов MCP. Вряд ли эти модели смогут экспертно использовать SDK, полагаясь только на исходный код и автогенерируемую документацию.
Для решения этой задачи мы разработали высоконастроенные навыки агентов, чтобы научить модели эффективно использовать наш SDK. Начальные версии были разработаны в соответствии с принципами проектирования навыков Perplexity, а затем оптимизированы с помощью специального цикла автоисследований, сфокусированного на тех же метриках, что и при оптимизации SDK. Мы также ограничиваем размер навыка, чтобы защититься от раздувания контекста, и наши финальные версии имеют менее 2000 токенов в своих корневых файлах SKILL.md.
Оптимизированные навыки выходят за рамки простого перечисления доступных строительных блоков SDK (что можно легко получить через рефлексию среды выполнения). Основная часть токенов тратится на предоставление кратких, обобщаемых рекомендаций и примеров (few-shot) для компоновки этих блоков в сложные шаблоны. Вооружившись этими навыками, мы наблюдаем, как модели эффективно используют SDK для оркестрации поисковых конвейеров, масштабируемых до тысяч дискретных операций.
Код как оркестратор и заполнитель пробелов
Комбинируя эти слои, SaC изменяет отношения между моделями и поисковым стеком. В поисковых системах с фиксированным конвейером модель находится «над» поиском и взаимодействует с ним через узкий интерфейс последовательных вызовов. В SaC модель становится активным участником оркестрации самого процесса поиска. Все элементы поискового стека становятся непосредственно программируемыми моделью, при этом песочница и Agentic Search SDK предоставляют необходимые интерфейсы к этим элементам.
Но как насчет возможностей, которые не существуют нативно? Код — мощная среда для оркестрации уже существующих возможностей. Однако сила кода выходит за рамки оркестрации. Он также может служить заполнителем для возможностей, которые отсутствуют в поисковом стеке или SDK. Агенты выигрывают от экономии, и было бы неэффективно, если бы SDK покрывал каждую потенциальную операцию выделенной функцией. Вместо этого SDK предоставляет самые фундаментальные примитивы, а модель может «на лету» создавать любые дополнительные компоненты с помощью кода.
Рассмотрим, например, сложное регулярное выражение, которое невозможно эффективно реализовать с помощью собственного синтаксиса запросов поисковой системы. Без возможностей программирования модель была бы вынуждена генерировать свое лучшее приближение, делать запрос и выполнять фильтрацию в пространстве токенов на очень зашумленном наборе результатов. С SaC модель может вместо этого сгенерировать программу, которая делает параллельные вызовы SDK для сбора супермножества результатов желаемого регулярного выражения. После дедупликации через SDK модель может написать дополнительный код для детерминированного сужения результатов до точного соответствия регулярному выражению. Таким образом, агенты могут реализовывать пользовательские возможности поиска, не раздувая SDK чрезмерно нишевыми подпрограммами.
Тематическое исследование: рекомендации поставщиков CVE
Мы представляем тематическое исследование, основанное на реальной задаче из нашего набора тестов. Эта задача просит агента идентифицировать и охарактеризовать более 200 CVE высокой степени серьезности за 2023–2025 годы. Каждая запись должна содержать ссылку на рекомендацию (advisory) самого затронутого поставщика, название продукта и версию исправления, а также показывать, что версия исправления привязана к конкретной CVE.
Ответ SaC получил 100% точности, при этом общее использование токенов снизилось на 85,1% по сравнению с базовой линией без SaC (с 288,7 тыс. токенов до 42,9 тыс. токенов). Протестированные системы, не относящиеся к Perplexity (обсуждаемые подробнее в разделе 4), получили менее 25%.
Мы представляем три стилизованных блока кода из траектории, чтобы проиллюстрировать, как программируемость SaC позволяет модели реализовывать эффективные стратегии.
# 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, необходимые на следующих этапах.
# 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 в качестве промежуточной подпрограммы планирования. Код суммирует, какие пары поставщик-год производят достаточно страниц-кандидатов, запрашивает целенаправленные уточнения и проверяет каждый предложенный запрос перед выполнением. Это сохраняет полезные шаблоны из траектории, такие как зондирование с точным совпадением фраз в рамках сайта и адаптивное заполнение, без жесткого кодирования специализированного сборщика рекомендаций CVE в SDK.
# 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")Финальный блок — это верификатор результатов, логика которого полностью определяется агентом посредством генерации кода. Хотя подпрограммы поиска могут находить правдоподобные страницы рекомендаций, задача требует более строгого отношения: рекомендация должна связывать одну CVE с одним затронутым продуктом и одной версией исправления в тексте, составленном поставщиком. Схема делает эту связь явной, поэтому последующий код может дедуплицировать по CVE, отклонять URL-адреса агрегаторов, отбрасывать слабые доказательства версии и продолжать заполнение до тех пор, пока не будет достигнут порог количества записей.
Результаты оценки
Мы оцениваем эффективность SaC на комплексном наборе тестов, фокусируясь как на абсолютной производительности, так и на границе стоимости и производительности.
Эталонные тесты и системы
Наш набор тестов состоит из пяти тестов, предназначенных для стресс-тестирования поисково-зависимых рабочих процессов ИИ в различных областях, форматах задач и уровнях сложности. Мы используем четыре существующих теста: DeepSearchQA (DSQA), BrowseComp, Humanity's Last Exam (HLE) и WideSearch. Для первых трех тестов (DSQA, BrowseComp и HLE) мы сообщаем точность как основную метрику. Для WideSearch мы сообщаем оценку F1 по строкам.
Мы также используем недавно разработанный тест WANDR, который фокусируется на сложных задачах «широкого исследования», требующих тщательной оркестрации поиска, вычислений и рассуждений модели. WANDR вдохновлен интенсивными профессиональными задачами, которые Perplexity Computer обрабатывает для пользователей. Он итерирует WideSearch и аналогичные тесты, но делает упор на более сложные задачи и структуры задач. Мы опубликуем тест WANDR в ближайшие недели.
Мы оцениваем пять агентных систем. Мы рассматриваем отдельные запуски, а также «лучшие из N» оценки, чтобы изолировать производительность базовой архитектуры, а не преимущества распараллеливания. Конфигурация каждой системы описана ниже:
Perplexity (SaC): Мы оцениваем архитектуру SaC в рамках производственного Agent API Perplexity. GPT 5.5 (высокие способности к рассуждению) служит базовой моделью.
OpenAI: Мы оцениваем OpenAI Responses API с включенным поиском (web_search) и средой выполнения Python (code_interpreter). GPT 5.5 (высокие способности к рассуждению) служит базовой моделью.
Anthropic: Мы оцениваем Anthropic Managed Agents с набором инструментов агента 20260401 и автоматически разрешенными командами. Opus 4.7 (высокие способности к рассуждению) служит базовой моделью.
Exa: Мы оцениваем Exa Agent через производственный API с установкой уровня усилий на «высокий».
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 достигает передовой производительности по всему набору тестов, его преимущество особенно выражено в WANDR. Рисунок 5 разбивает оценки WANDR, показывая, что реализация SaC от Perplexity превосходит следующую лучшую систему в 2,5 раза. Несмотря на этот большой отрыв, WANDR остается ненасыщенным и представляет собой проблему даже для SaC. Мы считаем, что сложные, сильно горизонтальные поисковые рабочие процессы, требуемые задачами WANDR, потребуют дополнительных достижений в исследованиях и поисковой инженерии для достижения стабильно высокой производительности.
Наконец, мы измеряем относительный выигрыш SaC по сравнению с более традиционным поисковым конвейером, использующим ту же поисковую инфраструктуру Perplexity. Рисунок 6 показывает разницу в оценках между архитектурами SaC и не-SaC для каждого теста. В целом, SaC обеспечивает существенный прирост производительности, с наибольшим абсолютным выигрышем на DSQA (+19,77 п.п., 29%) и наибольшим относительным выигрышем на WANDR (+12,00 п.п., 45%).
Граница стоимости и производительности
На практике пользователей волнует производительность относительно стоимости. Поэтому мы оцениваем границу стоимости и производительности на DSQA и WideSearch. Мы измеряем стоимость и производительность SaC при низком, среднем и высоком уровнях рассуждения модели, наряду с другими системами. Рисунки 7 и 8 отображают оценку теста относительно цены за задачу, при этом ось x перевернута, поэтому точки дальше справа дешевле, а точки выше представляют лучшую производительность.
В DSQA все три настройки SaC лежат на верхней правой границе. Настройка с низким уровнем рассуждения дешевле всех других систем, при этом работает лучше двух из них. Настройка со средним уровнем рассуждения превосходит все системы без SaC при цене менее $1 за задачу. Настройка с высоким уровнем рассуждения обеспечивает топовую производительность при конкурентной стоимости.
WideSearch показывает аналогичную границу. Как и в случае с DSQA, настройка с низким уровнем рассуждения достигает конкурентной производительности при более низкой стоимости, чем все системы без SaC, в то время как средний и высокий уровни рассуждения превосходят системы без SaC по производительности выполнения задач.
К новой архитектуре вычислений
«Поиск как код» отражает более широкие изменения в проектировании программного обеспечения. Десятилетиями программные системы организовывались вокруг детерминированных инструкций, выполняемых традиционными средами на CPU. Пограничные модели внедряют новую форму вычислений: рассуждение в пространстве токенов, которое может как следовать инструкциям, так и генерировать их. Наиболее способные вычислительные системы будут комбинировать эти две формы вычислений, а не выбирать между ними.
Поиск — естественный полигон для этой гибридной архитектуры. Модели хорошо подходят для решения того, какие доказательства нужны и как должна быть разрешена неопределенность. Детерминированные среды выполнения хорошо подходят для пакетирования, параллелизма, фильтрации, ранжирования и агрегации. Поисковая инфраструктура служит универсальным уровнем ввода-вывода, предоставляя среде выполнения полезные инструменты доступа к мировой информации, которые могут поддерживать тысячи операций в минуту. Когда эти части интегрированы, результирующая система становится гораздо более мощной и эффективной в выполнении практических задач.
Каждая часть этой архитектуры необходима для раскрытия этих возможностей. Без интеллектуальных моделей система не может рассуждать о стратегии поиска. Без песочниц модели принудительно переводятся в последовательный ввод-вывод и неэффективную обработку в пространстве токенов. И без атомизированного поискового стека модели нечего оркестровать. SaC работает, потому что рассуждения, детерминированные вычисления и ввод-вывод совместно разработаны так, чтобы подчеркнуть сильные стороны каждого слоя.
Этот совместный дизайн можно еще больше расширить за счет разработки циклов постоянного улучшения. Например, Agentic Search SDK и навыки агента SaC могут быть совместно оптимизированы в общем цикле автоисследований. Еще более амбициозно: модели можно обучать использовать низкоуровневые поисковые примитивы, открытые в виде SDK. Можно даже попытаться совместно развивать дизайн SDK в процессе обучения самой модели. Мы с нетерпением ждем возможности реализовать более агрессивные стратегии совместного проектирования в будущей работе.
Мы создали SaC, чтобы позволить моделям управлять процессом поиска, а не просто потреблять его результаты. Наши результаты доказывают силу этого контроля: SaC продвигает как абсолютную производительность, так и границу стоимости-производительности на тестах для агентов, работающих с интенсивными знаниями. Мы рады представить возможности SaC нашим пользователям, начиная с сегодняшнего дня, в Perplexity Computer и Agent API. Мы продолжим оптимизировать архитектуру SaC на всех уровнях стека, чтобы наши пользователи (и агенты, обслуживающие их) имели самые мощные и эффективные поисковые возможности из возможных.
Цитирование
@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}
}