該存儲庫包含一個參考客戶端又稱示例庫,用於連接OpenAI的實時API。該庫處於Beta,不應被視為最終實現。您可以使用它來輕鬆原型對話應用程序。
立即使用API播放的最簡單方法是使用實時控制台,它使用參考客戶端提供了功能齊全的API檢查器,其中包含語音可視化示例等。
該庫是在JavaScript和Typescript代碼庫中構建的,用於使用服務器端(Node.js)和瀏覽器(React,Vue)。在Beta時,要安裝庫,您需要直接從GitHub存儲庫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?` } ] ) ; 您可以直接從瀏覽器中使用此客戶端,例如React或Vue應用程序。我們不建議這樣做,如果您直接從瀏覽器連接到OpenAI,您的API鍵就會有風險。為了在瀏覽器環境中實例化客戶端,請使用:
import { RealtimeClient } from '@openai/realtime-api-beta' ;
const client = new RealtimeClient ( {
apiKey : process . env . OPENAI_API_KEY ,
dangerouslyAllowAPIKeyInBrowser : true ,
} ) ;如果您正在運行自己的繼電器服務器,例如使用實時控制台,則可以像這樣連接到中繼服務器URL:
const client = new RealtimeClient ( { url : RELAY_SERVER_URL } ) ;在此庫中,有三個用於與實時API接口的原始圖。我們建議您從RealtimeClient開始,但是更高級的用戶可能更願意更接近金屬。
RealtimeClientconversation.interrupted realtime.event conversation.item.completed conversation.updated conversation.item.appendedRealtimeAPIclient.realtime存在server.{event_name}和client.{event_name} ,分別RealtimeConversationclient.conversation存在客戶包裝有一些基本的實用程序,這些實用程序使快速構建實時應用程序變得易於構建。
向用戶發送消息很容易。
client . sendUserMessageContent ( [ { type : 'input_text' , text : `How are you?` } ] ) ;
// or (empty audio)
client . sendUserMessageContent ( [
{ type : 'input_audio' , audio : new Int16Array ( 0 ) } ,
] ) ; 要發送流音頻,請使用.appendInputAudio()方法。如果您處於turn_detection: 'disabled'模式,則需要使用.createResponse()告訴模型響應。
// 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 ( ) ; 使用工具很容易。只需調用.addTool()並將回調設置為第二個參數。回調將使用該工具的參數執行,結果將自動發送回模型。
// 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 ;
} ,
) ;.addTool()方法自動運行工具處理程序,並觸發處理程序完成的響應。有時您可能不希望這樣做:使用工具來生成用於其他目的的模式。
在這種情況下,我們可以使用帶有updateSession tools項目。在這種情況下,您必須指定type: 'function' ,而.addTool()不需要。
注意:在這樣的更新會話時,使用.addTool()添加的工具將不會被覆蓋,但是每個updateSession()更改將覆蓋以前的updateSession()更改。通過.addTool()添加的工具被持續使用,並將其附加到此處手動設置的任何內容。
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' ] ,
} ,
} ,
] ,
} ) ;然後,處理功能調用...
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
}
} ) ; 您可能需要手動中斷模型,尤其是在turn_detection: 'disabled'模式。為此,我們可以使用:
// 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 ) ;該方法將導致模型立即停止生成,但也通過sampleCount後刪除所有音頻並清除文本響應來截斷所播放的項目。通過使用此方法,您可以中斷模型,並防止其“記住”其生成的任何內容,這些內容比用戶狀態所在。
如果您需要更多的手動控件,並且想根據實時客戶端事件API參考發送自定義客戶端事件,則可以使用client.realtime.send()這樣的so:
// 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' ) ; 使用RealtimeClient ,我們將事件開銷從服務器事件減少到五個主要事件,這些事件對於您的應用程序控制流量最重要。這些事件不是API規範本身的一部分,而是包裝邏輯以使應用程序開發更加容易。
// 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' */
} ) ;如果您想對應用程序開發進行更多控制權,則可以使用realtime.event事件,只選擇響應服務器事件。這些事件的完整文檔可在實時服務器事件API參考上找到。
// 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 ) ;
}
} ) ;您將需要確保擁有一個.env文件,其中OPENAI_API_KEY=設置以運行測試。從那裡開始,運行測試套件很容易。
$ npm test要使用調試日誌運行測試(將發送到Websocket發送並接收到的日誌事件),請使用:
$ npm test -- --debug感謝您檢查實時API。很想听聽您的來信。特別感謝實時API團隊使這一切成為可能。