How to Build an AI Agent With Perplexity That Actually Works

Sami Ullah Khan

July 18, 2026

How to Build an AI Agent With Perplexity

📋 Executive Summary

🏗️

Architecture: A reliable Perplexity agent combines one narrow goal, an appropriate model or preset, explicit tools, a state store, validation and observability.

🔗

API Endpoint: The canonical Agent API endpoint is POST /v1/agent, while /v1/responses remains an OpenAI compatible alias.

💰

Pricing: Tool calls are billed separately from model tokens, including $0.005 for web_search and $0.0005 for fetch_url.

⚠️

Hidden Constraint: The public Agent API currently exposes search, URL fetch, people, finance and custom function tools, but it does not provide sandbox or remote MCP as native request types.

📈

Production Limits: Agent API throughput begins at 1 QPS and 50 requests per minute for Tier 0, making request queues and jittered backoff essential from the first production deployment.

Deployment Strategy: Start with a draft only research agent, measure source accuracy and tool efficiency, then introduce write actions behind human approval gates.

I build an AI agent with Perplexity by treating the Agent API as an orchestration layer, not as a magical autonomous worker: define one measurable job, choose a model or research preset, expose only the tools required, validate the response, and keep consequential actions behind human approval. That answer matters because how to build an AI agent with Perplexity is now less about writing a clever prompt and more about engineering a controlled loop around live search, tool calls, state, costs and failure recovery.

The platform changed materially in 2026. Perplexity made POST /v1/agent the canonical endpoint, kept /v1/responses as an OpenAI-compatible alias, added model fallback chains, exposed dynamic research presets, and documented exact tool-call costs. The result is a useful middle layer for teams that want access to multiple model providers and web-grounded tools through one API key. It also creates a new responsibility: the developer, not the model, must define permissions, stopping rules, audit evidence and safe recovery.

This guide builds a narrow research-and-action agent in Python. It can search the live web, fetch a selected source, call a custom business function, return schema-validated JSON, and log the cost and tool trace. I also show where the documentation is explicit, where it remains ambiguous, and where a direct provider SDK or deterministic workflow engine may be a better fit. The goal is a template you can run, inspect and harden, rather than a demo that succeeds only on the happy path.

Start With a Job, Not an Agent Persona

The first design decision is the unit of work. “Research companies” is too broad. “For a supplied company domain, find three current product signals, extract evidence, assign a confidence score, and save a draft brief for review” is testable. It gives the system an input contract, a bounded toolset, a measurable output and a clear stopping condition. This is the same operating discipline used in our business AI agent setup framework, where scope, ownership and escalation rules come before platform selection.

A useful first agent should be allowed to fail safely. Research, classification, drafting and data extraction are good starting tasks because a human can review the result before it changes a system of record. Sending money, deleting records, changing legal terms, publishing unreviewed claims or contacting customers without approval are poor first tasks. The risk is not that the model sounds uncertain. The risk is that it sounds certain while invoking a tool with real authority.

“It’s clear a new era of productivity is emerging as AI experiences rapidly evolve from answering questions to executing multi-step tasks.”
Satya Nadella, Microsoft Chairman and CEO, March 2026

Nadella’s emphasis on “clear user control points” is the important half of that shift. A production specification should name the person who owns the workflow, the systems the agent may read, the actions it may write, the maximum spend per run, the evidence required for completion, and the event that forces escalation. Those details become code, policies and tests later.

The Perplexity Agent Architecture in One Map

Perplexity describes the Agent API as a multi-provider interface with integrated real-time search, reasoning controls, token budgets and tool configuration. The canonical request is sent to POST /v1/agent. Existing OpenAI Responses API clients can use the /v1/responses alias by changing the base URL and API key. For broader context on why retrieval-first systems differ from ordinary text-generation endpoints, see our Perplexity API infrastructure guide.

LayerWhat It DoesProduction Decision
Goal and PolicyDefines the task, allowed actions, approval gates and stopping rules.Write a one-page agent contract before coding.
Model or PresetProvides language reasoning and tool selection.Choose for quality, latency, tool support and cost, not brand loyalty.
ToolsAdds web search, URL fetching, specialist search or custom business functions.Expose the minimum set and use strict schemas.
StateCarries task context, tool outputs, checkpoints and memory.Store externally when continuity matters.
ValidationChecks JSON shape, evidence, permissions and business constraints.Reject or repair outputs before execution.
ObservabilityRecords prompts, tool calls, latency, tokens, cost and decisions.Treat traces as a release requirement.

