Repensar la búsqueda como generación de código

Evolución de la búsqueda, de servicios monolíticos a primitivas programables para la era de los arneses de agentes.

AutoresPerplexity Research

La búsqueda es un elemento primitivo fundamental para los sistemas de IA. Los modelos de vanguardia mejoran su capacidad mes a mes, pero aún necesitan acceso a información fresca, precisa y bien curada del mundo exterior. La búsqueda es la forma principal en que los sistemas de IA aprovechan ese conocimiento y, por lo tanto, un componente fundamental de cualquier producto que necesite extraer conclusiones, tomar medidas y realizar trabajo en el mundo real.

Creemos que las canalizaciones de búsqueda tradicionales están cada vez más obsoletas en la era de los agentes. La búsqueda tradicional responde a consultas, pero los agentes de hoy completan tareas que pueden adoptar innumerables formas. Estas tareas requieren que los agentes definan estrategias de recuperación específicas para cada tarea directamente dentro de sus arneses. Dentro de Perplexity Computer, hemos visto que una sola tarea invoca cientos o incluso miles de operaciones de recuperación en pocos minutos: un flujo de trabajo que resulta imposible para los humanos pero absolutamente natural para los agentes.

En este mundo, la búsqueda misma debe volverse agéntica, con sus bloques de construcción accesibles directamente como SDK dentro del arnés del agente. Presentamos Search as Code (SaC) como la nueva arquitectura de búsqueda de referencia de Perplexity.

Introducción

La pila de búsqueda de Perplexity atiende miles de consultas cada segundo en nuestras aplicaciones y en la API Platform. En septiembre de 2025, publicamos la primera descripción general de la arquitectura de nuestros sistemas de búsqueda. La innovación constante dentro de estos sistemas ha respaldado el lanzamiento de nuevas ofertas como Search API, Agent API y Computer, con bucles de auto-mejora que optimizan la pila de búsqueda para servir mejor a los usuarios día con día.

Tradicionalmente, los sistemas de IA han tratado la búsqueda como un monolito: un modelo de IA emite una consulta, el motor de búsqueda ejecuta su canalización predefinida y el modelo consume los resultados como contexto. En su mayor parte, esto funcionó bien para abordar las necesidades de los primeros usuarios de IA. Dada la relativa simplicidad de sus solicitudes, no había razón para preocuparse por cómo se diseñó exactamente la canalización de búsqueda o si la arquitectura de esta era óptima para la tarea en cuestión. Se asumía que los valores predeterminados eran suficientemente buenos, al igual que las interfaces predeterminadas (llamada de funciones y MCP).

Las arquitecturas de búsqueda tradicionales exponen un único sistema fijo al que los modelos llaman de forma serial, mientras que Search as Code expone primitivas de búsqueda atomizadas que los agentes componen a través de código generado.

Sin embargo, hoy en día este enfoque se vuelve más obsoleto mes con mes. Los usuarios exigen mucho más que un análisis de un solo intento por parte de la IA. Esperan que los agentes completen tareas de extremo a extremo durante horas o incluso días. Estas tareas pueden ser complejas, abiertas y muy variables en sus necesidades de información, y las arquitecturas monolíticas están cediendo bajo el peso de estas demandas.

El cuello de botella clave es, en última instancia, el del control. Los modelos de vanguardia ya son bastante buenos razonando sobre un contexto fijo. Sin embargo, los sistemas de IA más potentes requerirán la capacidad de dirigir cómo se recupera, procesa, agrega y presenta dicho contexto al modelo.

Los sistemas de búsqueda tradicionales no se diseñaron teniendo en cuenta este grado de controlabilidad. Después de todo, no se puede esperar que los usuarios humanos ejerzan un control detallado sobre los elementos internos de la canalización de búsqueda, incluso si se ofreciera. Los primeros modelos de IA solo pueden controlar la búsqueda a través de una trayectoria lineal de llamadas de funciones y MCP. Pero los modelos de vanguardia de hoy, impulsados por arneses de agentes con capacidad de código, pueden ejercer un control detallado sobre cualquier primitiva computacional imaginable a través de código informático. Nuestra tarea pasa a ser proporcionar las primitivas adecuadas.

Para satisfacer esta necesidad, introducimos una nueva arquitectura de búsqueda en todos nuestros productos: Search as Code (SaC). Esta nueva arquitectura permite a los modelos adentrarse en la propia pila de búsqueda en lugar de limitarse a consumir sus resultados finales. La idea central es sencilla: exponemos los componentes de la pila de búsqueda como primitivas dentro de un SDK. Para cualquier solicitud que requiera búsqueda, un modelo ensambla estas primitivas bajo demanda para formar una canalización de recuperación adaptada a esa solicitud específica.

