بناء على Openai-Dotnet
حزمة Openai للوحدة لاستخدامها على الرغم من API المريح. تم تطويره بشكل مستقل ، هذه ليست مكتبة رسمية وأنا لا تابعة لـ Openai. مطلوب حساب API Openai.
جميع حقوق الطبع والنشر والعلامات التجارية والشعارات والأصول هي ملك لأصحابها المعنيين.
يتطلب الوحدة 2021.3 LTS أو أعلى.
طريقة التثبيت الموصى بها هي على الرغم من أن Manager Unity Package Manager و OpenUPM.
OpenUPMhttps://package.openupm.comcom.openaicom.utilities
My RegistriesOpenAIhttps://github.com/RageAgainstThePixel/com.openai.unity.git#upmملاحظة: هذا الريبو لديه تبعيات على مستودعات أخرى! أنت مسؤول عن إضافة هذه بنفسك.
تحقق من مستندات API الجديدة لدينا!
https://rageagainstthepixel.github.io/openai-dotnet
هناك 4 طرق لتوفير مفاتيح واجهة برمجة التطبيقات الخاصة بك ، حسب الأسبقية:
تحذير
لقد أوصينا باستخدام متغيرات البيئة لتحميل مفتاح API بدلاً من ترميزه الثابت في المصدر الخاص بك. لا ينصح باستخدام هذه الطريقة في الإنتاج ، ولكن فقط لقبول بيانات اعتماد المستخدم والاختبار المحلي وسيناريوهات البدء السريع.
يمكنك استخدام OpenAIAuthentication عند تهيئة واجهة برمجة التطبيقات كما هو موضح:
تحذير
لقد أوصينا باستخدام متغيرات البيئة لتحميل مفتاح API بدلاً من ترميزه الثابت في المصدر الخاص بك. لا ينصح باستخدام هذه الطريقة في الإنتاج ، ولكن فقط لقبول بيانات اعتماد المستخدم والاختبار المحلي وسيناريوهات البدء السريع.
var api = new OpenAIClient ( " sk-apiKey " ) ; أو إنشاء كائن OpenAIAuthentication يدويًا
var api = new OpenAIClient ( new OpenAIAuthentication ( " sk-apiKey " , " org-yourOrganizationId " , " proj_yourProjectId " ) ) ; يمكنك حفظ المفتاح مباشرة في كائن قابل للنص الموجود في مجلد Assets/Resources .
يمكنك إنشاء قائمة جديدة باستخدام قائمة السياق لجزء المشروع وإنشاء كائن قابل للرسوم OpenAIConfiguration جديد.
تحذير
احذر من التحقق من هذا الملف في عنصر تحكم المصدر ، حيث سيتمكن الأشخاص الآخرون من رؤية مفتاح API الخاص بك. يوصى باستخدام Openai-Dotnet-Proxy ومصادقة المستخدمين مع مزود OAuth المفضل لديك.