The hidden engineering insight is that the model is only one replaceable component. Aravind Srinivas, Perplexity’s co-founder and CEO, argued in March 2026 that “No model family can operate at its highest level without the talents of others.” That view explains the Agent API’s multi-provider direction and model fallback support. It does not mean every request should bounce among models. It means the orchestration layer should make model choice explicit and replaceable. (Perplexity, The AI Is the Computer).

Create the API Key and Install the SDK

Generate a key in the Perplexity API console, store it in a secret manager, and expose it to the application as PERPLEXITY_API_KEY. Do not paste the key into source code, notebooks, screenshots or client-side JavaScript. Our Perplexity API key guide explains why the credential is a machine identity tied to billing, rate limits and governance rather than a normal user login.

# macOS or Linux
export PERPLEXITY_API_KEY=”replace-with-secret-manager-value”

# Python SDK
pip install perplexityai

# Optional environment loader for local development
pip install python-dotenv pydantic

Perplexity’s SDK quickstart supports Python and TypeScript and reads the environment variable automatically. In production, separate keys by environment and workload. A research worker should not share a key with a customer-facing application, because one traffic spike or compromised process can consume the same rate-limit bucket and billing balance.

Send the First Search-Grounded Request

from perplexity import Perplexity

client = Perplexity()

response = client.responses.create(
    model=”perplexity/sonar”,
    input=(
        “Research three current signals that Acme Robotics is expanding “
        “its warehouse automation business. Cite the evidence and state uncertainty.”
    ),
    tools=[{“type”: “web_search”}],
    instructions=(
        “Use web search for current claims. Prefer company filings, official pages, “
        “regulators and reputable reporting. Do not infer expansion from one weak signal.”
    ),
    max_output_tokens=1200,
)

print(response.output_text)
print(response.usage.cost.total_cost)

The request is deliberately narrow. It defines the evidence standard and tells the model when not to overclaim. The response object includes the selected model, output items, token usage and cost information, so log those fields from the first prototype rather than adding telemetry after launch.

Choose a Model or Preset Deliberately

Perplexity offers direct model selection and dynamic presets. Direct selection is appropriate when you have evaluated a specific model and need predictable behaviour. Presets are useful when you want Perplexity to maintain the underlying configuration as models and search settings improve. The trade-off is reproducibility: a named preset is not version-pinned and can change underneath your application.

OptionCurrent Configuration SnapshotBest UseMain Risk
fast-searchLow search context, 1 step, web_search.Simple factual lookups and low-latency enrichment.Too shallow for ambiguous or evidence-heavy tasks.
pro-searchMedium context, 3 steps, web_search plus fetch_url.General research, comparisons and source verification.Dynamic configuration can change without a code release.
deep-researchHigh context, up to 10 steps, web_search plus fetch_url.Complex multi-source investigations.Longer latency and higher model/tool spend.
advanced-deep-researchHigh context, up to 10 steps, frontier model configuration.Institutional-grade synthesis where depth justifies cost.Most expensive and still requires evidence validation.
Direct modelA named provider/model identifier.Pinned evaluations, stable routing and controlled experiments.You must track deprecations and tool compatibility.

For the first agent, use pro-search when the work genuinely requires research, or use a low-cost direct model plus web_search when you want tighter control. Freeze the configuration before a regulated or customer-facing release. Perplexity’s documentation explicitly warns that dynamic preset names resolve to the latest recommended configuration, while a frozen copy locks the model, prompt, tools and parameters.

Model fallback is a separate availability feature. You may provide an ordered models array containing up to five choices. The API tries each model until one succeeds and bills only the model that serves the request. Cross-provider fallback reduces outage dependence, but it can change tone, latency and structured-output behaviour. Test every fallback candidate against the same evaluation set.

Add Web Search and URL Fetching With Evidence Rules

The most natural Perplexity agent is a research agent because web grounding is a first-class capability. Use web_search when the agent needs to discover current sources. Use fetch_url when it already knows which page must be read in detail. Their roles are different: search creates a candidate set, while URL fetch retrieves a specific document for closer extraction.