El ensamblaje de esta canalización se realiza mediante la generación y ejecución de código dentro de un entorno aislado seguro. A diferencia de otros enfoques de generación de código para la búsqueda, no nos limitamos a insertar una API de búsqueda tradicional dentro de un shell o tiempo de ejecución de lenguaje. En su lugar, hemos diseñado cuidadosamente un SDK de búsqueda agéntica que expone los bloques de construcción individuales de la búsqueda al nivel más atómico posible.

Search as Code (SaC) eleva la frontera de rendimiento de la búsqueda agéntica en un conjunto diverso de puntos de referencia.

Armado con estos bloques de construcción, SaC otorga a los modelos control directo sobre cada paso de búsqueda individual: recuperación, clasificación, filtrado, bifurcaciones (fanouts), renderizado y más. También proporciona al modelo acceso eficiente al estado intermedio, como las listas de candidatos y las señales de clasificación. Juntos, estos dos factores de control y legibilidad permiten a los agentes diseñar canalizaciones de búsqueda personalizadas que abarcan miles de operaciones de recuperación, optimizar dichas canalizaciones sobre la marcha y consumir únicamente la información más útil como contexto del modelo.

Este artículo describe la motivación, el diseño y la implementación de SaC, junto con los resultados empíricos en puntos de referencia tanto existentes como nuevos. SaC establece una nueva frontera de costo-rendimiento para la búsqueda agéntica, y nos emociona compartirlo con nuestros usuarios y con la comunidad de IA en general.

La rigidez de la búsqueda tradicional

Los primeros motores de búsqueda del mundo se crearon para usuarios humanos. Estos usuarios esperaban una experiencia predecible, que por lo general constaba de un número fijo de documentos clasificados por relevancia. Los usuarios no querían microgestionar el proceso de búsqueda; querían introducir una consulta y encontrar un resultado útil.

Como resultado, los motores de búsqueda orientados a humanos convergieron en una arquitectura monolítica común, orientada a producir páginas de resultados de motores de búsqueda (SERP) amigables para los humanos que contienen los mejores n aciertos para una consulta de entrada. Este patrón ha impulsado décadas de progreso en la búsqueda de consumo. Es rápido, familiar y muy eficaz para la navegación humana.

Luego llegaron los LLM, y los sistemas de IA también se convirtieron en consumidores de búsqueda. Perplexity fue pionera en este cambio con el lanzamiento de nuestro motor de respuestas en 2022. Desde entonces, nuestros esfuerzos de ingeniería de búsqueda se han centrado en cómo optimizar el valor de los resultados de búsqueda para los modelos de IA. Para construir la IA más precisa y confiable del mundo, tuvimos que diseñar un sistema de búsqueda enfocado en hacer que cada token sea lo más denso posible en información. Las innovaciones resultantes en recuperación de subdocumentos, eficiencia de contexto, comprensión semántica y otras áreas clave condujeron a mejoras drásticas en la capacidad de los sistemas de IA para recuperar información y actuar sobre ella.

Sin embargo, incluso los sistemas optimizados para IA han heredado en gran medida el mismo contrato fundamental que los motores de búsqueda tradicionales: aceptar una consulta, ejecutar una canalización de búsqueda predefinida y devolver un conjunto de resultados completamente procesado. Para las solicitudes simples, este enfoque funciona bien. Pero para solicitudes más complejas, esto se convierte en un cuello de botella cada vez más limitante que degrada el rendimiento, la latencia y el costo.

Los sistemas de búsqueda tradicionales obligan a los flujos de trabajo agénticos a secuenciar la búsqueda a través de turnos visibles para el modelo. Los modelos deben llamar repetidamente a las mismas canalizaciones de búsqueda con diferentes parámetros de consulta e introducir todos los resultados en el contexto del modelo.

Modos de fallo derivados de la rigidez

Las canalizaciones de búsqueda tradicionales están diseñadas en torno a un único punto de control: los parámetros de consulta. El motor de búsqueda posee el resto de la canalización según su lógica predefinida, y el modelo debe adaptarse a ella. Para el modelo, todo lo posterior a los parámetros de consulta es rígido; la forma del cálculo real escapa al control del modelo.

