Identify and avoid Perplexity anti-patterns and common integration mistakes. Use when reviewing Perplexity code for issues, onboarding new developers, or auditing existing Perplexity integrations for best practices violations. Trigger with phrases like "perplexity mistakes", "perplexity anti-patterns", "perplexity pitfalls", "perplexity what not to do", "perplexity code review".
From perplexity-packnpx claudepluginhub nickloveinvesting/nick-love-plugins --plugin perplexity-packThis skill is limited to using the following tools:
Guides Next.js Cache Components and Partial Prerendering (PPR) with cacheComponents enabled. Implements 'use cache', cacheLife(), cacheTag(), revalidateTag(), static/dynamic optimization, and cache debugging.
Migrates code, prompts, and API calls from Claude Sonnet 4.0/4.5 or Opus 4.1 to Opus 4.5, updating model strings on Anthropic, AWS, GCP, Azure platforms.
Facilitates interactive brainstorming sessions using diverse creative techniques and ideation methods. Activates when users say 'help me brainstorm' or 'help me ideate'.
Real gotchas when integrating Perplexity's AI search API (Sonar). Perplexity uses an OpenAI-compatible chat endpoint but returns grounded, cited answers from web sources -- a fundamentally different paradigm from standard LLM completions.
Perplexity Sonar searches the web per request. System prompts that assume a static knowledge model produce poor results.
import requests
# BAD: using it as a generic chatbot
response = requests.post("https://api.perplexity.ai/chat/completions", json={
"model": "sonar",
"messages": [{"role": "user", "content": "Tell me a joke"}]
}, headers={"Authorization": f"Bearer {api_key}"})
# Works but wastes a search query on non-search tasks
# GOOD: leverage its search capability
response = requests.post("https://api.perplexity.ai/chat/completions", json={
"model": "sonar",
"messages": [{"role": "user", "content": "What are the latest Next.js 15 features released this month?"}],
"search_recency_filter": "week"
}, headers={"Authorization": f"Bearer {api_key}"})
Perplexity returns inline citation markers [1], [2] with a separate citations array. Ignoring them loses the key value prop.
data = response.json()
answer = data["choices"][0]["message"]["content"]
citations = data.get("citations", [])
# BAD: displaying raw answer with [1] [2] markers
print(answer) # "According to [1], Next.js 15 adds..."
# GOOD: replace markers with actual URLs
import re
for i, url in enumerate(citations, 1):
answer = answer.replace(f"[{i}]", f"[{i}]({url})")
print(answer)
Using sonar-pro for simple factual queries wastes budget. Using sonar for complex research gives shallow answers.
# BAD: sonar-pro for a simple lookup
response = call_perplexity("What is the capital of France?", model="sonar-pro")
# Costs 5x more for a trivial question
# GOOD: match model to task complexity
def smart_search(query: str, complexity: str = "simple"):
model = "sonar-pro" if complexity == "deep" else "sonar"
return call_perplexity(query, model=model)
Not setting search_recency_filter returns results from any time period, which may include outdated information for fast-moving topics.
# BAD: no recency filter for current events
response = call_perplexity("current Bitcoin price") # may cite old articles
# GOOD: set recency for time-sensitive queries
response = call_perplexity(
"current Bitcoin price",
search_recency_filter="day" # options: day, week, month, year
)
Perplexity performs a web search per turn. Sending full conversation history triggers redundant searches.
# BAD: sending 20 turns of history
messages = long_conversation_history + [{"role": "user", "content": "summarize"}]
# Each message may trigger new searches
# GOOD: summarize history, send focused query
messages = [
{"role": "system", "content": "Answer based on web search results."},
{"role": "user", "content": f"Given context: {summary}\nQuestion: {question}"}
]
| Issue | Cause | Solution |
|---|---|---|
| Stale information | No recency filter | Set search_recency_filter |
| High costs | Using sonar-pro everywhere | Route simple queries to sonar |
| Missing citations | Not parsing response | Extract citations array from JSON |
| Slow responses | Large conversation context | Trim history before sending |
| Empty search results | Overly niche query | Broaden the question scope |
response = requests.post(url, json={
"model": "sonar",
"messages": messages,
"stream": True
}, headers=headers, stream=True)
for line in response.iter_lines():
if line.startswith(b"data: "):
chunk = json.loads(line[6:])
# Citations arrive in the final chunk
if chunk.get("citations"):
handle_citations(chunk["citations"])