A robust search instruction should specify source quality, recency, geographic scope, conflicting-evidence handling and the minimum evidence needed for a conclusion. This discipline matches the workflow controls in our AI automation workflow guide, where the model interprets context but deterministic rules decide whether a result can proceed.

response = client.responses.create(
    preset=”pro-search”,
    input=”Prepare a verified supplier-risk brief for the domain supplied by the user.”,
    tools=[
        {
            “type”: “web_search”,
            “search_context_size”: “medium”,
            “filters”: {
                “search_domain_filter”: [
                    “gov.uk”, “sec.gov”, “companieshouse.gov.uk”, “reuters.com”
                ]
            },
        },
        {“type”: “fetch_url”},
    ],
    instructions=(
        “Use at least two independent sources for adverse claims. “
        “Distinguish event date from publication date. “
        “Return ‘insufficient evidence’ when the threshold is not met.”
    ),
    max_steps=4,
)

Domain filters can allow or exclude up to 20 domains or URLs, but an allowlist is not a truth guarantee. Official pages can be outdated, company statements can be self-serving, and a reputable publisher can report an unverified allegation. The agent should separate retrieved facts, source statements and its own inference. It should also retain the source annotations returned by the API rather than asking the model to invent links inside JSON.

Connect Business Logic With Custom Functions

Search produces information. A business agent becomes useful when it can call controlled functions such as reading an approved CRM record, creating a draft task, checking inventory or saving a research brief. Perplexity’s function tool uses a name, description and JSON Schema parameters. The arguments arrive as a JSON string and must be parsed before execution.

This is also where many “agent” demos become unsafe. A vague tool description can lead the model to choose the wrong function, and a broad function can turn one model mistake into a data incident. Follow least privilege: separate read functions from write functions, validate every argument, enforce tenant and user scope server-side, and require idempotency keys for operations that may be retried.

import json
from typing import Any

TOOLS = [
    {
        “type”: “function”,
        “name”: “get_account_context”,
        “description”: (
            “Read approved, non-sensitive account context for research. “
            “Use only after the user supplies an account_id.”
        ),
        “parameters”: {
            “type”: “object”,
            “properties”: {
                “account_id”: {“type”: “string”, “minLength”: 3}
            },
            “required”: [“account_id”],
            “additionalProperties”: False,
        },
        “strict”: True,
    },
    {“type”: “web_search”},
    {“type”: “fetch_url”},
]

def get_account_context(account_id: str) -> dict[str, Any]:
    # Replace with a scoped database read. Never trust model-supplied identity.
    return {
        “account_id”: account_id,
        “approved_products”: [“Warehouse Vision”],
        “region”: “United Kingdom”,
        “write_access”: False,
    }

def dispatch_function(name: str, arguments_json: str) -> dict[str, Any]:
    args = json.loads(arguments_json)
    if name == “get_account_context”:
        return get_account_context(**args)
    raise ValueError(f”Unknown function: {name}”)

Run the Tool Loop

response = client.responses.create(
    model=”openai/gpt-5.4″,
    input=”Research account ACME-UK-42 and prepare a renewal-risk brief.”,
    tools=TOOLS,
    instructions=(
        “Read account context before web research. Do not perform write actions. “
        “Use current evidence and identify unresolved uncertainty.”
    ),
    max_steps=4,
)

function_outputs = []
for item in response.output:
    if getattr(item, “type”, None) == “function_call”:
        result = dispatch_function(item.name, item.arguments)
        function_outputs.append({
            “type”: “function_call_output”,
            “call_id”: item.call_id,
            “output”: json.dumps(result),
        })

if function_outputs:
    response = client.responses.create(
        model=”openai/gpt-5.4″,
        input=function_outputs,
        tools=TOOLS,
        instructions=”Use the function result and complete the evidence-based brief.”,
        max_steps=4,
    )

print(response.output_text)

The public Agent API reference currently enumerates web_search, fetch_url, people_search, finance_search and custom function tools. Perplexity also publishes an MCP server integration that lets compatible clients access its search and reasoning capabilities, but the current Agent API request schema does not list remote MCP or sandbox as native tool types. Treat claims about native Agent API MCP or sandbox support as version-sensitive and verify the live reference before coding. This is one place where the product surface and ecosystem language can be confused.

Force Structured JSON and Validate It Twice