Este es un límite razonable cuando el consumidor es un humano que escanea enlaces. Es un límite deficiente cuando el consumidor es un modelo de IA que intenta resolver tareas con uso intensivo de conocimientos en un bucle cerrado. En nuestra experiencia, esta rigidez crea tres modos de fallo recurrentes:

Contexto burdo. Los modelos de IA son sensibles a la calidad y compacidad del contexto. Tanto la calidad como la compacidad dependen en gran medida de la consulta, y las canalizaciones de búsqueda monolíticas no están diseñadas para funcionar de manera óptima en todas las consultas. Por ejemplo, si un modelo necesita una única pieza de información muy quirúrgica, pero solo tiene acceso a un extremo de búsqueda de extremo a extremo que prioriza la recuperación, el uso de ese punto final introducirá una gran cantidad de información irrelevante en el contexto del modelo. Por otro lado, si un modelo necesita muchas piezas de información que requieran cada una diferentes estrategias de búsqueda, puede verse obligado a invocar de forma consecutiva la misma canalización subóptima para todas ellas, lo que resulta en costos crecientes y contexto ruidoso.

Incapacidad para aprovechar el conocimiento de dominio. En muchos casos, el modelo puede tener conocimiento de dominio (de su entrenamiento, una Skill de agente, memoria o tokens anteriores en la trayectoria del LLM) que debería guiar la estrategia de búsqueda. Sin embargo, una interfaz de búsqueda rígida impide que el modelo aproveche ese conocimiento. Por ejemplo, el modelo puede darse cuenta para una solicitud específica de que debe combinar señales léxicas y semánticas de una manera particular, priorizar ciertas fuentes o agregar resultados por una clave específica. A menos que esas ideas se puedan implementar mediante parámetros de consulta, el modelo no puede actuar realmente sobre ellas.

Flujo de control ineficiente y contaminación del contexto. Muchos flujos de trabajo de búsqueda no son seriales por naturaleza. Es posible que necesiten bifurcaciones sobre variantes de consultas, obtención en paralelo, deduplicación y otras operaciones que requieren un flujo de control no lineal y asincrónico. Forzar estos pasos a través de turnos repetidos del modelo añade latencia y dificulta la optimización del flujo de trabajo. También contamina el contexto del modelo con un estado intermedio ruidoso que puede no ser útil para el razonamiento del modelo, lo que resulta en un rendimiento más pobre y compactaciones más frecuentes.

Poco se pudo hacer ante estos desafíos durante las eras de llamadas de funciones y MCP de la IA. Cuando cada operación de búsqueda requiere su propio viaje de ida y vuelta a la inferencia del LLM, los desarrolladores prefieren naturalmente hacer la mayor cantidad de trabajo posible en ese viaje de ida y vuelta. Esto significa canalizaciones de búsqueda de extremo a extremo que devuelven conjuntos de resultados completamente procesados para su consumo directo por parte de un modelo.

Como resultado, la mayoría de los sistemas de búsqueda orientados a la IA actuales siguen operando bajo este contrato monolítico. Sin embargo, con el crecimiento continuo de la inteligencia de los modelos y las demandas de los usuarios, las deficiencias de ese contrato se vuelven más pronunciadas. Los sistemas de IA más avanzados de hoy, construidos sobre arneses centrados en el código, pueden componer flujos de trabajo específicos de tareas que ejecutan miles de acciones por minuto. Los sistemas de búsqueda aún no han materializado plenamente este potencial.

Hace tiempo que sospechamos que el límite adecuado para la búsqueda nativa de IA se encuentra más abajo en la pila. Los modelos no deben limitarse a llamar a un motor de búsqueda. Deben ser capaces de orquestar las piezas individuales de la pila de búsqueda según lo exija la tarea específica. Eso requiere una arquitectura fundamentalmente diferente.

Diseño de una arquitectura de búsqueda programable

La próxima generación de arquitecturas de búsqueda dependerá de un principio fundamental: la búsqueda debe ser programable de forma nativa por los agentes de IA. Un agente no debe limitarse a un conjunto de canalizaciones de búsqueda preestablecidas. Más bien, un agente debe ser capaz de construir la canalización que la tarea específica requiere, utilizando bloques de construcción componibles diseñados en distintos niveles de abstracción.

Nuestra nueva arquitectura Search as Code (SaC) encarna este principio. En SaC, ni una sola operación de recuperación se envía a través de una llamada de función o interfaz MCP. En su lugar, todas las operaciones se orquestan mediante código Python generado por el modelo. Para las necesidades de búsqueda más sencillas, este código puede consistir en un puñado de solicitudes a un punto final de búsqueda de alto nivel. Pero para tareas complejas, el código puede ser tan intrincado como sea necesario, e implicar ejecución condicional, asincronía, paralelismo y llamadas a una amplia gama de primitivas de bajo nivel.

