Azure.AI.OpenAI (.NET)
Clientbibliothek für den Azure OpenAI-Dienst, die Zugriff auf OpenAI-Modelle einschließlich GPT-4, GPT-4o, Einbettungen, DALL-E und Whisper bietet.
Installation
dotnet add package Azure.AI.OpenAI
dotnet add package OpenAI
Aktuelle Version: 2.1.0 (stabil)
Umgebungsvariablen
AZURE_OPENAI_ENDPOINT=https://<resource-name>.openai.azure.com
AZURE_OPENAI_API_KEY=<api-key>
AZURE_OPENAI_DEPLOYMENT_NAME=gpt-4o-mini
AZURE_TOKEN_CREDENTIALS=prod
Client-Hierarchie
AzureOpenAIClient (Top-Level)
├── GetChatClient(deploymentName) → ChatClient
├── GetEmbeddingClient(deploymentName) → EmbeddingClient
├── GetImageClient(deploymentName) → ImageClient
├── GetAudioClient(deploymentName) → AudioClient
└── GetAssistantClient() → AssistantClient
Authentifizierung
API-Schlüssel-Authentifizierung
using Azure;
using Azure.AI.OpenAI;
AzureOpenAIClient client = new(
new Uri(Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")!),
new AzureKeyCredential(Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY")!));
Microsoft Entra Token-Anmeldeinformation
using Azure.Identity;
using Azure.AI.OpenAI;
var credential = new DefaultAzureCredential(
DefaultAzureCredential.DefaultEnvironmentVariableName
);
AzureOpenAIClient client = new(
new Uri(Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")!),
credential);
Direkte Verwendung des OpenAI SDK mit Azure
using Azure.Identity;
using OpenAI;
using OpenAI.Chat;
using System.ClientModel.Primitives;
#pragma warning disable OPENAI001
BearerTokenPolicy tokenPolicy = new(
new DefaultAzureCredential(),
"https://cognitiveservices.azure.com/.default");
ChatClient client = new(
model: "gpt-4o-mini",
authenticationPolicy: tokenPolicy,
options: new OpenAIClientOptions()
{
Endpoint = new Uri("https://YOUR-RESOURCE.openai.azure.com/openai/v1")
});
Chat-Vervollständigungen
Basis-Chat
using Azure.AI.OpenAI;
using OpenAI.Chat;
AzureOpenAIClient azureClient = new(
new Uri(endpoint),
new DefaultAzureCredential());
ChatClient chatClient = azureClient.GetChatClient("gpt-4o-mini");
ChatCompletion completion = chatClient.CompleteChat(
[
new SystemChatMessage("Du bist ein hilfreicher Assistent."),
new UserChatMessage("Was ist Azure OpenAI?")
]);
Console.WriteLine(completion.Content[0].Text);
Asynchroner Chat
ChatCompletion completion = await chatClient.CompleteChatAsync(
[
new SystemChatMessage("Du bist ein hilfreicher Assistent."),
new UserChatMessage("Erkläre Cloud Computing in einfachen Worten.")
]);
Console.WriteLine($"Antwort: {completion.Content[0].Text}");
Console.WriteLine($"Verwendete Tokens: {completion.Usage.TotalTokenCount}");
Streaming-Chat
await foreach (StreamingChatCompletionUpdate update
in chatClient.CompleteChatStreamingAsync(messages))
{
if (update.ContentUpdate.Count > 0)
{
Console.Write(update.ContentUpdate[0].Text);
}
}
Chat mit Optionen
ChatCompletionOptions options = new()
{
MaxOutputTokenCount = 1000,
Temperature = 0.7f,
TopP = 0.95f,
FrequencyPenalty = 0,
PresencePenalty = 0
};
ChatCompletion completion = await chatClient.CompleteChatAsync(messages, options);
Mehrrunden-Konversation
List<ChatMessage> messages = new()
{
new SystemChatMessage("Du bist ein hilfreicher Assistent."),
new UserChatMessage("Hallo, kannst du mir helfen?"),
new AssistantChatMessage("Natürlich! Wobei brauchst du Hilfe?"),
new UserChatMessage("Was ist die Hauptstadt von Frankreich?")
};
ChatCompletion completion = await chatClient.CompleteChatAsync(messages);
messages.Add(new AssistantChatMessage(completion.Content[0].Text));
Strukturierte Ausgaben (JSON-Schema)
using System.Text.Json;
ChatCompletionOptions options = new()
{
ResponseFormat = ChatResponseFormat.CreateJsonSchemaFormat(
jsonSchemaFormatName: "math_reasoning",
jsonSchema: BinaryData.FromBytes("""
{
"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
}
"""u8.ToArray()),
jsonSchemaIsStrict: true)
};
ChatCompletion completion = await chatClient.CompleteChatAsync(
[new UserChatMessage("Wie löse ich 8x + 7 = -23?")],
options);
using JsonDocument json = JsonDocument.Parse(completion.Content[0].Text);
Console.WriteLine($"Antwort: {json.RootElement.GetProperty("final_answer")}");
Reasoning-Modelle (o1, o4-mini)
ChatCompletionOptions options = new()
{
ReasoningEffortLevel = ChatReasoningEffortLevel.Low,
MaxOutputTokenCount = 100000
};
ChatCompletion completion = await chatClient.CompleteChatAsync(
[
new DeveloperChatMessage("Du bist ein hilfreicher Assistent"),
new UserChatMessage("Erkläre die Relativitätstheorie")
], options);
Azure KI Search-Integration (RAG)
using Azure.AI.OpenAI.Chat;
#pragma warning disable AOAI001
ChatCompletionOptions options = new();
options.AddDataSource(new AzureSearchChatDataSource()
{
Endpoint = new Uri(searchEndpoint),
IndexName = searchIndex,
Authentication = DataSourceAuthentication.FromApiKey(searchKey)
});
ChatCompletion completion = await chatClient.CompleteChatAsync(
[new UserChatMessage("Welche Krankenversicherungspläne sind verfügbar?")],
options);
ChatMessageContext context = completion.GetMessageContext();
if (context?.Intent is not null)
{
Console.WriteLine($"Absicht: {context.Intent}");
}
foreach (ChatCitation citation in context?.Citations ?? [])
{
Console.WriteLine($"Zitat: {citation.Content}");
}
Einbettungen
using OpenAI.Embeddings;
EmbeddingClient embeddingClient = azureClient.GetEmbeddingClient("text-embedding-ada-002");
OpenAIEmbedding embedding = await embeddingClient.GenerateEmbeddingAsync("Hallo, Welt!");
ReadOnlyMemory<float> vector = embedding.ToFloats();
Console.WriteLine($"Einbettungsdimensionen: {vector.Length}");
Batch-Einbettungen
List<string> inputs = new()
{
"Erster Dokumenttext",
"Zweiter Dokumenttext",
"Dritter Dokumenttext"
};
OpenAIEmbeddingCollection embeddings = await embeddingClient.GenerateEmbeddingsAsync(inputs);
foreach (OpenAIEmbedding emb in embeddings)
{
Console.WriteLine($"Index {emb.Index}: {emb.ToFloats().Length} Dimensionen");
}
Bildgenerierung (DALL-E)
using OpenAI.Images;
ImageClient imageClient = azureClient.GetImageClient("dall-e-3");
GeneratedImage image = await imageClient.GenerateImageAsync(
"Eine futuristische Stadtsilhouette bei Sonnenuntergang",
new ImageGenerationOptions
{
Size = GeneratedImageSize.W1024xH1024,
Quality = GeneratedImageQuality.High,
Style = GeneratedImageStyle.Vivid
});
Console.WriteLine($"Bild-URL: {image.ImageUri}");
Audio (Whisper)
Transkription
using OpenAI.Audio;
AudioClient audioClient = azureClient.GetAudioClient("whisper");
AudioTranscription transcription = await audioClient.TranscribeAudioAsync(
"audio.mp3",
new AudioTranscriptionOptions
{
ResponseFormat = AudioTranscriptionFormat.Verbose,
Language = "de"
});
Console.WriteLine(transcription.Text);
Text-zu-Sprache
BinaryData speech = await audioClient.GenerateSpeechAsync(
"Hallo, willkommen bei Azure OpenAI!",
GeneratedSpeechVoice.Alloy,
new SpeechGenerationOptions
{
SpeedRatio = 1.0f,
ResponseFormat = GeneratedSpeechFormat.Mp3
});
await File.WriteAllBytesAsync("output.mp3", speech.ToArray());
Funktionsaufruf (Tools)
ChatTool getCurrentWeatherTool = ChatTool.CreateFunctionTool(
functionName: "get_current_weather",
functionDescription: "Ruft das aktuelle Wetter an einem bestimmten Ort ab",
functionParameters: BinaryData.FromString("""
{
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "Stadt und Bundesland, z.B. Berlin, Deutschland"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"]
}
},
"required": ["location"]
}
"""));
ChatCompletionOptions options = new()
{
Tools = { getCurrentWeatherTool }
};
ChatCompletion completion = await chatClient.CompleteChatAsync(
[new UserChatMessage("Wie ist das Wetter in Seattle?")],
options);
if (completion.FinishReason == ChatFinishReason.ToolCalls)
{
foreach (ChatToolCall toolCall in completion.ToolCalls)
{
Console.WriteLine($"Funktion: {toolCall.FunctionName}");
Console.WriteLine($"Argumente: {toolCall.FunctionArguments}");
}
}
Referenz der wichtigsten Typen
| Typ | Zweck |
|---|
AzureOpenAIClient | Top-Level-Client für Azure OpenAI |
ChatClient | Chat-Vervollständigungen |
EmbeddingClient | Text-Einbettungen |
ImageClient | Bildgenerierung (DALL-E) |
AudioClient | Audiotranskription/TTS |
ChatCompletion | Chat-Antwort |
ChatCompletionOptions | Anforderungskonfiguration |
StreamingChatCompletionUpdate | Streaming-Antwortfragment |
ChatMessage | Basismessagetyp |
SystemChatMessage | System-Prompt |
UserChatMessage | Benutzereingabe |
AssistantChatMessage | Assistentenantwort |
DeveloperChatMessage | Entwicklernachricht (Reasoning-Modelle) |
ChatTool | Funktions-/Tooldefinition |
ChatToolCall | Tool-Aufrufanforderung |
Best Practices
- Entra ID in der Produktion verwenden — Vermeide API-Schlüssel; verwende
DefaultAzureCredential
- Client-Instanzen wiederverwenden — Einmal erstellen, über mehrere Anfragen teilen
- Ratenbegrenzungen behandeln — Exponentielles Backoff für 429-Fehler implementieren
- Streamen für lange Antworten — Verwende
CompleteChatStreamingAsync für bessere Benutzererfahrung
- Angemessene Timeouts setzen — Lange Vervollständigungen benötigen möglicherweise verlängerte Timeouts
- Strukturierte Ausgaben verwenden — JSON-Schema gewährleistet einheitliches Antwortformat
- Tokenverbrauch überwachen — Verfolge
completion.Usage für Kostenmanagement
- Tool-Aufrufe validieren — Funktionsargumente vor der Ausführung immer validieren
Fehlerbehandlung
using Azure;
try
{
ChatCompletion completion = await chatClient.CompleteChatAsync(messages);
}
catch (RequestFailedException ex) when (ex.Status == 429)
{
Console.WriteLine("Ratenbegrenzung erreicht. Wiederholung nach Verzögerung.");
await Task.Delay(TimeSpan.FromSeconds(10));
}
catch (RequestFailedException ex) when (ex.Status == 400)
{
Console.WriteLine($"Fehlerhafte Anfrage: {ex.Message}");
}
catch (RequestFailedException ex)
{
Console.WriteLine($"Azure OpenAI-Fehler: {ex.Status} - {ex.Message}");
}
Verwandte SDKs
| SDK | Zweck | Installation |
|---|
Azure.AI.OpenAI | Azure OpenAI-Client (dieses SDK) | dotnet add package Azure.AI.OpenAI |
OpenAI | OpenAI-Kompatibilität | dotnet add package OpenAI |
Azure.Identity | Authentifizierung | dotnet add package Azure.Identity |
Azure.Search.Documents | KI-Suche für RAG | dotnet add package Azure.Search.Documents |
Referenzlinks