A production agent should not hand a free-form paragraph directly to downstream automation. Perplexity supports JSON Schema structured outputs through response_format. The schema must be named, each object should define explicit properties, additionalProperties must be false, and recursive or unconstrained objects are not supported. The first use of a new schema can add roughly 10 to 30 seconds of preparation delay, so warm critical schemas before measuring user-facing latency.

from pydantic import BaseModel, Field
from typing import Literal

class Evidence(BaseModel):
    claim: str
    source_title: str
    source_url: str
    confidence: float = Field(ge=0, le=1)

class ResearchBrief(BaseModel):
    account_id: str
    risk_level: Literal[“low”, “medium”, “high”, “unknown”]
    summary: str
    evidence: list[Evidence]
    unresolved_questions: list[str]
    recommended_next_step: str

schema = ResearchBrief.model_json_schema()
schema[“additionalProperties”] = False

response = client.responses.create(
    preset=”pro-search”,
    input=”Create a renewal-risk brief for account ACME-UK-42.”,
    tools=[{“type”: “web_search”}, {“type”: “fetch_url”}],
    response_format={
        “type”: “json_schema”,
        “json_schema”: {
            “name”: “renewal_risk_brief”,
            “schema”: schema,
        },
    },
)

brief = ResearchBrief.model_validate_json(response.output_text)

Schema compliance is only the first validation layer. A field can be syntactically valid and factually wrong. Validate URLs against the API’s returned citations or search-results fields, check confidence thresholds, reject empty evidence arrays for high-risk conclusions, and apply business rules after parsing. Perplexity’s documentation specifically warns that asking the model to place links inside JSON can produce broken or hallucinated URLs, so use the retrieved source metadata as the authoritative link record.

In other words, typed output protects the pipeline from malformed data, not from bad judgement. The agent still needs evidence checks and, for consequential decisions, human review.

Design Memory as Application State

An agent may need to continue a task across turns, but “memory” is not one feature. Separate conversational continuity, task state, long-term user preferences, retrieved evidence and business records. Each has a different retention period and security requirement. A useful practical definition of an AI agent includes state and stopping rules because a model plus tools without reliable state is only a fragile sequence of calls.

Perplexity’s OpenAI-compatible response objects expose response IDs and a previous_response_id field in returned examples. However, the current public POST /v1/agent request reference does not clearly document previous_response_id as an accepted body property. That gap is material. Test multi-turn chaining against the exact SDK and endpoint version you deploy rather than assuming parity from the response shape alone.

For production continuity, keep canonical state in your application database. Store the task goal, compact working summary, approved facts, tool results, pending approvals, cost to date, schema version and last successful checkpoint. Send only the context needed for the next step. This reduces token growth, avoids dependence on opaque server retention and lets you redact or expire sensitive information deliberately.

state = {
    “task_id”: “task_2026_0717_0042”,
    “goal”: “Prepare a renewal-risk brief”,
    “account_id”: “ACME-UK-42”,
    “approved_facts”: [],
    “pending_approval”: None,
    “cost_usd”: 0.0,
    “schema_version”: “renewal_risk_brief_v1”,
}

# Persist state after each completed step.
# Reconstruct the next prompt from validated state, not the full raw transcript.

Long-term memory should be opt-in, inspectable and deletable. Do not silently convert every conversation into a permanent profile. For most B2B agents, the safest memory is task-specific and expires after the workflow or contractual retention window.

Build Retries, Rate Limits and Model Fallback Into the First Release

Agent API rate limits scale by cumulative API credit purchases. Tier 0 starts at 1 query per second and 50 requests per minute, while Tiers 4 and 5 reach 33 QPS and 2,000 requests per minute. The Search API has a separate 50 requests-per-second limit. These are architectural constraints, not billing footnotes. A burst of user traffic plus tool-loop calls can exhaust the bucket even when top-level request volume looks modest.

Our Perplexity API rate-limit guide explains the tier mechanics, while the 429 troubleshooting checklist covers practical recovery. The minimum production pattern is a shared queue, exponential backoff with jitter, bounded retries, an overall deadline and idempotency protection for write operations.

import random
import time

def call_with_backoff(call, attempts: int = 5):
    last_error = None
    for attempt in range(attempts):
        try:
            return call()
        except Exception as exc:
            last_error = exc
            status = getattr(exc, “status_code”, None)
            if status not in {429, 500, 502, 503, 504}:
                raise
            if attempt == attempts – 1:
                break
            delay = min(20.0, (2 ** attempt) + random.random())
            time.sleep(delay)
    raise RuntimeError(“Agent request failed after bounded retries”) from last_error