La arquitectura Search as Code (SaC) se basa en una pila que comprende modelos, entornos aislados de computación y un SDK de búsqueda agéntica que se encuentra sobre la infraestructura de búsqueda de Perplexity.

SaC involucra tres capas estrechamente acopladas:

Los modelos actúan como el plano de control. Razonan sobre la directiva del usuario (o del agente principal), descomponen la directiva en tareas, deciden qué canalizaciones de recuperación y procesamiento se necesitan para cada tarea y generan código para implementar dichas canalizaciones.

Los entornos aislados de computación proporcionan capacidad de cómputo determinista a través de un tiempo de ejecución de código seguro. Ofrecen un lienzo para que los modelos implementen flujo de control, procesamiento por lotes, reintentos, filtrado, uniones (joins), agregación y otras operaciones deterministas.

Nuestro SDK de búsqueda agéntica expone la pila de búsqueda de Perplexity como primitivas componibles. Proporciona bloques de construcción que van desde operaciones de recuperación de bajo nivel hasta análisis semántico de alto nivel. El SDK está integrado dentro de los entornos de ejecución de los entornos aislados, lo que permite a los modelos orquestar hasta miles de operaciones en un solo turno de inferencia. A continuación, analizamos nuestras decisiones de diseño para cada capa.

El SDK de búsqueda agéntica

El SDK de búsqueda agéntica define los bloques de construcción para la búsqueda programable. Es importante destacar que nuestro SDK no es una API de búsqueda preexistente empaquetada como biblioteca. Durante los últimos meses, nuestro equipo de ingeniería ha reestructurado nuestra pila de búsqueda en primitivas modulares y componibles. Hemos creado el SDK de búsqueda agéntica para proporcionar acceso directo a estas primitivas, lo que genera un lienzo mucho más potente sobre el cual el modelo puede orquestar canalizaciones de recuperación específicas para cada tarea.

Las canalizaciones de búsqueda de alto nivel y de extremo a extremo siguen estando disponibles dentro del SDK, pero ya no son la única opción. Más bien, sirven como una forma de taquigrafía para los patrones de búsqueda comunes. El modelo es libre de utilizarlas o ignorarlas según lo exija la tarea.

Elección del tiempo de ejecución: Consideramos Python, Rust, TypeScript y Bash como el tiempo de ejecución del SDK. Sospechábamos que Python sería la opción más natural dada su ubicuidad y su ecosistema de bibliotecas de procesamiento de datos. Las pruebas internas confirmaron que este era el caso, y la versión del SDK que se despliega hoy está basada en Python. Esperamos reevaluar periódicamente la elección del tiempo de ejecución para garantizar que continúe ofreciendo la mejor experiencia para los agentes.

Mejora continua mediante la autoinvestigación: También hemos optimizado la facilidad de consumo del SDK para los LLM de vanguardia mediante un bucle iterativo de autoinvestigación. Este bucle, que se ejecuta de forma continua durante semanas, propone y valida mejoras en el SDK frente a métricas que incluyen la latencia, la calidad de la generación de código y el rendimiento general de la tarea. El bucle de autoinvestigación ya ha realizado numerosos cambios tanto en la estructura como en la estética del SDK, con ganancias significativas en todas las dimensiones. Planeamos perfeccionar aún más el SDK a través de la autoinvestigación a medida que surjan nuevos modelos de vanguardia y componentes de búsqueda.

Entornos aislados

Los entornos aislados proporcionan entornos seguros para definir y ejecutar canalizaciones de SaC. Ejecutan código generado por el modelo, lo que proporciona acceso al SDK de búsqueda agéntica para facilitar la interacción con primitivas de búsqueda individuales.

Hemos realizado importantes inversiones en la optimización y el endurecimiento de nuestros entornos aislados, y el diseño general de su sistema merece un artículo propio. Aquí nos centramos en la consideración de diseño más relevante para SaC: la gestión de estados intermedios.

SaC permite a los agentes orquestar canalizaciones complejos dentro de un único turno de inferencia. Sin embargo, ciertos estados intermedios deben transmitirse a través de los turnos. Por ejemplo, un modelo puede querer recuperar algunos documentos en el turno 1, inspeccionar una submuestra de esos documentos en el turno 2 para decidir qué hacer a continuación y, a continuación, desarrollar una canalización de búsqueda posterior para investigar más a fondo dichos documentos a partir del turno 3 en adelante. Como se analizó anteriormente, pasar estados intermedios a través del espacio de tokens no es una estrategia eficaz.

