|
Add this skill
npx mdskills install sickn33/azure-ai-openai-dotnetComprehensive Azure OpenAI SDK reference with excellent code examples and best practices
1---2name: azure-ai-openai-dotnet3description: |4 Azure OpenAI SDK for .NET. Client library for Azure OpenAI and OpenAI services. Use for chat completions, embeddings, image generation, audio transcription, and assistants. Triggers: "Azure OpenAI", "AzureOpenAIClient", "ChatClient", "chat completions .NET", "GPT-4", "embeddings", "DALL-E", "Whisper", "OpenAI .NET".5package: Azure.AI.OpenAI6---78# Azure.AI.OpenAI (.NET)910Client library for Azure OpenAI Service providing access to OpenAI models including GPT-4, GPT-4o, embeddings, DALL-E, and Whisper.1112## Installation1314```bash15dotnet add package Azure.AI.OpenAI1617# For OpenAI (non-Azure) compatibility18dotnet add package OpenAI19```2021**Current Version**: 2.1.0 (stable)2223## Environment Variables2425```bash26AZURE_OPENAI_ENDPOINT=https://<resource-name>.openai.azure.com27AZURE_OPENAI_API_KEY=<api-key> # For key-based auth28AZURE_OPENAI_DEPLOYMENT_NAME=gpt-4o-mini # Your deployment name29```3031## Client Hierarchy3233```34AzureOpenAIClient (top-level)35├── GetChatClient(deploymentName) → ChatClient36├── GetEmbeddingClient(deploymentName) → EmbeddingClient37├── GetImageClient(deploymentName) → ImageClient38├── GetAudioClient(deploymentName) → AudioClient39└── GetAssistantClient() → AssistantClient40```4142## Authentication4344### API Key Authentication4546```csharp47using Azure;48using Azure.AI.OpenAI;4950AzureOpenAIClient client = new(51 new Uri(Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")!),52 new AzureKeyCredential(Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY")!));53```5455### Microsoft Entra ID (Recommended for Production)5657```csharp58using Azure.Identity;59using Azure.AI.OpenAI;6061AzureOpenAIClient client = new(62 new Uri(Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")!),63 new DefaultAzureCredential());64```6566### Using OpenAI SDK Directly with Azure6768```csharp69using Azure.Identity;70using OpenAI;71using OpenAI.Chat;72using System.ClientModel.Primitives;7374#pragma warning disable OPENAI0017576BearerTokenPolicy tokenPolicy = new(77 new DefaultAzureCredential(),78 "https://cognitiveservices.azure.com/.default");7980ChatClient client = new(81 model: "gpt-4o-mini",82 authenticationPolicy: tokenPolicy,83 options: new OpenAIClientOptions()84 {85 Endpoint = new Uri("https://YOUR-RESOURCE.openai.azure.com/openai/v1")86 });87```8889## Chat Completions9091### Basic Chat9293```csharp94using Azure.AI.OpenAI;95using OpenAI.Chat;9697AzureOpenAIClient azureClient = new(98 new Uri(endpoint),99 new DefaultAzureCredential());100101ChatClient chatClient = azureClient.GetChatClient("gpt-4o-mini");102103ChatCompletion completion = chatClient.CompleteChat(104[105 new SystemChatMessage("You are a helpful assistant."),106 new UserChatMessage("What is Azure OpenAI?")107]);108109Console.WriteLine(completion.Content[0].Text);110```111112### Async Chat113114```csharp115ChatCompletion completion = await chatClient.CompleteChatAsync(116[117 new SystemChatMessage("You are a helpful assistant."),118 new UserChatMessage("Explain cloud computing in simple terms.")119]);120121Console.WriteLine($"Response: {completion.Content[0].Text}");122Console.WriteLine($"Tokens used: {completion.Usage.TotalTokenCount}");123```124125### Streaming Chat126127```csharp128await foreach (StreamingChatCompletionUpdate update129 in chatClient.CompleteChatStreamingAsync(messages))130{131 if (update.ContentUpdate.Count > 0)132 {133 Console.Write(update.ContentUpdate[0].Text);134 }135}136```137138### Chat with Options139140```csharp141ChatCompletionOptions options = new()142{143 MaxOutputTokenCount = 1000,144 Temperature = 0.7f,145 TopP = 0.95f,146 FrequencyPenalty = 0,147 PresencePenalty = 0148};149150ChatCompletion completion = await chatClient.CompleteChatAsync(messages, options);151```152153### Multi-turn Conversation154155```csharp156List<ChatMessage> messages = new()157{158 new SystemChatMessage("You are a helpful assistant."),159 new UserChatMessage("Hi, can you help me?"),160 new AssistantChatMessage("Of course! What do you need help with?"),161 new UserChatMessage("What's the capital of France?")162};163164ChatCompletion completion = await chatClient.CompleteChatAsync(messages);165messages.Add(new AssistantChatMessage(completion.Content[0].Text));166```167168## Structured Outputs (JSON Schema)169170```csharp171using System.Text.Json;172173ChatCompletionOptions options = new()174{175 ResponseFormat = ChatResponseFormat.CreateJsonSchemaFormat(176 jsonSchemaFormatName: "math_reasoning",177 jsonSchema: BinaryData.FromBytes("""178 {179 "type": "object",180 "properties": {181 "steps": {182 "type": "array",183 "items": {184 "type": "object",185 "properties": {186 "explanation": { "type": "string" },187 "output": { "type": "string" }188 },189 "required": ["explanation", "output"],190 "additionalProperties": false191 }192 },193 "final_answer": { "type": "string" }194 },195 "required": ["steps", "final_answer"],196 "additionalProperties": false197 }198 """u8.ToArray()),199 jsonSchemaIsStrict: true)200};201202ChatCompletion completion = await chatClient.CompleteChatAsync(203 [new UserChatMessage("How can I solve 8x + 7 = -23?")],204 options);205206using JsonDocument json = JsonDocument.Parse(completion.Content[0].Text);207Console.WriteLine($"Answer: {json.RootElement.GetProperty("final_answer")}");208```209210## Reasoning Models (o1, o4-mini)211212```csharp213ChatCompletionOptions options = new()214{215 ReasoningEffortLevel = ChatReasoningEffortLevel.Low,216 MaxOutputTokenCount = 100000217};218219ChatCompletion completion = await chatClient.CompleteChatAsync(220[221 new DeveloperChatMessage("You are a helpful assistant"),222 new UserChatMessage("Explain the theory of relativity")223], options);224```225226## Azure AI Search Integration (RAG)227228```csharp229using Azure.AI.OpenAI.Chat;230231#pragma warning disable AOAI001232233ChatCompletionOptions options = new();234options.AddDataSource(new AzureSearchChatDataSource()235{236 Endpoint = new Uri(searchEndpoint),237 IndexName = searchIndex,238 Authentication = DataSourceAuthentication.FromApiKey(searchKey)239});240241ChatCompletion completion = await chatClient.CompleteChatAsync(242 [new UserChatMessage("What health plans are available?")],243 options);244245ChatMessageContext context = completion.GetMessageContext();246if (context?.Intent is not null)247{248 Console.WriteLine($"Intent: {context.Intent}");249}250foreach (ChatCitation citation in context?.Citations ?? [])251{252 Console.WriteLine($"Citation: {citation.Content}");253}254```255256## Embeddings257258```csharp259using OpenAI.Embeddings;260261EmbeddingClient embeddingClient = azureClient.GetEmbeddingClient("text-embedding-ada-002");262263OpenAIEmbedding embedding = await embeddingClient.GenerateEmbeddingAsync("Hello, world!");264ReadOnlyMemory<float> vector = embedding.ToFloats();265266Console.WriteLine($"Embedding dimensions: {vector.Length}");267```268269### Batch Embeddings270271```csharp272List<string> inputs = new()273{274 "First document text",275 "Second document text",276 "Third document text"277};278279OpenAIEmbeddingCollection embeddings = await embeddingClient.GenerateEmbeddingsAsync(inputs);280281foreach (OpenAIEmbedding emb in embeddings)282{283 Console.WriteLine($"Index {emb.Index}: {emb.ToFloats().Length} dimensions");284}285```286287## Image Generation (DALL-E)288289```csharp290using OpenAI.Images;291292ImageClient imageClient = azureClient.GetImageClient("dall-e-3");293294GeneratedImage image = await imageClient.GenerateImageAsync(295 "A futuristic city skyline at sunset",296 new ImageGenerationOptions297 {298 Size = GeneratedImageSize.W1024xH1024,299 Quality = GeneratedImageQuality.High,300 Style = GeneratedImageStyle.Vivid301 });302303Console.WriteLine($"Image URL: {image.ImageUri}");304```305306## Audio (Whisper)307308### Transcription309310```csharp311using OpenAI.Audio;312313AudioClient audioClient = azureClient.GetAudioClient("whisper");314315AudioTranscription transcription = await audioClient.TranscribeAudioAsync(316 "audio.mp3",317 new AudioTranscriptionOptions318 {319 ResponseFormat = AudioTranscriptionFormat.Verbose,320 Language = "en"321 });322323Console.WriteLine(transcription.Text);324```325326### Text-to-Speech327328```csharp329BinaryData speech = await audioClient.GenerateSpeechAsync(330 "Hello, welcome to Azure OpenAI!",331 GeneratedSpeechVoice.Alloy,332 new SpeechGenerationOptions333 {334 SpeedRatio = 1.0f,335 ResponseFormat = GeneratedSpeechFormat.Mp3336 });337338await File.WriteAllBytesAsync("output.mp3", speech.ToArray());339```340341## Function Calling (Tools)342343```csharp344ChatTool getCurrentWeatherTool = ChatTool.CreateFunctionTool(345 functionName: "get_current_weather",346 functionDescription: "Get the current weather in a given location",347 functionParameters: BinaryData.FromString("""348 {349 "type": "object",350 "properties": {351 "location": {352 "type": "string",353 "description": "The city and state, e.g. San Francisco, CA"354 },355 "unit": {356 "type": "string",357 "enum": ["celsius", "fahrenheit"]358 }359 },360 "required": ["location"]361 }362 """));363364ChatCompletionOptions options = new()365{366 Tools = { getCurrentWeatherTool }367};368369ChatCompletion completion = await chatClient.CompleteChatAsync(370 [new UserChatMessage("What's the weather in Seattle?")],371 options);372373if (completion.FinishReason == ChatFinishReason.ToolCalls)374{375 foreach (ChatToolCall toolCall in completion.ToolCalls)376 {377 Console.WriteLine($"Function: {toolCall.FunctionName}");378 Console.WriteLine($"Arguments: {toolCall.FunctionArguments}");379 }380}381```382383## Key Types Reference384385| Type | Purpose |386|------|---------|387| `AzureOpenAIClient` | Top-level client for Azure OpenAI |388| `ChatClient` | Chat completions |389| `EmbeddingClient` | Text embeddings |390| `ImageClient` | Image generation (DALL-E) |391| `AudioClient` | Audio transcription/TTS |392| `ChatCompletion` | Chat response |393| `ChatCompletionOptions` | Request configuration |394| `StreamingChatCompletionUpdate` | Streaming response chunk |395| `ChatMessage` | Base message type |396| `SystemChatMessage` | System prompt |397| `UserChatMessage` | User input |398| `AssistantChatMessage` | Assistant response |399| `DeveloperChatMessage` | Developer message (reasoning models) |400| `ChatTool` | Function/tool definition |401| `ChatToolCall` | Tool invocation request |402403## Best Practices4044051. **Use Entra ID in production** — Avoid API keys; use `DefaultAzureCredential`4062. **Reuse client instances** — Create once, share across requests4073. **Handle rate limits** — Implement exponential backoff for 429 errors4084. **Stream for long responses** — Use `CompleteChatStreamingAsync` for better UX4095. **Set appropriate timeouts** — Long completions may need extended timeouts4106. **Use structured outputs** — JSON schema ensures consistent response format4117. **Monitor token usage** — Track `completion.Usage` for cost management4128. **Validate tool calls** — Always validate function arguments before execution413414## Error Handling415416```csharp417using Azure;418419try420{421 ChatCompletion completion = await chatClient.CompleteChatAsync(messages);422}423catch (RequestFailedException ex) when (ex.Status == 429)424{425 Console.WriteLine("Rate limited. Retry after delay.");426 await Task.Delay(TimeSpan.FromSeconds(10));427}428catch (RequestFailedException ex) when (ex.Status == 400)429{430 Console.WriteLine($"Bad request: {ex.Message}");431}432catch (RequestFailedException ex)433{434 Console.WriteLine($"Azure OpenAI error: {ex.Status} - {ex.Message}");435}436```437438## Related SDKs439440| SDK | Purpose | Install |441|-----|---------|---------|442| `Azure.AI.OpenAI` | Azure OpenAI client (this SDK) | `dotnet add package Azure.AI.OpenAI` |443| `OpenAI` | OpenAI compatibility | `dotnet add package OpenAI` |444| `Azure.Identity` | Authentication | `dotnet add package Azure.Identity` |445| `Azure.Search.Documents` | AI Search for RAG | `dotnet add package Azure.Search.Documents` |446447## Reference Links448449| Resource | URL |450|----------|-----|451| NuGet Package | https://www.nuget.org/packages/Azure.AI.OpenAI |452| API Reference | https://learn.microsoft.com/dotnet/api/azure.ai.openai |453| Migration Guide (1.0→2.0) | https://learn.microsoft.com/azure/ai-services/openai/how-to/dotnet-migration |454| Quickstart | https://learn.microsoft.com/azure/ai-services/openai/quickstart |455| GitHub Source | https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/openai/Azure.AI.OpenAI |456
Full transparency — inspect the skill content before installing.