يحتوي هذا المستودع على عميل مرجعي ويعرف أيضًا باسم مكتبة عينة للاتصال بأجهزة واجهة برمجة تطبيقات Openai في الوقت الفعلي. هذه المكتبة في الإصدار التجريبي ولا ينبغي التعامل معها كتطبيق نهائي. يمكنك استخدامه لتطبيقات المحادثة النموذجية بسهولة.
أسهل طريقة للعب مع واجهة برمجة التطبيقات على الفور هي استخدام وحدة التحكم في الوقت الفعلي ، وهي تستخدم العميل المرجعي لتقديم مفتش واجهة برمجة التطبيقات (API) بالكامل مع أمثلة على التصور الصوتي والمزيد.
تم تصميم هذه المكتبة لاستخدامها على حد سواء من جانب الخادم (Node.js) وفي المتصفح (React ، Vue) ، في كل من JavaScript و TypeScript. أثناء وجوده في Beta ، لتثبيت المكتبة ، ستحتاج إلى npm install مباشرة من مستودع GitHub.
$ 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. لا نوصي بهذا ، مفاتيح API الخاصة بك في خطر إذا اتصلت بـ Openai مباشرة من المتصفح. من أجل إنشاء إنشاء العميل في بيئة المتصفح ، استخدم:
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 } ) ; في هذه المكتبة ، هناك ثلاثة بدايات للتفاعل مع واجهة برمجة التطبيقات في الوقت الفعلي. نوصي بالبدء في RealtimeClient ، ولكن قد يكون المستخدمون الأكثر تقدماً أكثر راحة في العمل بالقرب من المعدن.
RealtimeClientconversation.item.completed conversation.updated conversation.interrupted conversation.item.appended realtime.eventRealtimeAPIclient.realtimeserver.{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() تلقائيًا بتشغيل معالج الأدوات وتؤدي إلى استجابة على إكمال المعالج. في بعض الأحيان قد لا ترغب في ذلك ، على سبيل المثال: استخدام الأدوات لإنشاء مخطط تستخدمه لأغراض أخرى.
في هذه الحالة ، يمكننا استخدام عنصر tools مع updateSession . في هذه الحالة ، يجب عليك تحديد 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() مثل ذلك:
// 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 قمنا بتخفيض الحدث النفقات العامة من أحداث الخادم إلى خمسة أحداث رئيسية أكثر أهمية لتدفق التحكم في التطبيق. هذه الأحداث ليست جزءًا من مواصفات واجهة برمجة التطبيقات نفسها ، ولكنها تلتزم المنطق لجعل تطوير التطبيق أسهل.
// 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 أحداث Server Time Server.
// 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 في الوقت الفعلي لجعل هذا كله ممكنًا.