Rethinking Search as Code Generation

原始來源與檔名:2026-06-04T142254+0800-Rethinking Search as Code Generation.md


NAPKIN | 餐巾纸

一句話: 傳統的單體式搜尋服務已無法滿足 Agentic 任務的複雜並行需求,Perplexity 提出「Search as Code (SaC)」架構,將搜尋解構為原子化的 SDK 原語,讓模型能透過生成 Python 程式碼,在安全沙盒中動態編排任務專屬的檢索、過濾與聚合流程。

ROUND 1: SKELETON | 骨架掃描

ROUND 2: DISSECTION | 血肉解剖

ROUND 3: SOUL | 靈魂提取


Rethinking Search as Code Generation (Architectural Deep Dive)

前言/背景

這篇文章探討並解決了 AI 系統發展中的核心瓶頸:隨著 Agent 被賦予長達數小時的複雜任務,傳統「接受查詢、執行預定義流水線、返回結果」的單體式 (Monolithic) 搜尋架構已不堪重負。單體式架構迫使 Agent 只能從外部被動消費資訊,Perplexity 提出的 Search as Code (SaC) 徹底改變了這個邊界,允許模型透過程式碼生成,深入搜尋堆疊內部,動態組裝任務專屬的檢索流水線。

章節詳細總結

傳統搜尋是為人類設計的,追求產生固定數量、對人類友善的文件列表(SERP)。雖然 AI 時代已經對搜尋引擎進行了子文件檢索、上下文壓縮等最佳化,但底層通訊合約並未改變,這在 Agent 任務中導致了三大失敗模式:

  1. 粗粒度上下文 (Coarse context): 如果模型只需要精確片段,預設注重召回率的端點會帶入大量無關資訊,嚴重污染上下文並推升成本。
  2. 無法利用領域知識 (Failure to leverage domain knowledge): 模型可能知道某任務需要特定詞彙與語義信號混合,但僵化的 API 參數無法表達這些策略,導致檢索受限。
  3. 低效的控制流與上下文污染 (Inefficient control flow and context pollution): 複雜檢索需要非同步、並行 (Fan-out) 與去重。如果透過 Function Calling 串行執行,不僅延遲極高,中間狀態還會塞滿 LLM 的 Prompt 導致 Token 浪費與效能衰退。

設計可程式化的搜尋架構 (Designing a Programmable Search Architecture)

SaC 架構不再依賴 Function Calling,而是讓模型撰寫 Python 程式碼。SaC 包含三個緊密耦合的層次:

  1. Agentic Search SDK:

    • 團隊將搜尋基礎設施解構為模組化、可組合的原語(Primitives)。
    • 選擇 Python 作為執行階段,因為其擁有強大的資料處理生態系統。
    • 引入「自動研究 (Autoresearch)」迴圈,不斷根據延遲、程式碼生成品質與任務表現來改進 SDK 的 API 設計。
  2. 沙盒 (Sandboxes):

    • 提供安全環境來執行模型生成的程式碼,處理所有決定性計算(如批次、過濾)。
    • 架構決策 (Why): 在處理跨推論輪次 (Across Turns) 的中間狀態時,團隊比較了「REPL (記憶體駐留)」與「持續檔案系統 + 顯式序列化 (Filesystem + explicit serde)」。雖然 REPL 更省 Token,但團隊發現 基於檔案系統的明確序列化 在超長任務軌跡上可靠性更好。因為它強迫模型宣告性地管理與追蹤狀態,避免了 Jupyter Notebook 常見的命名空間混亂問題。
  3. 模型 (Models):

    • 作為控制平面,負責拆解任務並生成 SDK 調用代碼。
    • 為了解決模型未在預訓練中見過該自定義 SDK 的問題,團隊設計了高度最佳化的 Agent Skills。這些 SKILL.md 被嚴格限制在 2000 tokens 以下,不僅列出可用函數,更提供精簡的模式組合與 Few-shot 範例,成功教會模型編排數千次操作。

程式碼作為編排器與填補空白的工具 (Code as Orchestrator and Gap Filler)

當搜尋堆疊缺少特定的非常規能力(如極度複雜的正則表達式過濾)時,如果沒有 SaC,模型只能靠 Prompt 過濾充滿雜訊的結果。在 SaC 架構中,模型可以呼叫 SDK 獲取超集,再自己寫一段 Python 的正則邏輯進行去重與精準過濾。因此,程式碼不僅是編排器,更是填補特定領域能力缺口的關鍵工具。

案例分析:CVE 供應商安全公告 (Case Study: CVE Vendor Advisories)

任務要求識別 2023-2025 年間 200 多個高危 CVE,並綁定官方供應商的修復版本。SaC 架構達到了 100% 準確率,且 Token 消耗相較基準下降了 85.1%。 實作軌跡產生了三個關鍵代碼塊段落,展示了其強大控制力:

  1. 並發與 Fan-out (Part 1): Agent 撰寫 Python 迴圈,動態生成各家供應商的檢索語句,並使用 sdk.search.web_many 進行並行搜尋 (concurrency=12),直接將領域知識(只查特定官方站點)實現在代碼中。

    # Part 1: fan out over official advisory formats
    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)
  2. 利用 LLM 作為中間規劃子程序 (Part 2): 程式碼主動總結各廠商的檢索覆蓋率 (coverage),然後在沙盒內再次呼叫輕量級 query_llm(prompt) 來生成更多精準的 Query 以補足稀疏年份。這將 LLM 降級為一個普通的函式調用,無需中斷整個 Agent 的執行流。

  3. 嚴格的結果驗證與綁定 (Part 3): 使用 sdk.llm.extract_many 傳入嚴格的 Schema (包含 version_bound_to_cve 欄位),利用 LLM 對候選網頁文本進行萃取。隨後用常規 Python 邏輯去重並過濾低信心度的結果,確保了回傳資料的絕對純淨。

效能數據與基準測試 (Evaluation Results)

總結與結論 (Key Takeaways)

  1. 重構 API 為 SDK 原語: 為了適應長程 Agentic Workflow,系統應從提供「端到端 (End-to-End)」的單體式服務,轉向提供原子化的 SDK 原語,將控制與編排權限透過程式碼生成完全下放給 LLM。
  2. 混合運算架構 (Hybrid Compute Architecture): 系統的未來在於整合:利用 LLM 進行 Token 空間的模糊推理來處理不確定性,同時利用沙盒內的傳統 Runtime 來執行並行、批次、過濾與聚合等決定性計算。
  3. 主動的狀態持久化優於隱式上下文: 處理多輪複雜推論時,強制 Agent 透過讀寫檔案系統做狀態序列化(Serde),比依賴 REPL 的隱式上下文記憶更能保持環境的乾淨與可靠,避免命名空間污染。
  4. Agent Skill 的最佳實踐: 教會模型使用未見過的 SDK 不需依賴重新訓練,使用極度精簡的 SKILL.md (限制在 2000 tokens 內),重點提供模式組合思路與 Few-shot 範例,就能有效激發模型舉一反三的編排能力。