perplexity-reliability-patternsClaude Skill
Implement Perplexity reliability patterns including circuit breakers, idempotency, and graceful degradation.
| name | perplexity-reliability-patterns |
| description | Implement Perplexity reliability patterns including circuit breakers, idempotency, and graceful degradation. Use when building fault-tolerant Perplexity integrations, implementing retry strategies, or adding resilience to production Perplexity services. Trigger with phrases like "perplexity reliability", "perplexity circuit breaker", "perplexity idempotent", "perplexity resilience", "perplexity fallback", "perplexity bulkhead". |
| allowed-tools | Read, Write, Edit |
| version | 1.0.0 |
| license | MIT |
| author | Jeremy Longshore <jeremy@intentsolutions.io> |
Perplexity Reliability Patterns
Overview
Production-grade reliability patterns for Perplexity integrations.
Prerequisites
- Understanding of circuit breaker pattern
- opossum or similar library installed
- Queue infrastructure for DLQ
- Caching layer for fallbacks
Circuit Breaker
import CircuitBreaker from 'opossum'; const perplexityBreaker = new CircuitBreaker( async (operation: () => Promise<any>) => operation(), { timeout: 30000, errorThresholdPercentage: 50, resetTimeout: 30000, volumeThreshold: 10, } ); // Events perplexityBreaker.on('open', () => { console.warn('Perplexity circuit OPEN - requests failing fast'); alertOps('Perplexity circuit breaker opened'); }); perplexityBreaker.on('halfOpen', () => { console.info('Perplexity circuit HALF-OPEN - testing recovery'); }); perplexityBreaker.on('close', () => { console.info('Perplexity circuit CLOSED - normal operation'); }); // Usage async function safePerplexityCall<T>(fn: () => Promise<T>): Promise<T> { return perplexityBreaker.fire(fn); }
Idempotency Keys
import { v4 as uuidv4 } from 'uuid'; import crypto from 'crypto'; // Generate deterministic idempotency key from input function generateIdempotencyKey( operation: string, params: Record<string, any> ): string { const data = JSON.stringify({ operation, params }); return crypto.createHash('sha256').update(data).digest('hex'); } // Or use random key with storage class IdempotencyManager { private store: Map<string, { key: string; expiresAt: Date }> = new Map(); getOrCreate(operationId: string): string { const existing = this.store.get(operationId); if (existing && existing.expiresAt > new Date()) { return existing.key; } const key = uuidv4(); this.store.set(operationId, { key, expiresAt: new Date(Date.now() + 24 * 60 * 60 * 1000), }); return key; } }
Bulkhead Pattern
import PQueue from 'p-queue'; // Separate queues for different operations const perplexityQueues = { critical: new PQueue({ concurrency: 10 }), normal: new PQueue({ concurrency: 5 }), bulk: new PQueue({ concurrency: 2 }), }; async function prioritizedPerplexityCall<T>( priority: 'critical' | 'normal' | 'bulk', fn: () => Promise<T> ): Promise<T> { return perplexityQueues[priority].add(fn); } // Usage await prioritizedPerplexityCall('critical', () => perplexityClient.processPayment(order) ); await prioritizedPerplexityCall('bulk', () => perplexityClient.syncCatalog(products) );
Timeout Hierarchy
const TIMEOUT_CONFIG = { connect: 5000, // Initial connection request: 30000, // Standard requests upload: 120000, // File uploads longPoll: 300000, // Webhook long-polling }; async function timedoutPerplexityCall<T>( operation: 'connect' | 'request' | 'upload' | 'longPoll', fn: () => Promise<T> ): Promise<T> { const timeout = TIMEOUT_CONFIG[operation]; return Promise.race([ fn(), new Promise<never>((_, reject) => setTimeout(() => reject(new Error(`Perplexity ${operation} timeout`)), timeout) ), ]); }
Graceful Degradation
interface PerplexityFallback { enabled: boolean; data: any; staleness: 'fresh' | 'stale' | 'very_stale'; } async function withPerplexityFallback<T>( fn: () => Promise<T>, fallbackFn: () => Promise<T> ): Promise<{ data: T; fallback: boolean }> { try { const data = await fn(); // Update cache for future fallback await updateFallbackCache(data); return { data, fallback: false }; } catch (error) { console.warn('Perplexity failed, using fallback:', error.message); const data = await fallbackFn(); return { data, fallback: true }; } }
Dead Letter Queue
interface DeadLetterEntry { id: string; operation: string; payload: any; error: string; attempts: number; lastAttempt: Date; } class PerplexityDeadLetterQueue { private queue: DeadLetterEntry[] = []; add(entry: Omit<DeadLetterEntry, 'id' | 'lastAttempt'>): void { this.queue.push({ ...entry, id: uuidv4(), lastAttempt: new Date(), }); } async processOne(): Promise<boolean> { const entry = this.queue.shift(); if (!entry) return false; try { await perplexityClient[entry.operation](entry.payload); console.log(`DLQ: Successfully reprocessed ${entry.id}`); return true; } catch (error) { entry.attempts++; entry.lastAttempt = new Date(); if (entry.attempts < 5) { this.queue.push(entry); } else { console.error(`DLQ: Giving up on ${entry.id} after 5 attempts`); await alertOnPermanentFailure(entry); } return false; } } }
Health Check with Degraded State
type HealthStatus = 'healthy' | 'degraded' | 'unhealthy'; async function perplexityHealthCheck(): Promise<{ status: HealthStatus; details: Record<string, any>; }> { const checks = { api: await checkApiConnectivity(), circuitBreaker: perplexityBreaker.stats(), dlqSize: deadLetterQueue.size(), }; const status: HealthStatus = !checks.api.connected ? 'unhealthy' : checks.circuitBreaker.state === 'open' ? 'degraded' : checks.dlqSize > 100 ? 'degraded' : 'healthy'; return { status, details: checks }; }
Instructions
Step 1: Implement Circuit Breaker
Wrap Perplexity calls with circuit breaker.
Step 2: Add Idempotency Keys
Generate deterministic keys for operations.
Step 3: Configure Bulkheads
Separate queues for different priorities.
Step 4: Set Up Dead Letter Queue
Handle permanent failures gracefully.
Output
- Circuit breaker protecting Perplexity calls
- Idempotency preventing duplicates
- Bulkhead isolation implemented
- DLQ for failed operations
Error Handling
| Issue | Cause | Solution |
|---|---|---|
| Circuit stays open | Threshold too low | Adjust error percentage |
| Duplicate operations | Missing idempotency | Add idempotency key |
| Queue full | Rate too high | Increase concurrency |
| DLQ growing | Persistent failures | Investigate root cause |
Examples
Quick Circuit Check
const state = perplexityBreaker.stats().state; console.log('Perplexity circuit:', state);
Resources
Next Steps
For policy enforcement, see perplexity-policy-guardrails.
Similar Claude Skills & Agent Workflows
git-commit
Generate well-formatted git commit messages following conventional commit standards
code-review
Comprehensive code review assistant that analyzes code quality, security, and best practices
dsql
Build with Aurora DSQL - manage schemas, execute queries, and handle migrations with DSQL-specific requirements.
backend-dev-guidelines
Comprehensive backend development guide for Langfuse's Next.js 14/tRPC/Express/TypeScript monorepo.
Material Component Dev
FlowGram 物料组件开发指南 - 用于在 form-materials 包中创建新的物料组件
Create Node
用于在 FlowGram demo-free-layout 中创建新的自定义节点,支持简单节点(自动表单)和复杂节点(自定义 UI)