Model fallback helps with provider availability, but it is not a substitute for retries. Use a short retry policy for transient transport and capacity errors, then let the ordered fallback chain handle model-specific failure. Log which model actually served the request because costs and output behaviour may differ from the primary choice.

“Systems no longer fail in isolation.”
Brendan Burns, Microsoft Technical Fellow and Azure CVP, June 2026

That observation is particularly relevant to agents. A failure may begin in search, continue through a malformed tool result, trigger a retry, switch to a fallback model and finally produce a plausible but inconsistent answer. Your trace must connect the whole path.

Price the Whole Run, Not Just the Model

Perplexity separates model token charges from tool-call charges. As of the current documentation, web_search costs $0.005 per invocation, fetch_url costs $0.0005, people_search costs $0.005 and finance_search costs $0.005. Model prices vary by provider and are updated monthly. Every response includes usage and cost fields, which should feed per-run budgets and alerts.

Cost ComponentCurrent Published PriceHidden Cost DriverControl
web_search$0.005 per invocationA multi-step agent may search several times in one run.Cap max_steps and log tool count.
fetch_url$0.0005 per invocationFetching many candidate pages can multiply quickly.Fetch only shortlisted sources.
people_search$0.005 per invocationBroad lead-research loops can call it repeatedly.Require a named target and result cap.
finance_search$0.005 per invocationMultiple categories or tickers create multiple calls.Batch deliberately and cache allowed data.
Search API$5 per 1,000 requestsSeparate product with no token charge.Use when you need raw ranked results, not synthesis.
Model tokensProvider and model dependentReasoning, long prompts, large outputs and cache behaviour.Set output limits, compress state and evaluate cheaper models.

A simple estimated run cost is model input plus model output plus cache charges plus every tool invocation. A three-step research agent that performs four web searches and two URL fetches adds $0.021 in tool charges before model tokens. That may be negligible for one analyst, but it becomes $2,100 per 100,000 similar runs. Deep research can cost far more because it uses more steps, pages and reasoning.

Do not hard-code the model price table into business logic. Perplexity states that third-party rates are updated monthly. Query the current model list and maintain a configuration service or periodic pricing review. The full model catalogue is dynamic, and not every model supports every feature, so a static “cheapest model” rule can select an incompatible option.

“AI should show up in ways that are practical and genuinely useful for people.”
Sam Altman, OpenAI co-founder and CEO, February 2026

Practical usefulness includes economic usefulness. Measure cost per accepted result, not cost per API call. A cheap model that produces twice the review burden may be the expensive choice.

Secure the Tool Boundary Against Prompt Injection

Web-connected agents read untrusted content. A webpage, document or email can contain instructions designed to override the user’s goal, exfiltrate data or trigger an unsafe tool. OpenAI’s 2026 security guidance describes effective prompt injection as increasingly similar to social engineering. Perplexity’s own 2026 security response to NIST highlights indirect prompt injection, confused-deputy behaviour and cascading failures in long-running workflows.

“Agent architectures change core assumptions around code-data separation, authority boundaries, and execution predictability.”
Ninghui Li, Kaiyuan Zhang, Kyle Polley and Jerry Ma, 2026 security paper

The mitigation is layered. Treat retrieved content as data, never as policy. Keep credentials outside model-visible execution environments. Enforce permissions in the tool implementation, not in natural-language instructions. Separate read and write scopes. Add confirmation for high-consequence actions. Sanitize tool outputs. Limit network destinations. Record the exact evidence and arguments used for each action.

ThreatExampleRequired Control
Indirect Prompt InjectionA fetched page tells the agent to ignore the task and reveal secrets.Instruction hierarchy, content labelling, domain controls and no secrets in context.
Confused DeputyThe agent uses a privileged tool for an unauthorised user request.Server-side identity, authorisation and tenant checks.
Tool Argument AbuseThe model supplies an unexpected path, account or amount.Strict schema, allowlists, range checks and canonicalisation.
Retry DuplicationA timed-out request repeats a write action.Idempotency keys and transaction logs.
Evidence LaunderingThe final answer cites a source that was never retrieved.Bind claims to returned source records and reject unmatched citations.
Runaway CostThe loop keeps searching without improving evidence.Step limits, budget caps and marginal-gain stopping rules.

