GUIDE · LE CLUB IA VIP
Construire un agent vocal utile
Exemple fil rouge : un agent qui répond au téléphone d'un restaurant. Modèle utilisé : grok-voice-think-fast-1.0.
1. Comment ça marche, en 30 secondes
- Le navigateur (ou Twilio) ouvre un WebSocket vers
wss://api.x.ai/v1/realtime. - Le client envoie de l'audio mic (PCM16 base64) en streaming.
- Le serveur xAI répond en streaming : audio synthétisé + transcription + appels d'outils.
- La VAD côté serveur (
turn_detection: server_vad) détecte automatiquement quand l'utilisateur a fini de parler — pas besoin de bouton "send". - Le modèle
grok-voice-think-fast-1.0fait tout : ASR, raisonnement, TTS, et orchestration d'outils — un seul WebSocket, latence sub-seconde.
2. Les 4 fichiers à connaître
| Fichier | Rôle | Edit |
|---|---|---|
web/config/system_prompt.txt | Personnalité, mission, règles. | Souvent |
web/config/tools.json | Outils que l'agent peut appeler. | Oui |
web/static/voice.js | Implémentations des function tools côté navigateur. | Si tu ajoutes un tool |
web/server.py | Mint du token éphémère, sert /config, endpoints API. | Rarement |
/config relit le disque à chaque session. Recharge juste la page et clique Start.
3. Écrire un bon system prompt
Le prompt système conditionne tout. Pour un agent qui marche bien :
- Identité — un prénom et un rôle. "Tu es Margot, hôte du Petit Bistro."
- Mission claire — 2 à 4 tâches qu'il sait faire.
- Style — concis, max 1–2 phrases par tour. La voix coupe l'utilisateur si elle parle trop.
- Garde-fous — "Si ce n'est pas dans ta liste, propose qu'un humain rappelle."
- Confirmation — "Confirme TOUJOURS les détails à voix haute avant d'appeler le tool."
- Langue — précise-la explicitement si tu veux la verrouiller (par défaut le modèle s'aligne sur l'utilisateur).
4. Les outils — le cœur d'un vrai agent
Un agent qui ne peut que parler n'est pas un agent — c'est un chatbot. Quatre familles d'outils :
4.1 function — tools maison
Tu déclares un nom + un schéma JSON. Quand le modèle appelle la fonction, il émet response.function_call_arguments.done. Ton code l'exécute et renvoie le résultat.
// tools.json
{
"type": "function",
"name": "book_reservation",
"description": "Book a table. Call after oral confirmation.",
"parameters": {
"type": "object",
"properties": {
"name": { "type": "string" },
"phone": { "type": "string" },
"date": { "type": "string", "description": "YYYY-MM-DD" },
"time": { "type": "string", "description": "HH:MM" },
"party_size":{ "type": "integer" }
},
"required": ["name","phone","date","time","party_size"]
}
}
4.2 web_search — recherche web (zéro code)
xAI exécute la recherche, pas toi.
{ "type": "web_search" }
4.3 x_search — recherche sur X / Twitter
{ "type": "x_search", "allowed_x_handles": ["votre_resto"] }
4.4 file_search — RAG sur tes documents
Upload ton menu via la Collections API, récupère un collection_id, puis :
{
"type": "file_search",
"vector_store_ids": ["ton-collection-id"],
"max_num_results": 8
}
4.5 mcp — serveurs externes
Si tu as un serveur MCP (Stripe, Notion, ton CRM) :
{
"type": "mcp",
"server_url": "https://mcp.example.com/mcp",
"server_label": "crm",
"authorization": "Bearer ton-token"
}
4.6 Google Calendar — fait dans ce projet
Pas de MCP Google Calendar officiel. Pour un test perso, l'API directe est plus simple. On utilise un function tool qui POST vers /api/calendar/book ; le serveur FastAPI utilise l'API Google Calendar via OAuth Desktop, refresh-token sur disque.
Setup en 5 étapes :
- console.cloud.google.com → projet → active Google Calendar API.
- APIs & Services → Credentials → Create Credentials → OAuth client ID → Desktop app.
- Sauve le JSON sous
web/config/google_oauth_client.json. - Lance
python setup_google.py— un navigateur s'ouvre, tu autorises, le token est sauvé. - Recharge l'app, clique Start, dis : "I'd like to book a table for 4 tomorrow at 7 PM, name Eric, phone…"
google_token.json et google_oauth_client.json sont dans .gitignore. Pour la prod multi-utilisateurs, utilise un service account (Workspace) ou OAuth complet par utilisateur.
5. Recette : agent restaurant complet
- Identité & mission dans
system_prompt.txt. - Réservations —
book_reservation→ Google Calendar / Resy / DB. - Annulation / modif —
cancel_reservation,find_reservation_by_phone. - Menu & allergènes — menu PDF via Collections API →
file_search. - Horaires — outil simple
get_hours(date?). - Spéciaux du jour —
web_searchsur ton site/Insta. - Escalade humaine —
request_callback(phone, reason)qui SMS un manager (Twilio). - Bonus —
send_confirmation_sms,collect_feedback.
6. Connecter à un vrai téléphone (Twilio)
- Achète un numéro Twilio.
- Bridge serveur Python : Twilio Media Streams (WS µ-law 8 kHz) ↔ xAI realtime (configuré
audio/pcmu8 kHz, zéro transcoding). - Réutilise le même
system_prompt.txtettools.json. - Ref : xai-cookbook telephony.
7. 24/7 dans le cloud
- App web → Vercel (le WS vit dans le navigateur, le serveur ne fait que minter le token).
- Bridge Twilio → Fly.io / Render / Railway (process Python persistant).
- Variables d'env :
XAI_API_KEY, secrets Twilio, Google credentials. Healthcheck + auto-restart.
8. Astuces
- Latence : démarre la capture mic en parallèle du WS, bufferise, flush au
open— déjà fait. - Pas de chevauchement audio après tool call : attends la fin de la lecture avant
response.create. - Voix :
eve,ara,rex,sal,leo, ou voix custom. - µ-law 8 kHz : seulement pour Twilio. Browser → 24 kHz PCM.
- Sécurité : jamais la
XAI_API_KEYdans le navigateur. Toujours via/token(secret éphémère 5 min).
9. Debug
- Console DevTools → Network → WS → onglet Messages : tu vois chaque event en clair.
- Console
uvicorn:POST /token,GET /config,POST /api/calendar/book. - Si l'agent ne dit rien : vérifie
input_audio_buffer.speech_stopped+response.created. - Audio crachote ? Sample rate non assorti.
SAMPLE_RATE = 24000partout.