Maison >Périphériques technologiques >IA >API OpenAI en temps réel: un guide avec des exemples
L'API Openai en temps réel nouvellement introduit nous permet d'intégrer des expériences multimodales rapides, à faible latence dans nos applications. Avec cette API, nous pouvons créer des interactions de parole / discours transparentes entre les utilisateurs et les grands modèles de langage (LLMS).
Cette API élimine le besoin de plusieurs modèles pour réaliser des expériences vocales car elle offre la solution complète dans une API intégrée. Non seulement il vise à réduire la latence, mais il conserve également les nuances émotionnelles et le flux naturel des conversations.
Dans cet article, nous apprendrons à utiliser l'API OpenAI en temps réel pour construire des assistants d'IA contrôlés par la voix. Nous allons créer des connexions WebSocket persistantes à l'aide de Node.js et comment cela peut être utilisé dans le terminal pour communiquer avec l'API. De plus, je vais vous guider sur le déploiement d'une application React qui utilise les capacités de cette API.
Contrairement aux autres composants de l'API OpenAI, l'API en temps réel utilise WebSockets. WebSockets est un protocole de communication qui établit un canal de communication bidirectionnel entre un client et un serveur. Contrairement au modèle de demande de demande conventionnel utilisé par HTTP, les WebSockets prennent en charge les interactions en cours et en temps réel. Cela rend les bassages Web particulièrement adaptés aux applications en temps réel, telles que le chat vocal.
Cet article couvrira le fonctionnement des WebSockets et inclura plusieurs exemples d'interaction avec l'API en temps réel.
Nous allons utiliser Node.js, nous devons donc nous assurer qu'il est installé sur notre ordinateur. Sinon, nous pouvons télécharger et installer Node.js à partir de son site officiel.
Pour suivre, nous vous recommandons de créer un dossier avec le fichier .env créé ci-dessus. À l'intérieur de ce dossier, exécutez la commande suivante pour initialiser le script:
npm init -y && touch index.js
Une fois cette commande terminée, ces fichiers doivent être à l'intérieur du dossier:
Commencez par installer deux packages:
Installez-les en exécutant la commande:
npm install ws dotenv
Pour lancer une connexion avec l'API en temps réel, nous créons un nouvel objet WebSocket passant l'URL de l'API et les en-têtes avec les informations requises pour s'y connecter:
// Import the web socket library const WebSocket = require("ws"); // Load the .env file into memory so the code has access to the key const dotenv = require("dotenv"); dotenv.config(); function main() { // Connect to the API const url = "wss://api.openai.com/v1/realtime?model=gpt-4o-realtime-preview-2024-10-01"; const ws = new WebSocket(url, { headers: { "Authorization": "Bearer " + process.env.OPENAI_API_KEY, "OpenAI-Beta": "realtime=v1", }, }); } main();
Le code ci-dessus crée la connexion de socket web à l'API mais ne fait encore rien avec.
WebSockets nous permet de configurer des actions à exécuter lorsque certains événements se produisent. Nous pouvons utiliser l'événement ouvert pour spécifier un code que nous souhaitons exécuter une fois la connexion établie.
La syntaxe générique pour ajouter un écouteur d'événements est la suivante:
npm init -y && touch index.js
Remplacement & lt; Event & gt; avec une chaîne contenant le nom de l'événement et & lt; function & gt; avec une fonction à exécuter lorsque l'événement se produit.
Voici comment nous pouvons afficher le texte une fois que la connexion est prête:
npm install ws dotenv
Pour exécuter ce code, nous utilisons la commande:
// Import the web socket library const WebSocket = require("ws"); // Load the .env file into memory so the code has access to the key const dotenv = require("dotenv"); dotenv.config(); function main() { // Connect to the API const url = "wss://api.openai.com/v1/realtime?model=gpt-4o-realtime-preview-2024-10-01"; const ws = new WebSocket(url, { headers: { "Authorization": "Bearer " + process.env.OPENAI_API_KEY, "OpenAI-Beta": "realtime=v1", }, }); } main();
Si la touche API est correctement définie, nous verrons le message «Connexion est ouvert» dans le terminal. Le script continuera en cours d'exécution car la connexion est toujours ouverte, nous devons donc l'arrêter manuellement.
Un autre événement auquel nous pouvons répondre lors de l'utilisation de WebSockets est l'événement de message. Ceci est déclenché chaque fois qu'un message est reçu du serveur. Ajoutons une fonction qui affiche chaque message reçu:
ws.on(<event>, <function>);
L'exécution du script devrait également afficher l'événement Session.Created que l'API envoie lorsque la session est initialisée.
ci-dessus, nous avons appris à ajouter des auditeurs d'événements aux événements ouverts et de message. WebSockets prend en charge deux événements supplémentaires que nous n'utiliserons pas dans nos exemples.
L'événement de clôture peut être utilisé pour ajouter un rappel lorsque la prise est fermée:
// Add inside the main() function of index.js after creating ws async function handleOpen() { console.log("Connection is opened"); } ws.on("open", handleOpen);
L'événement d'erreur est utilisé pour ajouter un rappel lorsqu'il y a une erreur:
node index.js
Travailler avec WebSockets nous oblige à programmer de manière motivée par des événements. Les messages sont envoyés dans le canal de communication et nous ne pouvons pas contrôler lorsque ces messages seront livrés ou reçus.
Le code qui initie la communication doit être ajouté dans HandleOpen (). O Sinon, une erreur se produirait parce que ce code peut être exécuté avant la création du canal de communication de socket web.
Il en va de même pour les messages de traitement du code. Toute la logique doit entrer dans la fonction HandleMessage ().
Dans les prochains exemples, nous utiliserons le code suivant comme point de départ. La plupart des modifications impliquent la mise à jour du mancheper () et du handlemesage ().
// Add inside the main() function of index.js async function handleMessage(messageStr) { const message = JSON.parse(messageStr); console.log(message); } ws.on("message", handleMessage);
La communication avec l'API en temps réel se produit en utilisant des événements. L'API de documentation en temps réel OpenAI répertorie les événements qu'il prend en charge. Nous utilisons l'événement Conversation.Item.Create pour initier une conversation. Les événements sont représentés comme des objets JSON dont les champs sont décrits dans la documentation.
Voici un exemple de conversation.
async function handleClose() { console.log(“Socket closed”); } ws.on(“close”, handleClose);Cet événement indique à l'API que nous voulons lancer une conversation textuelle. Ceci est spécifié dans le champ de contenu, en utilisant un type de "input_text" et en fournissant une invite de texte.
Nous utilisons la méthode ws.Send () pour envoyer un message. Le package de socket Web attend une chaîne comme argument, nous devons donc convertir notre événement JSON en une chaîne à l'aide de la fonction JSON.Stringify (). Les assembler, voici comment nous pouvons envoyer l'événement ci-dessus:
npm init -y && touch index.js
Cela lancera la conversation, mais cela ne déclenchera pas l'API pour nous envoyer une réponse automatiquement. Pour déclencher une réponse, nous envoyons un événement de réponse. Voici un exemple:
npm install ws dotenv
Cet événement utilise le paramètre de réponse des modalités pour demander une réponse textuelle. Les instructions sont la partie la plus importante, décrivant ce que nous voulons que le modèle fasse, dans ce cas, une invite générique demandant d'aider l'utilisateur.
Nous envoyons ces deux événements dans la fonction HandleOpen () afin qu'une conversation soit lancée dès que la connexion est établie. Voici la mise en œuvre complète de la fonction HandleOpen () de cet exemple:
// Import the web socket library const WebSocket = require("ws"); // Load the .env file into memory so the code has access to the key const dotenv = require("dotenv"); dotenv.config(); function main() { // Connect to the API const url = "wss://api.openai.com/v1/realtime?model=gpt-4o-realtime-preview-2024-10-01"; const ws = new WebSocket(url, { headers: { "Authorization": "Bearer " + process.env.OPENAI_API_KEY, "OpenAI-Beta": "realtime=v1", }, }); } main();
En ce qui concerne les messages entrants, il existe trois types d'événements qui méritent d'être notés pour cet exemple: la réponse.Text.delta, la réponse.text.done et la réponse.
Dans cet exemple, nous utilisons l'événement Response.text.delta pour imprimer des morceaux de la réponse à la console au fur et à mesure que nous la recevons. Une fois la réponse terminée, l'événement Response.Text.Done est déclenché et nous imprimons une nouvelle ligne pour montrer que la sortie est terminée. Enfin, nous fermons la prise Web lorsque nous recevons l'événement de réponse.
ws.on(<event>, <function>);Pour exécuter cet exemple, nous collons ces fonctions dans le code de modèle ci-dessus et l'exécutons avec la commande:
Cela générera une réponse dans le terminal à l'invite "Expliquez en une phrase ce qu'est une prise Web", similaire à ce que nous utilisons ChatGpt.
// Add inside the main() function of index.js after creating ws async function handleOpen() { console.log("Connection is opened"); } ws.on("open", handleOpen);
Le code complet de l'exemple de texte est disponible ici.
en utilisant l'API en temps réel pour envoyer et recevoir l'audio
L'exemple précédent a montré comment nous gérons les données de texte. Cependant, le véritable intérêt pour l'API en temps réel est de créer un assistant vocal qui répond en temps réel.Tout d'abord, nous installons deux packages:
npm init -y && touch index.js
Nous devons également installer SOX (Sound Exchange), une utilité en ligne de commande pour le traitement audio que la bibliothèque de nœuds utilisera pour interfacer avec le microphone et enregistrer l'audio. Utilisez Brew Installer SOX pour l'installer sur macOS ou Sudo Apt Installer Sox sur Linux.
Avec ces packages installés, nous les importons et ajoutons une fonction startreCording () qui enregistre les invites audio de l'utilisateur. Nous n’expliquons pas la fonction en détail car elle nous éviterait trop de cours de notre sujet principal.
Ajoutez le code suivant au fichier index.js après le chargement de l'environnement:
npm install ws dotenv
La fonction startreCorDing () enregistre l'audio du microphone et attend que «entrez» à appuyer.
Ensuite, nous mettons à jour la fonction principale () en initialisant le haut-parleur () qui est utilisé pour lire la réponse de l'IA:
// Import the web socket library const WebSocket = require("ws"); // Load the .env file into memory so the code has access to the key const dotenv = require("dotenv"); dotenv.config(); function main() { // Connect to the API const url = "wss://api.openai.com/v1/realtime?model=gpt-4o-realtime-preview-2024-10-01"; const ws = new WebSocket(url, { headers: { "Authorization": "Bearer " + process.env.OPENAI_API_KEY, "OpenAI-Beta": "realtime=v1", }, }); } main();
avec cela à l'écart, nous pouvons implémenter le mancheOpen () et HandleMessage () pour traiter l'audio.
Dans la fonction HandleOpen (), nous devons seulement appeler la fonction startreCording () pour enregistrer l'invite audio de l'utilisateur. Nous devons également mettre à jour légèrement les événements:
Voici la fonction HandleOpen () mise à jour:
ws.on(<event>, <function>);
Pour implémenter la fonction HandleMesage (), nous modifions l'événement "Response.audio.delta" pour mettre à jour le tampon audio et lire le nouveau son delta:
// Add inside the main() function of index.js after creating ws async function handleOpen() { console.log("Connection is opened"); } ws.on("open", handleOpen);
Nous supprimons l'événement "Response.Text.done" de l'instruction Switch et mettons à jour l'événement "Response.done" pour arrêter le haut-parleur:
node index.js
L'implémentation finale de la fonction HandleMesage () ressemble à ceci:
// Add inside the main() function of index.js async function handleMessage(messageStr) { const message = JSON.parse(messageStr); console.log(message); } ws.on("message", handleMessage);
Pour exécuter cet exemple, appliquez ces modifications au code de modèle et exécutez-la avec la commande:
async function handleClose() { console.log(“Socket closed”); } ws.on(“close”, handleClose);
Le microphone commencera à enregistrer. Nous pouvons dire notre demande et appuyer sur «Entrer» pour l'envoyer. Ensuite, la réponse de l'IA jouera sur les haut-parleurs (assurez-vous que le microphone n'est pas muet et que les haut-parleurs ont un volume).
Le code complet de l'exemple audio est disponible ici.
Une fonctionnalité sympa de l'API OpenAI est la possibilité d'effectuer des appels de fonction. Nous pouvons ajouter des fonctions à l'assistant et s'il détecte que l'une de ces fonctions peut être utile pour fournir la réponse, elle enverra un événement demandant une fonction spécifique à appeler.
La documentation OpenAI fournit le diagramme suivant expliquant le cycle de vie d'un appel de fonction:
Source: Openai
À partir du diagramme, nous voyons que le client doit fournir les définitions des fonctions que LLM peut appeler. De plus, l'exécution de la fonction se produira du côté client; L'IA enverra un événement demandant la fonction d'appeler et ses arguments. Ensuite, nous sommes responsables de renvoyer le résultat.
Autoriser notre assistant avec une fonction qui ajoute deux nombres ensemble. Nous allons créer cet exemple en étendant l'exemple audio ci-dessus.
Pour spécifier les fonctions disponibles, nous devons fournir au LLM une liste d'outils. Chaque outil est un objet JSON qui spécifie les informations sur la fonction. Voici comment nous pouvons définir un outil pour la fonction de somme:
npm init -y && touch index.js
Expliquons la structure des objets:
L'étape suivante consiste à définir la fonction de notre code. Nous utiliserons un dictionnaire avec la clé Calculate_sum pour faciliter l'appel de la fonction appropriée lorsque nous répondons à un événement d'appel de fonction:
npm install ws dotenv
L'API fournira les arguments de fonction comme un dictionnaire avec la même structure définie sur les paramètres ci-dessus. Dans ce cas, pour ajouter, disons 3 et 5, le dictionnaire serait {"a": 3, "b": 5}.
Les constantes Sumtool et fonctions peuvent être ajoutées au sommet de l'index.js, après les importations et avant la fonction principale ().
Ensuite, nous mettons à jour l'événement Response.Create pour informer le LLM que les Sumtools sont disponibles. Cela se fait en ajoutant les champs d'outils et d'outils_choice à la réponse:
// Import the web socket library const WebSocket = require("ws"); // Load the .env file into memory so the code has access to the key const dotenv = require("dotenv"); dotenv.config(); function main() { // Connect to the API const url = "wss://api.openai.com/v1/realtime?model=gpt-4o-realtime-preview-2024-10-01"; const ws = new WebSocket(url, { headers: { "Authorization": "Bearer " + process.env.OPENAI_API_KEY, "OpenAI-Beta": "realtime=v1", }, }); } main();
Lorsque le LLM décide qu'il souhaite appeler une fonction, il émettra une réponse. Nous devons y répondre par:
Nous gérons cela en ajoutant le cas suivant à l'instruction Switch à l'intérieur de la fonction hanldeMessage ():
ws.on(<event>, <function>);
Si nous exécutons maintenant le script et demandons le résultat de l'ajout de deux nombres, le modèle doit appeler la fonction et fournir le résultat.
Cette fonction est relativement simple, mais parce que la fonction est exécutée par le client, elle pourrait être n'importe quoi. Dans la section suivante, nous verrons deux exemples de fonctions plus complexes.
Le code complet de cet exemple est disponible ici.
Configuration de l'application
Leur application est hébergée dans ce référentiel. Pour le configurer, commencez par le clonage en utilisant la commande git suivante:
Alternativement, nous pouvons également le télécharger manuellement à partir de l'interface GitHub.
npm init -y && touch index.js
Pour installer l'application, nous utilisons la commande NPM (Node Package Manage) suivante:
Une fois l'installation terminée, créez un fichier nommé .env dans le dossier racine du projet et collez le contenu suivant:
npm install ws dotenv
remplacer & lt; openai_api_key & gt; avec la clé API Openai.
// Import the web socket library const WebSocket = require("ws"); // Load the .env file into memory so the code has access to the key const dotenv = require("dotenv"); dotenv.config(); function main() { // Connect to the API const url = "wss://api.openai.com/v1/realtime?model=gpt-4o-realtime-preview-2024-10-01"; const ws = new WebSocket(url, { headers: { "Authorization": "Bearer " + process.env.OPENAI_API_KEY, "OpenAI-Beta": "realtime=v1", }, }); } main();
La demande doit désormais être prête à être exécutée. Il est composé de deux parties:
un frontend React qui se compose de l'interface utilisateur Web de l'application.
L'objectif principal d'implémenter un serveur de relais entre le frontend et l'API OpenAI est de stocker en toute sécurité la clé API. Interagir avec l'API est impossible sans cette clé.
Cependant, si la clé était stockée sur le frontend, elle serait accessible à tout utilisateur. Par conséquent, la solution consiste à configurer un serveur qui stocke en toute sécurité la clé et facilite l'échange de données entre l'API et le frontend. Dans ce scénario particulier, les problèmes de sécurité sont minimes car l'application ne sera exécutée que localement.
Pour lancer l'application, il est nécessaire d'initier à la fois le serveur de relais et le frontend. Pour démarrer le serveur de relais, utilisez la commande suivante:
Pour démarrer le frontage React, utilisez la commande:
ws.on(<event>, <function>);
Une fois le chargement terminé, un onglet s'ouvrira sur le navigateur avec l'application en cours d'exécution.
// Add inside the main() function of index.js after creating ws async function handleOpen() { console.log("Connection is opened"); } ws.on("open", handleOpen);
en utilisant l'application
Nous commençons par cliquer sur le bouton «Connecter». Cela enverra un message "Hello" à l'API en temps réel, et nous recevrons une salutation.
Une fois la connexion établie, un nouveau bouton apparaîtra au centre, ce qui nous permet de parler à l'assistant de l'IA.
pour l'utiliser, appuyez et parlez sans relâcher le bouton. Le message est envoyé lorsque le bouton est libéré.
L'application a également un mode VAD (détection d'activité vocale) dans laquelle nous n'avons besoin d'appuyer sur aucun bouton. Dans ce mode, l'application écoutera en continu nous permettant d'avoir une conversation active avec l'assistant. Pour l'utiliser, appuyez simplement sur le bouton «VAD» et parlez.
Comme nous l'avons appris, l'API en temps réel propose une fonctionnalité qui permet à l'IA d'effectuer des fonctions spécifiques. Cette démonstration présente deux fonctions: l'une pour s'enquérir des prévisions météorologiques dans un endroit particulier et un autre pour ajouter des éléments de mémoire pour personnaliser l'assistant.
Expérimentez ces fonctions en posant des questions telles que "Quel temps fait-il demain à New York?" Et énoncer des préférences comme «Ma couleur préférée est le bleu». L'assistant fournira des réponses verbales à ces requêtes, et les informations seront également affichées sur le côté droit de l'application.
Il y a eu des moments où j'ai demandé un rapport météo, et la réponse a indiqué une incapacité à y accéder à ce moment. Cependant, les informations étaient constamment affichées sur le côté droit. Étant une application de démonstration, il n'est pas destiné à être un produit entièrement fonctionnel mais sert plutôt à présenter les capacités de l'API.
Cette section nécessite une compréhension de haut niveau de la réaction à suivre, car nous couvrons certains des détails de mise en œuvre de l'application.
Nous examinerons le fichier consolepage.tsx. C'est là que la majeure partie de la logique d'application est définie. L'application de démonstration n'utilise pas les websockets bruts comme nous l'avons fait dans nos exemples d'applications de ligne de commande node.js. Ils ont construit un client en temps réel qui aide à interagir avec l'API. C'est ce qui est importé en haut du fichier:
npm init -y && touch index.js
L'intégration avec l'API est définie dans cet appel UseEFFECT (). Le code dans cette useeffct () est exécuté lorsque la page de console est initialement rendue. Semblable à notre script Node.js, il décrit comment répondre aux événements API. La principale distinction est son utilisation de l'emballage des clients réelSimeclient.
La fonction RealTimeClient.AddTool () est utilisée pour définir des outils. Il faut deux paramètres:
Cette approche simplifie l'intégration des outils car le client est déjà équipé pour gérer les événements et automatiser les invocations de la fonction. L'outil de mémoire est défini ici, tandis que la définition de l'outil météorologique est définie ici.
Par exemple, pour ajouter l'outil de somme défini précédemment, nous pouvons effectuer les éléments suivants:
npm init -y && touch index.js
Notez que l'application utilise TypeScript, nécessitant ainsi la spécification des types dans la définition de la fonction.
Pour écouter un événement, la fonction RealTimeClient.on () est utilisée. Il accepte deux paramètres:
Cette approche est similaire à la fonction WebSocket.on () précédemment utilisée, sauf qu'elle implémente un ensemble différent d'événements. Leur page GitHub fournit la liste des événements pris en charge.
Dans cet exemple particulier, les événements suivants sont utilisés:
Dans ce didacticiel, nous avons exploré l'API OpenAI en temps réel et comment il utilise des lignes Web pour une communication en temps réel. Nous avons couvert la configuration d'un environnement Node.js pour interagir avec l'API, envoyer et recevoir des messages de texte et audio, et implémenter une fonction appelant à une fonctionnalité améliorée.
Nous avons également exploré l'application Openai Demo React, démontrant comment déployer une application d'assistant vocal de base.
Pour en savoir plus sur les derniers outils de développement OpenAI, je recommande ces tutoriels:
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!