Простая клиентская библиотека C# .NET для OpenAI, хотя и их Restful API. Независимо разработан, это не официальная библиотека, и я не связан с Openai. Требуется аккаунт API OpenAI.
Первоначально раздвоился от Openai-Api-Dotnet. Больше контекста в блоге Роджера Пинкомбе.
Установите пакет OpenAI-DotNet от Nuget. Вот как через командную строку:
PowerShell:
Install-Package OpenAI-DotNet
Dotnet:
dotnet add package OpenAI-DotNet
Хотите использовать Openai-Dotnet в игровом двигателе Unity? Проверьте наш пакет Unity на OpenUpm:
Проверьте наши новые документы API!
https://rageagainstthepixel.github.io/openai-dotnet
Есть 3 способа обеспечить ваши ключи API, в порядке приоритета:
Предупреждение
Мы рекомендовали использовать переменные среды для загрузки клавиши 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 Open Deployments.
Вы можете найти необходимую информацию на игровой площадке 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 . Затем обязательно установите UseazureActiedRectory в True при создании ваших OpenAIClientSettings .
Учебное пособие: настольное приложение, которое вызывает веб -API: приобретать токен
// 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 непосредственно в вашем приложении переднего интерфейса может разоблачить ваши клавиши API и другую конфиденциальную информацию. Чтобы смягчить этот риск, рекомендуется настроить промежуточный API, который делает запросы OpenaI от имени вашего приложения для интерфейса. Эта библиотека может быть использована как для конфигураций хоста, так и для посредника, обеспечивая безопасную связь с API OpenAI.
В примере переднего конца вам нужно будет безопасно аутентифицировать своих пользователей, используя ваш предпочтительный провайдер OAuth. После того, как пользователь будет аутентифицирован, обменяйте свой пользовательский токен аудитория с вашим ключом API на бэкэнде.
Следуйте этим шагам:
OpenAIAuthentication и пропустите пользовательский токен с префиксом sess- .OpenAIClientSettings и укажите домен, где находится ваш промежуточный API.auth и settings Constructor 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, который затем направляет запросы в API OpenAI. Это гарантирует, что ваши ключи API Openai и другая конфиденциальная информация остаются безопасными на протяжении всего процесса.
В этом примере мы демонстрируем, как настроить и использовать OpenAIProxy в новом веб -приложении ASP.NET. Прокси -сервер будет обрабатывать аутентификацию и перенаправить запросы в API OpenAI, гарантируя, что ваши ключи API и другая конфиденциальная информация оставались безопасными.
Install-Package OpenAI-DotNet-Proxydotnet add package OpenAI-DotNet-Proxy<PackageReference Include="OpenAI-DotNet-Proxy" /> .AbstractAuthenticationFilter и переопределяет метод ValidateAuthentication . Это будет реализовать IAuthenticationFilter , который вы будете использовать для проверки токена сеанса пользователя на ваш внутренний сервер.OpenAIProxy.CreateWebApplication Program.cs AuthenticationFilterOpenAIAuthentication и OpenAIClientSettings , как обычно, с настройками API, ID или настройками 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 ( ) ;
}
}После того, как вы настроили свой прокси -сервер, ваши конечные пользователи теперь могут сделать аутентифицированные запросы в ваш прокси -API, а не непосредственно в API OpenAI. Прокси -сервер будет обрабатывать аутентификацию и перенаправить запросы в API OpenAI, гарантируя, что ваши ключи API и другая конфиденциальная информация оставались безопасными.
Перечислите и опишите различные модели, доступные в API. Вы можете ссылаться на документацию моделей, чтобы понять, какие модели доступны и различия между ними.
Также проверка модели Совместимость конечной точки, чтобы понять, какие модели работают, с какими конечными точками.
Чтобы указать пользовательскую модель, не предварительно определенную в этой библиотеке:
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 в режиме реального времени позволяет вам создавать многомодальный разговорной опыт с низкой задержкой. В настоящее время он поддерживает текст и аудио как ввод, так и вывод, а также вызов функций.
Помощники 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 -Send Это событие, чтобы отменить представление. Вы можете отправлять клиентские события в любое время на сервер, вызывая метод RealtimeSession.SendAsync в объекте сеанса. Вызов Send вернет рукоятку 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 ) ; Примечание
События Assistant Stream могут быть легко добавлены к существующим вызовам потоков путем передачи Func<IServerSentEvent, Task> streamEventHandler обратный вызов к любому существующему методу, который поддерживает потоковую передачу.
Создайте потоки, с которыми могут взаимодействовать помощники.
API Threads доступен через OpenAIClient.ThreadsEndpoint
Создайте ветку.
using var api = new OpenAIClient ( ) ;
var thread = await api . ThreadsEndpoint . CreateThreadAsync ( ) ;
Console . WriteLine ( $" Create thread { thread . Id } -> { thread . CreatedAt } " ) ; Создайте ветку и запустите его в одном запросе.
Смотрите также: Thread Runs
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 JSON String, но вы будете нести ответственность за десеризацию ваших данных ответа:
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 ) ; Векторные хранилища используются для хранения файлов для использования инструментом file_search .
Vector Stores API доступен через 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 ) ; Файлы Vector Store представляют файлы в векторном хранилище.
Возвращает список файлов Vector Store.
using var api = new OpenAIClient ( ) ;
var files = await api . VectorStoresEndpoint . ListVectorStoreFilesAsync ( " vector-store-id " ) ;
foreach ( var file in vectorStoreFiles . Items )
{
Console . WriteLine ( file ) ;
} Создайте файл Vector Store, подключив файл в векторный магазин.
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 ) ; Удалить файл векторного хранилища. Это удалит файл из векторного хранилища, но сам файл не будет удален. Чтобы удалить файл, используйте конечную точку Delete File.
using var api = new OpenAIClient ( ) ;
var isDeleted = await api . VectorStoresEndpoint . DeleteVectorStoreFileAsync ( " vector-store-id " , vectorStoreFile ) ;
Assert . IsTrue ( isDeleted ) ; Файлы Vector Store представляют файлы в векторном хранилище.
Создайте партию файла Vector Store.
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 ( ) ; Возвращает список файлов Vector Store в партии.
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 " ) ;Учитывая разговор в чате, модель вернет ответ на завершение чата.
Доступ к API чата через 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 ( ) ;Преобразует аудио в текст.
Audio API доступен через 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 ) ;Учитывая подсказку и/или входное изображение, модель будет генерировать новое изображение.
API Images доступен через 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
}Файлы используются для загрузки документов, которые можно использовать с такими функциями, как тонкая настройка.
Доступ к API файлов через 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 МБ. См. Руководство по инструментам помощников, чтобы узнать больше о типах поддерживаемых файлов. API с тонкой настройкой поддерживает только файлы .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 ) ) ;Управляйте хорошими заданиями, чтобы адаптировать модель к конкретным данным обучения.
Связанный гид: модели с тонкой настройкой
Доступ к API файлов через 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% скидки.
API пакетов доступен через 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 ( ) ; Отменяет фондовую партию. Партия будет в отмене состояния в течение до 10 минут, прежде чем переходить на отмену, где она будет иметь частичные результаты (если таковые имеются), доступные в выходном файле.
using var api = new OpenAIClient ( ) ;
var isCancelled = await api . BatchEndpoint . CancelBatchAsync ( batch ) ;
Assert . IsTrue ( isCancelled ) ;Получите векторное представление данного входа, который можно легко использовать моделями машинного обучения и алгоритмам.
Связанный гид: Entgeddings
API EDITS доступен через 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.
Связанный гид: Модерации
API модераций можно получить через 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 ( ) ) ;