重新思考作為程式碼生成的搜尋
將搜尋從單體服務演進為代理 harness 時代的可程式化原語。
搜尋是 AI 系統的核心基礎。先進模型每月都在變得更加強大,但它們仍然需要從更廣闊的世界中獲取最新、準確且經過妥善策劃的知識。搜尋是 AI 系統汲取這些知識的主要方式,因此它是任何需要得出結論、採取行動並執行現實世界工作之產品的基本組成部分。
我們相信,在代理時代,傳統的搜尋管線正日益過時。傳統的搜尋會回答查詢,但當今的代理所完成的任務可以有無數種形式。這些任務需要代理直接在其次束中定義特定於任務的檢索策略。在 Perplexity Computer 內,我們已經看到單個任務在幾分鐘內調用數百甚至數千次檢索操作:這種工作流程對於人類而言是不可能的,但對於代理而言卻是絕對自然的。
在這樣一個世界中,搜尋本身必須具備代理能力,其建構塊可以直接作為代理束中的 SDK 訪問。我們在此介紹 Search as Code (SaC) 作為 Perplexity 的全新參考搜尋架構。
簡介
Perplexity 的搜尋堆疊在我們的應用程式和 API 平台中每秒處理數千個查詢。在 2025 年 9 月,我們發布了搜尋系統的第一個架構概覽。這些系統內的持續創新支援了 Search API、Agent API 和 Computer 等新產品的推出,且具備自我改善迴圈,能不斷優化搜尋堆疊,以日復一日地更好地服務用戶。
傳統上,AI 系統將搜尋視為單體架構:AI 模型發出查詢,搜尋引擎運行其預定義的管線,然後模型將結果作為上下文消耗。在大多數情況下,這足以滿足早期 AI 用戶的需求。鑑於其請求的相對簡單性,沒有理由擔心搜尋管線是如何精確設計的,或者管線的架構是否對當前任務達到最佳狀態。預設值被認為足夠好,預設介面(函式調用和 MCP)亦然。
然而今天,隨著每個月過去,這種方法變得越來越過時。用戶對 AI 的要求遠不止於單次分析。他們期望代理能夠花費數小時甚至數天端對端地完成任務。這些任務可能是複雜的、開放式的,且其資訊需求具有高度可變性,而單體架構在這些需求的重壓下正逐漸崩潰。
關鍵瓶頸歸根結底是控制權的問題。先進模型在對固定上下文進行推理方面已經相當出色。然而,最強大的 AI 系統將需要能夠掌控該上下文是如何被檢索、處理、聚合並呈現給模型的方式。
傳統搜尋系統在設計時並未考慮到這種程度的可控性。畢竟,即使提供這種功能,也不能指望人類用戶對搜尋管線的內部細節進行精細控制。早期的 AI 模型只能透過函數調用和 MCP 的線性軌跡來控制搜尋。但當今的先進模型在具備程式碼能力的代理束驅動下,能夠透過電腦程式碼對任何想像得到的計算原語施加精細控制。我們的任務就是提供正確的原語。
為滿足這一需求,我們正在各個產品中引入一種新的搜尋架構:Search as Code (SaC)。這項新架構賦予模型直接深入至搜尋堆疊內部的能力,而不僅僅是消耗其最終輸出。核心概念很直接:我們將搜尋堆疊的組件作為 SDK 中的原語公開。對於任何需要搜尋的請求,模型會根據該特定請求即興將這些原語組合成量身定制的檢索管線。
組裝此管線是透過安全沙箱內的程式碼生成和執行來完成的。與其他基於程式碼生成的搜尋方法不同,我們並非僅僅將傳統搜尋 API 塞進 Shell 或語言運行時中。相反,我們精心設計了一個 Agentic Search SDK,在盡可能最原子的層級公開搜尋的各個建構塊。
憑藉這些建構塊,SaC 賦予模型對每個獨立搜尋步驟的直接控制權:檢索、排序、過濾、分發、渲染等。它還使模型能夠有效訪問中間狀態,例如候選列表和排序信號。結合控制和可讀性這雙重槓桿,代理能夠設計跨越數千次檢索操作的客製化搜尋管線、在運行過程中優化這些管線,並僅消耗最有用的資訊作為模型上下文。
本文介紹了 SaC 的動機、設計和實現,以及在現有和新基準測試上的實證結果。SaC 為代理搜尋建立了新的成本效益前沿,我們很高興能與用戶及更廣泛的 AI 社群分享它。
傳統搜尋的僵化性
世界上最早的搜尋引擎是為人類用戶而建構的。這些用戶逐漸期望獲得可預測的體驗,通常包含固定數量的按相關性排序的文件。用戶不想微觀管理搜尋過程;他們只想輸入查詢並找到有用的結果。
因此,面向人類的搜尋引擎收斂於一種共同的單體架構,旨在產生包含輸入查詢前 n 個命中結果的人類友好型搜尋引擎結果頁面 (SERP)。這種模式推動了消費者搜尋數十年的進步。它速度快、熟悉度高,且對人類瀏覽極其有效。
隨後 LLMs 問世,AI 系統也成為了搜尋的使用者。Perplexity 於 2022 年推出了我們的答案引擎,開創了這一轉變。自此以後,我們的搜尋工程工作一直專注於如何為 AI 模型優化搜尋價值的結果。為了建構世界上最準確、最可靠的 AI,我們必須設計一個搜尋系統,專注於使每個 Token 盡可能資訊密集。由此產生的子文件檢索、上下文效率、語意理解和其他關鍵領域的創新,大大提升了 AI 系統檢索和處理資訊的能力。
然而,即使是針對 AI 優化的系統,也很大程度上繼承了與傳統搜尋引擎相同的基本合約:接受查詢、運行預定義的搜尋管線、返回完全處理好的結果集。對於簡單的請求,這種方法運作良好。但對於更複雜的請求,這會成為一個日益受限的瓶頸,進而降低效能、延遲並增加成本。
僵化性帶來的失敗模式
傳統搜尋管線圍繞著單一控制點進行設計:查詢參數。搜尋引擎根據其預定義邏輯擁有管線的其餘部分,模型必須適應它。對於模型而言,查詢參數下游的任何東西都是僵化的——實際計算的形狀不在模型的控制範圍之內。
當使用者是瀏覽連結的人類時,這是一個合理的界限。但當使用者是試圖在閉環中解決知識密集型任務的 AI 模型時,這就是一個糟糕的界限。根據我們的經驗,這種僵化性會產生三種反覆出現的失敗模式:
粗粒度上下文。AI 模型對上下文的品質和精簡度很敏感。品質和精簡度都高度依賴於查詢,而單體搜尋管線並未被設計為在所有查詢中都達到最佳效能。例如,如果模型需要一條高度精準的特定資訊,但只能存取優先考慮召回率的端對端搜尋端點,則使用該端點會將大量不相關的資訊引入模型上下文。另一方面,如果模型需要許多各自需要不同搜尋策略的資訊片段,它可能會被迫為所有這些片段連續調用同一個次優管線,從而導致成本飆升和上下文充滿雜訊。
無法善用領域知識。在許多情況下,模型可能擁有領域知識(來自其訓練、Agent Skill、記憶或 LLM 軌跡中的早期 Token),這些知識應該指導搜尋策略。然而,僵化的搜尋介面阻止了模型利用這些知識。例如,模型可能會針對特定請求意識到它應該以特定方式融合詞彙和語意信號、優先處理某些來源,或者透過特定鍵聚合結果。除非這些見解剛好可以透過查詢參數來實現,否則模型實際上無法對其採取行動。
低效的控制流與上下文污染。許多搜尋工作流程並非天然串行的。它們可能需要對查詢變體進行分發、並行獲取、去重,以及其他需要非線性和非同步控制流的操作。透過重複的模型輪次強行進行這些步驟會增加延遲,並使工作流程更難以優化。它還會用可能對模型的推理無用的充滿雜訊的中介狀態來污染模型上下文,從而導致較差的效能和更頻繁的壓縮。
在 AI 的函數調用與 MCP 時代,對於這些挑戰可謂束手無策。當每個搜尋操作都需要其自身的 LLM 推理往返時,開發人員自然傾向於在該往返中完成盡可能多的工作。這意味著返回完全處理好的結果集以供模型直接消耗的端對端搜尋管線。
因此,當今大多數面向 AI 的搜尋系統仍然在這種單體合約下運作。然而,隨著模型智慧和用戶需求的持續增長,該合約的缺點變得更加明顯。當今最先進的 AI 系統建立在程式碼優先的代理束之上,能夠組合出每分鐘執行數千個動作的任務特定工作流程。搜尋系統尚未完全實現這種潛力。
長期以來,我們一直懷疑 AI 原生搜尋的正確邊界在堆疊更底層。模型不應該僅僅調用搜尋引擎。它們應該能夠根據特定任務的需求來協調搜尋堆疊的各個部分。這需要一種根本上不同的架構。
設計可程式化的搜尋架構
下一代搜尋架構將取決於一個核心原則:搜尋應該由 AI 代理進行原生程式設計。代理不應受限於一組預先決定的搜尋管線。相反,代理必須能夠使用在不同抽象層級設計的可組合建構塊,來建構特定任務所需的管線。
我們的新 Search as Code (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 對先進 LLMs 的可用性。這個迴圈持續運行數週,針對延遲、程式碼生成品質和整體任務效能等指標提出並驗證 SDK 的改進。自動研究迴圈已經對 SDK 的結構和美學進行了大量更改,並在所有維度上取得了顯著的提升。隨著新的先進模型和搜尋組件的出現,我們計劃透過自動研究進一步精進 SDK。
沙箱
沙箱為定義和運行 SaC 管線提供安全環境。它們執行模型生成的程式碼,提供對 Agentic Search SDK 的訪問,以促進與單個搜尋原語的互動。
我們在優化和強化沙箱方面進行了重大投資,其整體的系統設計值得專門寫一篇文章來探討。在這裡,我們專注於與 SaC 最相關的設計考量:管理中介狀態。
SaC 賦予代理在單個推理輪次內協調複雜管線的能力。然而,某些中介狀態需要跨輪次傳遞。例如,模型可能希望在第 1 輪獲取一些文件,在第 2 輪檢查這些文件的子樣本以決定下一步要做什麼,然後開發下游搜尋管線,從第 3 輪開始進一步調查這些文件。如上所述,透過 Token 空間傳遞中介狀態並不是一種有效的策略。
我們考慮了兩種跨輪次管理中介狀態的方法:
持久化檔案系統 + 顯式 serde:沙箱可以公開持久化檔案系統供模型在各輪次之間使用。希望持久化中介狀態的模型可以在某個輪次的生成程式碼中包含序列化步驟,並在後續輪次中包含反序列化步驟(供模型自身檢查或供下游使用)。檔案系統方法允許模型直接且明確地控制中介狀態如何在各輪次之間傳遞。它還透過強制對模型使用的資訊進行明確識別和持久化來確保可追溯性。缺點之一是由於生成 serde 程式碼而產生的延遲與上下文開銷,儘管設計良好的公用函數可以減輕這種開銷。
REPL:或者,沙箱可以在 REPL 風格的環境中跨輪次持久化執行運行時本身。這允許模型在記憶體中維持中介狀態,而完全不需要進行序列化,因為在先前輪次中定義或修改的變數可以在後續輪次中直接按名稱引用。REPL 方法由於避免了生成 serde 程式碼的需求,因此更加 Token 高效。然而,缺乏明確的序列化步驟可能會損害下游效能,這對於任何使用過 100 格 Jupyter Notebook 的人來說都是熟悉的理由:隨著變數命名空間變得混亂,要追蹤究竟什麼被持久化以及為什麼持久化變得更加困難。
我們測試了這兩種方法,發現雖然它們在日常使用中的表現相似,但基於檔案系統的 serde 在特別長的軌跡上提供了更好的可靠性。因此,我們採用基於檔案系統的 serde 作為我們的解決方案。我們推測,要求模型以宣告式而非隱式的方式傳遞狀態,有助於它們更有效地管理該狀態。這是一個初步的發現,我們將繼續對這兩種方法進行迭代。
模型
驅動代理束的模型充當了 SaC 的控制平面:從 Agentic Search SDK 的建構塊動態組裝搜尋管線以滿足每個任務的需求,然後將這些管線作為程式碼分發以進行沙箱執行。
Perplexity 在我們的代理束中採用了各種模型,我們發現最新的先進模型在通用程式碼生成方面全面表現相當出色。主要的挑戰是如何針對 Agentic Search SDK 引導有效的程式碼生成。也就是說,我們如何才能讓模型有效地將我們的 SDK 的建構塊交織成任務優化的管線?
與語言的標準庫不同,自訂建構的 SDK 不太可能出現在預訓練資料中。即使有了來自自動研究的 SDK 可用性改進,許多模型仍然被訓練為透過函數調用和直接 MCP 調用來與搜尋系統互動。這些模型不太可能僅憑原始程式碼和自動生成的文檔就精通該 SDK。
為了應對這一挑戰,我們開發了高度調校的 Agent Skills 來教導模型有效利用我們的 SDK。最初的版本是根據 Perplexity 的 Skills 設計原則開發的,然後透過專門的自動研究迴圈進行優化,該迴圈專注於與 SDK 優化中相同的指標。我們還限制技能大小以防範上下文膨脹,我們最終版本的根 SKILL.md 檔案中包含不到 2000 個 Token。
優化後的 Skills 不僅僅是列出 SDK 可用的建構塊(這也可以透過運行時反射輕鬆獲得)。大部分 Token 都花在提供簡潔、可推廣的指導以及將這些區塊組合成複雜模式的少樣本範例上。有了這些 Skills,我們觀察到模型有效地利用 SDK 來協調擴展到數千個離散操作的搜尋管線。
作為協調者和填補空白者的程式碼
透過結合這些層級,SaC 改變了模型與搜尋堆疊之間的關係。在固定管線的搜尋系統中,模型位於搜尋之上,並透過狹窄的串行調用者介面與其互動。在 SaC 中,模型成為協調搜尋過程本身的積極參與者。搜尋堆疊的所有元素都變得可由模型直接進行程式設計,沙箱和 Agentic Search SDK 為這些元素提供了必要的介面。
但是那些原本不存在的功能呢?程式碼是用於協調現有功能強大媒介。然而程式碼的力量超出了協調的範疇。它還可以充當搜尋堆疊或 SDK 中不存在的功能的填補者。代理受益於精簡,如果 SDK 用專用函數涵蓋每個潛在操作將是低效的。相反,SDK 提供了最基礎的原語,而模型可以用程式碼即興建構任何額外的組件。
例如,考慮一個無法透過搜尋系統自身的查詢語法高效實現的複雜正則表達式。如果沒有編碼能力,模型將被迫生成其最佳近似值、發出查詢,並在充滿雜訊的結果集上執行 Token 空間過濾。有了 SaC,模型可以改為生成一個程式專案,發出並行 SDK 調用以收集所需正則表達式結果集的超集。透過 SDK 進行去重後,模型隨後可以編寫額外的程式碼來確定性地將結果縮小到準確的正則表達式。透過這種方式,代理可以在不使 SDK 充斥著過於小眾的子常式的情況下實現自訂搜尋功能。
案例研究:CVE 供應商建議
我們展示了一個基於測試套件中真實任務的案例研究。此任務要求代理識別並描述 2023–2025 年間超過 200 個高嚴重性 CVE。每條記錄都必須引用受影響供應商自己的建議,命名產品和修復版本,並表明修復版本與特定的 CVE 綁定。
SaC 的答案在準確度上得分 100%,總 Token 使用量相對於非 SaC 基線下降了 85.1%(從 288.7K 個 Token 降至 42.9K 個 Token)。第 4 節中詳細討論的測試過的非 Perplexity 系統,得分全部低於 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 的有效性,重點關注絕對效能和成本效益前沿。
基準測試與系統
我們的基準測試套件總共包含五個基準測試,旨在跨一系列領域、任務格式和複雜度級別對依賴搜尋的 AI 工作流程進行壓力測試。我們使用了四個現有的基準測試:DeepSearchQA (DSQA)、BrowseComp、Humanity's Last Exam (HLE) 和 WideSearch。對於前三個基準測試(DSQA、BrowseComp 和 HLE),我們報告準確度作為頂層指標。對於 WideSearch,我們報告按行計算的 F1 分數。
我們還使用了新開發的 WANDR 基準測試,該測試側重於需要仔細協調搜尋、計算和模型推理的困難「廣泛研究」任務。WANDR 的靈感來自 Perplexity Computer 為用戶處理的知識密集型專業任務。它在 WideSearch 及類似基準測試的基礎上進行迭代,但強調更複雜的任務和任務結構。我們將在未來幾週內發布 WANDR 基準測試。
我們評估了五個基於代理的系統。我們考慮單個運行而不是「最佳 N」分數,以便隔離底層架構的效能,而不是並行化的好處。每個系統的配置描述如下:
Perplexity (SaC):我們在 Perplexity 的生產 Agent API 中評估 SaC 架構。GPT 5.5(高推理)作為底層模型。
OpenAI:我們評估啟用了搜尋 (web_search) 和 Python 運行時 (code_interpreter) 的 OpenAI Responses API。GPT 5.5(高推理)作為底層模型。
Anthropic:我們評估帶有 20260401 代理工具集和自動允許命令的 Anthropic Managed Agents。Opus 4.7(高推理)作為底層模型。
Exa:我們透過生產 API 評估 Exa Agent,並將力度設定為高。
Parallel:我們透過生產 API 評估 Parallel Tasks,並將處理器設定為 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 分數,表明 Perplexity 的 SaC 實現比次佳系統高出 2.5 倍。儘管有著巨大的差距,WANDR 仍然未飽和,甚至對 SaC 來說也證明具有挑戰性。我們相信,WANDR 任務所需的複雜、高度橫向的搜尋工作流程將需要研究和搜尋工程方面的進一步進展,才能實現持續的高效能。
最後,我們衡量了 SaC 相對於利用相同 Perplexity 搜尋基礎設施的更傳統搜尋管線的相對增益。圖 6 報告了 SaC 與非 SaC 架構在每個基準測試之間的分數差異。全面來看,SaC 提供了顯著的效能提升,其中 DSQA 的絕對增幅最大(+19.77 pp,29%),而 WANDR 的相對增幅最大(+12.00 pp,45%)。
成本效益前沿
在實踐中,用戶關心的是相對於成本的效能。因此,我們在 DSQA 和 WideSearch 上評估了成本效益前沿。我們衡量了 SaC 在低、中、高模型推理級別下的成本和效能,以及其他系統的成本和效能。圖 7 和圖 8 繪製了基準測試分數與每項任務價格的關係圖,其中 X 軸反轉,因此越往右的點越便宜,越往上的點代表更好的效能。
在 DSQA 上,所有三個 SaC 設定都位於右上角前沿。低推理設定比所有其他系統都便宜,同時表現優於其中的兩個。中推理設定在每項任務不到 1 美元的成本下,其表現優於所有非 SaC 系統。高推理設定以具競爭力的成本實現了頂級效能。
WideSearch 顯示出類似形狀的前沿。與 DSQA 一樣,低推理設定以低於所有非 SaC 系統的成本實現了具競爭力的效能,而中度和高度推理在任務效能上均優於非 SaC 系統。
這種共同設計可以透過持續改進迴圈的發展進一步推向深入。例如,Agentic Search SDK 和 SaC Agent Skills 可以在一個公共的自動研究迴圈中進行聯合優化。更雄心勃勃的是,可以訓練模型來利用作為 SDK 公開的低階搜尋原語。人們甚至可以嘗試在模型訓練過程本身中共同演進 SDK 設計。我們期待在未來的工作中追求更具侵略性的共同設計策略。
Search as Code 反映了軟體設計中的更廣泛變革。幾十年來,軟體系統一直圍繞著由 CPU 上的傳統運行時執行的確定性指令來組織。先進模型引入了一種新形式的計算:能夠遵循和生成指令的 Token 空間推理。最強大的計算系統將結合這兩種形式的計算,而不是在它們之間進行選擇。
搜尋是這種混合架構的天然試驗場。模型非常適合決定需要什麼證據以及如何解決不確定性。確定性運行時非常適合批次處理、並行、過濾、排序和聚合。搜尋基礎設施充當通用的 I/O 層,為運行時提供對世界資訊的有用的控制代碼,能夠支撐每分鐘數千次操作。當這些部分整合在一起時,產生的系統在完成現實世界的任務時會更加強大和高效。
該架構的每個部分對於釋放這些功能都是必不可少的。沒有智慧模型,系統就無法對搜尋策略進行推理。沒有沙箱,模型將被迫進行串行 I/O 和低效的 Token 空間處理。而沒有原子化的搜尋堆疊,模型就沒有什麼可協調的。SaC 之所以有效,是因為推理、確定性計算和 I/O 是經過共同設計的,以突顯每個層級的優勢。
這種共同設計理念還可以透過開發持續改進循環進一步深化。例如,Agentic Search SDK 與 SaC Agent Skills 可以在共同的自動研究循環中進行聯合最佳化。更有企圖心的是,可以訓練模型來充分利用作為 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}
}