Consideramos dos enfoques para gestionar los estados intermedios entre turnos:

Sistema de archivos persistente + serde explícito: Los entornos aislados pueden exponer sistemas de archivos persistentes para que los modelos los utilicen entre turnos. Los modelos que deseen persistir el estado intermedio pueden incluir un paso de serialización dentro del código generado para un turno, junto con un paso de deserialización dentro de un turno posterior (ya sea para la propia inspección de los modelos o para su uso posterior). El enfoque del sistema de archivos permite a los modelos controlar de forma directa y explícita cómo se transmite el estado intermedio entre los turnos. También garantiza la trazabilidad al exigir la identificación explícita y la persistencia de la información utilizada por el modelo. Una desventaja es la latencia y la sobrecarga de contexto generadas al crear el código de serde, aunque las funciones de utilidad bien diseñadas pueden mitigar esta sobrecarga.

REPL: Como alternativa, un entorno aislado puede persistir el propio tiempo de ejecución en los turnos en un entorno de estilo REPL. Esto permite a los modelos mantener el estado intermedio en la memoria sin tener que serializarlo en absoluto, ya que las variables definidas o modificadas en turnos anteriores se pueden simplemente referenciar por su nombre en turnos posteriores. El enfoque REPL es más eficiente en cuanto a tokens, ya que evita la necesidad de generar código de serde. Sin embargo, la falta de un paso de serialización explícito puede perjudicar el rendimiento posterior por razones familiares para cualquier persona que haya trabajado con un cuaderno Jupyter de 100 celdas: a medida que el espacio de nombres de las variables se satura, resulta más difícil realizar un seguimiento de lo que se persiste exactamente entre los turnos y por qué.

Probamos ambos enfoques y descubrimos que, aunque su rendimiento es similar en el uso ordinario, el serde basado en sistemas de archivos proporciona una mejor confiabilidad en trayectorias particularmente largas. Por lo tanto, adoptamos el serde basado en sistemas de archivos como nuestra solución. Conjeturamos que exigir a los modelos que transmitan el estado de manera declarativa en lugar de implícita les ayuda a gestionar dicho estado de forma más eficaz. Este es un hallazgo provisional y seguiremos iterando en ambos enfoques.

Modelos

Los modelos que impulsan los arneses de agentes sirven como plano de control de SaC: ensamblan dinámicamente canalizaciones de búsqueda a partir de los bloques de construcción del SDK de búsqueda agéntica para satisfacer las necesidades de cada tarea, y luego envían dichas canalizaciones como código para su ejecución en entornos aislados.

Perplexity emplea una variedad de modelos dentro de nuestros arneses de agentes, y hemos descubierto que los modelos de vanguardia más recientes son bastante eficaces en general para la generación de código de propósito general. El principal desafío es inducir una generación de código eficaz específicamente para el SDK de búsqueda agéntica. Es decir, ¿cómo podemos lograr que los modelos combinen eficazmente los bloques de construcción de nuestro SDK para crear canalizaciones optimizadas para tareas?

A diferencia de la biblioteca estándar de un lenguaje, es poco probable que un SDK creado a medida esté representado en los datos de preentrenamiento. Incluso con las mejoras en la facilidad de consumo del SDK derivadas de la autoinvestigación, muchos modelos siguen estando entrenados para interactuar con los sistemas de búsqueda mediante llamadas de funciones y la invocación directa de MCP. Es poco probable que estos modelos manejen el SDK con soltura utilizando únicamente el código fuente y la documentación generada automáticamente.

Para resolver este desafío, hemos desarrollado Skills de agentes altamente optimizados para enseñar a los modelos a aprovechar eficazmente nuestro SDK. Las versiones iniciales se desarrollaron de acuerdo con los principios de diseño de Perplexity para Skills, y luego se optimizaron a través de un bucle dedicado de autoinvestigación centrado en las mismas métricas utilizadas en la optimización del SDK. También limitamos el tamaño de los skills para protegernos contra la saturación del contexto, y nuestras versiones finales tienen menos de 2000 tokens en sus archivos raíz SKILL.md.

Los Skills optimizados van más algo más allá de simplemente enumerar los bloques de construcción disponibles en el SDK (algo que se puede obtener fácilmente mediante la reflexión en tiempo de ejecución). La mayor parte de los tokens se invierte en proporcionar orientación concisa y generalizable y ejemplos de pocos disparos (few-shot) para componer estos bloques en patrones complejos. Armados con estos Skills, observamos que los modelos aprovechan eficazmente el SDK para orquestar canalizaciones de búsqueda que escalan a miles de operaciones discretas.

