Une simple bibliothèque client C # .NET à utiliser OpenAI à utiliser par leur API RESTFUL. Développé indépendamment, ce n'est pas une bibliothèque officielle et je ne suis pas affilié à Openai. Un compte API OpenAI est requis.
À l'origine fourchu à partir d'Openai-API-Dotnet. Plus de contexte sur le blog de Roger Pinombe.
Installez le package OpenAI-DotNet depuis NuGet. Voici comment via la ligne de commande:
PowerShell:
Install-Package OpenAI-DotNet
dotnet:
dotnet add package OpenAI-DotNet
Vous cherchez à utiliser Openai-Dotnet dans le moteur Unity Game? Consultez notre package Unity sur OpenUpM:
Découvrez nos nouveaux documents API!
https://rageagainstthepixel.github.io/openai-dotnet
Il existe 3 façons de fournir vos clés API, par ordre de priorité:
Avertissement
Nous avons recommandé d'utiliser les variables d'environnement pour charger la touche API au lieu de le coder dur dans votre source. Il n'est pas recommandé d'utiliser cette méthode en production, mais uniquement pour accepter les informations d'identification utilisateur, les tests locaux et les scénarios de démarrage rapide.
Avertissement
Nous avons recommandé d'utiliser les variables d'environnement pour charger la touche API au lieu de le coder dur dans votre source. Il n'est pas recommandé d'utiliser cette méthode en production, mais uniquement pour accepter les informations d'identification utilisateur, les tests locaux et les scénarios de démarrage rapide.
using var api = new OpenAIClient ( " sk-apiKey " ) ; Ou créer un objet OpenAIAuthentication manuellement
using var api = new OpenAIClient ( new OpenAIAuthentication ( " sk-apiKey " , " org-yourOrganizationId " , " proj_yourProjectId " ) ) ; Tente de charger des clés d'API à partir d'un fichier de configuration, par défaut .openai dans le répertoire actuel, en train de traverser éventuellement l'arborescence du répertoire ou dans le répertoire domestique de l'utilisateur.
Pour créer un fichier de configuration, créez un nouveau fichier texte nommé .openai et contenant la ligne:
Note
Les entrées d'organisation et d'identification du projet sont facultatives.
{
"apiKey" : " sk-aaaabbbbbccccddddd " ,
"organizationId" : " org-yourOrganizationId " ,
"projectId" : " proj_yourProjectId "
}OPENAI_API_KEY=sk-aaaabbbbbccccddddd
OPENAI_ORGANIZATION_ID=org-yourOrganizationId
OPENAI_PROJECT_ID=proj_yourProjectId Vous pouvez également charger le fichier de configuration directement avec le chemin connu en appelant des méthodes statiques dans OpenAIAuthentication :
.openai par défaut dans le répertoire spécifié: using var api = new OpenAIClient ( OpenAIAuthentication . LoadFromDirectory ( " path/to/your/directory " ) ) ;.openai tant qu'il est conforme au format JSON: using var api = new OpenAIClient ( OpenAIAuthentication . LoadFromPath ( " path/to/your/file.json " ) ) ; Utilisez les variables d'environnement de votre système Spécifiez une clé API et une organisation à utiliser.
OPENAI_API_KEY pour votre clé API.OPENAI_ORGANIZATION_ID pour spécifier une organisation.OPENAI_PROJECT_ID pour spécifier un projet. using var api = new OpenAIClient ( OpenAIAuthentication . LoadFromEnv ( ) ) ; OpenAIClient implémente IDisposable pour gérer le cycle de vie des ressources qu'il utilise, y compris HttpClient . Lorsque vous initialisez OpenAIClient , il créera une instance HttpClient interne si l'on n'est pas fourni. Ce HttpClient interne est éliminé lorsque OpenAIClient est éliminé. Si vous fournissez une instance HttpClient externe à OpenAIClient , vous êtes responsable de la gestion de son élimination.
OpenAIClient crée son propre HttpClient , il s'occupera également de l'éliminer lorsque vous disposez OpenAIClient .HttpClient externe est transmis à OpenAIClient , il ne sera pas éliminé par OpenAIClient . Vous devez gérer vous-même l'élimination du HttpClient . Veuillez vous assurer de disposer de manière appropriée d' OpenAIClient pour libérer les ressources en temps opportun et d'éviter toute mémoire potentielle de mémoire ou de ressources dans votre application.
Utilisation typique avec un HttpClient interne:
using var api = new OpenAIClient ( ) ; HttpClient personnalisé (que vous devez vous éliminer):
using var customHttpClient = new HttpClient ( ) ;
// set custom http client properties here
var api = new OpenAIClient ( client : customHttpClient ) ;Vous pouvez également choisir d'utiliser également les déploiements Azure Openai de Microsoft.
Vous pouvez trouver les informations requises dans le terrain de jeu Azure en cliquant sur le bouton View Code et afficher une URL comme ceci:
https://{your-resource-name}.openai.azure.com/openai/deployments/{deployment-id}/chat/completions?api-version={api-version}your-resource-name de votre ressource Azure Openai.deployment-id Le nom de déploiement que vous avez choisi lorsque vous avez déployé le modèle.api-version La version API à utiliser pour cette opération. Cela suit le format Yyyy-MM-DD. Pour configurer le client pour utiliser votre déploiement, vous devrez passer dans OpenAIClientSettings dans le constructeur du client.
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 ) ; Authentifiez-vous avec MSAL comme d'habitude et obtenez un jeton d'accès, puis utilisez le jeton d'accès lors de la création de votre OpenAIAuthentication . Assurez-vous ensuite de définir UseAazureActiveDirectory sur true lors de la création de vos OpenAIClientSettings .
Tutoriel: application de bureau qui appelle les API Web: acquérir un jeton
// 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 ) ;L'utilisation des packages Openai-Dotnet ou com.openai.unity directement dans votre application frontale peut exposer vos clés API et autres informations sensibles. Pour atténuer ce risque, il est recommandé de créer une API intermédiaire qui fait des demandes d'ouverture au nom de votre application frontale. Cette bibliothèque peut être utilisée pour les configurations de l'hôte frontal et intermédiaire, assurant une communication sécurisée avec l'API OpenAI.
Dans l'exemple frontal, vous devrez authentifier en toute sécurité vos utilisateurs à l'aide de votre fournisseur OAuth préféré. Une fois que l'utilisateur est authentifié, échangez votre jeton Auth personnalisé avec votre clé API sur le backend.
Suivez ces étapes:
OpenAIAuthentication et passez dans le jeton personnalisé avec le préfixe sess- .OpenAIClientSettings et spécifiez le domaine où se trouve votre API intermédiaire.auth and settings au constructeur OpenAIClient lorsque vous créez l'instance client.Voici un exemple de la configuration de l'avant:
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 ) ;Cette configuration permet à votre application frontale de communiquer en toute sécurité avec votre backend qui utilisera l'OpenAI-Dotnet-Proxy, qui transmet ensuite les demandes à l'API OpenAI. Cela garantit que vos clés API OpenAI et autres informations sensibles restent en sécurité tout au long du processus.
Dans cet exemple, nous montrons comment configurer et utiliser OpenAIProxy dans une nouvelle application Web ASP.NET Core. Le serveur proxy gérera l'authentification et transférera les demandes à l'API OpenAI, garantissant que vos clés d'API et d'autres informations sensibles restent sécurisées.
Install-Package OpenAI-DotNet-Proxydotnet add package OpenAI-DotNet-Proxy<PackageReference Include="OpenAI-DotNet-Proxy" />AbstractAuthenticationFilter et remplacez la méthode ValidateAuthentication . Cela implémentera le IAuthenticationFilter que vous utiliserez pour vérifier le jeton de session utilisateur par rapport à votre serveur interne.Program.cs , créez une nouvelle application Web proxy en appelant OpenAIProxy.CreateWebApplication , en passant votre AuthenticationFilter personnalisé en tant qu'argument de type.OpenAIAuthentication et OpenAIClientSettings comme vous le feriez normalement avec vos touches API, votre ID org ou vos paramètres 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 ( ) ;
}
}Une fois que vous avez configuré votre serveur proxy, vos utilisateurs finaux peuvent désormais faire des demandes authentifiées à votre API proxy plutôt que directement à l'API OpenAI. Le serveur proxy gérera l'authentification et transférera les demandes à l'API OpenAI, garantissant que vos clés d'API et d'autres informations sensibles restent sécurisées.
Énumérez et décrivez les différents modèles disponibles dans l'API. Vous pouvez vous référer à la documentation des modèles pour comprendre quels modèles sont disponibles et les différences entre elles.
Découvrez également la compatibilité des points de terminaison pour comprendre quels modèles fonctionnent avec quels points de terminaison.
Pour spécifier un modèle personnalisé non prédéfini dans cette bibliothèque:
var model = new Model ( " model-id " ) ; L'API des modèles est accessible via OpenAIClient.ModelsEndpoint
Répertorie les modèles actuellement disponibles et fournit des informations de base sur chacune comme le propriétaire et la disponibilité.
using var api = new OpenAIClient ( ) ;
var models = await api . ModelsEndpoint . GetModelsAsync ( ) ;
foreach ( var model in models )
{
Console . WriteLine ( model . ToString ( ) ) ;
} Récupère une instance de modèle, fournissant des informations de base sur le modèle tel que le propriétaire et les autorisations.
using var api = new OpenAIClient ( ) ;
var model = await api . ModelsEndpoint . GetModelDetailsAsync ( " gpt-4o " ) ;
Console . WriteLine ( model . ToString ( ) ) ; Supprimer un modèle affiné. Vous devez avoir le rôle du propriétaire dans votre organisation.
using var api = new OpenAIClient ( ) ;
var isDeleted = await api . ModelsEndpoint . DeleteFineTuneModelAsync ( " your-fine-tuned-model " ) ;
Assert . IsTrue ( isDeleted ) ;Avertissement
Fonction bêta. API soumise à des changements de rupture.
L'API en temps réel vous permet de construire des expériences conversationnelles multimodales à faible latence. Il prend actuellement en charge le texte et l'audio en tant qu'entrée et sortie, ainsi que des appels de fonction.
L'API Assistants est accessible via OpenAIClient.RealtimeEndpoint
Voici un exemple simple de la façon de créer une session en temps réel et d'envoyer et de recevoir des messages du modèle.
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 ;
}
} La bibliothèque implémente l'interface IClientEvent pour les événements envoyés par le client sortant.
UpdateSessionRequest : Mettez à jour la session avec de nouvelles options de session.InputAudioBufferAppendRequest : Ajoutez l'audio dans le tampon audio d'entrée. (Contrairement à faire d'autres événements clients, le serveur n'enverra pas de réponse de confirmation à cet événement).InputAudioBufferCommitRequest : Commissez le tampon audio d'entrée. (En mode VAD Server, le client n'a pas besoin d'envoyer cet événement).InputAudioBufferClearRequest : Effacez le tampon audio d'entrée.ConversationItemCreateRequest : Créez un nouvel élément de conversation. C'est le principal moyen d'envoyer du contenu utilisateur au modèle.ConversationItemTruncateRequest : Envoyez cet événement pour tronquer l'audio d'un message assistant précédent.ConversationItemDeleteRequest : supprimez un élément de conversation. Ceci est utile lorsque vous souhaitez supprimer un message de l'historique de la conversation.CreateResponseRequest : créez une réponse à partir du modèle. Envoyez cet événement après avoir créé de nouveaux éléments de conversation ou invoquant des appels d'outils. Cela déclenchera le modèle pour générer une réponse.ResponseCancelRequest -Send cet événement pour annuler une réponse en cours. Vous pouvez envoyer des événements clients à tout moment sur le serveur en appelant la méthode RealtimeSession.SendAsync sur l'objet de session. L'appel d'envoi renverra une poignée IServerEvent qui représente le mieux la réponse appropriée du serveur pour cet événement. Ceci est utile si vous souhaitez gérer les réponses du serveur de manière plus granulaire.
Idéalement cependant, vous voudrez peut-être gérer toutes les réponses du serveur avec RealtimeSession.ReceiveUpdatesAsync .
Note
Le serveur n'enverra pas de réponse de confirmation à l'événement InputAudioBufferAppendRequest .
Important
Vous devrez également envoyer CreateResponseRequest pour déclencher le modèle pour générer une réponse.
var serverEvent = await session . SendAsync ( new ConversationItemCreateRequest ( " Hello! " ) ) ;
Console . WriteLine ( serverEvent . ToJsonString ( ) ) ;
serverEvent = await session . SendAsync ( new CreateResponseRequest ( ) ) ;
Console . WriteLine ( serverEvent . ToJsonString ( ) ) ; La bibliothèque implémente l'interface IServerEvent pour les événements envoyés de serveur entrant.
RealtimeEventError : renvoyé lorsqu'une erreur se produit, ce qui pourrait être un problème client ou un problème de serveur.SessionResponse : Retour pour une session.created et session.updated Event.RealtimeConversationResponse : Retourné lorsqu'un nouvel élément de conversation est créé.ConversationItemCreatedResponse : Retourné lorsqu'un nouvel élément de conversation est créé.ConversationItemInputAudioTranscriptionResponse : renvoyé lorsque la transcription audio d'entrée est terminée ou échouée.ConversationItemTruncatedResponse : Retourné lorsqu'un élément de conversation est tronqué.ConversationItemDeletedResponse : Retourné lorsqu'un élément de conversation est supprimé.InputAudioBufferCommittedResponse : Retourné lorsqu'un tampon audio d'entrée est engagé, soit par le client, soit automatiquement en mode VAD Server.InputAudioBufferClearedResponse : Retourné lorsqu'un tampon audio d'entrée est effacé.InputAudioBufferStartedResponse : envoyé par le serveur en mode server_vad pour indiquer que la parole a été détectée dans le tampon audio. Cela peut se produire à chaque fois que l'audio est ajouté au tampon (sauf si la parole est déjà détectée). Le client peut vouloir utiliser cet événement pour interrompre la lecture audio ou fournir des commentaires visuels à l'utilisateur.InputAudioBufferStoppedResponse : renvoyé en mode server_vad lorsque le serveur détecte la fin de la parole dans le tampon audio.RealtimeResponse : retourné lorsqu'une réponse est créée ou terminée.ResponseOutputItemResponse : Retourné lorsqu'un élément de sortie de réponse est ajouté ou terminé.ResponseContentPartResponse : Retournée lorsqu'une partie de contenu de réponse est ajoutée ou terminée.ResponseTextResponse : renvoyé lorsqu'un texte de réponse est mis à jour ou fait.ResponseAudioTranscriptResponse : Renvoyé lorsqu'un transcrit audio de réponse est mis à jour ou fait.ResponseAudioResponse : retourné lorsqu'un audio de réponse est mis à jour ou fait.ResponseFunctionCallArgumentsResponse : renvoyé lorsqu'une fonction de réponse des arguments d'appel est mise à jour ou terminée.RateLimitsResponse : retourné lorsque les limites de taux sont mises à jour. Pour recevoir des événements de serveur, vous devrez appeler la méthode RealtimeSession.ReceiveUpdatesAsync sur l'objet de session. Cette méthode renverra une Task ou IAsyncEnumerable<T> qui se terminera lorsque la session sera fermée ou lorsque le jeton d'annulation est déclenché. Idéalement, cette méthode doit être appelée une fois et s'exécute pendant la durée de la session.
Note
Vous pouvez également recevoir des rappels IClientEvent en utilisant l'interface IRealtimeEvent au lieu d' 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 ;
}
}Avertissement
Fonction bêta. API soumise à des changements de rupture.
Construisez des assistants qui peuvent appeler des modèles et utiliser des outils pour effectuer des tâches.
L'API Assistants est accessible via OpenAIClient.AssistantsEndpoint
Renvoie une liste d'assistants.
using var api = new OpenAIClient ( ) ;
var assistantsList = await api . AssistantsEndpoint . ListAssistantsAsync ( ) ;
foreach ( var assistant in assistantsList . Items )
{
Console . WriteLine ( $" { assistant } -> { assistant . CreatedAt } " ) ;
} Créez un assistant avec un modèle et des instructions.
using var api = new OpenAIClient ( ) ;
var request = new CreateAssistantRequest ( Model . GPT4o ) ;
var assistant = await api . AssistantsEndpoint . CreateAssistantAsync ( request ) ; Récupère un assistant.
using var api = new OpenAIClient ( ) ;
var assistant = await api . AssistantsEndpoint . RetrieveAssistantAsync ( " assistant-id " ) ;
Console . WriteLine ( $" { assistant } -> { assistant . CreatedAt } " ) ; Modifie un assistant.
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 ) ; Supprimer un assistant.
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 ) ; Note
Les événements de flux assistant peuvent être facilement ajoutés aux appels de fil existants en passant Func<IServerSentEvent, Task> streamEventHandler à toute méthode existante qui prend en charge le streaming.
Créer des fils avec lesquels les assistants peuvent interagir.
L'API Threads est accessible via OpenAIClient.ThreadsEndpoint
Créer un fil.
using var api = new OpenAIClient ( ) ;
var thread = await api . ThreadsEndpoint . CreateThreadAsync ( ) ;
Console . WriteLine ( $" Create thread { thread . Id } -> { thread . CreatedAt } " ) ; Créez un thread et exécutez-le en une seule demande.
Voir aussi: 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 } " ) ; Créez un thread et exécutez-le en une seule demande lors de la diffusion d'événements.
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 ( ) } " ) ;
} Récupère un fil.
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 } " ) ; Modifie un fil.
Remarque: seules les métadonnées peuvent être modifiées.
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 " ] } " ) ; Supprimer un fil.
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 ) ; Créer des messages dans les threads.
Renvoie une liste de messages pour un thread donné.
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 ( ) } " ) ;
} Créer un message.
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 ( ) } " ) ; Récupérez un message.
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 ( ) } " ) ; Modifier un message.
Remarque: seules les métadonnées du message peuvent être modifiées.
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 " ] } " ) ; Représente une exécution exécutée sur un thread.
Renvoie une liste de cycles appartenant à un fil.
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 } " ) ;
} Créez une course.
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 } " ) ; Créez une exécution et diffusez les événements.
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 ( ) } " ) ;
} Récupère une course.
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 } " ) ; Modifie une course.
Remarque: seules les métadonnées peuvent être modifiées.
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 " ] } " ) ; Lorsqu'une exécution a le statut: requires_action et required_action.type est submit_tool_outputs , ce point de terminaison peut être utilisé pour soumettre les sorties des appels d'outil une fois tous terminés. Toutes les sorties doivent être soumises en une seule demande.
Note
Voir Créer un exemple de thread et d'exécuter un exemple de streaming sur la façon de diffuser des événements de sortie de l'outil.
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 ( ) } " ) ;
} Les sorties structurées sont l'évolution du mode JSON. Bien que les deux garantissent que le JSON valide soit produit, seules les sorties structurées garantissent l'adhésion au schéma.
Important
finish_reason est la longueur, ce qui indique que la génération a dépassé Max_Tokens ou la conversation a dépassé la limite de jeton. Pour vous prémunir, vérifiez finish_reason avant d'analyser la réponse.Définissez d'abord la structure de vos réponses. Ceux-ci seront utilisés comme schéma. Ce sont les objets auxquels vous désérialiser, alors assurez-vous d'utiliser des modèles d'objets JSON standard.
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 ; }
} Pour utiliser, spécifiez simplement le type MathResponse comme une contrainte générique dans CreateAssistantAsync , CreateRunAsync ou 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 ) ;
}
}Vous pouvez également créer manuellement la chaîne JSON JSON Schema, mais vous serez responsable de désérialiser vos données de réponse:
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 ) ;
}
} Renvoie une liste des étapes d'exécution appartenant à une course.
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 } " ) ;
} Récupère une étape de course.
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 } " ) ; Annule une course qui est 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 ) ; Les magasins vectoriels sont utilisés pour stocker des fichiers à utiliser par l'outil file_search .
L'API Vector Stores est accessible via OpenAIClient.VectorStoresEndpoint
Renvoie une liste de magasins vectoriels.
using var api = new OpenAIClient ( ) ;
var vectorStores = await api . VectorStoresEndpoint . ListVectorStoresAsync ( ) ;
foreach ( var vectorStore in vectorStores . Items )
{
Console . WriteLine ( vectorStore ) ;
} Créez un magasin vectoriel.
using var api = new OpenAIClient ( ) ;
var createVectorStoreRequest = new CreateVectorStoreRequest ( " test-vector-store " ) ;
var vectorStore = await api . VectorStoresEndpoint . CreateVectorStoreAsync ( createVectorStoreRequest ) ;
Console . WriteLine ( vectorStore ) ; Récupère un magasin vectoriel.
using var api = new OpenAIClient ( ) ;
var vectorStore = await api . VectorStoresEndpoint . GetVectorStoreAsync ( " vector-store-id " ) ;
Console . WriteLine ( vectorStore ) ; Modifie un magasin vectoriel.
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 ) ; Supprimer un magasin vectoriel.
using var api = new OpenAIClient ( ) ;
var isDeleted = await api . VectorStoresEndpoint . DeleteVectorStoreAsync ( " vector-store-id " ) ;
Assert . IsTrue ( isDeleted ) ; Les fichiers de magasin vectoriel représentent des fichiers dans un magasin vectoriel.
Renvoie une liste de fichiers de magasin vectoriel.
using var api = new OpenAIClient ( ) ;
var files = await api . VectorStoresEndpoint . ListVectorStoreFilesAsync ( " vector-store-id " ) ;
foreach ( var file in vectorStoreFiles . Items )
{
Console . WriteLine ( file ) ;
} Créez un fichier de magasin vectoriel en joignant un fichier à un magasin vectoriel.
using var api = new OpenAIClient ( ) ;
var file = await api . VectorStoresEndpoint . CreateVectorStoreFileAsync ( " vector-store-id " , " file-id " , new ChunkingStrategy ( ChunkingStrategyType . Static ) ) ;
Console . WriteLine ( file ) ; Récupère un fichier de magasin vectoriel.
using var api = new OpenAIClient ( ) ;
var file = await api . VectorStoresEndpoint . GetVectorStoreFileAsync ( " vector-store-id " , " vector-store-file-id " ) ;
Console . WriteLine ( file ) ; Supprimer un fichier de magasin vectoriel. Cela supprimera le fichier du magasin vectoriel, mais le fichier lui-même ne sera pas supprimé. Pour supprimer le fichier, utilisez le point de terminaison de suppression.
using var api = new OpenAIClient ( ) ;
var isDeleted = await api . VectorStoresEndpoint . DeleteVectorStoreFileAsync ( " vector-store-id " , vectorStoreFile ) ;
Assert . IsTrue ( isDeleted ) ; Les fichiers de magasin vectoriel représentent des fichiers dans un magasin vectoriel.
Créez un lot de fichiers de magasin vectoriel.
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 ) ; Récupère un lot de fichiers de magasin vectoriel.
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 ( ) ; Renvoie une liste de fichiers de magasin vectoriel dans un lot.
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 ) ;
} Annuler un lot de fichiers de magasin vectoriel. Cela tente d'annuler le traitement des fichiers dans ce lot dès que possible.
using var api = new OpenAIClient ( ) ;
var isCancelled = await api . VectorStoresEndpoint . CancelVectorStoreFileBatchAsync ( " vector-store-id " , " vector-store-file-batch-id " ) ;Compte tenu d'une conversation de chat, le modèle renverra une réponse d'achèvement de chat.
L'API de chat est accessible via OpenAIClient.ChatEndpoint
Crée une réalisation du message de chat
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 } " ) ; Ou si vous utilisez 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. Avertissement
Fonction bêta. API soumise à des changements de rupture.
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 L'évolution du mode JSON. Bien que les deux garantissent que le JSON valide soit produit, seules les sorties structurées garantissent l'adhésion au schéma.
Important
finish_reason est la longueur, ce qui indique que la génération a dépassé Max_Tokens ou la conversation a dépassé la limite de jeton. Pour vous prémunir, vérifiez finish_reason avant d'analyser la réponse.Définissez d'abord la structure de vos réponses. Ceux-ci seront utilisés comme schéma. Ce sont les objets auxquels vous désérialiser, alors assurez-vous d'utiliser des modèles d'objets JSON standard.
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 ; }
} Pour utiliser, spécifiez simplement le type MathResponse comme une contrainte générique lors de la demande d'un achèvement.
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 ( ) ; Important
finish_reason est la longueur, ce qui indique que la génération a dépassé Max_Tokens ou la conversation a dépassé la limite de jeton. Pour vous prémunir, vérifiez finish_reason avant d'analyser la réponse. 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 ( ) ;Convertit l'audio en texte.
L'API audio est accessible via OpenAIClient.AudioEndpoint
Génère l'audio à partir du texte d'entrée.
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 ( ) ) ; Transcrit l'audio dans la langue d'entrée.
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 ) ; Vous pouvez également obtenir des informations détaillées à l'aide de verbose_json pour obtenir des granulations d'horodatage:
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 } " " ) ;
} Traduit l'audio en anglais.
using var api = new OpenAIClient ( ) ;
using var request = new AudioTranslationRequest ( Path . GetFullPath ( audioAssetPath ) ) ;
var response = await api . AudioEndpoint . CreateTranslationTextAsync ( request ) ;
Console . WriteLine ( response ) ;Étant donné une invite et / ou une image d'entrée, le modèle générera une nouvelle image.
L'API Images est accessible via OpenAIClient.ImagesEndpoint
Crée une image donnée une invite.
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
} Crée une image modifiée ou étendue étant donné une image originale et une invite.
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
} Crée une variation d'une image donnée.
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
}Les fichiers sont utilisés pour télécharger des documents qui peuvent être utilisés avec des fonctionnalités telles que le réglage fin.
L'API des fichiers est accessible via OpenAIClient.FilesEndpoint
Renvoie une liste de fichiers appartenant à l'organisation de l'utilisateur.
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 " ) ;
} Téléchargez un fichier qui peut être utilisé sur divers points de terminaison. La taille de tous les fichiers téléchargés par une organisation peut atteindre 100 Go.
La taille des fichiers individuels peut être un maximum de 512 Mo. Voir le guide des outils Assistants pour en savoir plus sur les types de fichiers pris en charge. L'API à réglage fin ne prend en charge que les fichiers .jsonl.
using var api = new OpenAIClient ( ) ;
var file = await api . FilesEndpoint . UploadFileAsync ( " path/to/your/file.jsonl " , FilePurpose . FineTune ) ;
Console . WriteLine ( file . Id ) ; Supprimer un fichier.
using var api = new OpenAIClient ( ) ;
var isDeleted = await api . FilesEndpoint . DeleteFileAsync ( fileId ) ;
Assert . IsTrue ( isDeleted ) ; Renvoie des informations sur un fichier spécifique.
using var api = new OpenAIClient ( ) ;
var file = await api . FilesEndpoint . GetFileInfoAsync ( fileId ) ;
Console . WriteLine ( $" { file . Id } -> { file . Object } : { file . FileName } | { file . Size } bytes " ) ; Télécharge le contenu du fichier dans le répertoire spécifié.
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 ) ) ;Gérez les travaux de réglage fin pour adapter un modèle à vos données de formation spécifiques.
Guide connexe: modèles affinés
L'API des fichiers est accessible via OpenAIClient.FineTuningEndpoint
Crée un travail qui affine un modèle spécifié à partir d'un ensemble de données donné.
La réponse comprend les détails du travail en file d'attente, y compris l'état du travail et le nom des modèles affinés une fois terminés.
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 } " ) ; Énumérez les travaux de réglage fin de votre organisation.
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 } " ) ;
} Obtient des informations sur le travail final.
using var api = new OpenAIClient ( ) ;
var job = await api . FineTuningEndpoint . GetJobInfoAsync ( fineTuneJob ) ;
Console . WriteLine ( $" { job . Id } -> { job . CreatedAt } | { job . Status } " ) ; Annulez immédiatement un travail d'adaptation.
using var api = new OpenAIClient ( ) ;
var isCancelled = await api . FineTuningEndpoint . CancelFineTuneJobAsync ( fineTuneJob ) ;
Assert . IsTrue ( isCancelled ) ; Obtenez des mises à jour de statut pour un travail de réglage fin.
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 } " ) ;
}Créez de grands lots de demandes d'API pour le traitement asynchrone. L'API par lots renvoie les achèvements dans les 24 heures pour une remise de 50%.
L'API Batches est accessible via OpenAIClient.BatchesEndpoint
Énumérez les lots de votre organisation.
using var api = new OpenAIClient ( ) ;
var batches = await api . BatchEndpoint . ListBatchesAsync ( ) ;
foreach ( var batch in listResponse . Items )
{
Console . WriteLine ( batch ) ;
} Crée et exécute un lot à partir d'un fichier de demandes téléchargé
using var api = new OpenAIClient ( ) ;
var batchRequest = new CreateBatchRequest ( " file-id " , Endpoint . ChatCompletions ) ;
var batch = await api . BatchEndpoint . CreateBatchAsync ( batchRequest ) ; Récupère un lot.
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 ( ) ; Annule un lot en cours. Le lot sera dans l'annulation de l'état jusqu'à 10 minutes, avant de passer à l'annulation, où il aura des résultats partiels (le cas échéant) disponibles dans le fichier de sortie.
using var api = new OpenAIClient ( ) ;
var isCancelled = await api . BatchEndpoint . CancelBatchAsync ( batch ) ;
Assert . IsTrue ( isCancelled ) ;Obtenez une représentation vectorielle d'une entrée donnée qui peut être facilement consommée par les modèles d'apprentissage automatique et les algorithmes.
Guide connexe: intégres
L'API Edits est accessible via OpenAIClient.EmbeddingsEndpoint
Crée un vecteur d'intégration représentant le texte d'entrée.
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 ) ;Compte tenu d'un texte d'entrée, les sorties si le modèle le classe comme violant la politique de contenu d'Openai.
Guide connexe: modérations
L'API des modérations est accessible via OpenAIClient.ModerationsEndpoint
Classifie si le texte viole la politique de contenu d'Openai.
using var api = new OpenAIClient ( ) ;
var isViolation = await api . ModerationsEndpoint . GetModerationAsync ( " I want to kill them. " ) ;
Assert . IsTrue ( isViolation ) ;De plus, vous pouvez également obtenir les scores d'une entrée donnée.
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 ( ) ) ;