OpenAIがRESTFUL APIを使用して使用する簡単なC#.NETクライアントライブラリ。独立して開発された、これは公式図書館ではなく、私はOpenaiと提携していません。 OpenAI APIアカウントが必要です。
もともとOpenai-Api-Dotnetからフォークされていました。 Roger Pincombeのブログに関するより多くのコンテキスト。
NugetからPackage OpenAI-DotNetをインストールします。コマンドライン経由の方法は次のとおりです。
PowerShell:
Install-Package OpenAI-DotNet
dotnet:
dotnet add package OpenAI-DotNet
UnityゲームエンジンでOpenai-Dotnetを使用したいですか? OpenUPMでUnityパッケージをご覧ください:
新しいAPIドキュメントをご覧ください!
https://rageagainstthepixel.github.io/openai-dotnet
APIキーを提供するには、優先順位の順に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という名前の新しいテキストファイルを作成し、行を含みます。
注記
組織およびプロジェクトIDエントリはオプションです。
{
"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という名前を付ける必要はありません。 using var api = new OpenAIClient ( OpenAIAuthentication . LoadFromPath ( " path/to/your/file.json " ) ) ; システムの環境変数を使用して、使用するAPIキーと組織を指定します。
OPENAI_API_KEYを使用します。OPENAI_ORGANIZATION_IDを使用して、組織を指定します。OPENAI_PROJECT_IDを使用して、プロジェクトを指定します。 using var api = new OpenAIClient ( OpenAIAuthentication . LoadFromEnv ( ) ) ;OpenAIClient 、 HttpClientを含む、使用するリソースのライフサイクルを管理するためにIDisposable実装を実装しています。 OpenAIClient初期化すると、提供されていない場合は内部HttpClientインスタンスが作成されます。この内部HttpClientは、 OpenAIClientが廃棄されたときに廃棄されます。 OpenAIClientに外部HttpClientインスタンスを提供する場合、お客様はその処分を管理する責任があります。
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 Playground] 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 。これは、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作成するときにアクセストークンを使用します。次に、 OpenAIClientSettingsを作成するときに、useazureativedirectoryを真に設定してください。
チュートリアル:Web 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キーやその他の機密情報が公開される場合があります。このリスクを軽減するには、フロントエンドアプリに代わってOpenAIにリクエストを行う中間APIを設定することをお勧めします。このライブラリは、フロントエンドと中間ホストの両方のホスト構成に使用して、OpenAI APIとの安全な通信を確保できます。
フロントエンドの例では、希望するOAuthプロバイダーを使用してユーザーを安全に認証する必要があります。ユーザーが認証されたら、バックエンドのAPIキーとカスタム認証トークンを交換します。
次の手順に従ってください:
OpenAIAuthenticationオブジェクトを作成し、プレフィックスsess-でカスタムトークンを渡します。OpenAIClientSettingsオブジェクトを作成し、中間APIが配置されているドメインを指定します。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にリクエストを転送します。これにより、OpenAI APIキーやその他の機密情報がプロセス全体で安全なままになります。
この例では、新しいASP.NETコアWebアプリでOpenAIProxyセットアップおよび使用する方法を示します。プロキシサーバーは、APIキーやその他の機密情報が安全であることを保証し、Openai APIに認証と転送要求を処理します。
Install-Package OpenAI-DotNet-Proxydotnet add package OpenAI-DotNet-Proxy<PackageReference Include="OpenAI-DotNet-Proxy" />AbstractAuthenticationFilterから継承する新しいクラスを作成し、 ValidateAuthentication法をオーバーライドします。これにより、内部サーバーに対するユーザーセッショントークンを確認するために使用するIAuthenticationFilterが実装されます。Program.csでは、 OpenAIProxy.CreateWebApplicationメソッドを呼び出して、カスタムAuthenticationFilterタイプ引数として渡すことにより、新しいプロキシWebアプリケーションを作成します。OpenAIAuthenticationとOpenAIClientSettingsを作成します。 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に認証されたリクエストを作成できるようになりました。プロキシサーバーは、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を使用すると、低遅延のマルチモーダルの会話エクスペリエンスを構築できます。現在、入力と出力の両方としてテキストとオーディオ、および関数呼び出しをサポートしています。
Assistants 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イベントの両方で返されます。RealtimeConversationResponse :新しい会話アイテムが作成されたときに返されます。ConversationItemCreatedResponse :新しい会話アイテムが作成されたときに返されます。ConversationItemInputAudioTranscriptionResponse :入力オーディオ転写が完了または失敗したときに返されます。ConversationItemTruncatedResponse :会話項目が切り捨てられたときに返されます。ConversationItemDeletedResponse :会話アイテムが削除されたときに返されます。InputAudioBufferCommittedResponse :クライアントによって、またはサーバーVADモードで自動的に入力オーディオバッファーがコミットされたときに返されます。InputAudioBufferClearedResponse :入力オーディオバッファーがクリアされたときに返されます。InputAudioBufferStartedResponse :サーバーモードのときにサーバーによって送信され、音声がオーディオバッファで検出されたことを示します。これは、バッファーにオーディオが追加されるときにいつでも発生する可能性があります(スピーチが既に検出されていない限り)。クライアントは、このイベントを使用してオーディオ再生を中断したり、ユーザーに視覚的なフィードバックを提供したりすることをお勧めします。InputAudioBufferStoppedResponse :サーバーがオーディオバッファーのスピーチの終了を検出したときにserver_vadモードで返されます。RealtimeResponse :応答が作成または実行されたときに返されます。ResponseOutputItemResponse :応答出力アイテムが追加または完了したときに返されます。ResponseContentPartResponse :応答コンテンツパーツが追加または完了したときに返されます。ResponseTextResponse :応答テキストが更新または完了したときに返されます。ResponseAudioTranscriptResponse :応答オーディオトランスクリプトが更新または完了したときに返されます。ResponseAudioResponse :応答オーディオが更新または完了したときに返されます。ResponseFunctionCallArgumentsResponse :応答関数呼び出しの引数が更新または完了したときに返されます。RateLimitsResponse :レート制限が更新されたときに返されます。 サーバーイベントを受信するには、セッションオブジェクトのRealtimeSession.ReceiveUpdatesAsyncメソッドを呼び出す必要があります。このメソッドは、セッションが閉じられたときまたはキャンセルトークンがトリガーされたときに完了するTaskまたはIAsyncEnumerable<T>を返します。理想的には、この方法は1回呼び出し、セッションの期間中に実行する必要があります。
注記
IServerEventの代わりにIRealtimeEventインターフェイスを使用して、 IClientEventコールバックを送信することもできます。
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は、壊れた変更の対象となります。
モデルを呼び出し、ツールを使用してタスクを実行できるアシスタントを構築します。
Assistants 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コールバックを通過することにより、既存のスレッドコールに簡単に追加できます。
アシスタントが対話できるスレッドを作成します。
Threads APIは、 OpenAIClient.ThreadsEndpointを介してアクセスされます
スレッドを作成します。
using var api = new OpenAIClient ( ) ;
var thread = await api . ThreadsEndpoint . CreateThreadAsync ( ) ;
Console . WriteLine ( $" Create thread { thread . Id } -> { thread . CreatedAt } " ) ; スレッドを作成し、1つのリクエストで実行します。
参照:スレッド実行
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 } " ) ; スレッドを作成し、イベントのストリーミング中に1つのリクエストで実行します。
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 and 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が長さである場合、モデルが返すメッセージのJSONは部分的に(つまり、カットオフ)できます。これを防ぐには、応答を解析する前に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ツールで使用するファイルを保存するために使用されます。
ベクトルストア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 ) ; ベクトルストアファイルは、ベクターストア内のファイルを表します。
ベクトルストアファイルのリストを返します。
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 ) ; ベクトルストアファイルを削除します。これにより、Vectorストアからファイルが削除されますが、ファイル自体は削除されません。ファイルを削除するには、削除ファイルエンドポイントを使用します。
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 " ) ;チャットの会話を考えると、モデルはチャット完了応答を返します。
チャット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が長さである場合、モデルが返すメッセージのJSONは部分的に(つまり、カットオフ)できます。これを防ぐには、応答を解析する前に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が長さである場合、モデルが返すメッセージのJSONは部分的に(つまり、カットオフ)できます。これを防ぐには、応答を解析する前に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 ) ;プロンプトおよび/または入力画像が与えられた場合、モデルは新しい画像を生成します。
Images APIは、 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 " ) ;
} さまざまなエンドポイントで使用できるファイルをアップロードします。 1つの組織によってアップロードされたすべてのファイルのサイズは、最大100 GBです。
個々のファイルのサイズは、最大512 MBです。サポートされているファイルの種類の詳細については、アシスタントツールガイドを参照してください。微調整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は、50%の割引で24時間以内に完了を返します。
Batches 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 ) ;機械学習モデルとアルゴリズムで簡単に消費できる特定の入力のベクトル表現を取得します。
関連ガイド:埋め込み
編集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のコンテンツポリシーに違反するものとしてモデルを分類すると出力されます。
関連ガイド:モデレーション
Moderations 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 ( ) ) ;