El código como orquestador y rellenador de lagunas

Al combinar estas capas, SaC cambia la relación entre los modelos y la pila de búsqueda. En los sistemas de búsqueda de canalización fija, el modelo se sitúa por encima de la búsqueda e interactúa con ella a través de una interfaz de llamada en serie estrecha. En SaC, el modelo se convierte en un participante activo en la orquestación del propio proceso de búsqueda. Todos los elementos de la pila de búsqueda se vuelven directamente programables por el modelo, y el entorno aislado y el SDK de búsqueda agéntica proporcionan las interfaces necesarias para dichos elementos.

Pero ¿qué pasa con las capacidades que no existen de forma nativa? El código es un medio potente para orquestar capacidades preexistentes. Sin embargo, el poder del código va más allá de la orquestación. También puede servir como un rellenador de lagunas para las capacidades que no están presentes en la pila de búsqueda o en el SDK. Los agentes se benefician de la parsimonencia, y sería ineficiente que el SDK cubriera cada operación potencial con una función dedicada. En su lugar, el SDK proporciona las primitivas más fundamentales, y el modelo puede construir cualquier componente adicional sobre la marcha con código.

Consideremos, por ejemplo, una expresión regular compleja que no se puede implementar de manera eficiente a través de la sintaxis de consulta propia del sistema de búsqueda. Sin capacidades de codificación, el modelo se vería obligado a generar su mejor aproximación, realizar una consulta y realizar un filtrado en el espacio de tokens en un conjunto de resultados muy ruidoso. Con SaC, el modelo puede generar en su lugar un programa que realice llamadas al SDK en paralelo para recopilar un superconjunto del conjunto de resultados de la expresión regular deseada. Tras la deduplicación a través del SDK, el modelo puede escribir código adicional para acotar determinísticamente los resultados a la expresión regular exacta. De este modo, los agentes pueden implementar capacidades de búsqueda personalizadas sin saturar el SDK con subrutinas demasiado especializadas.

Estudio de caso: avisos de proveedores de CVE

Presentamos un estudio de caso basado en una tarea del mundo real dentro de nuestra suite de pruebas. Esta tarea pide a un agente que identifique y caracterice más de 200 CVE de alta gravedad de 2023–2025. Cada registro debe citar el aviso propio del proveedor afectado, nombrar el producto y la versión de corrección, y mostrar que la versión de corrección está vinculada al CVE específico.

La respuesta de SaC obtuvo un 100% de precisión, y el uso total de tokens se redujo en un 85.1% en relación con la línea de base sin SaC (de 288.7K tokens a 42.9K tokens). Los sistemas que no son de Perplexity probados, analizados con más detalle en la Sección 4, obtuvieron todos puntuaciones inferiores al 25%.

Presentamos tres bloques de código estilizados de la trayectoria para ilustrar cómo la programabilidad de SaC permite al modelo implementar estrategias eficaces.

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

Este primer bloque es de pura orquestación. El programa generado comienza codificando la regla de clase de fuente directamente en el plan de consulta: solo los formatos de aviso propiedad de los proveedores son relevantes. Las fuentes que no son de proveedores, incluidos NVD, MITRE, CVE Details, noticias, páginas de CERT y bases de datos de terceros, están estructuralmente fuera del alcance. Las restricciones de frase exacta también empujan la búsqueda hacia páginas cuyo texto indexado ya contiene los detalles precisos de las CVE necesarios posteriormente.

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

El segundo bloque utiliza un LLM como subrutina de planificación intermedia. El código resume qué pares de proveedor-año están produciendo suficientes páginas candidatas, solicita refinamientos específicos y valida cada consulta propuesta antes de la ejecución. Esto preserva patrones útiles de la trayectoria, como sondeos de frase exacta acotados al sitio y rellenado adaptable, sin codificar rígidamente un rastreador de avisos de CVE dedicado en el 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")

El bloque final es un verificador de resultados cuya lógica es definida enteramente por el agente mediante la generación de código. Si bien las subrutinas de búsqueda pueden encontrar páginas de avisos plausibles, la tarea requiere una relación más estricta: el aviso debe vincular un CVE a un producto afectado y una versión de corrección en un texto redactado por el proveedor. El esquema hace que esa relación sea explícita, por lo que el código posterior puede deduplicar por CVE, rechazar URL de agregadores, descartar evidencia de versión débil y continuar rellenando hasta alcanzar el límite mínimo de recuento de registros.

