Microsoft menjangkau saya tentang transisi perpustakaan ini ke Perpustakaan C# Openai resmi baru dan sekarang siap untuk pergi! Dimulai dengan v2.0.0-beta.3, perpustakaan resmi sekarang memiliki cakupan penuh dan akan tetap up-to-date. Rincian lebih lanjut dalam posting blog di sini: https://devblogs.microsoft.com/dotnet/openai-dotnet-library
Repo GitHub ini akan tetap di sini untuk mendokumentasikan versi asli saya dari perpustakaan melalui versi 1.11, yang masih tersedia di Nuget juga. ?
Perpustakaan C# .NET Wrapper sederhana untuk digunakan dengan API Openai. Lebih banyak konteks di blog saya. Ini adalah perpustakaan pembungkus tidak resmi asli saya di sekitar API Openai.
var api = new OpenAI_API . OpenAIAPI ( " YOUR_API_KEY " ) ;
var result = await api . Chat . CreateChatCompletionAsync ( " Hello! " ) ;
Console . WriteLine ( result ) ;
// should print something like "Hi! How can I help you?" Dimulai dengan v2.0.0-beta, perpustakaan ini telah diadopsi oleh Microsoft. Versi resmi perpustakaan baru akan memiliki cakupan penuh dan akan tetap mutakhir. Rincian lebih lanjut dalam posting blog di sini: https://devblogs.microsoft.com/dotnet/openai-dotnet-library/ repo github ini akan tetap di sini untuk mendokumentasikan versi asli perpustakaan saya melalui versi 1.11, yang masih tersedia di Nuget juga.
Perpustakaan ini didasarkan pada .NET Standard 2.0, sehingga harus bekerja di semua versi .NET, dari .NET Framework tradisional> = 4.7.2 hingga .net (core)> = 3.0. Ini harus bekerja di seluruh aplikasi konsol, WinForms, WPF, ASP.NET, Unity, Xamarin, dll. Ini harus bekerja di seluruh Windows, Linux, dan Mac, dan bahkan mungkin mobile. Ada dependensi minimal, dan dilisensikan dalam domain publik.
Instal Paket OpenAI V1.11 dari Nuget. Begini cara melalui Commandline:
Install-Package OpenAI - Version 1.11 . 0Ada 3 cara untuk memberikan kunci API Anda, dalam urutan prioritas:
APIAuthentication(string key) konstruktor.openai dan berisi baris: OPENAI_API_KEY=sk-aaaabbbbbccccddddd Anda menggunakan APIAuthentication saat Anda menginisialisasi API seperti yang ditunjukkan:
// for example
OpenAIAPI api = new OpenAIAPI ( " YOUR_API_KEY " ) ; // shorthand
// or
OpenAIAPI api = new OpenAIAPI ( new APIAuthentication ( " YOUR_API_KEY " ) ) ; // create object manually
// or
OpenAIAPI api = new OpenAIAPI ( APIAuthentication LoadFromEnv ( ) ) ; // use env vars
// or
OpenAIAPI api = new OpenAIAPI ( APIAuthentication LoadFromPath ( ) ) ; // use config file (can optionally specify where to look)
// or
OpenAIAPI api = new OpenAIAPI ( ) ; // uses default, env, or config fileAnda secara opsional dapat menyertakan OpenAorganisasi (OpenAI_Organization di Env atau Config File) yang menentukan organisasi mana yang digunakan untuk permintaan API. Penggunaan dari permintaan API ini akan diperhitungkan terhadap kuota berlangganan organisasi yang ditentukan. ID Organisasi dapat ditemukan di halaman Pengaturan Organisasi Anda.
// for example
OpenAIAPI api = new OpenAIAPI ( new APIAuthentication ( " YOUR_API_KEY " , " org-yourOrgHere " ) ) ; API obrolan diakses melalui OpenAIAPI.Chat . Ada dua cara untuk menggunakan titik akhir obrolan, baik melalui percakapan yang disederhanakan atau dengan metode permintaan/respons penuh.
Kelas percakapan memungkinkan Anda untuk dengan mudah berinteraksi dengan chatgpt dengan menambahkan pesan ke obrolan dan meminta chatgpt untuk membalas.
var chat = api . Chat . CreateConversation ( ) ;
chat . Model = Model . GPT4_Turbo ;
chat . RequestParameters . Temperature = 0 ;
/// give instruction as System
chat . AppendSystemMessage ( " You are a teacher who helps children understand if things are animals or not. If the user tells you an animal, you say " yes " . If the user tells you something that is not an animal, you say " no " . You only ever respond with " yes " or " no " . You do not say anything else. " ) ;
// give a few examples as user and assistant
chat . AppendUserInput ( " Is this an animal? Cat " ) ;
chat . AppendExampleChatbotOutput ( " Yes " ) ;
chat . AppendUserInput ( " Is this an animal? House " ) ;
chat . AppendExampleChatbotOutput ( " No " ) ;
// now let's ask it a question
chat . AppendUserInput ( " Is this an animal? Dog " ) ;
// and get the response
string response = await chat . GetResponseFromChatbotAsync ( ) ;
Console . WriteLine ( response ) ; // "Yes"
// and continue the conversation by asking another
chat . AppendUserInput ( " Is this an animal? Chair " ) ;
// and get another response
response = await chat . GetResponseFromChatbotAsync ( ) ;
Console . WriteLine ( response ) ; // "No"
// the entire chat history is available in chat.Messages
foreach ( ChatMessage msg in chat . Messages )
{
Console . WriteLine ( $" { msg . Role } : { msg . Content } " ) ;
} Streaming memungkinkan Anda untuk mendapatkan hasil yang dihasilkan, yang dapat membantu aplikasi Anda merasa lebih responsif.
Menggunakan C# 8.0 Async Iterators yang baru:
var chat = api . Chat . CreateConversation ( ) ;
chat . AppendUserInput ( " How to make a hamburger? " ) ;
await foreach ( var res in chat . StreamResponseEnumerableFromChatbotAsync ( ) )
{
Console . Write ( res ) ;
}Atau jika menggunakan kerangka kerja .NET klasik atau C# <8.0:
var chat = api . Chat . CreateConversation ( ) ;
chat . AppendUserInput ( " How to make a hamburger? " ) ;
await chat . StreamResponseFromChatbotAsync ( res =>
{
Console . Write ( res ) ;
} ) ; Anda dapat mengirim gambar ke obrolan untuk menggunakan model Visi GPT-4 baru. Ini hanya berfungsi dengan model Model.GPT4_Vision . Silakan lihat https://platform.openai.com/docs/guides/vision untuk informasi dan batasan lebih lanjut.
// the simplest form
var result = await api . Chat . CreateChatCompletionAsync ( " What is the primary non-white color in this logo? " , ImageInput . FromFile ( " path/to/logo.png " ) ) ;
// or in a conversation
var chat = api . Chat . CreateConversation ( ) ;
chat . Model = Model . GPT4_Vision ;
chat . AppendSystemMessage ( " You are a graphic design assistant who helps identify colors. " ) ;
chat . AppendUserInput ( " What are the primary non-white colors in this logo? " , ImageInput . FromFile ( " path/to/logo.png " ) ) ;
string response = await chat . GetResponseFromChatbotAsync ( ) ;
Console . WriteLine ( response ) ; // "Blue and purple"
chat . AppendUserInput ( " What are the primary non-white colors in this logo? " , ImageInput . FromImageUrl ( " https://rogerpincombe.com/templates/rp/center-aligned-no-shadow-small.png " ) ) ;
response = await chat . GetResponseFromChatbotAsync ( ) ;
Console . WriteLine ( response ) ; // "Blue, red, and yellow"
// or when manually creating the ChatMessage
messageWithImage = new ChatMessage ( ChatMessageRole . User , " What colors do these logos have in common? " ) ;
messageWithImage . images . Add ( ImageInput . FromFile ( " path/to/logo.png " ) ) ;
messageWithImage . images . Add ( ImageInput . FromImageUrl ( " https://rogerpincombe.com/templates/rp/center-aligned-no-shadow-small.png " ) ) ;
// you can specify multiple images at once
chat . AppendUserInput ( " What colors do these logos have in common? " , ImageInput . FromFile ( " path/to/logo.png " ) , ImageInput . FromImageUrl ( " https://rogerpincombe.com/templates/rp/center-aligned-no-shadow-small.png " ) ) ; Jika riwayat percakapan obrolan terlalu lama, itu mungkin tidak sesuai dengan panjang konteks model. Secara default, pesan non-sistem yang paling awal akan dihapus dari riwayat obrolan dan panggilan API akan diceritakan kembali. Anda dapat menonaktifkan ini dengan mengatur chat.AutoTruncateOnContextLengthExceeded = false .
chat . OnTruncationNeeded += ( sender , args ) =>
{
// args is a List<ChatMessage> with the current chat history. Remove or edit as nessisary.
// replace this with more sophisticated logic for your use-case, such as summarizing the chat history
for ( int i = 0 ; i < args . Count ; i ++ )
{
if ( args [ i ] . Role != ChatMessageRole . System )
{
args . RemoveAt ( i ) ;
return ;
}
}
} ; Anda juga mungkin ingin menggunakan model baru dengan panjang konteks yang lebih besar. Anda dapat melakukan ini dengan mengatur chat.Model = Model.GPT4_Turbo atau chat.Model = Model.ChatGPTTurbo_16k , dll.
Anda dapat melihat penggunaan token melalui chat.MostRecentApiResult.Usage.PromptTokens dan properti terkait.
Anda dapat mengakses kontrol penuh API obrolan dengan menggunakan OpenAIAPI.Chat.CreateChatCompletionAsync() dan metode terkait.
async Task < ChatResult > CreateChatCompletionAsync ( ChatRequest request ) ;
// for example
var result = await api . Chat . CreateChatCompletionAsync ( new ChatRequest ( )
{
Model = Model . ChatGPTTurbo ,
Temperature = 0.1 ,
MaxTokens = 50 ,
Messages = new ChatMessage [ ] {
new ChatMessage ( ChatMessageRole . User , " Hello! " )
}
} )
// or
var result = api . Chat . CreateChatCompletionAsync ( " Hello! " ) ;
var reply = results . Choices [ 0 ] . Message ;
Console . WriteLine ( $" { reply . Role } : { reply . Content . Trim ( ) } " ) ;
// or
Console . WriteLine ( results ) ; Ini mengembalikan ChatResult yang sebagian besar metadata, jadi gunakan metode .ToString() untuk mendapatkan teks jika yang Anda inginkan hanyalah teks balasan asisten.
Ada juga API streaming async yang bekerja sama dengan hasil akhir streaming titik akhir.
ChatRequest.ResponseFormat Model.GPT4_Turbo gpt-3.5-turbo-1106 ChatRequest.ResponseFormats.JsonObject Ketika mode JSON diaktifkan, model dibatasi hanya untuk menghasilkan string yang menguraikan objek JSON yang valid. Lihat https://platform.openai.com/docs/guides/text-generation/json-pode untuk detail lebih lanjut.
ChatRequest chatRequest = new ChatRequest ( )
{
Model = model ,
Temperature = 0.0 ,
MaxTokens = 500 ,
ResponseFormat = ChatRequest . ResponseFormats . JsonObject ,
Messages = new ChatMessage [ ] {
new ChatMessage ( ChatMessageRole . System , " You are a helpful assistant designed to output JSON. " ) ,
new ChatMessage ( ChatMessageRole . User , " Who won the world series in 2020? Return JSON of a 'wins' dictionary with the year as the numeric key and the winning team as the string value. " )
}
} ;
var results = await api . Chat . CreateChatCompletionAsync ( chatRequest ) ;
Console . WriteLine ( results ) ;
/* prints:
{
"wins": {
2020: "Los Angeles Dodgers"
}
}
*/ Penyelesaian dianggap warisan oleh Openai. API penyelesaian diakses melalui OpenAIAPI.Completions .
async Task < CompletionResult > CreateCompletionAsync ( CompletionRequest request ) ;
// for example
var result = await api . Completions . CreateCompletionAsync ( new CompletionRequest ( " One Two Three One Two " , model : Model . CurieText , temperature : 0.1 ) ) ;
// or
var result = await api . Completions . CreateCompletionAsync ( " One Two Three One Two " , temperature : 0.1 ) ;
// or other convenience overloads Anda dapat membuat CompletionRequest Anda sebelumnya atau menggunakan salah satu penolong kelebihan untuk kenyamanan. Ini mengembalikan CompletionResult yang sebagian besar metadata, jadi gunakan metode .ToString() untuk mendapatkan teks jika yang Anda inginkan hanyalah penyelesaian.
Streaming memungkinkan Anda untuk mendapatkan hasil yang dihasilkan, yang dapat membantu aplikasi Anda merasa lebih responsif, terutama pada model lambat seperti DaVinci.
Menggunakan C# 8.0 Async Iterators yang baru:
IAsyncEnumerable < CompletionResult > StreamCompletionEnumerableAsync ( CompletionRequest request ) ;
// for example
await foreach ( var token in api . Completions . StreamCompletionEnumerableAsync ( new CompletionRequest ( " My name is Roger and I am a principal software engineer at Salesforce. This is my resume: " , Model . DavinciText , 200 , 0.5 , presencePenalty : 0.1 , frequencyPenalty : 0.1 ) ) )
{
Console . Write ( token ) ;
}Atau jika menggunakan kerangka kerja .NET klasik atau C# <8.0:
async Task StreamCompletionAsync ( CompletionRequest request , Action < CompletionResult > resultHandler ) ;
// for example
await api . Completions . StreamCompletionAsync (
new CompletionRequest ( " My name is Roger and I am a principal software engineer at Salesforce. This is my resume: " , Model . DavinciText , 200 , 0.5 , presencePenalty : 0.1 , frequencyPenalty : 0.1 ) ,
res => ResumeTextbox . Text += res . ToString ( ) ) ;API audio adalah teks ke ucapan, transkripsi (pidato ke teks), dan terjemahan (pidato non-Inggris ke teks bahasa Inggris).
API TTS diakses melalui OpenAIAPI.TextToSpeech :
await api . TextToSpeech . SaveSpeechToFileAsync ( " Hello, brave new world! This is a test. " , outputPath ) ;
// You can open it in the defaul audio player like this:
Process . Start ( outputPath ) ; Anda juga dapat menentukan semua parameter permintaan dengan objek TextToSpeechRequest :
var request = new TextToSpeechRequest ( )
{
Input = " Hello, brave new world! This is a test. " ,
ResponseFormat = ResponseFormats . AAC ,
Model = Model . TTS_HD ,
Voice = Voices . Nova ,
Speed = 0.9
} ;
await api . TextToSpeech . SaveSpeechToFileAsync ( request , " test.aac " ) ; Alih -alih menyimpan ke file, Anda bisa mendapatkan aliran byte audio dengan api.TextToSpeech.GetSpeechAsStreamAsync(request) :
using ( Stream result = await api . TextToSpeech . GetSpeechAsStreamAsync ( " Hello, brave new world! " , Voices . Fable ) )
using ( StreamReader reader = new StreamReader ( result ) )
{
// do something with the audio stream here
} Audio transcription API memungkinkan Anda untuk menghasilkan teks dari audio, dalam salah satu bahasa yang didukung. Diakses melalui OpenAIAPI.Transcriptions :
string resultText = await api . Transcriptions . GetTextAsync ( " path/to/file.mp3 " ) ;Anda dapat meminta hasil verbose, yang akan memberi Anda informasi tingkat dan tingkat token, serta metadata openai standar seperti waktu pemrosesan:
AudioResultVerbose result = await api . Transcriptions . GetWithDetailsAsync ( " path/to/file.m4a " ) ;
Console . WriteLine ( result . ProcessingTime . TotalMilliseconds ) ; // 496ms
Console . WriteLine ( result . text ) ; // "Hello, this is a test of the transcription function."
Console . WriteLine ( result . language ) ; // "english"
Console . WriteLine ( result . segments [ 0 ] . no_speech_prob ) ; // 0.03712
// etcAnda juga dapat meminta hasil dalam format SRT atau VTT, yang berguna untuk menghasilkan subtitle untuk video:
string result = await api . Transcriptions . GetAsFormatAsync ( " path/to/file.m4a " , AudioRequest . ResponseFormats . SRT ) ;Parameter tambahan seperti suhu, prompt, bahasa, dll dapat ditentukan baik per permintaan atau sebagai default:
// inline
result = await api . Transcriptions . GetTextAsync ( " conversation.mp3 " , " en " , " This is a transcript of a conversation between a medical doctor and her patient: " , 0.3 ) ;
// set defaults
api . Transcriptions . DefaultTranscriptionRequestArgs . Language = " en " ;Alih -alih menyediakan file lokal pada disk, Anda dapat memberikan aliran byte audio. Ini dapat berguna untuk streaming audio dari mikrofon atau sumber lain tanpa harus terlebih dahulu menulis ke disk. Harap tidak, Anda harus menentukan nama file, yang tidak harus ada, tetapi yang harus memiliki ekstensi yang akurat untuk jenis audio yang Anda kirim. OpenAI menggunakan ekstensi nama file untuk menentukan format aliran audio Anda.
using ( var audioStream = File . OpenRead ( " path-here.mp3 " ) )
{
return await api . Transcriptions . GetTextAsync ( audioStream , " file.mp3 " ) ;
} Terjemahan memungkinkan Anda untuk menuliskan teks dari salah satu bahasa yang didukung ke bahasa Inggris. Openai tidak mendukung menerjemahkan ke dalam bahasa lain, hanya bahasa Inggris. Diakses melalui OpenAIAPI.Translations . Ini mendukung semua fungsi yang sama dengan transkripsi.
string result = await api . Translations . GetTextAsync ( " chinese-example.m4a " ) ; API embedding diakses melalui OpenAIAPI.Embeddings :
async Task < EmbeddingResult > CreateEmbeddingAsync ( EmbeddingRequest request ) ;
// for example
var result = await api . Embeddings . CreateEmbeddingAsync ( new EmbeddingRequest ( " A test text for embedding " , model : Model . AdaTextEmbedding ) ) ;
// or
var result = await api . Embeddings . CreateEmbeddingAsync ( " A test text for embedding " ) ;Hasil embedding mengandung banyak metadata, vektor float yang sebenarnya ada.
Untuk kesederhanaan, Anda dapat secara langsung meminta vektor pelampung dan menjijikkan metadata ekstra dengan api.Embeddings.GetEmbeddingsAsync("test text here")
API moderasi diakses melalui OpenAIAPI.Moderation :
async Task < ModerationResult > CreateEmbeddingAsync ( ModerationRequest request ) ;
// for example
var result = await api . Moderation . CallModerationAsync ( new ModerationRequest ( " A test text for moderating " , Model . TextModerationLatest ) ) ;
// or
var result = await api . Moderation . CallModerationAsync ( " A test text for moderating " ) ;
Console . WriteLine ( result . results [ 0 ] . MainContentFlag ) ; Hasilnya ada di .results[0] dan memiliki metode pembantu yang bagus seperti FlaggedCategories dan MainContentFlag .
Titik akhir API File diakses melalui OpenAIAPI.Files :
// uploading
async Task < File > UploadFileAsync ( string filePath , string purpose = " fine-tune " ) ;
// for example
var response = await api . Files . UploadFileAsync ( " fine-tuning-data.jsonl " ) ;
Console . Write ( response . Id ) ; //the id of the uploaded file
// listing
async Task < List < File > > GetFilesAsync ( ) ;
// for example
var response = await api . Files . GetFilesAsync ( ) ;
foreach ( var file in response )
{
Console . WriteLine ( file . Name ) ;
}Ada juga metode untuk mendapatkan konten file, menghapus file, dll.
Titik akhir yang menyempurnakan itu sendiri belum diterapkan, tetapi akan segera ditambahkan.
API Pembuatan Gambar Dall-E diakses melalui OpenAIAPI.ImageGenerations :
async Task < ImageResult > CreateImageAsync ( ImageGenerationRequest request ) ;
// for example
var result = await api . ImageGenerations . CreateImageAsync ( new ImageGenerationRequest ( " A drawing of a computer writing a test " , 1 , ImageSize . _512 ) ) ;
// or
var result = await api . ImageGenerations . CreateImageAsync ( " A drawing of a computer writing a test " ) ;
Console . WriteLine ( result . Data [ 0 ] . Url ) ;Hasil gambar berisi URL untuk gambar online atau gambar yang dikodekan base64, tergantung pada ImageGenerationRequest.ResponsEformat (URL adalah default).
Gunakan Dall-e 3 seperti ini:
async Task < ImageResult > CreateImageAsync ( ImageGenerationRequest request ) ;
// for example
var result = await api . ImageGenerations . CreateImageAsync ( new ImageGenerationRequest ( " A drawing of a computer writing a test " , OpenAI_API . Models . Model . DALLE3 , ImageSize . _1024x1792 , " hd " ) ) ;
// or
var result = await api . ImageGenerations . CreateImageAsync ( " A drawing of a computer writing a test " , OpenAI_API . Models . Model . DALLE3 ) ;
Console . WriteLine ( result . Data [ 0 ] . Url ) ; Untuk menggunakan layanan Azure OpenAi, Anda perlu menentukan nama sumber daya OpenAi Azure Anda serta ID Penyebaran Model Anda.
Saya tidak memiliki akses ke layanan OpenAi Microsoft Azure, jadi saya tidak dapat menguji fungsi ini. Jika Anda memiliki akses dan dapat menguji, silakan kirim masalah yang menggambarkan hasil Anda. PR dengan tes integrasi juga akan sangat dihargai. Secara khusus, tidak jelas bagi saya bahwa menentukan model bekerja dengan cara yang sama dengan Azure.
Rujuk dokumentasi Azure Openai dan tangkapan layar terperinci di #64 untuk informasi lebih lanjut.
Konfigurasi seharusnya terlihat seperti ini untuk layanan Azure:
OpenAIAPI api = OpenAIAPI . ForAzure ( " YourResourceName " , " deploymentId " , " api-key " ) ;
api . ApiVersion = " 2023-03-15-preview " ; // needed to access chat endpoint on Azure Anda kemudian dapat menggunakan objek api seperti normal. Anda juga dapat menentukan APIAuthentication adalah salah satu cara lain yang tercantum di bagian otentikasi di atas. Saat ini perpustakaan ini hanya mendukung aliran API-Key, bukan aliran iklan.
Pada 2 April 2023, Anda perlu memilih API versi 2023-03-15-preview secara manual seperti yang ditunjukkan di atas untuk mengakses titik akhir obrolan di Azure. Setelah ini di luar pratinjau saya akan memperbarui default.
Anda dapat menentukan IHttpClientFactory yang akan digunakan untuk permintaan HTTP, yang memungkinkan untuk mengubah properti permintaan HTTP, pengumpulan koneksi, dan mengejek. Detail di #103.
OpenAIAPI api = new OpenAIAPI ( ) ;
api . HttpClientFactory = myIHttpClientFactoryObject ; Setiap kelas, metode, dan properti memiliki dokumentasi XML yang luas, sehingga harus muncul secara otomatis di Intellisense. Itu dikombinasikan dengan dokumentasi resmi OpenAI harus cukup untuk memulai. Jangan ragu untuk membuka masalah di sini jika Anda memiliki pertanyaan. Dokumentasi yang lebih baik mungkin datang nanti.
Domain Publik CC-0
Perpustakaan ini berlisensi CC-0, di domain publik. Anda dapat menggunakannya untuk apa pun yang Anda inginkan, secara publik atau pribadi, tanpa khawatir tentang izin atau lisensi atau apa pun. Ini hanya pembungkus di sekitar API Openai, jadi Anda masih perlu mendapatkan akses ke Openai dari mereka secara langsung. Saya tidak berafiliasi dengan Openai dan perpustakaan ini tidak didukung oleh mereka, saya hanya memiliki akses beta dan ingin membuat perpustakaan C# untuk mengaksesnya lebih mudah. Semoga orang lain juga bermanfaat. Jangan ragu untuk membuka PR jika ada yang ingin Anda kontribusikan.