For the complete documentation index, see llms.txt. Markdown versions of documentation pages are available by appending .md to the page URL.
Navigation principale
Theme
Mar 25, 2026 Audio

Comment Perplexity a rendu la recherche vocale accessible à des millions de personnes grâce à la Realtime API

Ce que nous avons appris en développant l’agent vocal de Perplexity Computer avec la Realtime API.

Auteurs: Paul Fryzel (Perplexity), Charu Jaiswal (OpenAI)

Comment Perplexity a rendu la recherche vocale accessible à des millions de personnes grâce à la Realtime API

Chez Perplexity, nous tenons à créer des produits qu’on prend plaisir à utiliser. Pour Perplexity Comet, notre navigateur agentique, et Perplexity Computer, notre puissant agent numérique polyvalent, il était donc essentiel de pouvoir tout faire à la voix. Il y a quelque chose de particulièrement satisfaisant à pouvoir simplement dire ce qu’on veut, confier la tâche à l’agent et le regarder s’en charger. Nous croyons beaucoup aux interfaces vocales parce qu’elles donnent à l’interaction un côté presque magique.

Nous avons utilisé Realtime-1.5 en production pour apporter un peu de cette magie aux millions de sessions vocales que Perplexity gère chaque mois. Voir l’usage de la voix se développer dans l’interface de Computer a été aussi passionnant qu’instructif. Voici quelques enseignements qui nous ont surpris en chemin. Nous vous invitons à essayer Realtime-1.5 et à partager vos découvertes avec nous.

1. Définissez votre stratégie de gestion du contexte

Les contenus longs, en particulier les podcasts de plusieurs heures au contenu dense, ont été l’un des tests les plus révélateurs de notre gestion du contexte. Nous voulions permettre aux utilisateurs d’interroger une transcription à la voix. Ils devaient pouvoir demander d’emblée ce qui se disait à un instant précis, deux heures et demie après le début du podcast, et obtenir une réponse cohérente.

La transcription entière ne tient pas dans la fenêtre de contexte. Nous avons d’abord essayé de l’envoyer par gros blocs. Nous avons vite découvert qu’avec des mises à jour de cette taille, c’est tout ou rien. Si vous essayez d’envoyer une mise à jour de 10 000 tokens dans une fenêtre où il ne reste de la place que pour 5 000, le modèle perd tout l’historique. Les gros blocs étaient donc particulièrement risqués. Une seule mise à jour trop volumineuse pouvait effacer tout un pan du contexte, alors qu’il aurait été préférable que le système oublie les informations progressivement.

Nous avons donc changé de méthode. Nous avons découpé le contenu en blocs beaucoup plus petits, de 2 000 tokens chacun, pour les transmettre au fur et à mesure. Cela demande davantage de traitement, mais le comportement est beaucoup plus stable. Lorsqu’une troncature se produit, seule une petite partie de l’historique disparaît.

Nous avons aussi découvert une subtilité : la façon de transmettre le contexte au modèle doit dépendre de sa nature. Quand on utilise conversation.item.create pour mettre à jour le contexte, un élément de type item.type: "message" peut avoir l’un des trois rôles suivants : system, user et assistant. Ces rôles indiquent au modèle quel genre de message il reçoit. Le rôle system sert à donner des instructions et à orienter le comportement du modèle, user correspond à ce que fournit l’utilisateur final et assistant à ce que génère le modèle.

Quand nous attribuions mal ces rôles, l’échange perdait en naturel. Si nous transmettions trop de contexte avec le rôle user, le modèle se comportait comme si l’utilisateur avait lu à voix haute chaque bloc de texte, y compris les extraits de pages web et les commentaires, alors qu’il posait simplement une question à leur sujet. Avec trop de contexte transmis sous le rôle system, c’était l’inverse. Le modèle ne distinguait plus ce qu’il « savait » déjà, les informations qu’il avait reçues comme contexte et la question que l’utilisateur lui posait à cet instant.

La navigation en est un bon exemple. Quand quelqu’un fait défiler une page, nous transmettons en continu au modèle ce qui s’affiche à l’écran. Si tout ce contenu lui est présenté comme venant de l’utilisateur, le modèle réagit comme si celui-ci avait prononcé chaque paragraphe. Cela ne correspond pas à la manière dont on s’attend à interagir avec lui. Nous voulons donner l’impression que le système suit discrètement le contenu de la page et répond naturellement quand l’utilisateur pose une question. En fin de compte, le volume de contexte comptait moins que le sens donné à chaque message dans la conversation.

2. Standardisez l’audio dans les différentes interfaces

Perplexity propose plusieurs interfaces, dont Ask, Comet et Computer. Chacune repose sur une pile technique différente côté client. Les tampons audio natifs produits en Swift, TypeScript, Rust ou C++ peuvent tous différer. Lorsque nous laissions chaque client envoyer à la Realtime API l’audio brut ou dans son format natif, les performances variaient d’un client à l’autre.