Resultados de la evaluación

Evaluamos la eficacia de SaC en un conjunto integral de puntos de referencia, centrándonos tanto en el rendimiento absoluto como en la frontera de costo-rendimiento.

Puntos de referencia y sistemas

Nuestro conjunto de puntos de referencia comprende cinco puntos de referencia en total, diseñados para someter a pruebas de esfuerzo flujos de trabajo de IA dependientes de la búsqueda en una variedad de dominios, formatos de tareas y niveles de complejidad. Utilizamos cuatro puntos de referencia preexistentes: DeepSearchQA (DSQA), BrowseComp, Humanity's Last Exam (HLE) y WideSearch. Para los primeros tres puntos de referencia (DSQA, BrowseComp y HLE), informamos la precisión como la métrica principal. Para WideSearch, informamos la puntuación F1 por fila.

También utilizamos el recién desarrollado punto de referencia WANDR, que se centra en tareas difíciles de "investigación amplia" (wide research) que requieren una cuidadosa orquestación de la búsqueda, el cálculo y el razonamiento del modelo. WANDR está inspirado en las tareas profesionales con uso intensivo de conocimientos que Perplexity Computer maneja para los usuarios. Itera sobre WideSearch y puntos de referencia similares, pero enfatiza tareas y estructuras de tareas más complejas. Publicaremos el punto de referencia WANDR en las próximas semanas.

Evaluamos cinco sistemas basados en agentes. Consideramos ejecuciones individuales en lugar de puntuaciones de "mejor de N" para aislar el rendimiento de la arquitectura subyacente en lugar de los beneficios de la paralelización. La configuración de cada sistema se describe a continuación:

Perplexity (SaC): Evaluamos la arquitectura SaC dentro de la Agent API de producción de Perplexity. GPT 5.5 (alto razonamiento) sirve como modelo subyacente.

OpenAI: Evaluamos la OpenAI Responses API con la búsqueda (web_search) y el tiempo de ejecución de Python (code_interpreter) habilitados. GPT 5.5 (alto razonamiento) sirve como modelo subyacente.

Anthropic: Evaluamos Anthropic Managed Agents con el conjunto de herramientas de agentes 20260401 y comandos permitidos automáticamente. Opus 4.7 (alto razonamiento) sirve como modelo subyacente.

Exa: Evaluamos Exa Agent a través de la API de producción, con el esfuerzo configurado en alto.

Parallel: Evaluamos Parallel Tasks a través de la API de producción, con el procesador configurado en ultra4x.

Rendimiento comparativo

La Tabla 1 muestra las puntuaciones de los puntos de referencia para cada sistema. SaC supera a todos los demás sistemas en cuatro de los cinco puntos de referencia. En el punto de referencia restante (HLE), SaC empata prácticamente por el primer puesto con OpenAI Responses. La Figura 2 de la Introducción visualiza estas puntuaciones en forma gráfica.

Punto de referencia

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

Tabla 1 | Puntuaciones de los puntos de referencia para cada sistema evaluado. La mejor puntuación por fila en negrita.

Aunque SaC logra un rendimiento de última generación en todo el conjunto de puntos de referencia, su ventaja es especialmente pronunciada en WANDR. La Figura 5 desglosa las puntuaciones de WANDR y muestra que la implementación de SaC de Perplexity supera al siguiente mejor sistema por un factor de 2.5×. A pesar de este amplio margen, WANDR sigue sin estar saturado y resulta desafiante incluso para SaC. Creemos que los flujos de trabajo de búsqueda complejos y altamente horizontales requeridos por las tareas de WANDR exigirán avances adicionales en la investigación y en la ingeniería de búsqueda para lograr un rendimiento consistentemente alto.

Puntuaciones de WANDR en los sistemas evaluados. La Perplexity Agent API supera al siguiente mejor sistema por un factor de 2.5×.

Por último, medimos las ganancias relativas de SaC frente a una canalización de búsqueda más tradicional que aprovecha la misma infraestructura de búsqueda de Perplexity. La Figura 6 informa la diferencia de puntuación entre las arquitecturas con SaC y sin SaC en cada punto de referencia. En general, SaC proporciona un impulso sustancial en el rendimiento, con la mayor ganancia absoluta en DSQA (+19.77 pp, 29%) y la mayor ganancia relativa en WANDR (+12.00 pp, 45%).