NIST launched its AI Agent Standards Initiative in February 2026 around secure delegation, interoperability and identity. That direction reinforces a simple deployment principle: an agent should have a recognisable identity, a limited authority set and an auditable chain from request to action.

Test the Agent Like a System, Not a Chatbot

A good answer in one demo is not evidence of reliability. Build an evaluation set from real tasks, edge cases and deliberate attacks. Each case should define expected evidence, forbidden actions, output schema, maximum cost, maximum latency and the human decision that follows. The relevant metric is not “looks good”. It is whether the result is correct enough, grounded enough and safe enough to reduce total work.

For low-code deployment, a platform such as Make can wrap the Perplexity API with triggers and downstream apps. Our Make.com automation tutorial is useful when the workflow is mostly deterministic and the agent is one bounded reasoning step. A custom Python service is better when you need strict permissions, custom state, detailed traces or regulated controls.

  1. Create 30 to 100 representative tasks, including incomplete and contradictory inputs.
  2. Record a human-reviewed reference answer or acceptable decision range.
  3. Run every candidate model and preset with the same tools and budget.
  4. Score factual accuracy, citation validity, schema compliance, tool efficiency, latency and cost.
  5. Add adversarial pages, malicious tool outputs, stale data and partial outages.
  6. Measure human edit time and rejection reasons, not only model scores.
  7. Release in shadow mode, then draft-only mode, then low-risk execution behind approvals.

OpenAI reported in June 2026 that more than 70 per cent of Codex users had asked it to complete a task estimated to take a person more than an hour. The statistic shows why evaluation must cover long-horizon work rather than isolated turns. Longer tasks compound small errors, costs and state inconsistencies. (OpenAI Economic Research).

A Production-Ready Python Template

The following template combines a narrow goal, web tools, a read-only business function, structured output, bounded retries, validation and cost logging. Replace the mock account function and logging sink with your own scoped services. The template intentionally does not execute write actions.

import json
import logging
import os
import random
import time
from typing import Any, Literal

from perplexity import Perplexity
from pydantic import BaseModel, Field, ValidationError

logging.basicConfig(level=logging.INFO)
log = logging.getLogger(“perplexity-agent”)
client = Perplexity(api_key=os.environ.get(“PERPLEXITY_API_KEY”))

class Evidence(BaseModel):
    claim: str
    source_title: str
    source_url: str
    confidence: float = Field(ge=0, le=1)

class Brief(BaseModel):
    account_id: str
    risk_level: Literal[“low”, “medium”, “high”, “unknown”]
    summary: str
    evidence: list[Evidence]
    unresolved_questions: list[str]
    recommended_next_step: str

def get_account_context(account_id: str) -> dict[str, Any]:
    # Replace with a tenant-scoped, read-only database query.
    if account_id != “ACME-UK-42”:
        raise ValueError(“Account not found or not authorised”)
    return {
        “account_id”: account_id,
        “region”: “United Kingdom”,
        “products”: [“Warehouse Vision”],
        “renewal_month”: “October 2026”,
        “write_access”: False,
    }

def dispatch(name: str, arguments: str) -> dict[str, Any]:
    args = json.loads(arguments)
    if name == “get_account_context”:
        return get_account_context(**args)
    raise ValueError(f”Unknown function: {name}”)

TOOLS = [
    {
        “type”: “function”,
        “name”: “get_account_context”,
        “description”: “Read approved account context for renewal research.”,
        “parameters”: {
            “type”: “object”,
            “properties”: {“account_id”: {“type”: “string”}},
            “required”: [“account_id”],
            “additionalProperties”: False,
        },
        “strict”: True,
    },
    {“type”: “web_search”, “search_context_size”: “medium”},
    {“type”: “fetch_url”},
]

def request_with_backoff(**kwargs):
    last_error = None
    for attempt in range(5):
        try:
            return client.responses.create(**kwargs)
        except Exception as exc:
            last_error = exc
            status = getattr(exc, “status_code”, None)
            if status not in {429, 500, 502, 503, 504}:
                raise
            if attempt == 4:
                break
            time.sleep(min(20.0, (2 ** attempt) + random.random()))
    raise RuntimeError(“Request failed after bounded retries”) from last_error

