Implement Retell AI reference architecture with best-practice project layout. Use when designing new Retell AI integrations, reviewing project structure, or establishing architecture standards for Retell AI applications. Trigger with phrases like "retellai architecture", "retellai best practices", "retellai project structure", "how to organize retellai", "retellai layout".
From retellai-packnpx claudepluginhub nickloveinvesting/nick-love-plugins --plugin retellai-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.
Details PluginEval's skill quality evaluation: 3 layers (static, LLM judge), 10 dimensions, rubrics, formulas, anti-patterns, badges. Use to interpret scores, improve triggering, calibrate thresholds.
Production architecture for AI voice agents with Retell AI. Covers agent design, LLM configuration, telephony integration, custom tool functions, and call analytics for conversational AI applications.
retell-sdk npm packageset -euo pipefail
┌──────────────────────────────────────────────────────┐
│ Phone/Web Interface │
│ Twilio Number │ Web Call │ SIP Trunk │
└──────────┬───────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────┐
│ Retell AI Platform │
│ ┌──────────────┐ ┌──────────────┐ ┌───────────┐ │
│ │ Voice Agent │ │ LLM Engine │ │ Voice │ │
│ │ (config) │ │ (prompts) │ │ (TTS/STT) │ │
│ └──────┬───────┘ └──────┬───────┘ └───────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌──────────────────────────────────────────────┐ │
│ │ Custom Tool Functions │ │
│ │ Book Appt │ Check Status │ Transfer Call │ │
│ └──────────────────────┬───────────────────────┘ │
└─────────────────────────┼───────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────┐
│ Your Backend │
│ Webhook Handler │ Tool Endpoints │ Call Analytics │
└──────────────────────────────────────────────────────┘
import Retell from 'retell-sdk';
const retell = new Retell({ apiKey: process.env.RETELL_API_KEY! });
// Create LLM with personality and tools
async function createAgentLLM() {
const llm = await retell.llm.create({
model: 'gpt-4o-mini',
general_prompt: `You are Sarah, a friendly appointment scheduling assistant.
Instructions:
- Greet callers warmly and ask how you can help
- Collect: name, preferred date/time, reason for appointment
- Confirm all details before booking
- Keep responses under 2 sentences
- Be conversational, not robotic`,
begin_message: "Hi there! This is Sarah. How can I help you today?",
general_tools: [
{
type: 'end_call',
name: 'end_call',
description: 'End call when conversation is complete',
},
{
type: 'custom',
name: 'book_appointment',
description: 'Book an appointment after collecting all details',
url: `${process.env.BASE_URL}/api/retell/book`,
parameters: {
type: 'object',
properties: {
name: { type: 'string', description: 'Caller name' },
date: { type: 'string', description: 'Preferred date' },
time: { type: 'string', description: 'Preferred time' },
reason: { type: 'string', description: 'Appointment reason' },
},
required: ['name', 'date', 'time'],
},
},
],
});
return llm;
}
async function createVoiceAgent(llmId: string) {
return retell.agent.create({
agent_name: 'Appointment Scheduler',
response_engine: { type: 'retell-llm', llm_id: llmId },
voice_id: 'eleven_labs_rachel',
language: 'en-US',
responsiveness: 0.8,
interruption_sensitivity: 0.7,
enable_backchannel: true,
voice_speed: 1.0,
voice_temperature: 0.5,
});
}
import express from 'express';
const app = express();
// Tool function: book appointment
app.post('/api/retell/book', express.json(), async (req, res) => {
const { name, date, time, reason } = req.body.args;
const booking = await bookAppointment({ name, date, time, reason });
res.json({
result: `Appointment booked for ${name} on ${date} at ${time}. Confirmation number: ${booking.id}`,
});
});
// Webhook: call events
app.post('/api/retell/webhook', express.json(), async (req, res) => {
const { event, call } = req.body;
if (event === 'call_ended') {
await saveCallRecord({
callId: call.call_id,
duration: call.end_timestamp - call.start_timestamp,
transcript: call.transcript,
sentiment: call.call_analysis?.sentiment,
});
}
res.json({ received: true });
});
async function makeOutboundCall(
toNumber: string,
agentId: string,
metadata?: Record<string, string>
) {
return retell.call.createPhoneCall({
from_number: process.env.RETELL_PHONE_NUMBER!,
to_number: toNumber,
override_agent_id: agentId,
metadata,
});
}
| Issue | Cause | Solution |
|---|---|---|
| Agent not responding | LLM prompt too complex | Simplify prompt, use shorter responses |
| Tool call fails | Webhook URL unreachable | Verify endpoint is publicly accessible |
| Poor voice quality | High latency | Use gpt-4o-mini, increase responsiveness |
| Call drops | WebSocket timeout | Check network stability, add reconnection |
// Create a web call for testing (no phone needed)
const webCall = await retell.call.createWebCall({
agent_id: agentId,
metadata: { test: 'true' },
});
console.log(`Test call URL: ${webCall.call_id}`);