| name | perplexity-reference-architecture |
| description | Implement Perplexity reference architecture with model routing, citation pipeline,
and research automation. Use when designing new Perplexity integrations,
reviewing project structure, or establishing architecture for search-augmented apps.
Trigger with phrases like "perplexity architecture", "perplexity project structure",
"how to organize perplexity", "perplexity design patterns".
|
| allowed-tools | Read, Grep |
| version | 1.12.0 |
| license | MIT |
| author | Jeremy Longshore <jeremy@intentsolutions.io> |
| tags | ["saas","perplexity","perplexity-reference"] |
| compatibility | Designed for Claude Code, also compatible with Codex and OpenClaw |
Perplexity Reference Architecture
Overview
Production architecture for AI-powered search with Perplexity Sonar API. Three tiers: search service (model routing + caching), citation pipeline (extract, validate, store), and research orchestrator (multi-query synthesis).
Architecture
┌─────────────────────────────────────────────┐
│ Application Layer │
│ (Search Widget, Research Agent, Fact Check) │
└──────────────────────┬──────────────────────┘
│
┌──────────────────────▼──────────────────────┐
│ Search Service Layer │
│ ┌──────────┐ ┌──────────┐ ┌─────────────┐ │
│ │ Model │ │ Query │ │ Response │ │
│ │ Router │ │ Cache │ │ Parser │ │
│ └──────────┘ └──────────┘ └─────────────┘ │
└──────────────────────┬──────────────────────┘
│
┌──────────────────────▼──────────────────────┐
│ api.perplexity.ai/chat/completions │
│ sonar | sonar-pro | sonar-reasoning-pro │
└─────────────────────────────────────────────┘
Prerequisites
- Perplexity API key with Sonar access
- OpenAI-compatible client library (
openai package)
- Redis for production caching (LRU for development)
Instructions
Step 1: Search Service with Model Routing
import OpenAI from "openai";
import { createHash } from "crypto";
type SearchDepth = "quick" | "standard" | "deep" | "reasoning";
const MODEL_MAP: Record<SearchDepth, { model: string; maxTokens: number; timeout: number }> = {
quick: { model: "sonar", : , : },
: { : , : , : },
: { : , : , : },
: { : , : , : },
};
{
() {}
() {
config = [depth];
cacheKey = .(query, config., opts);
cached = ..(cacheKey);
(cached && cached. > .()) {
{ ...cached., : };
}
response = ....({
: config.,
: [
...(opts. ? [{ : , : opts. }] : []),
{ : , : query },
],
: config.,
...(opts. && { : opts. }),
...(opts. && { : opts. }),
} );
result = {
: response.[].. || ,
: (response ). || [],
: (response ). || [],
: response.,
: response.,
};
ttl = opts. === ? : ;
..(cacheKey, { result, : .() + ttl });
{ ...result, : };
}
(: , : , : ): {
()
.(.({ : query.().(), model, ...opts }))
.();
}
}