def build_brief(account_id: str) -> Brief:
    schema = Brief.model_json_schema()
    schema[“additionalProperties”] = False

    first = request_with_backoff(
        models=[
            “openai/gpt-5.4”,
            “anthropic/claude-sonnet-4-6”,
            “perplexity/sonar”,
        ],
        input=(
            f”Prepare a current renewal-risk brief for account {account_id}. “
            “Read approved context first, then verify external claims.”
        ),
        tools=TOOLS,
        instructions=(
            “Do not perform write actions. Prefer official and reputable sources. “
            “Use at least two independent sources for adverse claims. “
            “Return unknown when evidence is insufficient.”
        ),
        max_steps=4,
        max_output_tokens=1800,
    )

    outputs = []
    for item in first.output:
        if getattr(item, “type”, None) == “function_call”:
            result = dispatch(item.name, item.arguments)
            outputs.append({
                “type”: “function_call_output”,
                “call_id”: item.call_id,
                “output”: json.dumps(result),
            })

    final_input = outputs or [
        {“role”: “user”, “content”: “Complete the brief with the evidence already retrieved.”}
    ]

    final = request_with_backoff(
        models=[
            “openai/gpt-5.4”,
            “anthropic/claude-sonnet-4-6”,
            “perplexity/sonar”,
        ],
        input=final_input,
        tools=TOOLS,
        instructions=(
            “Return only the requested schema. Do not invent source URLs. “
            “Use source metadata returned by tools.”
        ),
        response_format={
            “type”: “json_schema”,
            “json_schema”: {“name”: “renewal_risk_brief”, “schema”: schema},
        },
        max_steps=4,
        max_output_tokens=1800,
    )

    try:
        brief = Brief.model_validate_json(final.output_text)
    except ValidationError as exc:
        log.exception(“Schema validation failed”)
        raise

    if brief.risk_level == “high” and len(brief.evidence) < 2:
        raise ValueError(“High-risk conclusion requires at least two evidence items”)

    cost = getattr(getattr(final, “usage”, None), “cost”, None)
    log.info(
        “agent_complete model=%s total_cost=%s evidence=%s”,
        final.model,
        getattr(cost, “total_cost”, None),
        len(brief.evidence),
    )
    return brief

if __name__ == “__main__”:
    result = build_brief(“ACME-UK-42”)
    print(result.model_dump_json(indent=2))

Before deployment, adapt the response chaining to the exact behaviour of the current SDK. Some workflows can send function_call_output items back directly, while longer conversations may require explicit application-managed context. Confirm the live API reference and run an integration test in your environment.

When Perplexity Is Not the Best Fit

Perplexity is a strong fit for web-grounded research, multi-provider routing and workflows that benefit from search and URL retrieval. It is not automatically the best orchestration platform for every agent. A direct provider SDK may be preferable when you need a provider-specific feature, the lowest possible latency to one model, or a fully documented conversation-state primitive. A workflow engine may be better when the process is deterministic and only one step needs language understanding. An internal RAG stack may be better when the agent must stay inside a private corpus and the open web adds risk rather than value.

The public documentation gap around native MCP and sandbox request types is a concrete example. Perplexity offers an MCP server integration for compatible clients and broader products use secure sandbox concepts, but the current Agent API body schema does not show those as native tools. If remote MCP servers or isolated code execution are central requirements, verify availability before committing the architecture or use a separate execution service behind a custom function.

The best choice follows the workload. Use Perplexity when current web evidence and model flexibility are core. Use a simpler, deterministic stack when the work is stable, private and rule-based. Use a specialist runtime when durable execution, computer use or complex multi-agent handoffs dominate the design.

Our Content Testing Methodology

This guide was verified against Perplexity’s Agent API quickstart, API reference, pricing page, model catalogue, preset documentation, tool documentation, output-control guide, structured-output cookbook, function-calling cookbook, model fallback guide, OpenAI compatibility guide, MCP integration page, changelog and rate-limit tiers. The implementation examples were checked for a narrow read-only business workflow, JSON Schema constraints, bounded retries, source-validation rules and current documented parameter limits such as max_steps from 1 to 10 and fallback chains of up to five models.

The internal-link selection attempted the publication’s sitemap endpoints first. They did not return parseable XML through the available browsing layer, so no sitemap entries were fabricated. Eight semantically relevant, indexed Perplexity AI Magazine pages were selected from live search results and placed once each in body sections only. Pricing is presented as a July 2026 snapshot and the article directs production systems to the live model and pricing references because third-party rates change monthly.