محاولات تحميل مفاتيح API من ملف التكوين ، بشكل افتراضي .openai في الدليل الحالي ، يجتاز اختياريا شجرة الدليل أو في الدليل الرئيسي للمستخدم.
لإنشاء ملف تكوين ، قم بإنشاء ملف نصي جديد يسمى .openai ويحتوي على السطر:
ملحوظة
إدخالات معرف التنظيم ومعرف المشروع اختياري.
{
"apiKey" : " sk-aaaabbbbbccccddddd " ,
"organizationId" : " org-yourOrganizationId " ,
"projectId" : " proj_yourProjectId "
}OPENAI_API_KEY=sk-aaaabbbbbccccddddd
OPENAI_ORGANIZATION_ID=org-yourOrganizationId
OPENAI_PROJECT_ID=proj_yourProjectId يمكنك أيضًا تحميل ملف التكوين مباشرةً مع المسار المعروف عن طريق استدعاء الطرق الثابتة في OpenAIAuthentication :
.openai في الدليل المحدد: var api = new OpenAIClient ( new OpenAIAuthentication ( ) . LoadFromDirectory ( " path/to/your/directory " ) ) ;.openai طالما أنه يتوافق مع تنسيق JSON: var api = new OpenAIClient ( new OpenAIAuthentication ( ) . LoadFromPath ( " path/to/your/file.json " ) ) ; استخدم متغيرات بيئة نظامك ، حدد مفتاح API ومؤسسة لاستخدامها.
OPENAI_API_KEY لمفتاح API الخاص بك.OPENAI_ORGANIZATION_ID لتحديد مؤسسة.OPENAI_PROJECT_ID لتحديد مشروع. var api = new OpenAIClient ( new OpenAIAuthentication ( ) . LoadFromEnvironment ( ) ) ;يمكنك أيضًا اختيار استخدام عمليات نشر Microsoft Azure Openai أيضًا.
يمكنك العثور على المعلومات المطلوبة في ملعب Azure من خلال النقر على زر View Code وعرض عنوان URL مثل هذا:
https://{your-resource-name}.openai.azure.com/openai/deployments/{deployment-id}/chat/completions?api-version={api-version}your-resource-name اسم مورد Azure Openai الخاص بك.deployment-id اسم النشر الذي اخترته عند نشر النموذج.api-version إصدار API لاستخدامه في هذه العملية. هذا يتبع تنسيق yyyy-mm-dd. لإعداد العميل لاستخدام النشر الخاص بك ، ستحتاج إلى تمرير OpenAISettings إلى مُنشئ العميل.
var auth = new OpenAIAuthentication ( " sk-apiKey " ) ;
var settings = new OpenAISettings ( resourceName : " your-resource-name " , deploymentId : " deployment-id " , apiVersion : " api-version " ) ;
var api = new OpenAIClient ( auth , settings ) ; قم بالتوثيق مع MSAL كالمعتاد واحصل على رمز الوصول ، ثم استخدم رمز الوصول عند إنشاء OpenAIAuthentication . ثم تأكد من تعيين useazureActivedirectory إلى صحيح عند إنشاء OpenAISettings .
البرنامج التعليمي: تطبيق سطح المكتب الذي يدعو ويب واجهات برمجة التطبيقات: الحصول على رمز رمزي
// get your access token using any of the MSAL methods
var accessToken = result . AccessToken ;
var auth = new OpenAIAuthentication ( accessToken ) ;
var settings = new OpenAISettings ( resourceName : " your-resource " , deploymentId : " deployment-id " , apiVersion : " api-version " , useActiveDirectoryAuthentication : true ) ;
var api = new OpenAIClient ( auth , settings ) ;قد يؤدي استخدام حزم Openai-DotNet أو Com.Openai.Unity مباشرة في تطبيقك الأمامي إلى كشف مفاتيح واجهة برمجة التطبيقات والمعلومات الحساسة الأخرى. للتخفيف من هذا الخطر ، يوصى بإعداد واجهة برمجة تطبيقات وسيطة تقدم طلبات إلى Openai نيابة عن تطبيقك الأمامي. يمكن استخدام هذه المكتبة لكل من تكوينات المضيف الأمامي والوسيط ، مما يضمن التواصل الآمن مع API Openai.
في المثال الأمامي ، ستحتاج إلى مصادقة المستخدمين بشكل آمن باستخدام مزود OAuth المفضل لديك. بمجرد مصادقة المستخدم ، قم بتبادل رمز Auth Auth الخاص بك مع مفتاح API الخاص بك على الواجهة الخلفية.
اتبع هذه الخطوات:
OpenAIAuthentication جديد وقم بالمرور في الرمز المخصص مع البادئة sess- .OpenAISettings جديد وحدد المجال حيث يوجد واجهة برمجة التطبيقات المتوسطة.auth الجديدة settings الخاصة بك إلى مُنشئ OpenAIClient عند إنشاء مثيل العميل.إليك مثال على كيفية إعداد الواجهة الأمامية:
var authToken = await LoginAsync ( ) ;
var auth = new OpenAIAuthentication ( $" sess- { authToken } " ) ;
var settings = new OpenAISettings ( domain : " api.your-custom-domain.com " ) ;
var api = new OpenAIClient ( auth , settings ) ;يسمح هذا الإعداد بتطبيقك الأمامي للتواصل بشكل آمن مع الواجهة الخلفية التي ستستخدم Openai-Dotnet-Proxy ، والتي تقوم بعد ذلك بإعادة توجيه الطلبات إلى Openai API. هذا يضمن أن تظل مفاتيح API Openai والمعلومات الحساسة الأخرى آمنة طوال العملية.
في هذا المثال ، نوضح كيفية إعداد واستخدام OpenAIProxy في تطبيق ASP.NET Core Web جديد. سيتعامل خادم الوكيل مع المصادقة وإعادة توجيه الطلبات إلى API Openai ، مما يضمن أن تظل مفاتيح API والمعلومات الحساسة الأخرى آمنة.
Install-Package OpenAI-DotNet-Proxydotnet add package OpenAI-DotNet-Proxy<PackageReference Include="OpenAI-DotNet-Proxy" /> يدويًا .csproj:AbstractAuthenticationFilter وتجاوز طريقة ValidateAuthentication . سيؤدي ذلك إلى تنفيذ IAuthenticationFilter الذي ستستخدمه للتحقق من رمز جلسة المستخدم مقابل الخادم الداخلي الخاص بك.OpenAIProxy.CreateWebApplication Program.cs AuthenticationFilterOpenAIAuthentication و OpenAIClientSettings كما تفعل عادة مع مفاتيح API أو معرف org أو Azure. public partial class Program
{
private class AuthenticationFilter : AbstractAuthenticationFilter
{
public override async Task ValidateAuthenticationAsync ( IHeaderDictionary request )
{
await Task . CompletedTask ; // remote resource call to verify token
// You will need to implement your own class to properly test
// custom issued tokens you've setup for your end users.
if ( ! request . Authorization . ToString ( ) . Contains ( TestUserToken ) )
{
throw new AuthenticationException ( " User is not authorized " ) ;
}
}
}
public static void Main ( string [ ] args )
{
var auth = OpenAIAuthentication . LoadFromEnv ( ) ;
var settings = new OpenAIClientSettings ( /* your custom settings if using Azure OpenAI */ ) ;
using var openAIClient = new OpenAIClient ( auth , settings ) ;
OpenAIProxy . CreateWebApplication < AuthenticationFilter > ( args , openAIClient ) . Run ( ) ;
}
}بمجرد إعداد خادم الوكيل الخاص بك ، يمكن للمستخدمين النهائيين الآن تقديم طلبات مصادقة على واجهة برمجة تطبيقات الوكيل بدلاً من Openai API مباشرة. سيتعامل خادم الوكيل مع المصادقة وإعادة توجيه الطلبات إلى API Openai ، مما يضمن أن تظل مفاتيح API والمعلومات الحساسة الأخرى آمنة.
قائمة ووصف النماذج المختلفة المتاحة في API. يمكنك الرجوع إلى وثائق النماذج لفهم النماذج المتوفرة والاختلافات بينها.
أيضا Checkout نموذج نهاية نقطة النهاية لفهم النماذج التي تعمل مع نقاط النهاية.
لتحديد نموذج مخصص غير محدد مسبقًا في هذه المكتبة:
var model = new Model ( " model-id " ) ; يتم الوصول إلى API للموديلات عبر OpenAIClient.ModelsEndpoint
يسرد النماذج المتاحة حاليًا ، ويوفر معلومات أساسية عن كل واحدة مثل المالك والتوافر.
var api = new OpenAIClient ( ) ;
var models = await api . ModelsEndpoint . GetModelsAsync ( ) ;
foreach ( var model in models )
{
Debug . Log ( model . ToString ( ) ) ;
} يسترجع مثيل نموذج ، ويوفر معلومات أساسية حول النموذج مثل المالك والأذونات.
var api = new OpenAIClient ( ) ;
var model = await api . ModelsEndpoint . GetModelDetailsAsync ( " gpt-4o " ) ;
Debug . Log ( model . ToString ( ) ) ; حذف نموذج دقيق. يجب أن يكون لديك دور المالك في مؤسستك.
var api = new OpenAIClient ( ) ;
var isDeleted = await api . ModelsEndpoint . DeleteFineTuneModelAsync ( " your-fine-tuned-model " ) ;
Assert . IsTrue ( isDeleted ) ;تحذير
ميزة بيتا. واجهة برمجة التطبيقات (API) مع مراعاة التغييرات.
تمكنك واجهة برمجة التطبيقات في الوقت الفعلي من بناء تجارب محادثة منخفضة البشر. وهو يدعم حاليًا النصوص والصوت كإدخال ومخرجات ، وكذلك استدعاء الوظائف.
يتم الوصول إلى API المساعدين عبر OpenAIClient.RealtimeEndpoint
فيما يلي مثال بسيط على كيفية إنشاء جلسة في الوقت الفعلي وإرسال واستقبال الرسائل من النموذج.
var api = new OpenAIClient ( ) ;
var cancellationTokenSource = new CancellationTokenSource ( ) ;
var tools = new List < Tool >
{
Tool . FromFunc ( " goodbye " , ( ) =>
{
cancellationTokenSource . Cancel ( ) ;
return " Goodbye! " ;
} )
} ;
var options = new Options ( Model . GPT4oRealtime , tools : tools ) ;
using var session = await api . RealtimeEndpoint . CreateSessionAsync ( options ) ;
var responseTask = session . ReceiveUpdatesAsync < IServerEvent > ( ServerEvents , cancellationTokenSource . Token ) ;
await session . SendAsync ( new ConversationItemCreateRequest ( " Hello! " ) ) ;
await session . SendAsync ( new CreateResponseRequest ( ) ) ;
await session . SendAsync ( new InputAudioBufferAppendRequest ( new ReadOnlyMemory < byte > ( new byte [ 1024 * 4 ] ) ) , cancellationTokenSource . Token ) ;
await session . SendAsync ( new ConversationItemCreateRequest ( " GoodBye! " ) ) ;
await session . SendAsync ( new CreateResponseRequest ( ) ) ;
await responseTask ;
void ServerEvents ( IServerEvent @event )
{
switch ( @event )
{
case ResponseAudioTranscriptResponse transcriptResponse :
Debug . Log ( transcriptResponse . ToString ( ) ) ;
break ;
case ResponseFunctionCallArgumentsResponse functionCallResponse :
if ( functionCallResponse . IsDone )
{
ToolCall toolCall = functionCallResponse ;
toolCall . InvokeFunction ( ) ;
}
break ;
}
} تقوم المكتبة بتنفيذ واجهة IClientEvent للأحداث التي أرسلها العميل المنتهية ولايتها.
UpdateSessionRequest : قم بتحديث الجلسة بخيارات جلسة جديدة.InputAudioBufferAppendRequest : إلحاق الصوت إلى المخزن المؤقت للصوت الإدخال. (على عكس أحداث العميل الأخرى ، لن يرسل الخادم استجابة تأكيد لهذا الحدث).InputAudioBufferCommitRequest : ارتكاب عازلة الصوت الإدخال. (عندما يكون في وضع الخادم VAD ، لا يحتاج العميل إلى إرسال هذا الحدث).InputAudioBufferClearRequest : قم بمسح المخزن المؤقت للصوت الإدخال.ConversationItemCreateRequest : إنشاء عنصر محادثة جديد. هذه هي الطريقة الرئيسية لإرسال محتوى المستخدم إلى النموذج.ConversationItemTruncateRequest : أرسل هذا الحدث لاقتطاع صوت رسالة مساعد سابق.ConversationItemDeleteRequest : حذف عنصر محادثة. هذا مفيد عندما تريد إزالة رسالة من تاريخ المحادثة.CreateResponseRequest : إنشاء استجابة من النموذج. أرسل هذا الحدث بعد إنشاء عناصر محادثة جديدة أو استدعاء مكالمات الأدوات. هذا سوف يؤدي إلى النموذج لتوليد استجابة.ResponseCancelRequest -احصل على هذا الحدث لإلغاء استجابة قيد التقدم. يمكنك إرسال أحداث العميل في أي وقت إلى الخادم عن طريق الاتصال بطريقة RealtimeSession.SendAsync على كائن الجلسة. ستعيد استدعاء إرسال مقبض IServerEvent الذي يمثل أفضل الاستجابة المناسبة من الخادم لهذا الحدث. هذا مفيد إذا كنت ترغب في التعامل مع استجابات الخادم بطريقة أكثر حبيبًا.
من الناحية المثالية ، قد ترغب في التعامل مع جميع استجابات الخادم باستخدام RealtimeSession.ReceiveUpdatesAsync .
ملحوظة
لن يرسل الخادم استجابة تأكيد إلى حدث InputAudioBufferAppendRequest .
مهم
ستحتاج أيضًا إلى إرسال CreateResponseRequest لتحفيز النموذج لإنشاء استجابة.
var serverEvent = await session . SendAsync ( new ConversationItemCreateRequest ( " Hello! " ) ) ;
Debug . Log ( serverEvent . ToJsonString ( ) ) ;
serverEvent = await session . SendAsync ( new CreateResponseRequest ( ) ) ;
Debug . Log ( serverEvent . ToJsonString ( ) ) ; تقوم المكتبة بتنفيذ واجهة IServerEvent للأحداث المرسلة للخادم الوارد.
RealtimeEventError : يتم إرجاعه عند حدوث خطأ ، والتي قد تكون مشكلة عميل أو مشكلة خادم.SessionResponse : تم إرجاعه لكل من session.created و session.updated Event.RealtimeConversationResponse : تم إرجاعه عند إنشاء عنصر محادثة جديد.ConversationItemCreatedResponse : يتم إرجاعه عند إنشاء عنصر محادثة جديد.ConversationItemInputAudioTranscriptionResponse : تم إرجاعه عند اكتمال أو فشل نسخ صوت الإدخال.ConversationItemTruncatedResponse : يتم إرجاعه عند اقتطاع عنصر محادثة.ConversationItemDeletedResponse : يتم إرجاعه عند حذف عنصر محادثة.InputAudioBufferCommittedResponse : يتم إرجاعه عند ارتكاب مخزن صوت إدخال ، إما من قبل العميل أو تلقائيًا في وضع الخادم VAD.InputAudioBufferClearedResponse : يتم إرجاعه عند مسح المخزن المؤقت للصوت الإدخال.InputAudioBufferStartedResponse : أرسله الخادم عندما يكون في وضع Server_vad للإشارة إلى أنه تم اكتشاف الكلام في المخزن المؤقت للصوت. يمكن أن يحدث هذا في أي وقت يتم فيه إضافة الصوت إلى المخزن المؤقت (ما لم يتم اكتشاف الكلام بالفعل). قد يرغب العميل في استخدام هذا الحدث لمقاطعة تشغيل الصوت أو تقديم ملاحظات مرئية للمستخدم.InputAudioBufferStoppedResponse : تم إرجاعه في وضع server_vad عندما يكتشف الخادم نهاية الكلام في المخزن المؤقت للصوت.RealtimeResponse : تم إرجاعه عند إنشاء استجابة أو القيام به.ResponseOutputItemResponse : يتم إرجاعه عند إضافة عنصر إخراج الاستجابة أو القيام به.ResponseContentPartResponse : يتم إرجاعه عند إضافة جزء محتوى الاستجابة أو القيام به.ResponseTextResponse : يتم إرجاعه عند تحديث نص الاستجابة أو القيام به.ResponseAudioTranscriptResponse : يتم إرجاعه عند تحديث نسخة صوت الاستجابة أو القيام به.ResponseAudioResponse : يتم إرجاعه عند تحديث صوت الاستجابة أو القيام به.ResponseFunctionCallArgumentsResponse : يتم إرجاعها عند تحديث وسيطات استدعاء وظيفة الاستجابة أو القيام بها.RateLimitsResponse : يتم إرجاعه عند تحديث حدود المعدل. لتلقي أحداث الخادم ، ستحتاج إلى استدعاء طريقة RealtimeSession.ReceiveUpdatesAsync على كائن الجلسة. ستُرجع هذه الطريقة Task تكتمل عند إغلاق الجلسة أو عند تشغيل رمز الإلغاء. من الناحية المثالية ، يجب استدعاء هذه الطريقة مرة واحدة وركض طوال فترة الجلسة.
ملحوظة
يمكنك أيضًا الحصول على عوائد IClientEvent أيضًا باستخدام واجهة IRealtimeEvent بدلاً من IServerEvent .
await session . ReceiveUpdatesAsync < IServerEvent > ( ServerEvents , cancellationTokenSource . Token ) ;
void ServerEvents ( IServerEvent @event )
{
switch ( @event )
{
case RealtimeEventError error :
// raised anytime an error occurs
break ;
case SessionResponse sessionResponse :
// raised when a session is created or updated
break ;
case RealtimeConversationResponse conversationResponse :
// raised when a new conversation is created
break ;
case ConversationItemCreatedResponse conversationItemCreated :
// raised when a new conversation item is created
break ;
case ConversationItemInputAudioTranscriptionResponse conversationItemTranscription :
// raised when the input audio transcription is completed or failed
break ;
case ConversationItemTruncatedResponse conversationItemTruncated :
// raised when a conversation item is truncated
break ;
case ConversationItemDeletedResponse conversationItemDeleted :
// raised when a conversation item is deleted
break ;
case InputAudioBufferCommittedResponse committedResponse :
// raised when an input audio buffer is committed
break ;
case InputAudioBufferClearedResponse clearedResponse :
// raised when an input audio buffer is cleared
break ;
case InputAudioBufferStartedResponse startedResponse :
// raised when speech is detected in the audio buffer
break ;
case InputAudioBufferStoppedResponse stoppedResponse :
// raised when speech stops in the audio buffer
break ;
case RealtimeResponse realtimeResponse :
// raised when a response is created or done
break ;
case ResponseOutputItemResponse outputItemResponse :
// raised when a response output item is added or done
break ;
case ResponseContentPartResponse contentPartResponse :
// raised when a response content part is added or done
break ;
case ResponseTextResponse textResponse :
// raised when a response text is updated or done
break ;
case ResponseAudioTranscriptResponse transcriptResponse :
// raised when a response audio transcript is updated or done
break ;
case ResponseFunctionCallArgumentsResponse functionCallResponse :
// raised when a response function call arguments are updated or done
break ;
case RateLimitsResponse rateLimitsResponse :
// raised when rate limits are updated
break ;
}
}تحذير
ميزة بيتا. واجهة برمجة التطبيقات (API) مع مراعاة التغييرات.
بناء مساعدين يمكنهم الاتصال بالموديلات واستخدام الأدوات لأداء المهام.
يتم الوصول إلى API المساعدين عبر OpenAIClient.AssistantsEndpoint
إرجاع قائمة المساعدين.
var api = new OpenAIClient ( ) ;
var assistantsList = await api . AssistantsEndpoint . ListAssistantsAsync ( ) ;
foreach ( var assistant in assistantsList . Items )
{
Debug . Log ( $" { assistant } -> { assistant . CreatedAt } " ) ;
} إنشاء مساعد مع نموذج وتعليمات.
var api = new OpenAIClient ( ) ;
var request = new CreateAssistantRequest ( Model . GPT4o ) ;
var assistant = await api . AssistantsEndpoint . CreateAssistantAsync ( request ) ; يسترجع مساعد.
var api = new OpenAIClient ( ) ;
var assistant = await api . AssistantsEndpoint . RetrieveAssistantAsync ( " assistant-id " ) ;
Debug . Log ( $" { assistant } -> { assistant . CreatedAt } " ) ; يعدل مساعد.
var api = new OpenAIClient ( ) ;
var createRequest = new CreateAssistantRequest ( Model . GPT4_Turbo ) ;
var assistant = await api . AssistantsEndpoint . CreateAssistantAsync ( createRequest ) ;
var modifyRequest = new CreateAssistantRequest ( Model . GPT4o ) ;
var modifiedAssistant = await api . AssistantsEndpoint . ModifyAssistantAsync ( assistant . Id , modifyRequest ) ;
// OR AssistantExtension for easier use!
var modifiedAssistantEx = await assistant . ModifyAsync ( modifyRequest ) ; حذف مساعد.
var api = new OpenAIClient ( ) ;
var isDeleted = await api . AssistantsEndpoint . DeleteAssistantAsync ( " assistant-id " ) ;
// OR AssistantExtension for easier use!
var isDeleted = await assistant . DeleteAsync ( ) ;
Assert . IsTrue ( isDeleted ) ; ملحوظة
يمكن إضافة أحداث الدفق المساعد بسهولة إلى مكالمات مؤشرات الترابط الحالية عن طريق تمرير رد اتصال Func<IServerSentEvent, Task> streamEventHandler إلى أي طريقة موجودة تدعم البث.
إنشاء مواضيع يمكن للمساعدين التفاعل معها.
يتم الوصول إلى واجهة برمجة تطبيقات المواضيع عبر OpenAIClient.ThreadsEndpoint
إنشاء موضوع.
var api = new OpenAIClient ( ) ;
var thread = await api . ThreadsEndpoint . CreateThreadAsync ( ) ;
Debug . Log ( $" Create thread { thread . Id } -> { thread . CreatedAt } " ) ; قم بإنشاء موضوع وقم بتشغيله في طلب واحد.
انظر أيضًا: تشغيل الخيط
var api = new OpenAIClient ( ) ;
var assistant = await api . AssistantsEndpoint . CreateAssistantAsync (
new CreateAssistantRequest (
name : " Math Tutor " ,
instructions : " You are a personal math tutor. Answer questions briefly, in a sentence or less. " ,
model : Model . GPT4o ) ) ;
var messages = new List < Message > { " I need to solve the equation `3x + 11 = 14`. Can you help me? " } ;
var threadRequest = new CreateThreadRequest ( messages ) ;
var run = await assistant . CreateThreadAndRunAsync ( threadRequest ) ;
Debug . Log ( $" Created thread and run: { run . ThreadId } -> { run . Id } -> { run . CreatedAt } " ) ; قم بإنشاء موضوع وقم بتشغيله في طلب واحد أثناء دفق الأحداث.
var api = new OpenAIClient ( ) ;
var tools = new List < Tool >
{
Tool . GetOrCreateTool ( typeof ( WeatherService ) , nameof ( WeatherService . GetCurrentWeatherAsync ) )
} ;
var assistantRequest = new CreateAssistantRequest ( tools : tools , instructions : " You are a helpful weather assistant. Use the appropriate unit based on geographical location. " ) ;
var assistant = await api . AssistantsEndpoint . CreateAssistantAsync ( assistantRequest ) ;
ThreadResponse thread = null ;
async Task StreamEventHandler ( IServerSentEvent streamEvent )
{
switch ( streamEvent )
{
case ThreadResponse threadResponse :
thread = threadResponse ;
break ;
case RunResponse runResponse :
if ( runResponse . Status == RunStatus . RequiresAction )
{
var toolOutputs = await assistant . GetToolOutputsAsync ( runResponse ) ;
foreach ( var toolOutput in toolOutputs )
{
Debug . Log ( $" Tool Output: { toolOutput } " ) ;
}
await runResponse . SubmitToolOutputsAsync ( toolOutputs , StreamEventHandler ) ;
}
break ;
default :
Debug . Log ( streamEvent . ToJsonString ( ) ) ;
break ;
}
}
var run = await assistant . CreateThreadAndRunAsync ( " I'm in Kuala-Lumpur, please tell me what's the temperature now? " , StreamEventHandler ) ;
run = await run . WaitForStatusChangeAsync ( ) ;
var messages = await thread . ListMessagesAsync ( ) ;
foreach ( var response in messages . Items . Reverse ( ) )
{
Debug . Log ( $" { response . Role } : { response . PrintContent ( ) } " ) ;
} يسترجع موضوع.
var api = new OpenAIClient ( ) ;
var thread = await api . ThreadsEndpoint . RetrieveThreadAsync ( " thread-id " ) ;
// OR if you simply wish to get the latest state of a thread
thread = await thread . UpdateAsync ( ) ;
Debug . Log ( $" Retrieve thread { thread . Id } -> { thread . CreatedAt } " ) ; يعدل موضوع.
ملاحظة: يمكن تعديل البيانات الوصفية فقط.
var api = new OpenAIClient ( ) ;
var thread = await api . ThreadsEndpoint . CreateThreadAsync ( ) ;
var metadata = new Dictionary < string , string >
{
{ " key " , " custom thread metadata " }
}
thread = await api . ThreadsEndpoint . ModifyThreadAsync ( thread . Id , metadata ) ;
// OR use extension method for convenience!
thread = await thread . ModifyAsync ( metadata ) ;
Debug . Log ( $" Modify thread { thread . Id } -> { thread . Metadata [ " key " ] } " ) ; حذف موضوع.
var api = new OpenAIClient ( ) ;
var isDeleted = await api . ThreadsEndpoint . DeleteThreadAsync ( " thread-id " ) ;
// OR use extension method for convenience!
var isDeleted = await thread . DeleteAsync ( ) ;
Assert . IsTrue ( isDeleted ) ; إنشاء رسائل داخل المواضيع.
إرجاع قائمة الرسائل لخيط معين.
var api = new OpenAIClient ( ) ;
var messageList = await api . ThreadsEndpoint . ListMessagesAsync ( " thread-id " ) ;
// OR use extension method for convenience!
var messageList = await thread . ListMessagesAsync ( ) ;
foreach ( var message in messageList . Items )
{
Debug . Log ( $" { message . Id } : { message . Role } : { message . PrintContent ( ) } " ) ;
} إنشاء رسالة.
var api = new OpenAIClient ( ) ;
var thread = await api . ThreadsEndpoint . CreateThreadAsync ( ) ;
var request = new CreateMessageRequest ( " Hello world! " ) ;
var message = await api . ThreadsEndpoint . CreateMessageAsync ( thread . Id , request ) ;
// OR use extension method for convenience!
var message = await thread . CreateMessageAsync ( " Hello World! " ) ;
Debug . Log ( $" { message . Id } : { message . Role } : { message . PrintContent ( ) } " ) ; استرداد رسالة.
var api = new OpenAIClient ( ) ;
var message = await api . ThreadsEndpoint . RetrieveMessageAsync ( " thread-id " , " message-id " ) ;
// OR use extension methods for convenience!
var message = await thread . RetrieveMessageAsync ( " message-id " ) ;
var message = await message . UpdateAsync ( ) ;
Debug . Log ( $" { message . Id } : { message . Role } : { message . PrintContent ( ) } " ) ; تعديل رسالة.
ملاحظة: يمكن تعديل بيانات تعريف الرسالة فقط.
var api = new OpenAIClient ( ) ;
var metadata = new Dictionary < string , string >
{
{ " key " , " custom message metadata " }
} ;
var message = await api . ThreadsEndpoint . ModifyMessageAsync ( " thread-id " , " message-id " , metadata ) ;
// OR use extension method for convenience!
var message = await message . ModifyAsync ( metadata ) ;
Debug . Log ( $" Modify message metadata: { message . Id } -> { message . Metadata [ " key " ] } " ) ; يمثل تشغيل تنفيذ على موضوع.
إرجاع قائمة من عمليات التشغيل التي تنتمي إلى موضوع.
var api = new OpenAIClient ( ) ;
var runList = await api . ThreadsEndpoint . ListRunsAsync ( " thread-id " ) ;
// OR use extension method for convenience!
var runList = await thread . ListRunsAsync ( ) ;
foreach ( var run in runList . Items )
{
Debug . Log ( $" [ { run . Id } ] { run . Status } | { run . CreatedAt } " ) ;
} إنشاء تشغيل.
var api = new OpenAIClient ( ) ;
var assistant = await api . AssistantsEndpoint . CreateAssistantAsync (
new CreateAssistantRequest (
name : " Math Tutor " ,
instructions : " You are a personal math tutor. Answer questions briefly, in a sentence or less. " ,
model : Model . GPT4o ) ) ;
var thread = await api . ThreadsEndpoint . CreateThreadAsync ( ) ;
var message = await thread . CreateMessageAsync ( " I need to solve the equation `3x + 11 = 14`. Can you help me? " ) ;
var run = await thread . CreateRunAsync ( assistant ) ;
Debug . Log ( $" [ { run . Id } ] { run . Status } | { run . CreatedAt } " ) ; إنشاء تشغيل ودفق الأحداث.
var api = new OpenAIClient ( ) ;
var assistant = await api . AssistantsEndpoint . CreateAssistantAsync (
new CreateAssistantRequest (
name : " Math Tutor " ,
instructions : " You are a personal math tutor. Answer questions briefly, in a sentence or less. Your responses should be formatted in JSON. " ,
model : Model . GPT4o ,
responseFormat : ChatResponseFormat . Json ) ) ;
var thread = await api . ThreadsEndpoint . CreateThreadAsync ( ) ;
var message = await thread . CreateMessageAsync ( " I need to solve the equation `3x + 11 = 14`. Can you help me? " ) ;
var run = await thread . CreateRunAsync ( assistant , async streamEvent =>
{
Debug . Log ( streamEvent . ToJsonString ( ) ) ;
await Task . CompletedTask ;
} ) ;
var messages = await thread . ListMessagesAsync ( ) ;
foreach ( var response in messages . Items . Reverse ( ) )
{
Debug . Log ( $" { response . Role } : { response . PrintContent ( ) } " ) ;
} يسترجع الجري.
var api = new OpenAIClient ( ) ;
var run = await api . ThreadsEndpoint . RetrieveRunAsync ( " thread-id " , " run-id " ) ;
// OR use extension method for convenience!
var run = await thread . RetrieveRunAsync ( " run-id " ) ;
var run = await run . UpdateAsync ( ) ;
Debug . Log ( $" [ { run . Id } ] { run . Status } | { run . CreatedAt } " ) ; يعدل التشغيل.
ملاحظة: يمكن تعديل البيانات الوصفية فقط.
var api = new OpenAIClient ( ) ;
var metadata = new Dictionary < string , string >
{
{ " key " , " custom run metadata " }
} ;
var run = await api . ThreadsEndpoint . ModifyRunAsync ( " thread-id " , " run-id " , metadata ) ;
// OR use extension method for convenience!
var run = await run . ModifyAsync ( metadata ) ;
Debug . Log ( $" Modify run { run . Id } -> { run . Metadata [ " key " ] } " ) ; عندما يكون للتشغيل الحالة: requires_action required_action.type submit_tool_outputs ، يمكن استخدام نقطة النهاية هذه لإرسال المخرجات من مكالمات الأداة بمجرد اكتمالها جميعًا. يجب تقديم جميع المخرجات في طلب واحد.
ملحوظة
انظر إنشاء مؤشر ترابط وتشغيل مثال على كيفية دفق أحداث إخراج الأداة.
var api = new OpenAIClient ( ) ;
var tools = new List < Tool >
{
// Use a predefined tool
Tool . Retrieval , Tool . CodeInterpreter ,
// Or create a tool from a type and the name of the method you want to use for function calling
Tool . GetOrCreateTool ( typeof ( WeatherService ) , nameof ( WeatherService . GetCurrentWeatherAsync ) ) ,
// Pass in an instance of an object to call a method on it
Tool . GetOrCreateTool ( api . ImagesEndPoint , nameof ( ImagesEndpoint . GenerateImageAsync ) ) ,
// Define func<,> callbacks
Tool . FromFunc ( " name_of_func " , ( ) => { /* callback function */ } ) ,
Tool . FromFunc < T1 , T2 , TResult > ( " func_with_multiple_params " , ( t1 , t2 ) => { /* logic that calculates return value */ return tResult ; } )
} ;
var assistantRequest = new CreateAssistantRequest ( tools : tools , instructions : " You are a helpful weather assistant. Use the appropriate unit based on geographical location. " ) ;
var testAssistant = await api . AssistantsEndpoint . CreateAssistantAsync ( assistantRequest ) ;
var run = await testAssistant . CreateThreadAndRunAsync ( " I'm in Kuala-Lumpur, please tell me what's the temperature now? " ) ;
// waiting while run is Queued and InProgress
run = await run . WaitForStatusChangeAsync ( ) ;
// Invoke all of the tool call functions and return the tool outputs.
var toolOutputs = await testAssistant . GetToolOutputsAsync ( run . RequiredAction . SubmitToolOutputs . ToolCalls ) ;
foreach ( var toolOutput in toolOutputs )
{
Debug . Log ( $" tool call output: { toolOutput . Output } " ) ;
}
// submit the tool outputs
run = await run . SubmitToolOutputsAsync ( toolOutputs ) ;
// waiting while run in Queued and InProgress
run = await run . WaitForStatusChangeAsync ( ) ;
var messages = await run . ListMessagesAsync ( ) ;
foreach ( var message in messages . Items . OrderBy ( response => response . CreatedAt ) )
{
Debug . Log ( $" { message . Role } : { message . PrintContent ( ) } " ) ;
} المخرجات المهيكلة هي تطور وضع JSON. في حين أن كلاهما يضمن إنتاج JSON صالح ، إلا أن المخرجات المهيكلة فقط تضمن الالتزام بالمخطط.
مهم
finish_reason من الطول ، مما يشير إلى أن الجيل تجاوز max_tokens أو تجاوز المحادثة حد الرمز المميز. للحماية من هذا ، تحقق finish_reason قبل تحليل الرد.حدد أولاً بنية ردودك. سيتم استخدام هذه كمخططك. هذه هي الكائنات التي ستعمل عليها ، لذا تأكد من استخدام نماذج كائن JSON القياسية.
public class MathResponse
{
[ JsonProperty ( " steps " ) ]
public IReadOnlyList < MathStep > Steps { get ; private set ; }
[ JsonProperty ( " final_answer " ) ]
public string FinalAnswer { get ; private set ; }
}
public class MathStep
{
[ JsonProperty ( " explanation " ) ]
public string Explanation { get ; private set ; }
[ JsonProperty ( " output " ) ]
public string Output { get ; private set ; }
} للاستخدام ، ما عليك سوى تحديد نوع MathResponse كقيد عام في إما CreateAssistantAsync أو CreateRunAsync أو CreateThreadAndRunAsync .
var api = new OpenAIClient ( ) ;
var assistant = await api . AssistantsEndpoint . CreateAssistantAsync < MathResponse > (
new CreateAssistantRequest (
name : " Math Tutor " ,
instructions : " You are a helpful math tutor. Guide the user through the solution step by step. " ,
model : " gpt-4o-2024-08-06 " ) ) ;
ThreadResponse thread = null ;
try
{
async Task StreamEventHandler ( IServerSentEvent @event )
{
try
{
switch ( @event )
{
case MessageResponse message :
if ( message . Status != MessageStatus . Completed )
{
Debug . Log ( @event . ToJsonString ( ) ) ;
break ;
}
var mathResponse = message . FromSchema < MathResponse > ( ) ;
for ( var i = 0 ; i < mathResponse . Steps . Count ; i ++ )
{
var step = mathResponse . Steps [ i ] ;
Debug . Log ( $" Step { i } : { step . Explanation } " ) ;
Debug . Log ( $" Result: { step . Output } " ) ;
}
Debug . Log ( $" Final Answer: { mathResponse . FinalAnswer } " ) ;
break ;
default :
Debug . Log ( @event . ToJsonString ( ) ) ;
break ;
}
}
catch ( Exception e )
{
Debug . Log ( e ) ;
throw ;
}
await Task . CompletedTask ;
}
var run = await assistant . CreateThreadAndRunAsync ( " how can I solve 8x + 7 = -23 " , StreamEventHandler ) ;
thread = await run . GetThreadAsync ( ) ;
run = await run . WaitForStatusChangeAsync ( ) ;
Debug . Log ( $" Created thread and run: { run . ThreadId } -> { run . Id } -> { run . CreatedAt } " ) ;
var messages = await thread . ListMessagesAsync ( ) ;
foreach ( var response in messages . Items . OrderBy ( response => response . CreatedAt ) )
{
Debug . Log ( $" { response . Role } : { response . PrintContent ( ) } " ) ;
}
}
finally
{
await assistant . DeleteAsync ( deleteToolResources : thread == null ) ;
if ( thread != null )
{
var isDeleted = await thread . DeleteAsync ( deleteToolResources : true ) ;
}
}يمكنك أيضًا إنشاء سلسلة JSON Schema JSON يدويًا أيضًا ، لكنك ستكون مسؤولاً عن إلغاء توزيع بيانات الاستجابة الخاصة بك:
var api = new OpenAIClient ( ) ;
var mathSchema = new JsonSchema ( " math_response " , @"
{
""type"": ""object"",
""properties"": {
""steps"": {
""type"": ""array"",
""items"": {
""type"": ""object"",
""properties"": {
""explanation"": {
""type"": ""string""
},
""output"": {
""type"": ""string""
}
},
""required"": [
""explanation"",
""output""
],
""additionalProperties"": false
}
},
""final_answer"": {
""type"": ""string""
}
},
""required"": [
""steps"",
""final_answer""
],
""additionalProperties"": false
}" ) ;
var assistant = await api . AssistantsEndpoint . CreateAssistantAsync (
new CreateAssistantRequest (
name : " Math Tutor " ,
instructions : " You are a helpful math tutor. Guide the user through the solution step by step. " ,
model : " gpt-4o-2024-08-06 " ,
jsonSchema : mathSchema ) ) ;
ThreadResponse thread = null ;
try
{
var run = await assistant . CreateThreadAndRunAsync ( " how can I solve 8x + 7 = -23 " ,
async @event =>
{
Debug . Log ( @event . ToJsonString ( ) ) ;
await Task . CompletedTask ;
} ) ;
thread = await run . GetThreadAsync ( ) ;
run = await run . WaitForStatusChangeAsync ( ) ;
Debug . Log ( $" Created thread and run: { run . ThreadId } -> { run . Id } -> { run . CreatedAt } " ) ;
var messages = await thread . ListMessagesAsync ( ) ;
foreach ( var response in messages . Items )
{
Debug . Log ( $" { response . Role } : { response . PrintContent ( ) } " ) ;
}
}
finally
{
await assistant . DeleteAsync ( deleteToolResources : thread == null ) ;
if ( thread != null )
{
var isDeleted = await thread . DeleteAsync ( deleteToolResources : true ) ;
Assert . IsTrue ( isDeleted ) ;
}
} إرجاع قائمة خطوات التشغيل التي تنتمي إلى تشغيل.
var api = new OpenAIClient ( ) ;
var runStepList = await api . ThreadsEndpoint . ListRunStepsAsync ( " thread-id " , " run-id " ) ;
// OR use extension method for convenience!
var runStepList = await run . ListRunStepsAsync ( ) ;
foreach ( var runStep in runStepList . Items )
{
Debug . Log ( $" [ { runStep . Id } ] { runStep . Status } { runStep . CreatedAt } -> { runStep . ExpiresAt } " ) ;
} يسترجع خطوة التشغيل.
var api = new OpenAIClient ( ) ;
var runStep = await api . ThreadsEndpoint . RetrieveRunStepAsync ( " thread-id " , " run-id " , " step-id " ) ;
// OR use extension method for convenience!
var runStep = await run . RetrieveRunStepAsync ( " step-id " ) ;
var runStep = await runStep . UpdateAsync ( ) ;
Debug . Log ( $" [ { runStep . Id } ] { runStep . Status } { runStep . CreatedAt } -> { runStep . ExpiresAt } " ) ; يلغي تشغيل in_progress .
var api = new OpenAIClient ( ) ;
var isCancelled = await api . ThreadsEndpoint . CancelRunAsync ( " thread-id " , " run-id " ) ;
// OR use extension method for convenience!
var isCancelled = await run . CancelAsync ( ) ;
Assert . IsTrue ( isCancelled ) ; يتم استخدام متاجر Vector لتخزين الملفات لاستخدامها بواسطة أداة file_search .
يتم الوصول إلى واجهة برمجة تطبيقات Stores Stores عبر OpenAIClient.VectorStoresEndpoint
إرجاع قائمة متاجر المتجهات.
var api = new OpenAIClient ( ) ;
var vectorStores = await api . VectorStoresEndpoint . ListVectorStoresAsync ( ) ;
foreach ( var vectorStore in vectorStores . Items )
{
Debug . Log ( vectorStore ) ;
} إنشاء متجر ناقلات.
var api = new OpenAIClient ( ) ;
var createVectorStoreRequest = new CreateVectorStoreRequest ( " test-vector-store " ) ;
var vectorStore = await api . VectorStoresEndpoint . CreateVectorStoreAsync ( createVectorStoreRequest ) ;
Debug . Log ( vectorStore ) ; يسترجع متجر متجه.
var api = new OpenAIClient ( ) ;
var vectorStore = await api . VectorStoresEndpoint . GetVectorStoreAsync ( " vector-store-id " ) ;
Debug . Log ( vectorStore ) ; يعدل متجر المتجهات.
var api = new OpenAIClient ( ) ;
var metadata = new Dictionary < string , object > { { " Test " , DateTime . UtcNow } } ;
var vectorStore = await api . VectorStoresEndpoint . ModifyVectorStoreAsync ( " vector-store-id " , metadata : metadata ) ;
Debug . Log ( vectorStore ) ; حذف متجر متجه.
var api = new OpenAIClient ( ) ;
var isDeleted = await api . VectorStoresEndpoint . DeleteVectorStoreAsync ( " vector-store-id " ) ;
Assert . IsTrue ( isDeleted ) ; تمثل ملفات متجر المتجهات الملفات داخل متجر متجه.
إرجاع قائمة ملفات متجر المتجهات.
var api = new OpenAIClient ( ) ;
var files = await api . VectorStoresEndpoint . ListVectorStoreFilesAsync ( " vector-store-id " ) ;
foreach ( var file in vectorStoreFiles . Items )
{
Debug . Log ( file ) ;
} قم بإنشاء ملف متجر متجه عن طريق إرفاق ملف بمتجر متجه.
var api = new OpenAIClient ( ) ;
var file = await api . VectorStoresEndpoint . CreateVectorStoreFileAsync ( " vector-store-id " , " file-id " , new ChunkingStrategy ( ChunkingStrategyType . Static ) ) ;
Debug . Log ( file ) ; يسترجع ملف متجر المتجهات.
var api = new OpenAIClient ( ) ;
var file = await api . VectorStoresEndpoint . GetVectorStoreFileAsync ( " vector-store-id " , " vector-store-file-id " ) ;
Debug . Log ( file ) ; حذف ملف متجر المتجهات. سيؤدي ذلك إلى إزالة الملف من متجر المتجهات ولكن لن يتم حذف الملف نفسه. لحذف الملف ، استخدم نقطة نهاية ملف حذف.
var api = new OpenAIClient ( ) ;
var isDeleted = await api . VectorStoresEndpoint . DeleteVectorStoreFileAsync ( " vector-store-id " , vectorStoreFile ) ;
Assert . IsTrue ( isDeleted ) ; تمثل ملفات متجر المتجهات الملفات داخل متجر متجه.
إنشاء دفعة ملف متجه متجر.
var api = new OpenAIClient ( ) ;
var files = new List < string > { " file_id_1 " , " file_id_2 " } ;
var vectorStoreFileBatch = await api . VectorStoresEndpoint . CreateVectorStoreFileBatchAsync ( " vector-store-id " , files ) ;
Debug . Log ( vectorStoreFileBatch ) ; يسترجع دفعة ملف متجه متجر.
var api = new OpenAIClient ( ) ;
var vectorStoreFileBatch = await api . VectorStoresEndpoint . GetVectorStoreFileBatchAsync ( " vector-store-id " , " vector-store-file-batch-id " ) ;
// you can also use convenience methods!
vectorStoreFileBatch = await vectorStoreFileBatch . UpdateAsync ( ) ;
vectorStoreFileBatch = await vectorStoreFileBatch . WaitForStatusChangeAsync ( ) ; إرجاع قائمة ملفات متجر المتجهات في دفعة.
var api = new OpenAIClient ( ) ;
var files = await api . VectorStoresEndpoint . ListVectorStoreBatchFilesAsync ( " vector-store-id " , " vector-store-file-batch-id " ) ;
foreach ( var file in files . Items )
{
Debug . Log ( file ) ;
} إلغاء دفعة ملف متجه متجر. هذه المحاولات لإلغاء معالجة الملفات في هذه الدفعة في أقرب وقت ممكن.
var api = new OpenAIClient ( ) ;
var isCancelled = await api . VectorStoresEndpoint . CancelVectorStoreFileBatchAsync ( " vector-store-id " , " vector-store-file-batch-id " ) ;بالنظر إلى محادثة الدردشة ، سيعود النموذج استجابة لإكمال الدردشة.
يتم الوصول إلى واجهة برمجة تطبيقات الدردشة عبر OpenAIClient.ChatEndpoint
يخلق إكمال رسالة الدردشة
var api = new OpenAIClient ( ) ;
var messages = new List < Message >
{
new Message ( Role . System , " You are a helpful assistant. " ) ,
new Message ( Role . User , " Who won the world series in 2020? " ) ,
new Message ( Role . Assistant , " The Los Angeles Dodgers won the World Series in 2020. " ) ,
new Message ( Role . User , " Where was it played? " ) ,
} ;
var chatRequest = new ChatRequest ( messages , Model . GPT4o ) ;
var response = await api . ChatEndpoint . GetCompletionAsync ( chatRequest ) ;
var choice = response . FirstChoice ;
Debug . Log ( $" [ { choice . Index } ] { choice . Message . Role } : { choice . Message } | Finish Reason: { choice . FinishReason } " ) ; var api = new OpenAIClient ( ) ;
var messages = new List < Message >
{
new Message ( Role . System , " You are a helpful assistant. " ) ,
new Message ( Role . User , " Who won the world series in 2020? " ) ,
new Message ( Role . Assistant , " The Los Angeles Dodgers won the World Series in 2020. " ) ,
new Message ( Role . User , " Where was it played? " ) ,
} ;
var chatRequest = new ChatRequest ( messages ) ;
var response = await api . ChatEndpoint . StreamCompletionAsync ( chatRequest , async partialResponse =>
{
Debug . Log ( partialResponse . FirstChoice . Delta . ToString ( ) ) ;
await Task . CompletedTask ;
} ) ;
var choice = response . FirstChoice ;
Debug . Log ( $" [ { choice . Index } ] { choice . Message . Role } : { choice . Message } | Finish Reason: { choice . FinishReason } " ) ; var api = new OpenAIClient ( ) ;
var messages = new List < Message >
{
new ( Role . System , " You are a helpful weather assistant. Always prompt the user for their location. " ) ,
new Message ( Role . User , " What's the weather like today? " ) ,
} ;
foreach ( var message in messages )
{
Debug . Log ( $" { message . Role } : { message } " ) ;
}
// Define the tools that the assistant is able to use:
// 1. Get a list of all the static methods decorated with FunctionAttribute
var tools = Tool . GetAllAvailableTools ( includeDefaults : false , forceUpdate : true , clearCache : true ) ;
// 2. Define a custom list of tools:
var tools = new List < Tool >
{
Tool . GetOrCreateTool ( objectInstance , " TheNameOfTheMethodToCall " ) ,
Tool . FromFunc ( " a_custom_name_for_your_function " , ( ) => { /* Some logic to run */ } )
} ;
var chatRequest = new ChatRequest ( messages , tools : tools , toolChoice : " auto " ) ;
var response = await api . ChatEndpoint . GetCompletionAsync ( chatRequest ) ;
messages . Add ( response . FirstChoice . Message ) ;
Debug . Log ( $" { response . FirstChoice . Message . Role } : { response . FirstChoice } | Finish Reason: { response . FirstChoice . FinishReason } " ) ;
var locationMessage = new Message ( Role . User , " I'm in Glasgow, Scotland " ) ;
messages . Add ( locationMessage ) ;
Debug . Log ( $" { locationMessage . Role } : { locationMessage . Content } " ) ;
chatRequest = new ChatRequest ( messages , tools : tools , toolChoice : " auto " ) ;
response = await api . ChatEndpoint . GetCompletionAsync ( chatRequest ) ;
messages . Add ( response . FirstChoice . Message ) ;
if ( response . FirstChoice . FinishReason == " stop " )
{
Debug . Log ( $" { response . FirstChoice . Message . Role } : { response . FirstChoice } | Finish Reason: { response . FirstChoice . FinishReason } " ) ;
var unitMessage = new Message ( Role . User , " Fahrenheit " ) ;
messages . Add ( unitMessage ) ;
Debug . Log ( $" { unitMessage . Role } : { unitMessage . Content } " ) ;
chatRequest = new ChatRequest ( messages , tools : tools , toolChoice : " auto " ) ;
response = await api . ChatEndpoint . GetCompletionAsync ( chatRequest ) ;
}
// iterate over all tool calls and invoke them
foreach ( var toolCall in response . FirstChoice . Message . ToolCalls )
{
Debug . Log ( $" { response . FirstChoice . Message . Role } : { toolCall . Function . Name } | Finish Reason: { response . FirstChoice . FinishReason } " ) ;
Debug . Log ( $" { toolCall . Function . Arguments } " ) ;
// Invokes function to get a generic json result to return for tool call.
var functionResult = await toolCall . InvokeFunctionAsync ( ) ;
// If you know the return type and do additional processing you can use generic overload
var functionResult = await toolCall . InvokeFunctionAsync < string > ( ) ;
messages . Add ( new Message ( toolCall , functionResult ) ) ;
Debug . Log ( $" { Role . Tool } : { functionResult } " ) ;
}
// System: You are a helpful weather assistant.
// User: What's the weather like today?
// Assistant: Sure, may I know your current location? | Finish Reason: stop
// User: I'm in Glasgow, Scotland
// Assistant: GetCurrentWeather | Finish Reason: tool_calls
// {
// "location": "Glasgow, Scotland",
// "unit": "celsius"
// }
// Tool: The current weather in Glasgow, Scotland is 39°C. تحذير
ميزة بيتا. واجهة برمجة التطبيقات (API) مع مراعاة التغييرات.
var api = new OpenAIClient ( ) ;
var messages = new List < Message >
{
new Message ( Role . System , " You are a helpful assistant. " ) ,
new Message ( Role . User , new List < Content >
{
" What's in this image? " ,
new ImageUrl ( " https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg " , ImageDetail . Low )
} )
} ;
var chatRequest = new ChatRequest ( messages , model : Model . GPT4o ) ;
var response = await api . ChatEndpoint . GetCompletionAsync ( chatRequest ) ;
Debug . Log ( $" { response . FirstChoice . Message . Role } : { response . FirstChoice . Message . Content } | Finish Reason: { response . FirstChoice . FinishDetails } " ) ; يمكنك حتى المرور في Texture2D !
var api = new OpenAIClient ( ) ;
var messages = new List < Message >
{
new Message ( Role . System , " You are a helpful assistant. " ) ,
new Message ( Role . User , new List < Content >
{
" What's in this image? " ,
texture
} )
} ;
var chatRequest = new ChatRequest ( messages , model : Model . GPT4o ) ;
var result = await api . ChatEndpoint . GetCompletionAsync ( chatRequest ) ;
Debug . Log ( $" { result . FirstChoice . Message . Role } : { result . FirstChoice } | Finish Reason: { result . FirstChoice . FinishDetails } " ) ; var api = new OpenAIClient ( ) ;
var messages = new List < Message >
{
new Message ( Role . System , " You are a helpful assistant. " ) ,
new Message ( Role . User , " Is a golden retriever a good family dog? " )
} ;
var chatRequest = new ChatRequest ( messages , Model . GPT4oAudio , audioConfig : Voice . Alloy ) ;
var response = await api . ChatEndpoint . GetCompletionAsync ( chatRequest ) ;
Debug . Log ( $" { response . FirstChoice . Message . Role } : { response . FirstChoice } | Finish Reason: { response . FirstChoice . FinishDetails } " ) ;
audioSource . PlayOneShot ( response . FirstChoice . Message . AudioOutput . AudioClip ) ; تطور وضع JSON. في حين أن كلاهما يضمن إنتاج JSON صالح ، إلا أن المخرجات المهيكلة فقط تضمن الالتزام بالمخطط.
مهم
finish_reason من الطول ، مما يشير إلى أن الجيل تجاوز max_tokens أو تجاوز المحادثة حد الرمز المميز. للحماية من هذا ، تحقق finish_reason قبل تحليل الرد.حدد أولاً بنية ردودك. سيتم استخدام هذه كمخططك. هذه هي الكائنات التي ستعمل عليها ، لذا تأكد من استخدام نماذج كائن JSON القياسية.
public class MathResponse
{
[ JsonProperty ( " steps " ) ]
public IReadOnlyList < MathStep > Steps { get ; private set ; }
[ JsonProperty ( " final_answer " ) ]
public string FinalAnswer { get ; private set ; }
}
public class MathStep
{
[ JsonProperty ( " explanation " ) ]
public string Explanation { get ; private set ; }
[ JsonProperty ( " output " ) ]
public string Output { get ; private set ; }
} للاستخدام ، ما عليك سوى تحديد نوع MathResponse كقيد عام عند طلب الانتهاء.
var api = new OpenAIClient ( ) ;
var messages = new List < Message >
{
new ( Role . System , " You are a helpful math tutor. Guide the user through the solution step by step. " ) ,
new ( Role . User , " how can I solve 8x + 7 = -23 " )
} ;
var chatRequest = new ChatRequest ( messages , model : " gpt-4o-2024-08-06 " ) ;
var ( mathResponse , chatResponse ) = await api . ChatEndpoint . GetCompletionAsync < MathResponse > ( chatRequest ) ;
for ( var i = 0 ; i < mathResponse . Steps . Count ; i ++ )
{
var step = mathResponse . Steps [ i ] ;
Debug . Log ( $" Step { i } : { step . Explanation } " ) ;
Debug . Log ( $" Result: { step . Output } " ) ;
}
Debug . Log ( $" Final Answer: { mathResponse . FinalAnswer } " ) ;
chatResponse . GetUsage ( ) ; مهم
finish_reason من الطول ، مما يشير إلى أن الجيل تجاوز max_tokens أو تجاوز المحادثة حد الرمز المميز. للحماية من هذا ، تحقق finish_reason قبل تحليل الرد. var messages = new List < Message >
{
new Message ( Role . System , " You are a helpful assistant designed to output JSON. " ) ,
new Message ( Role . User , " Who won the world series in 2020? " ) ,
} ;
var chatRequest = new ChatRequest ( messages , Model . GPT4o , responseFormat : ChatResponseFormat . Json ) ;
var response = await api . ChatEndpoint . GetCompletionAsync ( chatRequest ) ;
foreach ( var choice in response . Choices )
{
Debug . Log ( $" [ { choice . Index } ] { choice . Message . Role } : { choice } | Finish Reason: { choice . FinishReason } " ) ;
}
response . GetUsage ( ) ;يحول الصوت إلى نص.
يتم الوصول إلى واجهة برمجة تطبيقات الصوت عبر OpenAIClient.AudioEndpoint
يولد الصوت من نص الإدخال.
var api = new OpenAIClient ( ) ;
var request = new SpeechRequest ( " Hello world! " ) ;
var speechClip = await api . AudioEndpoint . GetSpeechAsync ( request ) ;
audioSource . PlayOneShot ( speechClip ) ;
Debug . Log ( speechClip ) ; قم بإنشاء صوت تم بثه من نص الإدخال.
var api = new OpenAIClient ( ) ;
var request = new SpeechRequest ( " Hello world! " , responseFormat : SpeechResponseFormat . PCM ) ;
var speechClip = await api . AudioEndpoint . GetSpeechAsync ( request , partialClip =>
{
audioSource . PlayOneShot ( partialClip ) ;
} ) ;
Debug . Log ( speechClip ) ; ملحوظة
الخروج من أي من المشاهد التجريبية لأفضل الممارسات حول كيفية التعامل مع التشغيل مع OnAudioFilterRead .
ينسخ الصوت إلى لغة الإدخال.
var api = new OpenAIClient ( ) ;
var request = new AudioTranscriptionRequest ( audioClip , language : " en " ) ;
var result = await api . AudioEndpoint . CreateTranscriptionAsync ( request ) ;
Debug . Log ( result ) ; يمكنك أيضًا الحصول على معلومات مفصلة باستخدام verbose_json للحصول على حبيبات الطابع الزمني:
var api = new OpenAIClient ( ) ;
using var request = new AudioTranscriptionRequest ( transcriptionAudio , responseFormat : AudioResponseFormat . Verbose_Json , timestampGranularity : TimestampGranularity . Word , temperature : 0.1f , language : " en " ) ;
var response = await api . AudioEndpoint . CreateTranscriptionTextAsync ( request ) ;
foreach ( var word in response . Words )
{
Debug . Log ( $" [ { word . Start } - { word . End } ] " { word . Word } " " ) ;
} يترجم الصوت إلى اللغة الإنجليزية.
var api = new OpenAIClient ( ) ;
var request = new AudioTranslationRequest ( audioClip ) ;
var result = await api . AudioEndpoint . CreateTranslationAsync ( request ) ;
Debug . Log ( result ) ;بالنظر إلى موجه و/أو صورة إدخال ، سيقوم النموذج بإنشاء صورة جديدة.
يتم الوصول إلى واجهة برمجة تطبيقات الصور عبر OpenAIClient.ImagesEndpoint
يخلق صورة تعطى موجه.
var api = new OpenAIClient ( ) ;
var request = new ImageGenerationRequest ( " A house riding a velociraptor " , Models . Model . DallE_3 ) ;
var imageResults = await api . ImagesEndPoint . GenerateImageAsync ( request ) ;
foreach ( var result in imageResults )
{
Debug . Log ( result . ToString ( ) ) ;
Assert . IsNotNull ( result . Texture ) ;
} ينشئ صورة تم تحريرها أو ممتدة مع إعطاء صورة أصلية ومطالبة.
var api = new OpenAIClient ( ) ;
var request = new ImageEditRequest ( Path . GetFullPath ( imageAssetPath ) , Path . GetFullPath ( maskAssetPath ) , " A sunlit indoor lounge area with a pool containing a flamingo " , size : ImageSize . Small ) ;
var imageResults = await api . ImagesEndPoint . CreateImageEditAsync ( request ) ;
foreach ( var result in imageResults )
{
Debug . Log ( result . ToString ( ) ) ;
Assert . IsNotNull ( result . Texture ) ;
} يخلق تباينًا في صورة معينة.
var api = new OpenAIClient ( ) ;
var request = new ImageVariationRequest ( imageTexture , size : ImageSize . Small ) ;
var imageResults = await api . ImagesEndPoint . CreateImageVariationAsync ( request ) ;
foreach ( var result in imageResults )
{
Debug . Log ( result . ToString ( ) ) ;
Assert . IsNotNull ( result . Texture ) ;
}بدلاً من ذلك ، يمكن أن تأخذ نقطة النهاية مباشرةً texture2d مع تمكين القراءة/الكتابة وتعيين الضغط على لا شيء.
var api = new OpenAIClient ( ) ;
var request = new ImageVariationRequest ( imageTexture , size : ImageSize . Small ) ;
var imageResults = await api . ImagesEndPoint . CreateImageVariationAsync ( request ) ;
foreach ( var result in imageResults )
{
Debug . Log ( result . ToString ( ) ) ;
Assert . IsNotNull ( result . Texture ) ;
}تُستخدم الملفات لتحميل المستندات التي يمكن استخدامها مع ميزات مثل الضبط الدقيق.
يتم الوصول إلى واجهة برمجة تطبيقات الملفات عبر OpenAIClient.FilesEndpoint
إرجاع قائمة الملفات التي تنتمي إلى منظمة المستخدم.
var api = new OpenAIClient ( ) ;
var fileList = await api . FilesEndpoint . ListFilesAsync ( ) ;
foreach ( var file in fileList )
{
Debug . Log ( $" { file . Id } -> { file . Object } : { file . FileName } | { file . Size } bytes " ) ;
} قم بتحميل ملف يمكن استخدامه عبر نقاط النهاية المختلفة. يمكن أن يصل حجم جميع الملفات التي تم تحميلها بواسطة مؤسسة واحدة إلى 100 جيجابايت.
يمكن أن يكون حجم الملفات الفردية بحد أقصى 512 ميغابايت. راجع دليل أدوات المساعدين لمعرفة المزيد حول أنواع الملفات المدعومة. يدعم واجهة برمجة تطبيقات الضبط فقط ملفات .jsonl.
var api = new OpenAIClient ( ) ;
var file = await api . FilesEndpoint . UploadFileAsync ( " path/to/your/file.jsonl " , FilePurpose . FineTune ) ;
Debug . Log ( file . Id ) ; حذف ملف.
var api = new OpenAIClient ( ) ;
var isDeleted = await api . FilesEndpoint . DeleteFileAsync ( fileId ) ;
Assert . IsTrue ( isDeleted ) ; إرجاع المعلومات حول ملف معين.
var api = new OpenAIClient ( ) ;
var file = await api . FilesEndpoint . GetFileInfoAsync ( fileId ) ;
Debug . Log ( $" { file . Id } -> { file . Object } : { file . FileName } | { file . Size } bytes " ) ; يقوم بتنزيل محتوى الملف إلى الدليل المحدد.
var api = new OpenAIClient ( ) ;
var downloadedFilePath = await api . FilesEndpoint . DownloadFileAsync ( fileId ) ;
Debug . Log ( downloadedFilePath ) ;
Assert . IsTrue ( File . Exists ( downloadedFilePath ) ) ;إدارة الوظائف الدقيقة لتكييف نموذج لبيانات التدريب الخاصة بك.
الدليل ذي الصلة: نماذج النقطة الدقيقة
يتم الوصول إلى واجهة برمجة تطبيقات الملفات عبر OpenAIClient.FineTuningEndpoint
ينشئ وظيفة تقوم بتشكيل نموذج محدد من مجموعة بيانات معينة.
يتضمن الاستجابة تفاصيل الوظيفة المتوفرة بما في ذلك حالة الوظيفة واسم النماذج التي تم ضبطها مرة واحدة.
var api = new OpenAIClient ( ) ;
var fileId = " file-abc123 " ;
var request = new CreateFineTuneRequest ( fileId ) ;
var job = await api . FineTuningEndpoint . CreateJobAsync ( Model . GPT3_5_Turbo , request ) ;
Debug . Log ( $" Started { job . Id } | Status: { job . Status } " ) ; قائمة وظائف المنظمات الخاصة بمؤسستك.
var api = new OpenAIClient ( ) ;
var jobList = await api . FineTuningEndpoint . ListJobsAsync ( ) ;
foreach ( var job in jobList . Items . OrderByDescending ( job => job . CreatedAt ) ) )
{
Debug . Log ( $" { job . Id } -> { job . CreatedAt } | { job . Status } " ) ;
} يحصل على معلومات حول وظيفة ضبطها.
var api = new OpenAIClient ( ) ;
var job = await api . FineTuningEndpoint . GetJobInfoAsync ( fineTuneJob ) ;
Debug . Log ( $" { job . Id } -> { job . CreatedAt } | { job . Status } " ) ; إلغاء وظيفة ضبطها على الفور.
var api = new OpenAIClient ( ) ;
var isCancelled = await api . FineTuningEndpoint . CancelFineTuneJobAsync ( fineTuneJob ) ;
Assert . IsTrue ( isCancelled ) ; احصل على تحديثات الحالة للحصول على وظيفة صقل.
var api = new OpenAIClient ( ) ;
var eventList = await api . FineTuningEndpoint . ListJobEventsAsync ( fineTuneJob ) ;
Debug . Log ( $" { fineTuneJob . Id } -> status: { fineTuneJob . Status } | event count: { eventList . Events . Count } " ) ;
foreach ( var @event in eventList . Items . OrderByDescending ( @event => @event . CreatedAt ) )
{
Debug . Log ( $" { @event . CreatedAt } [ { @event . Level } ] { @event . Message } " ) ;
}قم بإنشاء دفعات كبيرة من طلبات API للمعالجة غير المتزامنة. يعود API الدُفعات إلى إكمال في غضون 24 ساعة للحصول على خصم 50 ٪.
يتم الوصول إلى واجهة برمجة تطبيقات الدفعات عبر OpenAIClient.BatchesEndpoint
قائمة دفعات مؤسستك.
var api = new OpenAIClient ( ) ;
var batches = await api . BatchEndpoint . ListBatchesAsync ( ) ;
foreach ( var batch in listResponse . Items )
{
Debug . Log ( batch ) ;
} يقوم بإنشاء وتنفيذ دفعة من ملف الطلبات المحمّلة
var api = new OpenAIClient ( ) ;
var batchRequest = new CreateBatchRequest ( " file-id " , Endpoint . ChatCompletions ) ;
var batch = await api . BatchEndpoint . CreateBatchAsync ( batchRequest ) ; يسترجع دفعة.
var api = new OpenAIClient ( ) ;
var batch = await api . BatchEndpoint . RetrieveBatchAsync ( " batch-id " ) ;
// you can also use convenience methods!
batch = await batch . UpdateAsync ( ) ;
batch = await batch . WaitForStatusChangeAsync ( ) ; يلغي دفعة داخل progress. ستكون الدفعة في إلغاء الحالة لمدة تصل إلى 10 دقائق ، قبل التغيير إلى الإلغاء ، حيث سيكون لها نتائج جزئية (إن وجدت) في ملف الإخراج.
var api = new OpenAIClient ( ) ;
var isCancelled = await api . BatchEndpoint . CancelBatchAsync ( batch ) ;
Assert . IsTrue ( isCancelled ) ;احصل على تمثيل متجه لمدخلات معينة يمكن استهلاكها بسهولة بواسطة نماذج التعلم الآلي والخوارزميات.
دليل ذي صلة: التضمينات
يتم الوصول إلى API OpenAIClient.EmbeddingsEndpoint
يخلق ناقل تضمين يمثل نص الإدخال.
var api = new OpenAIClient ( ) ;
var response = await api . EmbeddingsEndpoint . CreateEmbeddingAsync ( " The food was delicious and the waiter... " , Models . Embedding_Ada_002 ) ;
Debug . Log ( response ) ;بالنظر إلى نص الإدخال ، يتم الإخراج إذا صنف النموذج على أنه ينتهك سياسة محتوى Openai.
الدليل ذي الصلة: التعتيم
يمكن الوصول إلى واجهة برمجة تطبيقات التعتيم عبر OpenAIClient.ModerationsEndpoint
يصنف ما إذا كان النص ينتهك سياسة محتوى Openai.
var api = new OpenAIClient ( ) ;
var isViolation = await api . ModerationsEndpoint . GetModerationAsync ( " I want to kill them. " ) ;
Assert . IsTrue ( isViolation ) ;بالإضافة إلى ذلك ، يمكنك أيضًا الحصول على عشرات مدخلات معينة.
var api = new OpenAIClient ( ) ;
var response = await api . ModerationsEndpoint . CreateModerationAsync ( new ModerationsRequest ( " I love you " ) ) ;
Assert . IsNotNull ( response ) ;
Debug . Log ( response . Results ? [ 0 ] ? . Scores ? . ToString ( ) ) ;