OpenAI API 的官方 .NET 库
The OpenAI .NET library provides convenient access to the OpenAI REST API from .NET applications.
It is generated from our OpenAPI specification in collaboration with Microsoft.
To call the OpenAI REST API, you will need an API key. To obtain one, first create a new OpenAI account or log in. Next, navigate to the API key page and select "Create new secret key", optionally naming the key. Make sure to save your API key somewhere safe and do not share it with anyone.
Add the client library to your .NET project by installing the NuGet package via your IDE or by running the following command in the .NET CLI:
dotnet add package OpenAI
Note that the code examples included below were written using .NET 10. The OpenAI .NET library is compatible with all .NET Standard 2.0 applications, but the syntax used in some of the code examples in this document may depend on newer language features.
Some client APIs are marked with [Experimental] while their .NET design is still evolving. Using one produces a compiler error that you must explicitly suppress for its diagnostic ID. See Preview APIs for .NET guidance and Feature lifecycle for how OpenAI .NET APIs are introduced and promoted to stable.
The public API listings for this library can be found in the api/ folder (organized by target framework), and there are many code examples to help. For instance, the following snippet illustrates the basic use of the chat completions API:
ChatClient client = new(model: "gpt-5.1", apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY"));
ChatCompletion completion = client.CompleteChat("Say 'this is a test.'");
Console.WriteLine($"[ASSISTANT]: {completion.Content[0].Text}");
While you can pass your API key directly as a string, it is highly recommended that you keep it in a secure location and instead access it via an environment variable or configuration file as shown above to avoid storing it in source control.
If you need to connect to an alternative API endpoint (for example, a proxy or self-hosted OpenAI-compatible LLM), you can specify a custom base URL and API key using the ApiKeyCredential and OpenAIClientOptions:
ChatClient client = new(
model: "MODEL_NAME",
credential: new ApiKeyCredential(Environment.GetEnvironmentVariable("OPENAI_API_KEY")),
options: new OpenAIClientOptions()
{
Endpoint = new Uri("https://YOUR_BASE_URL")
});
Replace MODEL_NAME with your model name and BASE_URL with your endpoint URI. This is useful when working with OpenAI-compatible APIs or custom deployments.
The library is organized into namespaces by feature areas in the OpenAI REST API. Each namespace contains a corresponding client class.
Namespace Client classOpenAI.Assistants
AssistantClient
OpenAI.Audio
AudioClient
OpenAI.Batch
BatchClient
OpenAI.Chat
ChatClient
OpenAI.Embeddings
EmbeddingClient
OpenAI.Evals
EvaluationClient
OpenAI.FineTuning
FineTuningClient
OpenAI.Files
OpenAIFileClient
OpenAI.Images
ImageClient
OpenAI.Models
OpenAIModelClient
OpenAI.Moderations
ModerationClient
OpenAI.Realtime
RealtimeClient
OpenAI.Responses
ResponsesClient
OpenAI.VectorStores
VectorStoreClient
Every client method that performs a synchronous API call has an asynchronous variant in the same client class. For instance, the asynchronous variant of the ChatClient's CompleteChat method is CompleteChatAsync. To rewrite the call above using the asynchronous counterpart, simply await the call to the corresponding async variant:
ChatCompletion completion = await client.CompleteChatAsync("Say 'this is a test.'");
OpenAIClient classIn addition to the namespaces mentioned above, there is also the parent OpenAI namespace itself:
using OpenAI;
This namespace contains the OpenAIClient class, which offers certain conveniences when you need to work with multiple feature area clients. Specifically, you can use an instance of this class to create instances of the other clients and have them share the same implementation details, which might be more efficient.
You can create an OpenAIClient by specifying the API key that all clients will use for authentication:
OpenAIClient client = new(Environment.GetEnvironmentVariable("OPENAI_API_KEY"));
Next, to create an instance of an AudioClient, for example, you can call the OpenAIClient's GetAudioClient method by passing the OpenAI model that the AudioClient will use, just as if you were using the AudioClient constructor directly. If necessary, you can create additional clients of the same type to target different models.
AudioClient ttsClient = client.GetAudioClient("tts-1");
AudioClient whisperClient = client.GetAudioClient("whisper-1");
The OpenAI clients are thread-safe and can be safely registered as singletons in ASP.NET Core's Dependency Injection container. This maximizes resource efficiency and HTTP connection reuse. In your Program.cs file, register the ChatClient as follows:
builder.AddChatClient("Clients:ChatClient");
Then inject and use the client in your controllers or services:
[ApiController]
[Route("api/[controller]")]
public class ChatController : ControllerBase
{
private readonly ChatClient _chatClient;
public ChatController(ChatClient chatClient)
{
_chatClient = chatClient;
}
[HttpPost("complete")]
public async Task<IActionResult> CompleteChat([FromBody] string message)
{
ChatCompletion completion = await _chatClient.CompleteChatAsync(message);
return Ok(new { response = completion.Content[0].Text });
}
}
For a complete ASP.NET Core sample project, see the dependency injection sample.
When you request a chat completion, the default behavior is for the server to generate it in its entirety before sending it back in a single response. Consequently, long chat completions can require waiting for several seconds before hearing back from the server. To mitigate this, the OpenAI REST API supports the ability to stream partial results back as they are being generated, allowing you to start processing the beginning of the completion before it is finished.
The client library offers a convenient approach to working with streaming chat completions. If you wanted to re-write the example from the previous section using streaming, rather than calling the ChatClient's CompleteChat method, you would call its CompleteChatStreaming method instead:
CollectionResult<StreamingChatCompletionUpdate> completionUpdates = client.CompleteChatStreaming("Say 'this is a test.'");
Notice that the returned value is a CollectionResult<StreamingChatCompletionUpdate> instance, which can be enumerated to process the streaming response chunks as they arrive:
CollectionResult<StreamingChatCompletionUpdate> completionUpdates = client.CompleteChatStreaming("Say 'this is a test.'");
Console.Write($"[ASSISTANT]: ");
foreach (StreamingChatCompletionUpdate completionUpdate in completionUpdates)
{
if (completionUpdate.ContentUpdate.Count > 0)
{
Console.Write(completionUpdate.ContentUpdate[0].Text);
}
}
Alternatively, you can do this asynchronously by calling the CompleteChatStreamingAsync method to get an AsyncCollectionResult<StreamingChatCompletionUpdate> and enumerate it using await foreach:
AsyncCollectionResult<StreamingChatCompletionUpdate> completionUpdates = client.CompleteChatStreamingAsync("Say 'this is a test.'");
Console.Write($"[ASSISTANT]: ");
await foreach (StreamingChatCompletionUpdate completionUpdate in completionUpdates)
{
if (completionUpdate.ContentUpdate.Count > 0)
{
Console.Write(completionUpdate.ContentUpdate[0].Text);
}
}
In this example, you have two functions. The first function can retrieve a user's current geographic location (e.g., by polling the location service APIs of the user's device), while the second function can query the weather in a given location (e.g., by making an API call to some third-party weather service). You want the model to be able to call these functions if it deems it necessary to ha
暂无开放 Issues,或尚未同步最近议题。