Security and market context were cross-checked against NIST’s 2026 AI Agent Standards Initiative, NIST’s May 2026 agent-security response analysis, Perplexity’s 2026 security paper, Microsoft executive commentary and OpenAI’s 2026 agent and prompt-injection publications. No claim of native Agent API MCP or sandbox tooling was made because the current request schema does not list those tool types.

This article was researched and drafted with AI assistance and reviewed by the Sami Ullah Khan editorial desk at Perplexity AI Magazine. All data, citations, pricing figures, and named quotes have been independently verified against primary sources before publication.

Conclusion

Building an AI agent with Perplexity is straightforward at the API-call level and demanding at the system level. The reliable path starts with one narrow job, a measurable output and a small permission surface. Perplexity then provides a useful orchestration layer: one endpoint, multiple model providers, built-in web research, custom functions, structured JSON, fallback chains and transparent usage data.

The important work surrounds that layer. Application-managed state prevents fragile memory. Schema and evidence validation stop plausible text from becoming untrusted data. Queues, jittered retries and budget caps contain operational failures. Server-side authorisation and approval gates keep a model from inheriting more authority than the task requires. Evaluations reveal whether the agent saves time after review rather than merely producing impressive output.

Open questions remain. Dynamic presets improve without version pinning, the documented tool surface can lag broader product language, and model compatibility changes as providers update their systems. Those uncertainties do not block deployment, but they reward conservative architecture. Treat models and tools as replaceable components, keep evidence and state under your control, and expand autonomy only after the agent has proved reliable in shadow and draft-only modes.

Frequently Asked Questions

Can I build an AI agent directly with the Perplexity API?

Yes. Use the Agent API at POST /v1/agent with a model or preset, input, optional tools and output controls. The /v1/responses alias supports OpenAI-compatible clients. Production use still requires your own validation, state, security and observability.

Which Perplexity tool should a research agent use?

Use web_search to discover current sources and fetch_url to read a known page in detail. Use a custom function when the agent needs approved business data or must request an action from your backend.

Does the Agent API support structured JSON output?

Yes. Set response_format to json_schema and provide a named JSON Schema. Define every object explicitly, set additionalProperties to false and validate the returned JSON again in your application.

How much does a Perplexity AI agent cost?

Total cost combines model tokens and tool calls. Current documented tool prices include $0.005 per web_search, $0.0005 per fetch_url, and $0.005 per people_search or finance_search. Model rates vary and change monthly.

How do I give a Perplexity agent memory?

Keep canonical state in your own database. Store task goals, validated facts, tool results, approvals, cost and checkpoints. The current public request reference should be checked before relying on server-side previous-response chaining.

Can Perplexity Agent API call my own functions?

Yes. Define a function tool with a clear description and strict JSON Schema. Parse the returned argument string, validate it, enforce permissions server-side and return the function result for the model to continue.

How should I handle Perplexity API 429 errors?

Use a shared queue, exponential backoff with jitter, bounded retries and rate-aware concurrency. Tier 0 Agent API limits start at 1 QPS and 50 requests per minute, so design for throttling before launch.

Is Perplexity the best platform for every AI agent?

No. It is particularly strong for web-grounded research and multi-provider access. Direct provider SDKs, deterministic workflow engines or private RAG systems may be better for provider-specific, rule-based or closed-corpus workloads.

References

1. National Institute of Standards and Technology. (2026, February 17). Announcing the AI Agent Standards Initiative for interoperable and secure innovation.

2. Perplexity AI. (2026). Agent API quickstart.

3. Perplexity AI. (2026). Agent API pricing.

4. Perplexity AI. (2026). Agent API presets.

5. Perplexity AI. (2026). Rate limits and usage tiers.

6. Perplexity AI. (2026). Structured output extraction.

7. Li, N., Zhang, K., Polley, K., & Ma, J. (2026). Security considerations for artificial intelligence agents.

8. OpenAI. (2026, March 11). Designing AI agents to resist prompt injection.

9. Srinivas, A. (2026, March 3). The AI is the computer.

Stay Ahead of AI

Get the latest AI news delivered to your inbox.

We don’t spam! Read our privacy policy for more info.