Dieses Repository enthält eine Referenzclient -AKA -Beispielbibliothek für eine Verbindung zur Echtzeit -API von OpenAI. Diese Bibliothek befindet sich in der Beta und sollte nicht als endgültige Implementierung behandelt werden. Sie können es verwenden, um Konversations -Apps problemlos zu prototypisieren.
Der einfachste Weg, um sofort mit der API zu spielen , besteht darin, die Echtzeitkonsole zu verwenden. Er verwendet den Referenzclient, um einen voll funktionsfähigen API-Inspektor mit Beispielen für die Sprachvisualisierung und vieles mehr zu liefern.
Diese Bibliothek ist so erstellt, dass sie sowohl serverseitig (node.js) als auch im Browser (React, VUE) in JavaScript- und Typscript-Codebasen verwendet werden. Um die Bibliothek zu installieren, müssen Sie in der Beta -Installation direkt über das GitHub -Repository npm install .
$ npm i openai/openai-realtime-api-beta --save import { RealtimeClient } from '@openai/realtime-api-beta' ;
const client = new RealtimeClient ( { apiKey : process . env . OPENAI_API_KEY } ) ;
// Can set parameters ahead of connecting, either separately or all at once
client . updateSession ( { instructions : 'You are a great, upbeat friend.' } ) ;
client . updateSession ( { voice : 'alloy' } ) ;
client . updateSession ( {
turn_detection : { type : 'none' } , // or 'server_vad'
input_audio_transcription : { model : 'whisper-1' } ,
} ) ;
// Set up event handling
client . on ( 'conversation.updated' , ( event ) => {
const { item , delta } = event ;
const items = client . conversation . getItems ( ) ;
/**
* item is the current item being updated
* delta can be null or populated
* you can fetch a full list of items at any time
*/
} ) ;
// Connect to Realtime API
await client . connect ( ) ;
// Send a item and triggers a generation
client . sendUserMessageContent ( [ { type : 'input_text' , text : `How are you?` } ] ) ; Sie können diesen Client direkt aus dem Browser in EG React- oder VUE -Apps verwenden. Wir empfehlen dies nicht, Ihre API -Schlüssel sind gefährdet, wenn Sie sich direkt vom Browser mit OpenAI verbinden. Um den Kunden in einer Browserumgebung zu instanziieren, verwenden Sie:
import { RealtimeClient } from '@openai/realtime-api-beta' ;
const client = new RealtimeClient ( {
apiKey : process . env . OPENAI_API_KEY ,
dangerouslyAllowAPIKeyInBrowser : true ,
} ) ;Wenn Sie Ihren eigenen Relay -Server ausführen, z. B. mit der Echtzeitkonsole, können Sie sich stattdessen wie SO eine Verbindung zur Relay -Server -URL herstellen:
const client = new RealtimeClient ( { url : RELAY_SERVER_URL } ) ; In dieser Bibliothek gibt es drei Primitive für die Verbindung mit der Echtzeit -API. Wir empfehlen, mit dem RealtimeClient zu beginnen, aber fortgeschrittenere Benutzer können sich wohler fühlen, wenn sie näher am Metall arbeiten.
RealtimeClientconversation.updated , conversation.item.appended , conversation.item.completed , conversation.interrupted und realtime.event EreignisseRealtimeAPIclient.realtimeserver.{event_name} bzw. client.{event_name}RealtimeConversationclient.conversationDer Kunde wird mit einigen grundlegenden Dienstprogrammen verpackt, die es einfach machen, Echtzeit -Apps schnell zu erstellen.
Das Senden von Nachrichten vom Benutzer an den Server ist einfach.
client . sendUserMessageContent ( [ { type : 'input_text' , text : `How are you?` } ] ) ;
// or (empty audio)
client . sendUserMessageContent ( [
{ type : 'input_audio' , audio : new Int16Array ( 0 ) } ,
] ) ; Um das Streaming -Audio zu senden, verwenden Sie die Methode .appendInputAudio() . Wenn Sie turn_detection: 'disabled' -Modus sind, müssen Sie .createResponse() verwenden, um das Modell zu antworten.
// Send user audio, must be Int16Array or ArrayBuffer
// Default audio format is pcm16 with sample rate of 24,000 Hz
// This populates 1s of noise in 0.1s chunks
for ( let i = 0 ; i < 10 ; i ++ ) {
const data = new Int16Array ( 2400 ) ;
for ( let n = 0 ; n < 2400 ; n ++ ) {
const value = Math . floor ( ( Math . random ( ) * 2 - 1 ) * 0x8000 ) ;
data [ n ] = value ;
}
client . appendInputAudio ( data ) ;
}
// Pending audio is committed and model is asked to generate
client . createResponse ( ) ; Die Arbeit mit Tools ist einfach. Rufen Sie einfach .addTool() an und setzen Sie einen Rückruf als zweiter Parameter. Der Rückruf wird mit den Parametern für das Tool ausgeführt und das Ergebnis wird automatisch an das Modell zurückgesendet.
// We can add tools as well, with callbacks specified
client . addTool (
{
name : 'get_weather' ,
description :
'Retrieves the weather for a given lat, lng coordinate pair. Specify a label for the location.' ,
parameters : {
type : 'object' ,
properties : {
lat : {
type : 'number' ,
description : 'Latitude' ,
} ,
lng : {
type : 'number' ,
description : 'Longitude' ,
} ,
location : {
type : 'string' ,
description : 'Name of the location' ,
} ,
} ,
required : [ 'lat' , 'lng' , 'location' ] ,
} ,
} ,
async ( { lat , lng , location } ) => {
const result = await fetch (
`https://api.open-meteo.com/v1/forecast?latitude= ${ lat } &longitude= ${ lng } ¤t=temperature_2m,wind_speed_10m` ,
) ;
const json = await result . json ( ) ;
return json ;
} ,
) ; Die .addTool() -Methode führt automatisch einen Werkzeughandler aus und löst eine Antwort auf die Fertigstellung des Handlers aus. Manchmal möchten Sie dies möglicherweise nicht, zum Beispiel: Verwenden von Tools, um ein Schema zu generieren, das Sie für andere Zwecke verwenden.
In diesem Fall können wir das tools -Element mit updateSession verwenden. In diesem Fall müssen Sie type: 'function' angeben, der für .addTool() nicht erforderlich ist.
HINWEIS: Tools, die mit .addTool() hinzugefügt wurden, werden bei der so manuellen Aktualisierung von Sitzungen nicht überschrieben, aber jede Änderung updateSession() wird vorherige Änderungen updateSession() überschreiben. Tools, die über .addTool() hinzugefügt wurden, werden angehalten und an alles angehängt, was hier manuell festgelegt ist.
client . updateSession ( {
tools : [
{
type : 'function' ,
name : 'get_weather' ,
description :
'Retrieves the weather for a given lat, lng coordinate pair. Specify a label for the location.' ,
parameters : {
type : 'object' ,
properties : {
lat : {
type : 'number' ,
description : 'Latitude' ,
} ,
lng : {
type : 'number' ,
description : 'Longitude' ,
} ,
location : {
type : 'string' ,
description : 'Name of the location' ,
} ,
} ,
required : [ 'lat' , 'lng' , 'location' ] ,
} ,
} ,
] ,
} ) ;Dann, um Funktionen aufzurufen ...
client . on ( 'conversation.updated' , ( { item , delta } ) => {
if ( item . type === 'function_call' ) {
// do something
if ( delta . arguments ) {
// populating the arguments
}
}
} ) ;
client . on ( 'conversation.item.completed' , ( { item } ) => {
if ( item . type === 'function_call' ) {
// your function call is complete, execute some custom code
}
} ) ; Möglicherweise möchten Sie das Modell manuell unterbrochen, insbesondere nach turn_detection: 'disabled' -Modus. Dazu können wir verwenden:
// id is the id of the item currently being generated
// sampleCount is the number of audio samples that have been heard by the listener
client . cancelResponse ( id , sampleCount ) ; Diese Methode bewirkt, dass das Modell die Erzeugung sofort eingestellt hat, aber auch das gespielte Element durch Entfernen des gesamten Audios nach sampleCount und der Löschung der Textantwort abgespielt wird. Durch die Verwendung dieser Methode können Sie das Modell unterbrechen und verhindern, dass es alles "Erinnern", was es generiert hat und der dem Status des Benutzers liegt.
Wenn Sie mehr manuelle Steuerung benötigen und benutzerdefinierte Client -Ereignisse gemäß der API -Referenz für Echtzeit -Client -Ereignisse senden möchten, können Sie client.realtime.send() wie SO verwenden:
// manually send a function call output
client . realtime . send ( 'conversation.item.create' , {
item : {
type : 'function_call_output' ,
call_id : 'my-call-id' ,
output : '{function_succeeded:true}' ,
} ,
} ) ;
client . realtime . send ( 'response.create' ) ; Mit RealtimeClient haben wir den Ereignisaufwand von Serverereignissen auf fünf wichtigste Ereignisse reduziert, die für Ihren Anwendungssteuerungsfluss am wichtigsten sind. Diese Ereignisse sind nicht Teil der API -Spezifikation selbst, sondern Logik, um die Anwendungsentwicklung zu vereinfachen.
// errors like connection failures
client . on ( 'error' , ( event ) => {
// do thing
} ) ;
// in VAD mode, the user starts speaking
// we can use this to stop audio playback of a previous response if necessary
client . on ( 'conversation.interrupted' , ( ) => {
/* do something */
} ) ;
// includes all changes to conversations
// delta may be populated
client . on ( 'conversation.updated' , ( { item , delta } ) => {
// get all items, e.g. if you need to update a chat window
const items = client . conversation . getItems ( ) ;
switch ( item . type ) {
case 'message' :
// system, user, or assistant message (item.role)
break ;
case 'function_call' :
// always a function call from the model
break ;
case 'function_call_output' :
// always a response from the user / application
break ;
}
if ( delta ) {
// Only one of the following will be populated for any given event
// delta.audio = Int16Array, audio added
// delta.transcript = string, transcript added
// delta.arguments = string, function arguments added
}
} ) ;
// only triggered after item added to conversation
client . on ( 'conversation.item.appended' , ( { item } ) => {
/* item status can be 'in_progress' or 'completed' */
} ) ;
// only triggered after item completed in conversation
// will always be triggered after conversation.item.appended
client . on ( 'conversation.item.completed' , ( { item } ) => {
/* item status will always be 'completed' */
} ) ; Wenn Sie mehr Kontrolle über Ihre Anwendungsentwicklung wünschen, können Sie das realtime.event Event verwenden und nur auf Serverereignisse antworten. Die vollständige Dokumentation für diese Ereignisse finden Sie in der API -Referenz für Echtzeitsereignisse.
// all events, can use for logging, debugging, or manual event handling
client . on ( 'realtime.event' , ( { time , source , event } ) => {
// time is an ISO timestamp
// source is 'client' or 'server'
// event is the raw event payload (json)
if ( source === 'server' ) {
doSomething ( event ) ;
}
} ) ; Sie müssen sicherstellen, dass Sie eine .env -Datei mit OPENAI_API_KEY= SET haben, um Tests auszuführen. Von dort aus ist es einfach, die Testsuite auszuführen.
$ npm testVerwenden Sie:
$ npm test -- --debugVielen Dank, dass Sie sich die Echtzeit -API angesehen haben. Würde gerne von dir hören. Besonderer Dank geht an das Echtzeit -API -Team, das dies alles möglich gemacht hat.