explainx / blog
Perplexity introduces Search as Code (SaC), a revolutionary architecture that makes search natively programmable by AI agents through code generation. Explore how SaC achieves 2.5x better performance than alternatives.

Jul 9, 2026
Perplexity post-trained GLM 5.2 for the Computer harness — research preview with an advisor tool that escalates to stronger models, ~half Opus cost on WANDR, hosted on US Nvidia B200s. explainx.ai breaks down the July 9 orchestrator drop.
Jun 29, 2026
"AI agent" covers everything from a chatbot with one tool to a fleet of orchestrated coding agents. This guide maps every major type — reactive vs deliberative, ReAct vs plan-and-execute, coding vs research vs browser agents, single vs multi-agent — and tells you which to build when.
Jun 27, 2026
ReAct is not a framework feature — it is a prompting pattern. Once you understand the Thought/Action/Observation loop you will see it everywhere: in LangChain agents, Claude Code, and every serious agentic system built in 2024 and beyond.
Traditional search was designed for humans: you type a query, get back 10 blue links, and click through. This worked for decades. But in 2026, the primary consumers of search are no longer humans—they're AI agents.
And AI agents don't just need answers. They need to orchestrate complex retrieval workflows with thousands of operations, custom logic, and dynamic strategies tailored to each task.
Perplexity has just introduced Search as Code (SaC), a fundamental rearchitecture of search for the agentic era. Instead of offering search as a monolithic service that returns fixed results, SaC exposes search primitives as an SDK that models program through generated code.
The results are dramatic: 2.5x performance improvement on complex benchmarks, 85% reduction in token usage, and the ability to execute search workflows that were previously impossible.
Let's dive into what makes SaC revolutionary and why it represents the future of agentic search.
For the past three years of AI development, search has followed a simple pattern:
This architecture has three fundamental limitations:
| Limitation | Impact on Agents |
|---|---|
| Coarse context | Pipeline optimized for recall, not precision—introduces irrelevant information |
| No domain knowledge leverage | Model can't apply its understanding to customize search strategy |
| Serial, inefficient control flow | Each search operation requires a model turn, adding latency and polluting context |
Example 1: Vendor Advisory Research
A task requires finding 200+ high-severity CVEs from official vendor advisories (not aggregators like NVD or MITRE).
Traditional approach:
SaC approach:
Example 2: Multi-Domain Research
An agent needs to:
Traditional approach:
SaC approach:
SaC fundamentally reimagines how models interact with search infrastructure.
┌────────────────────────────────────┐
│ Models (GPT-5.5) │ ← Control plane: reasoning, planning, code generation
├────────────────────────────────────┤
│ Compute Sandboxes │ ← Execution: deterministic compute, state management
├────────────────────────────────────┤
│ Agentic Search SDK │ ← I/O layer: atomized search primitives
└────────────────────────────────────┘
↓
Perplexity Search Infrastructure
Role: Decide what to search, how to search it, and generate code to execute the strategy
Key capabilities:
Models used: GPT-5.5 (high reasoning), optimized with Agent Skills that teach SDK usage patterns
Role: Execute model-generated code in a secure, deterministic environment
Key features:
Why not REPL-style state? Perplexity tested both approaches and found filesystem-based serde performs better on long trajectories. Requiring explicit state management helps models track what's preserved and why—crucial for complex workflows.
Role: Expose Perplexity's search stack as composable primitives
This is the revolutionary piece. Instead of wrapping an existing search API, Perplexity rearchitected their entire search stack into modular, atomic primitives.
SDK components:
| Primitive Category | Examples | What It Enables |
|---|---|---|
| Retrieval | search.web(), search.web_many() | Fetch candidates from index |
| Ranking | rank(), rerank_by() | Custom relevance scoring |
| Filtering | filter_by_domain(), filter_by_date() | Remove irrelevant results |
| Deduplication | dedupe_by_url(), dedupe_by_content() | Remove redundancy |
| Aggregation | group_by(), summarize() | Structured data extraction |
| Parsing | extract_fields(), parse_structured() | Schema-based extraction |
High-level shortcuts are also available (full end-to-end search), but models can bypass them when the task requires more control.
Continual improvement: The SDK itself is optimized through autoresearch loops that test changes against latency, codegen quality, and task performance over weeks.
Let's walk through the CVE vendor advisory example mentioned in the original research article.
Find 230+ high-severity CVEs from 2023-2025, citing only official vendor advisories. Each record must include:
Part 1: Fan out over vendor advisory formats
# Define vendor-specific query templates
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}"'),
# ... more vendors
]
# Generate queries for each vendor-year combination
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))
]
# Execute in parallel with concurrency control
seed_hits = sdk.search.web_many(queries, limit_per_query=8, concurrency=12)
# Filter to official vendor advisories only
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[])
]
What happened:
Part 2: Adaptive refinement with LLM subroutine
# Summarize coverage by vendor-year
coverage = summarize(pages, by=["vendor", "year", "url_kind"])
# Use LLM to suggest refinements for sparse areas
prompt = """
Goal: 230+ high or critical CVEs from official vendor advisories.
Avoid aggregators, CERTs, news, NVD, MITRE.
Current coverage:
{coverage}
Suggest site-scoped exact-phrase queries for sparse vendor-years.
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"])
]
# Execute expansion queries
expanded_hits = sdk.search.web_many(
unique(expanded_queries),
limit_per_query=8,
concurrency=12
)
What happened:
Part 3: Verification with custom logic
# Deduplicate and filter
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))
]
# Extract and verify CVE-version binding
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,
},
)
# Final filtering and deduplication
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")
What happened:
| Metric | Traditional Search | SaC |
|---|---|---|
| Accuracy | < 25% | 100% |
| Token usage | 288.7K | 42.9K (85% reduction) |
| Time to complete | Multiple hours | Minutes |
Old paradigm:
New paradigm:
SaC doesn't just orchestrate existing primitives. Code can fill capability gaps on the fly.
Example: You need results matching a complex regex not supported by the query syntax.
Traditional approach: Try to approximate with query operators, get noisy results, filter in token space (expensive and error-prone).
SaC approach:
# Get superset with parallel queries
results = sdk.search.web_many(approximate_queries, concurrency=8)
# Deduplicate
unique_results = sdk.dedupe_by_url(flatten(results))
# Apply exact regex in code
import re
pattern = re.compile(complex_regex)
filtered = [r for r in unique_results if pattern.search(r.text)]
Result: Exact match without bloating SDK with niche functions.
Perplexity evaluated SaC against four other agent systems across five benchmarks.
| Benchmark | 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 |
SaC leads or ties on 4 of 5 benchmarks.
WANDR tests complex "wide research" tasks requiring careful orchestration of search, compute, and reasoning—exactly what SaC was designed for.
Performance:
SaC doesn't just win on performance—it dominates the cost-performance tradeoff across reasoning levels:
| Reasoning Level | DSQA Score | Cost per Task | Position |
|---|---|---|---|
| SaC Low | 0.82 | $0.50 | Frontier (cheaper than all non-SaC, better than 2 of them) |
| SaC Medium | 0.85 | $0.85 | Frontier (best score under $1) |
| SaC High | 0.871 | $1.20 | Frontier (best absolute) |
SaC vs. traditional search pipeline (same infrastructure):
| Benchmark | Absolute Gain | Relative Gain |
|---|---|---|
| DSQA | +19.77 pp | +29% |
| BrowseComp | +15.30 pp | +23% |
| HLE | +8.50 pp | +16% |
| WideSearch | +9.20 pp | +17% |
| WANDR | +12.00 pp | +45% |
1. Atomicity Break search into the smallest useful primitives. Don't expose "smart" functions—expose building blocks that can be composed into smart behaviors.
2. Composability Every primitive should work with every other primitive. No special cases or incompatible operations.
3. Efficiency Operations must be fast enough to support thousands of calls per minute. Latency directly impacts agent capability.
4. Consumability for LLMs API design optimized through autoresearch for codegen quality. Function names, parameter ordering, and documentation all tuned for model understanding.
Perplexity considered Python, Rust, TypeScript, and Bash.
Python won because:
REPL approach:
Filesystem + serde approach:
Perplexity's choice: Filesystem + serde
Testing showed that while both approaches perform similarly in normal use, filesystem-based serde provides better reliability on long trajectories. The requirement to explicitly serialize state helps models manage complexity better—analogous to the difference between a clean notebook vs. a 100-cell Jupyter notebook with cluttered namespace.
The SDK is custom-built and unlikely to appear in pretraining data. Even with excellent documentation, models need guidance to compose primitives effectively.
Solution: Highly-tuned Agent Skills
These Skills:
Size constraint: < 2000 tokens in root SKILL.md
Both the SDK and Agent Skills are optimized via continual autoresearch loops that:
This runs continuously over weeks, making hundreds of improvements.
GPT-5.5 and Claude Opus 4.5 reliably generate complex, multi-step programs with:
Modern sandboxes provide:
Perplexity invested months rearchitecting their search stack into composable primitives. This wasn't just API design—it required rethinking every layer of the search pipeline.
Tools like Perplexity Computer and Agent API provide:
Example: Competitive intelligence
Example: GDPR compliance audit
Example: Vulnerability tracking
Example: Product-market fit analysis
| Limitation | Impact | Mitigation |
|---|---|---|
| Model capability ceiling | Complex tasks require frontier models | Use GPT-5.5 or Claude Opus 4.5 |
| Sandbox overhead | Code execution adds ~200-500ms latency | Minimize turns, maximize work per turn |
| SDK learning curve | New models need Agent Skills | Continual autoresearch optimization |
| Cost at scale | Thousands of searches can be expensive | Aggressive deduplication and caching |
1. Joint optimization of SDK + Skills Currently optimized separately. Joint autoresearch loop could find better local minima.
2. Model training on SDK usage Train models specifically on SaC patterns to improve codegen quality and reduce reliance on Agent Skills.
3. SDK co-evolution during training Design the SDK itself during model training to maximize synergy.
4. Multi-agent SaC Enable multiple agents to share a SaC pipeline, coordinating searches and sharing state.
5. Physical world integration Extend SaC beyond information retrieval to physical actions (e.g., IoT, robotics).
SaC is rolling out in Perplexity Computer, the consumer-facing autonomous AI agent product.
Access: perplexity.ai/computer
SaC is available in Perplexity's Agent API for developers building agentic applications.
Documentation: docs.perplexity.ai/api/agents
Key features:
Traditional search—one query, one response—is fundamentally mismatched to agentic workflows.
SaC proves that programmable, atomic search primitives are the future:
Function calling and MCPs were transitional technologies. Generated code is the endgame interface for:
Search companies now compete on:
| Dimension | Perplexity SaC | Traditional Search APIs | RAG Pipelines |
|---|---|---|---|
| Control | Full programmatic control | Query parameters only | Fixed pipeline |
| Parallelism | Thousands of concurrent ops | Serial function calls | Single vector search |
| Custom logic | Arbitrary code | None | Limited via configuration |
| Context efficiency | Work in code, not tokens | All results in context | All chunks in context |
| Adaptability | Task-specific pipelines | One-size-fits-all | One-size-fits-all |
| Performance | 2.5x advantage (WANDR) | Baseline | Not designed for search |
Search as Code represents a fundamental paradigm shift in how AI systems interact with information retrieval:
Before SaC:
With SaC:
The performance gains speak for themselves: 2.5x better on complex benchmarks, 85% token reduction, 100% accuracy on tasks where alternatives fail.
More importantly, SaC enables entirely new classes of agent capabilities that were impossible with traditional search architectures.
As AI agents become the primary consumers of search, every search provider will need to adopt programmable architectures like SaC or risk irrelevance.
Perplexity has shown the path forward. The agentic era demands agentic search.
Analysis based on Perplexity's research article "Rethinking Search as Code Generation" published June 2026.