Línea base de Perplexity frente a puntuación de SaC en cada punto de referencia, con deltas absolutos y relativos anotados.

Frontera de costo-rendimiento

En la práctica, a los usuarios les importa el rendimiento en relación con el costo. Por lo tanto, evaluamos la frontera de costo-rendimiento en DSQA y WideSearch. Medimos el costo y el rendimiento de SaC en niveles de razonamiento de modelo bajo, medio y alto, junto con los otros sistemas. Las Figuras 7 y 8 representan gráficamente la puntuación del punto de referencia frente al precio por tarea, con el eje x invertido para que los puntos más a la derecha sean más baratos y los puntos más altos representen un mejor rendimiento.

Puntuación de DSQA frente al precio por tarea. La línea discontinua conecta las configuraciones de razonamiento del modelo de SaC.

En DSQA, las tres configuraciones de SaC se encuentran en la frontera superior derecha. La configuración de bajo razonamiento es más barata que todos los otros sistemas a la vez que rinde mejor que dos de ellos. La configuración de razonamiento medio supera a todos los sistemas sin SaC por menos de $1 por tarea. La configuración de alto razonamiento alcanza el máximo rendimiento con un costo competitivo.

Puntuación de WideSearch frente al precio por tarea. La línea discontinua conecta las configuraciones de razonamiento del modelo de SaC.

WideSearch muestra una frontera de forma similar. Al igual que con DSQA, la configuración de bajo razonamiento logra un rendimiento competitivo a un costo menor que todos los sistemas sin SaC, mientras que tanto el razonamiento medio como el alto superan a los sistemas sin SaC en el rendimiento de las tareas.

Hacia una nueva arquitectura de la computación

Search as Code refleja un cambio más amplio en el diseño de software. Durante décadas, los sistemas de software se organizaron en torno a instrucciones deterministas ejecutadas por tiempos de ejecución tradicionales en CPU. Los modelos de vanguardia introducen una nueva forma de computación: el razonamiento en el espacio de tokens que puede seguir y generar instrucciones. Los sistemas computacionales más capaces combinarán estas dos formas de computación en lugar de elegir entre ellas.

La búsqueda es un terreno de pruebas natural para esta arquitectura híbrida. Los modelos son idóneos para decidir qué evidencia se necesita y cómo debe resolverse la incertidumbre. Los tiempos de ejecución deterministas son idóneos para el procesamiento por lotes, el paralelismo, el filtrado, la clasificación y la agregación. La infraestructura de búsqueda sirve como una capa de E/S universal, proporcionando al tiempo de ejecución identificadores útiles para la información del mundo que pueden sostener miles de operaciones por minuto. Cuando estas piezas se integran, el sistema resultante es mucho más potente y eficiente en el cumplimiento de tareas del mundo real.

Cada parte de esta arquitectura es necesaria para desbloquear estas capacidades. Sin modelos inteligentes, el sistema no puede razonar sobre la estrategia de búsqueda. Sin entornos aislados, los modelos se ven abocados a la E/S en serie y al procesamiento ineficiente en el espacio de tokens. Y sin una pila de búsqueda atomizada, el modelo no tiene nada que orquestar. SaC funciona porque el razonamiento, el cálculo determinista y la E/S se diseñan conjuntamente para realzar las fortalezas de cada capa.

Este codiseño se puede llevar aún más lejos mediante el desarrollo de bucles de mejora continua. Por ejemplo, el SDK de búsqueda agéntica y los Skills de agente de SaC podrían optimizarse conjuntamente en un bucle común de autoinvestigación. De forma más ambiciosa, se puede entrenar a los modelos para que aprovechen las primitivas de búsqueda de bajo nivel expuestas como un SDK. Incluso se podría intentar coevolucionar el diseño del SDK durante el propio proceso de entrenamiento del modelo. Esperamos poder aplicar estrategias de codiseño más agresivas en futuros trabajos.

Construimos SaC para permitir que los modelos controlen el proceso de búsqueda, en lugar de limitarse a consumir sus resultados. Nuestros resultados demuestran el poder de este control: SaC avanza tanto en el rendimiento absoluto como en la frontera de costo-rendimiento en puntos de referencia de agentes con uso intensivo de conocimientos. Nos emociona llevar las capacidades de SaC a nuestros usuarios, comenzando hoy con Perplexity Computer y Agent API. Seguiremos optimizando la arquitectura de SaC en todas las capas de la pila para garantizar que nuestros usuarios (y los agentes que los atienden) tengan las capacidades de búsqueda más potentes y eficientes posibles.

Citación

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