مكتبة عميل C# .NET بسيطة لاستخدام Openai على الرغم من واجهة برمجة التطبيقات الخاصة بهم. تم تطويره بشكل مستقل ، هذه ليست مكتبة رسمية وأنا لا تابعة لـ Openai. مطلوب حساب API Openai.
شوكة في الأصل من Openai-api-dotnet. المزيد من السياق على مدونة روجر بينكومب.
قم بتثبيت Package OpenAI-DotNet من Nuget. إليك كيف عبر سطر الأوامر:
PowerShell:
Install-Package OpenAI-DotNet
dotnet:
dotnet add package OpenAI-DotNet
هل تتطلع إلى استخدام Openai-Dotnet في محرك لعبة الوحدة؟ تحقق من حزمة الوحدة الخاصة بنا على openupm:
تحقق من مستندات API الجديدة لدينا!
https://rageagainstthepixel.github.io/openai-dotnet
هناك 3 طرق لتوفير مفاتيح واجهة برمجة التطبيقات الخاصة بك ، حسب الأسبقية:
تحذير
لقد أوصينا باستخدام متغيرات البيئة لتحميل مفتاح API بدلاً من ترميزه الثابت في المصدر الخاص بك. لا ينصح باستخدام هذه الطريقة في الإنتاج ، ولكن فقط لقبول بيانات اعتماد المستخدم والاختبار المحلي وسيناريوهات البدء السريع.
تحذير
لقد أوصينا باستخدام متغيرات البيئة لتحميل مفتاح API بدلاً من ترميزه الثابت في المصدر الخاص بك. لا ينصح باستخدام هذه الطريقة في الإنتاج ، ولكن فقط لقبول بيانات اعتماد المستخدم والاختبار المحلي وسيناريوهات البدء السريع.
using var api = new OpenAIClient ( " sk-apiKey " ) ; أو إنشاء كائن OpenAIAuthentication يدويًا
using var api = new OpenAIClient ( new OpenAIAuthentication ( " sk-apiKey " , " org-yourOrganizationId " , " proj_yourProjectId " ) ) ; محاولات تحميل مفاتيح 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 في الدليل المحدد: using var api = new OpenAIClient ( OpenAIAuthentication . LoadFromDirectory ( " path/to/your/directory " ) ) ;.openai طالما أنه يتوافق مع تنسيق JSON: using var api = new OpenAIClient ( OpenAIAuthentication . LoadFromPath ( " path/to/your/file.json " ) ) ; استخدم متغيرات بيئة نظامك ، حدد مفتاح API ومؤسسة لاستخدامها.
OPENAI_API_KEY لمفتاح API الخاص بك.OPENAI_ORGANIZATION_ID لتحديد مؤسسة.OPENAI_PROJECT_ID لتحديد مشروع. using var api = new OpenAIClient ( OpenAIAuthentication . LoadFromEnv ( ) ) ; ينفذ OpenAIClient IDisposable دورة حياة الموارد التي تستخدمها ، بما في ذلك HttpClient . عند تهيئة OpenAIClient ، سيقوم بإنشاء مثيل HttpClient داخلي إذا لم يتم توفير واحدة. يتم التخلص من هذا HttpClient الداخلي عندما يتم التخلص من OpenAIClient . إذا قمت بتقديم مثيل HttpClient خارجي إلى OpenAIClient ، فأنت مسؤول عن إدارة التخلص منه.
OpenAIClient بإنشاء HttpClient الخاص به ، فسوف يعتني أيضًا بالتخلص منه عند التخلص من OpenAIClient .HttpClient خارجية إلى OpenAIClient ، فلن يتم التخلص منها بواسطة OpenAIClient . يجب عليك إدارة التخلص من HttpClient بنفسك. يرجى التأكد من التخلص بشكل مناسب من OpenAIClient لإصدار الموارد في الوقت المناسب ومنع أي تسربات محتملة للذاكرة أو الموارد في التطبيق الخاص بك.
الاستخدام النموذجي مع HttpClient داخلي:
using var api = new OpenAIClient ( ) ; HttpClient مخصصة (والتي يجب أن تتخلص من نفسك):
using var customHttpClient = new HttpClient ( ) ;
// set custom http client properties here
var api = new OpenAIClient ( client : customHttpClient ) ;يمكنك أيضًا اختيار استخدام عمليات نشر 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. لإعداد العميل لاستخدام النشر الخاص بك ، ستحتاج إلى تمريرها في OpenAIClientSettings إلى مُنشئ العميل.
var auth = new OpenAIAuthentication ( " sk-apiKey " ) ;
var settings = new OpenAIClientSettings ( resourceName : " your-resource-name " , deploymentId : " deployment-id " , apiVersion : " api-version " ) ;
using var api = new OpenAIClient ( auth , settings ) ; قم بالتوثيق مع MSAL كالمعتاد واحصل على رمز الوصول ، ثم استخدم رمز الوصول عند إنشاء OpenAIAuthentication . ثم تأكد من تعيين useazureActivediveIrectory إلى True عند إنشاء OpenAIClientSettings .
البرنامج التعليمي: تطبيق سطح المكتب الذي يدعو ويب واجهات برمجة التطبيقات: الحصول على رمز رمزي
// get your access token using any of the MSAL methods
var accessToken = result . AccessToken ;
var auth = new OpenAIAuthentication ( accessToken ) ;
var settings = new OpenAIClientSettings ( resourceName : " your-resource " , deploymentId : " deployment-id " , apiVersion : " api-version " , useActiveDirectoryAuthentication : true ) ;
using var api = new OpenAIClient ( auth , settings ) ;قد يؤدي استخدام حزم Openai-DotNet أو Com.Openai.Unity مباشرة في تطبيقك الأمامي إلى كشف مفاتيح واجهة برمجة التطبيقات والمعلومات الحساسة الأخرى. للتخفيف من هذا الخطر ، يوصى بإعداد واجهة برمجة تطبيقات وسيطة تقدم طلبات إلى Openai نيابة عن تطبيقك الأمامي. يمكن استخدام هذه المكتبة لكل من تكوينات المضيف الأمامي والوسيط ، مما يضمن التواصل الآمن مع API Openai.
في المثال الأمامي ، ستحتاج إلى مصادقة المستخدمين بشكل آمن باستخدام مزود OAuth المفضل لديك. بمجرد مصادقة المستخدم ، قم بتبادل رمز Auth Auth الخاص بك مع مفتاح API الخاص بك على الواجهة الخلفية.
اتبع هذه الخطوات:
OpenAIAuthentication جديد وقم بالمرور في الرمز المخصص مع البادئة sess- .OpenAIClientSettings جديد وحدد المجال حيث يوجد واجهة برمجة التطبيقات المتوسطة.auth الجديدة settings الخاصة بك إلى مُنشئ OpenAIClient عند إنشاء مثيل العميل.إليك مثال على كيفية إعداد الواجهة الأمامية:
var authToken = await LoginAsync ( ) ;
var auth = new OpenAIAuthentication ( $" sess- { authToken } " ) ;
var settings = new OpenAIClientSettings ( domain : " api.your-custom-domain.com " ) ;
using 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
يسرد النماذج المتاحة حاليًا ، ويوفر معلومات أساسية عن كل واحدة مثل المالك والتوافر.
using var api = new OpenAIClient ( ) ;
var models = await api . ModelsEndpoint . GetModelsAsync ( ) ;
foreach ( var model in models )
{
Console . WriteLine ( model . ToString ( ) ) ;
} يسترجع مثيل نموذج ، ويوفر معلومات أساسية حول النموذج مثل المالك والأذونات.
using var api = new OpenAIClient ( ) ;
var model = await api . ModelsEndpoint . GetModelDetailsAsync ( " gpt-4o " ) ;
Console . WriteLine ( model . ToString ( ) ) ; حذف نموذج دقيق. يجب أن يكون لديك دور المالك في مؤسستك.
using var api = new OpenAIClient ( ) ;
var isDeleted = await api . ModelsEndpoint . DeleteFineTuneModelAsync ( " your-fine-tuned-model " ) ;
Assert . IsTrue ( isDeleted ) ;تحذير
ميزة بيتا. واجهة برمجة التطبيقات (API) مع مراعاة التغييرات.
تمكنك واجهة برمجة التطبيقات في الوقت الفعلي من بناء تجارب محادثة منخفضة البشر. وهو يدعم حاليًا النصوص والصوت كإدخال ومخرجات ، وكذلك استدعاء الوظائف.
يتم الوصول إلى API المساعدين عبر OpenAIClient.RealtimeEndpoint
فيما يلي مثال بسيط على كيفية إنشاء جلسة في الوقت الفعلي وإرسال واستقبال الرسائل من النموذج.
using 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 :
Console . WriteLine ( 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! " ) ) ;
Console . WriteLine ( serverEvent . ToJsonString ( ) ) ;
serverEvent = await session . SendAsync ( new CreateResponseRequest ( ) ) ;
Console . WriteLine ( 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 أو IAsyncEnumerable<T> سيتم إكمالها عند إغلاق الجلسة أو عند تشغيل رمز الإلغاء. من الناحية المثالية ، يجب استدعاء هذه الطريقة مرة واحدة وركض طوال فترة الجلسة.
ملحوظة
يمكنك أيضًا الحصول على عوائد IClientEvent أيضًا باستخدام واجهة IRealtimeEvent بدلاً من IServerEvent .
await foreach ( var @event in session . ReceiveUpdatesAsync < IServerEvent > ( cts . Token ) )
{
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
إرجاع قائمة المساعدين.
using var api = new OpenAIClient ( ) ;
var assistantsList = await api . AssistantsEndpoint . ListAssistantsAsync ( ) ;
foreach ( var assistant in assistantsList . Items )
{
Console . WriteLine ( $" { assistant } -> { assistant . CreatedAt } " ) ;
} إنشاء مساعد مع نموذج وتعليمات.
using var api = new OpenAIClient ( ) ;
var request = new CreateAssistantRequest ( Model . GPT4o ) ;
var assistant = await api . AssistantsEndpoint . CreateAssistantAsync ( request ) ; يسترجع مساعد.
using var api = new OpenAIClient ( ) ;
var assistant = await api . AssistantsEndpoint . RetrieveAssistantAsync ( " assistant-id " ) ;
Console . WriteLine ( $" { assistant } -> { assistant . CreatedAt } " ) ; يعدل مساعد.
using 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 ) ; حذف مساعد.
using 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
إنشاء موضوع.
using var api = new OpenAIClient ( ) ;
var thread = await api . ThreadsEndpoint . CreateThreadAsync ( ) ;
Console . WriteLine ( $" Create thread { thread . Id } -> { thread . CreatedAt } " ) ; قم بإنشاء موضوع وقم بتشغيله في طلب واحد.
انظر أيضًا: تشغيل الخيط
using 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 ) ;
Console . WriteLine ( $" Created thread and run: { run . ThreadId } -> { run . Id } -> { run . CreatedAt } " ) ; قم بإنشاء موضوع وقم بتشغيله في طلب واحد أثناء دفق الأحداث.
using 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 )
{
Console . WriteLine ( $" Tool Output: { toolOutput } " ) ;
}
await runResponse . SubmitToolOutputsAsync ( toolOutputs , StreamEventHandler ) ;
}
break ;
default :
Console . WriteLine ( 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 ( ) )
{
Console . WriteLine ( $" { response . Role } : { response . PrintContent ( ) } " ) ;
} يسترجع موضوع.
using 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 ( ) ;
Console . WriteLine ( $" Retrieve thread { thread . Id } -> { thread . CreatedAt } " ) ; يعدل موضوع.
ملاحظة: يمكن تعديل البيانات الوصفية فقط.
using 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 ) ;
Console . WriteLine ( $" Modify thread { thread . Id } -> { thread . Metadata [ " key " ] } " ) ; حذف موضوع.
using 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 ) ; إنشاء رسائل داخل المواضيع.
إرجاع قائمة الرسائل لخيط معين.
using 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 )
{
Console . WriteLine ( $" { message . Id } : { message . Role } : { message . PrintContent ( ) } " ) ;
} إنشاء رسالة.
using 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! " ) ;
Console . WriteLine ( $" { message . Id } : { message . Role } : { message . PrintContent ( ) } " ) ; استرداد رسالة.
using 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 ( ) ;
Console . WriteLine ( $" { message . Id } : { message . Role } : { message . PrintContent ( ) } " ) ; تعديل رسالة.
ملاحظة: يمكن تعديل بيانات تعريف الرسالة فقط.
using 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 ) ;
Console . WriteLine ( $" Modify message metadata: { message . Id } -> { message . Metadata [ " key " ] } " ) ; يمثل تشغيل تنفيذ على موضوع.
إرجاع قائمة من عمليات التشغيل التي تنتمي إلى موضوع.
using 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 )
{
Console . WriteLine ( $" [ { run . Id } ] { run . Status } | { run . CreatedAt } " ) ;
} إنشاء تشغيل.
using 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 ) ;
Console . WriteLine ( $" [ { run . Id } ] { run . Status } | { run . CreatedAt } " ) ; إنشاء تشغيل ودفق الأحداث.
using 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 =>
{
Console . WriteLine ( streamEvent . ToJsonString ( ) ) ;
await Task . CompletedTask ;
} ) ;
var messages = await thread . ListMessagesAsync ( ) ;
foreach ( var response in messages . Items . Reverse ( ) )
{
Console . WriteLine ( $" { response . Role } : { response . PrintContent ( ) } " ) ;
} يسترجع الجري.
using 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 ( ) ;
Console . WriteLine ( $" [ { run . Id } ] { run . Status } | { run . CreatedAt } " ) ; يعدل التشغيل.
ملاحظة: يمكن تعديل البيانات الوصفية فقط.
using 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 ) ;
Console . WriteLine ( $" Modify run { run . Id } -> { run . Metadata [ " key " ] } " ) ; عندما يكون للتشغيل الحالة: requires_action required_action.type submit_tool_outputs ، يمكن استخدام نقطة النهاية هذه لإرسال المخرجات من مكالمات الأداة بمجرد اكتمالها جميعًا. يجب تقديم جميع المخرجات في طلب واحد.
ملحوظة
انظر إنشاء مؤشر ترابط وتشغيل مثال على كيفية دفق أحداث إخراج الأداة.
using 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 )
{
Console . WriteLine ( $" 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 ) )
{
Console . WriteLine ( $" { message . Role } : { message . PrintContent ( ) } " ) ;
} المخرجات المهيكلة هي تطور وضع JSON. في حين أن كلاهما يضمن إنتاج JSON صالح ، إلا أن المخرجات المهيكلة فقط تضمن الالتزام بالمخطط.
مهم
finish_reason من الطول ، مما يشير إلى أن الجيل تجاوز max_tokens أو تجاوز المحادثة حد الرمز المميز. للحماية من هذا ، تحقق finish_reason قبل تحليل الرد.حدد أولاً بنية ردودك. سيتم استخدام هذه كمخططك. هذه هي الكائنات التي ستعمل عليها ، لذا تأكد من استخدام نماذج كائن JSON القياسية.
public class MathResponse
{
[ JsonInclude ]
[ JsonPropertyName ( " steps " ) ]
public IReadOnlyList < MathStep > Steps { get ; private set ; }
[ JsonInclude ]
[ JsonPropertyName ( " final_answer " ) ]
public string FinalAnswer { get ; private set ; }
}
public class MathStep
{
[ JsonInclude ]
[ JsonPropertyName ( " explanation " ) ]
public string Explanation { get ; private set ; }
[ JsonInclude ]
[ JsonPropertyName ( " output " ) ]
public string Output { get ; private set ; }
} للاستخدام ، ما عليك سوى تحديد نوع MathResponse كقيد عام في إما CreateAssistantAsync أو CreateRunAsync أو CreateThreadAndRunAsync .
using 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 )
{
Console . WriteLine ( @event . ToJsonString ( ) ) ;
break ;
}
var mathResponse = message . FromSchema < MathResponse > ( ) ;
for ( var i = 0 ; i < mathResponse . Steps . Count ; i ++ )
{
var step = mathResponse . Steps [ i ] ;
Console . WriteLine ( $" Step { i } : { step . Explanation } " ) ;
Console . WriteLine ( $" Result: { step . Output } " ) ;
}
Console . WriteLine ( $" Final Answer: { mathResponse . FinalAnswer } " ) ;
break ;
default :
Console . WriteLine ( @event . ToJsonString ( ) ) ;
break ;
}
}
catch ( Exception e )
{
Console . WriteLine ( 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 ( ) ;
Console . WriteLine ( $" 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 ) )
{
Console . WriteLine ( $" { response . Role } : { response . PrintContent ( ) } " ) ;
}
}
finally
{
await assistant . DeleteAsync ( deleteToolResources : thread == null ) ;
if ( thread != null )
{
var isDeleted = await thread . DeleteAsync ( deleteToolResources : true ) ;
}
}يمكنك أيضًا إنشاء سلسلة JSON Schema JSON يدويًا أيضًا ، لكنك ستكون مسؤولاً عن إلغاء توزيع بيانات الاستجابة الخاصة بك:
using 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 =>
{
Console . WriteLine ( @event . ToJsonString ( ) ) ;
await Task . CompletedTask ;
} ) ;
thread = await run . GetThreadAsync ( ) ;
run = await run . WaitForStatusChangeAsync ( ) ;
Console . WriteLine ( $" Created thread and run: { run . ThreadId } -> { run . Id } -> { run . CreatedAt } " ) ;
var messages = await thread . ListMessagesAsync ( ) ;
foreach ( var response in messages . Items )
{
Console . WriteLine ( $" { response . Role } : { response . PrintContent ( ) } " ) ;
}
}
finally
{
await assistant . DeleteAsync ( deleteToolResources : thread == null ) ;
if ( thread != null )
{
var isDeleted = await thread . DeleteAsync ( deleteToolResources : true ) ;
Assert . IsTrue ( isDeleted ) ;
}
} إرجاع قائمة خطوات التشغيل التي تنتمي إلى تشغيل.
using 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 )
{
Console . WriteLine ( $" [ { runStep . Id } ] { runStep . Status } { runStep . CreatedAt } -> { runStep . ExpiresAt } " ) ;
} يسترجع خطوة التشغيل.
using 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 ( ) ;
Console . WriteLine ( $" [ { runStep . Id } ] { runStep . Status } { runStep . CreatedAt } -> { runStep . ExpiresAt } " ) ; يلغي تشغيل in_progress .
using 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
إرجاع قائمة متاجر المتجهات.
using var api = new OpenAIClient ( ) ;
var vectorStores = await api . VectorStoresEndpoint . ListVectorStoresAsync ( ) ;
foreach ( var vectorStore in vectorStores . Items )
{
Console . WriteLine ( vectorStore ) ;
} إنشاء متجر ناقلات.
using var api = new OpenAIClient ( ) ;
var createVectorStoreRequest = new CreateVectorStoreRequest ( " test-vector-store " ) ;
var vectorStore = await api . VectorStoresEndpoint . CreateVectorStoreAsync ( createVectorStoreRequest ) ;
Console . WriteLine ( vectorStore ) ; يسترجع متجر متجه.
using var api = new OpenAIClient ( ) ;
var vectorStore = await api . VectorStoresEndpoint . GetVectorStoreAsync ( " vector-store-id " ) ;
Console . WriteLine ( vectorStore ) ; يعدل متجر المتجهات.
using var api = new OpenAIClient ( ) ;
var metadata = new Dictionary < string , object > { { " Test " , DateTime . UtcNow } } ;
var vectorStore = await api . VectorStoresEndpoint . ModifyVectorStoreAsync ( " vector-store-id " , metadata : metadata ) ;
Console . WriteLine ( vectorStore ) ; حذف متجر متجه.
using var api = new OpenAIClient ( ) ;
var isDeleted = await api . VectorStoresEndpoint . DeleteVectorStoreAsync ( " vector-store-id " ) ;
Assert . IsTrue ( isDeleted ) ; تمثل ملفات متجر المتجهات الملفات داخل متجر متجه.
إرجاع قائمة ملفات متجر المتجهات.
using var api = new OpenAIClient ( ) ;
var files = await api . VectorStoresEndpoint . ListVectorStoreFilesAsync ( " vector-store-id " ) ;
foreach ( var file in vectorStoreFiles . Items )
{
Console . WriteLine ( file ) ;
} قم بإنشاء ملف متجر متجه عن طريق إرفاق ملف بمتجر متجه.
using var api = new OpenAIClient ( ) ;
var file = await api . VectorStoresEndpoint . CreateVectorStoreFileAsync ( " vector-store-id " , " file-id " , new ChunkingStrategy ( ChunkingStrategyType . Static ) ) ;
Console . WriteLine ( file ) ; يسترجع ملف متجر المتجهات.
using var api = new OpenAIClient ( ) ;
var file = await api . VectorStoresEndpoint . GetVectorStoreFileAsync ( " vector-store-id " , " vector-store-file-id " ) ;
Console . WriteLine ( file ) ; حذف ملف متجر المتجهات. سيؤدي ذلك إلى إزالة الملف من متجر المتجهات ولكن لن يتم حذف الملف نفسه. لحذف الملف ، استخدم نقطة نهاية ملف حذف.
using var api = new OpenAIClient ( ) ;
var isDeleted = await api . VectorStoresEndpoint . DeleteVectorStoreFileAsync ( " vector-store-id " , vectorStoreFile ) ;
Assert . IsTrue ( isDeleted ) ; تمثل ملفات متجر المتجهات الملفات داخل متجر متجه.
إنشاء دفعة ملف متجه متجر.
using 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 ) ;
Console . WriteLine ( vectorStoreFileBatch ) ; يسترجع دفعة ملف متجه متجر.
using 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 ( ) ; إرجاع قائمة ملفات متجر المتجهات في دفعة.
using var api = new OpenAIClient ( ) ;
var files = await api . VectorStoresEndpoint . ListVectorStoreBatchFilesAsync ( " vector-store-id " , " vector-store-file-batch-id " ) ;
foreach ( var file in files . Items )
{
Console . WriteLine ( file ) ;
} إلغاء دفعة ملف متجه متجر. هذه المحاولات لإلغاء معالجة الملفات في هذه الدفعة في أقرب وقت ممكن.
using var api = new OpenAIClient ( ) ;
var isCancelled = await api . VectorStoresEndpoint . CancelVectorStoreFileBatchAsync ( " vector-store-id " , " vector-store-file-batch-id " ) ;بالنظر إلى محادثة الدردشة ، سيعود النموذج استجابة لإكمال الدردشة.
يتم الوصول إلى واجهة برمجة تطبيقات الدردشة عبر OpenAIClient.ChatEndpoint
يخلق إكمال رسالة الدردشة
using 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 ;
Console . WriteLine ( $" [ { choice . Index } ] { choice . Message . Role } : { choice . Message } | Finish Reason: { choice . FinishReason } " ) ; using 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 =>
{
Console . Write ( partialResponse . FirstChoice . Delta . ToString ( ) ) ;
await Task . CompletedTask ;
} ) ;
var choice = response . FirstChoice ;
Console . WriteLine ( $" [ { choice . Index } ] { choice . Message . Role } : { choice . Message } | Finish Reason: { choice . FinishReason } " ) ; أو إذا كنت تستخدم IAsyncEnumerable{T} (c# 8.0+)
using 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 cumulativeDelta = string . Empty ;
var chatRequest = new ChatRequest ( messages ) ;
await foreach ( var partialResponse in api . ChatEndpoint . StreamCompletionEnumerableAsync ( chatRequest ) )
{
foreach ( var choice in partialResponse . Choices . Where ( choice => choice . Delta ? . Content != null ) )
{
cumulativeDelta += choice . Delta . Content ;
}
}
Console . WriteLine ( cumulativeDelta ) ; using 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 )
{
Console . WriteLine ( $" { 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 ) ;
Console . WriteLine ( $" { 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 ) ;
Console . WriteLine ( $" { 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 " )
{
Console . WriteLine ( $" { response . FirstChoice . Message . Role } : { response . FirstChoice } | Finish Reason: { response . FirstChoice . FinishReason } " ) ;
var unitMessage = new Message ( Role . User , " Fahrenheit " ) ;
messages . Add ( unitMessage ) ;
Console . WriteLine ( $" { 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 )
{
Console . WriteLine ( $" { response . FirstChoice . Message . Role } : { toolCall . Function . Name } | Finish Reason: { response . FirstChoice . FinishReason } " ) ;
Console . WriteLine ( $" { 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 ) ) ;
Console . WriteLine ( $" { 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) مع مراعاة التغييرات.
using 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 ) ;
Console . WriteLine ( $" { response . FirstChoice . Message . Role } : { response . FirstChoice . Message . Content } | Finish Reason: { response . FirstChoice . FinishDetails } " ) ; using 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 ) ;
Console . WriteLine ( $" { response . FirstChoice . Message . Role } : { response . FirstChoice } | Finish Reason: { response . FirstChoice . FinishDetails } " ) ;
// todo play response.FirstChoice.Message.AudioOutput.Data تطور وضع JSON. في حين أن كلاهما يضمن إنتاج JSON صالح ، إلا أن المخرجات المهيكلة فقط تضمن الالتزام بالمخطط.
مهم
finish_reason من الطول ، مما يشير إلى أن الجيل تجاوز max_tokens أو تجاوز المحادثة حد الرمز المميز. للحماية من هذا ، تحقق finish_reason قبل تحليل الرد.حدد أولاً بنية ردودك. سيتم استخدام هذه كمخططك. هذه هي الكائنات التي ستعمل عليها ، لذا تأكد من استخدام نماذج كائن JSON القياسية.
public class MathResponse
{
[ JsonInclude ]
[ JsonPropertyName ( " steps " ) ]
public IReadOnlyList < MathStep > Steps { get ; private set ; }
[ JsonInclude ]
[ JsonPropertyName ( " final_answer " ) ]
public string FinalAnswer { get ; private set ; }
}
public class MathStep
{
[ JsonInclude ]
[ JsonPropertyName ( " explanation " ) ]
public string Explanation { get ; private set ; }
[ JsonInclude ]
[ JsonPropertyName ( " output " ) ]
public string Output { get ; private set ; }
} للاستخدام ، ما عليك سوى تحديد نوع MathResponse كقيد عام عند طلب الانتهاء.
using 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 ] ;
Console . WriteLine ( $" Step { i } : { step . Explanation } " ) ;
Console . WriteLine ( $" Result: { step . Output } " ) ;
}
Console . WriteLine ( $" 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 )
{
Console . WriteLine ( $" [ { choice . Index } ] { choice . Message . Role } : { choice } | Finish Reason: { choice . FinishReason } " ) ;
}
response . GetUsage ( ) ;يحول الصوت إلى نص.
يتم الوصول إلى واجهة برمجة تطبيقات الصوت عبر OpenAIClient.AudioEndpoint
يولد الصوت من نص الإدخال.
using var api = new OpenAIClient ( ) ;
var request = new SpeechRequest ( " Hello World! " ) ;
async Task ChunkCallback ( ReadOnlyMemory < byte > chunkCallback )
{
// TODO Implement audio playback as chunks arrive
await Task . CompletedTask ;
}
var response = await api . AudioEndpoint . CreateSpeechAsync ( request , ChunkCallback ) ;
await File . WriteAllBytesAsync ( " ../../../Assets/HelloWorld.mp3 " , response . ToArray ( ) ) ; ينسخ الصوت إلى لغة الإدخال.
using var api = new OpenAIClient ( ) ;
using var request = new AudioTranscriptionRequest ( Path . GetFullPath ( audioAssetPath ) , language : " en " ) ;
var response = await api . AudioEndpoint . CreateTranscriptionTextAsync ( request ) ;
Console . WriteLine ( response ) ; يمكنك أيضًا الحصول على معلومات مفصلة باستخدام verbose_json للحصول على حبيبات الطابع الزمني:
using 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 )
{
Console . WriteLine ( $" [ { word . Start } - { word . End } ] " { word . Word } " " ) ;
} يترجم الصوت إلى اللغة الإنجليزية.
using var api = new OpenAIClient ( ) ;
using var request = new AudioTranslationRequest ( Path . GetFullPath ( audioAssetPath ) ) ;
var response = await api . AudioEndpoint . CreateTranslationTextAsync ( request ) ;
Console . WriteLine ( response ) ;بالنظر إلى موجه و/أو صورة إدخال ، سيقوم النموذج بإنشاء صورة جديدة.
يتم الوصول إلى واجهة برمجة تطبيقات الصور عبر OpenAIClient.ImagesEndpoint
يخلق صورة تعطى موجه.
using 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 image in imageResults )
{
Console . WriteLine ( image ) ;
// image == url or b64_string
} ينشئ صورة تم تحريرها أو ممتدة مع إعطاء صورة أصلية ومطالبة.
using var api = new OpenAIClient ( ) ;
var request = new ImageEditRequest ( imageAssetPath , maskAssetPath , " A sunlit indoor lounge area with a pool containing a flamingo " , size : ImageSize . Small ) ;
var imageResults = await api . ImagesEndPoint . CreateImageEditAsync ( request ) ;
foreach ( var image in imageResults )
{
Console . WriteLine ( image ) ;
// image == url or b64_string
} يخلق تباينًا في صورة معينة.
using var api = new OpenAIClient ( ) ;
var request = new ImageVariationRequest ( imageAssetPath , size : ImageSize . Small ) ;
var imageResults = await api . ImagesEndPoint . CreateImageVariationAsync ( request ) ;
foreach ( var image in imageResults )
{
Console . WriteLine ( image ) ;
// image == url or b64_string
}تُستخدم الملفات لتحميل المستندات التي يمكن استخدامها مع ميزات مثل الضبط الدقيق.
يتم الوصول إلى واجهة برمجة تطبيقات الملفات عبر OpenAIClient.FilesEndpoint
إرجاع قائمة الملفات التي تنتمي إلى منظمة المستخدم.
using var api = new OpenAIClient ( ) ;
var fileList = await api . FilesEndpoint . ListFilesAsync ( ) ;
foreach ( var file in fileList )
{
Console . WriteLine ( $" { file . Id } -> { file . Object } : { file . FileName } | { file . Size } bytes " ) ;
} قم بتحميل ملف يمكن استخدامه عبر نقاط النهاية المختلفة. يمكن أن يصل حجم جميع الملفات التي تم تحميلها بواسطة مؤسسة واحدة إلى 100 جيجابايت.
يمكن أن يكون حجم الملفات الفردية بحد أقصى 512 ميغابايت. راجع دليل أدوات المساعدين لمعرفة المزيد حول أنواع الملفات المدعومة. يدعم واجهة برمجة تطبيقات الضبط فقط ملفات .jsonl.
using var api = new OpenAIClient ( ) ;
var file = await api . FilesEndpoint . UploadFileAsync ( " path/to/your/file.jsonl " , FilePurpose . FineTune ) ;
Console . WriteLine ( file . Id ) ; حذف ملف.
using var api = new OpenAIClient ( ) ;
var isDeleted = await api . FilesEndpoint . DeleteFileAsync ( fileId ) ;
Assert . IsTrue ( isDeleted ) ; إرجاع المعلومات حول ملف معين.
using var api = new OpenAIClient ( ) ;
var file = await api . FilesEndpoint . GetFileInfoAsync ( fileId ) ;
Console . WriteLine ( $" { file . Id } -> { file . Object } : { file . FileName } | { file . Size } bytes " ) ; يقوم بتنزيل محتوى الملف إلى الدليل المحدد.
using var api = new OpenAIClient ( ) ;
var downloadedFilePath = await api . FilesEndpoint . DownloadFileAsync ( fileId , " path/to/your/save/directory " ) ;
Console . WriteLine ( downloadedFilePath ) ;
Assert . IsTrue ( File . Exists ( downloadedFilePath ) ) ;إدارة الوظائف الدقيقة لتكييف نموذج لبيانات التدريب الخاصة بك.
الدليل ذي الصلة: نماذج النقطة الدقيقة
يتم الوصول إلى واجهة برمجة تطبيقات الملفات عبر OpenAIClient.FineTuningEndpoint
ينشئ وظيفة تقوم بتشكيل نموذج محدد من مجموعة بيانات معينة.
يتضمن الاستجابة تفاصيل الوظيفة المتوفرة بما في ذلك حالة الوظيفة واسم النماذج التي تم ضبطها مرة واحدة.
using var api = new OpenAIClient ( ) ;
var fileId = " file-abc123 " ;
var request = new CreateFineTuneRequest ( fileId ) ;
var job = await api . FineTuningEndpoint . CreateJobAsync ( Model . GPT3_5_Turbo , request ) ;
Console . WriteLine ( $" Started { job . Id } | Status: { job . Status } " ) ; قائمة وظائف المنظمات الخاصة بمؤسستك.
using var api = new OpenAIClient ( ) ;
var jobList = await api . FineTuningEndpoint . ListJobsAsync ( ) ;
foreach ( var job in jobList . Items . OrderByDescending ( job => job . CreatedAt ) )
{
Console . WriteLine ( $" { job . Id } -> { job . CreatedAt } | { job . Status } " ) ;
} يحصل على معلومات حول وظيفة ضبطها.
using var api = new OpenAIClient ( ) ;
var job = await api . FineTuningEndpoint . GetJobInfoAsync ( fineTuneJob ) ;
Console . WriteLine ( $" { job . Id } -> { job . CreatedAt } | { job . Status } " ) ; إلغاء وظيفة ضبطها على الفور.
using var api = new OpenAIClient ( ) ;
var isCancelled = await api . FineTuningEndpoint . CancelFineTuneJobAsync ( fineTuneJob ) ;
Assert . IsTrue ( isCancelled ) ; احصل على تحديثات الحالة للحصول على وظيفة صقل.
using var api = new OpenAIClient ( ) ;
var eventList = await api . FineTuningEndpoint . ListJobEventsAsync ( fineTuneJob ) ;
Console . WriteLine ( $" { fineTuneJob . Id } -> status: { fineTuneJob . Status } | event count: { eventList . Events . Count } " ) ;
foreach ( var @event in eventList . Items . OrderByDescending ( @event => @event . CreatedAt ) )
{
Console . WriteLine ( $" { @event . CreatedAt } [ { @event . Level } ] { @event . Message } " ) ;
}قم بإنشاء دفعات كبيرة من طلبات API للمعالجة غير المتزامنة. يعود API الدُفعات إلى إكمال في غضون 24 ساعة للحصول على خصم 50 ٪.
يتم الوصول إلى واجهة برمجة تطبيقات الدفعات عبر OpenAIClient.BatchesEndpoint
قائمة دفعات مؤسستك.
using var api = new OpenAIClient ( ) ;
var batches = await api . BatchEndpoint . ListBatchesAsync ( ) ;
foreach ( var batch in listResponse . Items )
{
Console . WriteLine ( batch ) ;
} يقوم بإنشاء وتنفيذ دفعة من ملف الطلبات المحمّلة
using var api = new OpenAIClient ( ) ;
var batchRequest = new CreateBatchRequest ( " file-id " , Endpoint . ChatCompletions ) ;
var batch = await api . BatchEndpoint . CreateBatchAsync ( batchRequest ) ; يسترجع دفعة.
using 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 دقائق ، قبل التغيير إلى الإلغاء ، حيث سيكون لها نتائج جزئية (إن وجدت) في ملف الإخراج.
using var api = new OpenAIClient ( ) ;
var isCancelled = await api . BatchEndpoint . CancelBatchAsync ( batch ) ;
Assert . IsTrue ( isCancelled ) ;احصل على تمثيل متجه لمدخلات معينة يمكن استهلاكها بسهولة بواسطة نماذج التعلم الآلي والخوارزميات.
دليل ذي صلة: التضمينات
يتم الوصول إلى API OpenAIClient.EmbeddingsEndpoint
يخلق ناقل تضمين يمثل نص الإدخال.
using var api = new OpenAIClient ( ) ;
var response = await api . EmbeddingsEndpoint . CreateEmbeddingAsync ( " The food was delicious and the waiter... " , Models . Embedding_Ada_002 ) ;
Console . WriteLine ( response ) ;بالنظر إلى نص الإدخال ، يتم الإخراج إذا صنف النموذج على أنه ينتهك سياسة محتوى Openai.
الدليل ذي الصلة: التعتيم
يمكن الوصول إلى واجهة برمجة تطبيقات التعتيم عبر OpenAIClient.ModerationsEndpoint
يصنف ما إذا كان النص ينتهك سياسة محتوى Openai.
using var api = new OpenAIClient ( ) ;
var isViolation = await api . ModerationsEndpoint . GetModerationAsync ( " I want to kill them. " ) ;
Assert . IsTrue ( isViolation ) ;بالإضافة إلى ذلك ، يمكنك أيضًا الحصول على عشرات مدخلات معينة.
using var api = new OpenAIClient ( ) ;
var response = await api . ModerationsEndpoint . CreateModerationAsync ( new ModerationsRequest ( " I love you " ) ) ;
Assert . IsNotNull ( response ) ;
Console . WriteLine ( response . Results ? [ 0 ] ? . Scores ? . ToString ( ) ) ;