Nous avons fini par développer un SDK en Rust pour masquer ces différences entre plateformes et garantir que tous les clients envoient à l’API un signal audio conforme aux mêmes spécifications. Concrètement, nous traitons le signal avant même qu’il n’arrive au serveur. Nous le rééchantillonnons en mono à 48 kHz, la fréquence privilégiée par le codec Opus et utilisée en interne par WebRTC. Nous le faisons ensuite passer par le module APM de WebRTC pour annuler l’écho, régler automatiquement le gain, réduire le bruit et appliquer un filtre passe-haut, puis nous l’encodons pour le transport. Le SDK nous a permis de centraliser les constantes audio, le rééchantillonnage et la configuration de toute la chaîne de traitement, au lieu de nous en charger séparément pour chaque client.

3. Adaptez les réglages aux conditions réelles

Il est important de régler la détection d’activité vocale (VAD) dans l’environnement où les gens utilisent le produit. Il faut donc la calibrer en tenant compte de leurs microphones, du volume des haut-parleurs et du bruit ambiant. Pour l’un de nos tests internes, nous avons choisi un bar bruyant de San Francisco, car il était facile d’y imaginer une scène bien réelle. Quelqu’un demande à un ami : « Tu as essayé la nouvelle appli Perplexity ? » L’ami sort son téléphone. Si la voix ne fonctionne pas, nous venons de perdre deux utilisateurs. Si elle fonctionne, la réaction ressemble plutôt à « Pu**in ! » Ce scénario nous a obligés à revoir nos critères. Ce qui fonctionne dans des conditions idéales échoue souvent sur le terrain. Mieux vaut commencer par régler le système dans des conditions difficiles.

L’une des principales difficultés dans la conception de l’interface vocale a été de bien gérer les pauses. Il est naturel de s’arrêter pour réfléchir, afficher quelque chose à l’écran ou se préparer à lire un passage à voix haute. Le modèle peut facilement interpréter ce silence comme une fin de tour de parole et intervenir trop tôt. Nous l’avons constaté, par exemple, quand quelqu’un demandait de l’aide pour une démonstration mathématique. La personne s’arrêtait pour retrouver la formule et le modèle intervenait avant qu’elle ait fini de poser sa question. C’est ce qui nous a amenés à permettre à l’utilisateur de verrouiller son tour de parole. Dans un système classique, le micro est coupé par défaut et il faut appuyer pour parler. Nous avons inversé le principe. Par défaut, le système reste à l’écoute, mais si l’utilisateur veut garder la parole un moment, il peut verrouiller son tour et décider lui-même quand le terminer. Nous pensons que cette idée dépasse le cadre de cette fonctionnalité. À mesure que les interfaces vocales s’intégreront à des workflows plus complexes, nous pensons que ce mode d’interaction deviendra courant sous une forme ou une autre.

4. Limitez-vous aux outils essentiels et utilisez des formats familiers au modèle

Ne retenez que les outils qui comptent le plus. Dans notre cas, il y en avait moins de dix. Nous en avons retenu un petit nombre qui couvrait les actions les plus utiles. Ce compromis nous convenait et devrait devenir encore plus intéressant à mesure que de meilleures versions des modèles seront disponibles.

Dans notre prompt système, nous avons précisé quand et comment appeler chaque outil. Nous avons veillé à ce que les schémas des outils et les résultats qu’ils renvoient correspondent aux formats auxquels le modèle est habitué. Concrètement, nous avons présenté les résultats comme des données structurées classiques, sans leur donner la forme d’une réplique de l’assistant. Nous renvoyions du JSON structuré avec des champs bien distincts, par exemple response_text pour le texte à prononcer et des indicateurs comme require_repeat_verbatim pour préciser le comportement attendu. Cela évitait de mêler des instructions au texte à lire. L’utilisation des outils est ainsi devenue plus stable et les échanges ressemblaient davantage à ceux que le modèle avait probablement rencontrés pendant son entraînement.

// Good:
{
  "response_text": "I kicked-off the task to create a market research dashboard",
  "require_repeat_verbatim": true
}
// Avoid:

I kicked-off the task to create a market research dashboard

# Response Instructions

Read the above instructions EXACTLY as they are

Realtime est prêt

Realtime-1.5 marque un tournant pour le secteur. Des progrès restent à faire pour gérer des contextes longs, utiliser davantage d’outils et accomplir des tâches qui exigent un raisonnement poussé. Mais nous nous attendons à ce que les modèles s’améliorent. Chez Perplexity, nous tenons compte de cette évolution dès la conception de nos produits. Nous voulons que les systèmes actuels soient utilisables dès aujourd’hui, tout en nous préparant à la prochaine génération de modèles Realtime et aux nouvelles interactions vocales qu’ils rendront possibles.