mcpField
A
azure-ai-openai-dotnet

azure-ai-openai-dotnet

github.com/sickn33开发48.7k75 次安装今天更新
代码仓库

关于 azure-ai-openai-dotnet

面向 .NET 开发者的客户端库 Skill,介绍如何通过 Azure.AI.OpenAI 和 OpenAI SDK 使用 Azure OpenAI Service,涵盖聊天、嵌入、图像与音频 API、身份验证及请求模式。

主要功能

  1. 01聊天补全与流式响应
  2. 02结构化 JSON Schema 输出
  3. 03文本嵌入
  4. 04图像生成与音频 API
  5. 05API 密钥和 Entra ID 身份验证
  6. 06函数调用

适用场景

  1. 01构建 .NET 聊天应用
  2. 02为文本生成嵌入
  3. 03开发图像或音频功能
  4. 04配置结构化模型响应

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/sickn33/agentic-awesome-skills --skill azure-ai-openai-dotnet

安装后在 Claude Code 中输入/azure-ai-openai-dotnet确认已加载。

详细介绍

Azure.AI.OpenAI(.NET)

Azure OpenAI Service 的客户端库,可访问 GPT-4、GPT-4o、嵌入、DALL-E 和 Whisper 等 OpenAI 模型。

安装

dotnet add package Azure.AI.OpenAI

# For OpenAI (non-Azure) compatibility
dotnet add package OpenAI

历史示例基线:2.1.0;请验证并固定兼容的 Azure.AI.OpenAI/OpenAI 版本。以下较新的 v1 API 示例可能需要更新的软件包。

环境变量

AZURE_OPENAI_ENDPOINT=https://<resource-name>.openai.azure.com
AZURE_OPENAI_API_KEY=<api-key>                    # For key-based auth
AZURE_OPENAI_DEPLOYMENT_NAME=<deployment-name>    # Azure deployment, not necessarily the model ID

客户端层级

AzureOpenAIClient (top-level)
├── GetChatClient(deploymentName)      → ChatClient
├── GetEmbeddingClient(deploymentName) → EmbeddingClient
├── GetImageClient(deploymentName)     → ImageClient
├── GetAudioClient(deploymentName)     → AudioClient
└── GetAssistantClient()               → AssistantClient

身份验证

API 密钥身份验证
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 ID(生产环境推荐)
using Azure.Identity;
using Azure.AI.OpenAI;

AzureOpenAIClient client = new(
    new Uri(Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")!),
    new DefaultAzureCredential());
直接通过 Azure 使用 OpenAI SDK
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")
    });

聊天补全

基本聊天
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("You are a helpful assistant."),
    new UserChatMessage("What is Azure OpenAI?")
]);

Console.WriteLine(completion.Content[0].Text);
异步聊天
ChatCompletion completion = await chatClient.CompleteChatAsync(
[
    new SystemChatMessage("You are a helpful assistant."),
    new UserChatMessage("Explain cloud computing in simple terms.")
]);

Console.WriteLine($"Response: {completion.Content[0].Text}");
Console.WriteLine($"Tokens used: {completion.Usage.TotalTokenCount}");
流式聊天
await foreach (StreamingChatCompletionUpdate update 
    in chatClient.CompleteChatStreamingAsync(messages))
{
    if (update.ContentUpdate.Count > 0)
    {
        Console.Write(update.ContentUpdate[0].Text);
    }
}
带选项的聊天
ChatCompletionOptions options = new()
{
    MaxOutputTokenCount = 1000,
    Temperature = 0.7f,
    TopP = 0.95f,
    FrequencyPenalty = 0,
    PresencePenalty = 0
};

ChatCompletion completion = await chatClient.CompleteChatAsync(messages, options);
多轮对话
List<ChatMessage> messages = new()
{
    new SystemChatMessage("You are a helpful assistant."),
    new UserChatMessage("Hi, can you help me?"),
    new AssistantChatMessage("Of course! What do you need help with?"),
    new UserChatMessage("What's the capital of France?")
};

ChatCompletion completion = await chatClient.CompleteChatAsync(messages);
messages.Add(new AssistantChatMessage(completion.Content[0].Text));

结构化输出(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("How can I solve 8x + 7 = -23?")],
    options);

using JsonDocument json = JsonDocument.Parse(completion.Content[0].Text);
Console.WriteLine($"Answer: {json.RootElement.GetProperty("final_answer")}");

推理模型(o1、o4-mini)

ChatCompletionOptions options = new()
{
    ReasoningEffortLevel = ChatReasoningEffortLevel.Low,
    MaxOutputTokenCount = 100000
};

ChatCompletion completion = await chatClient.CompleteChatAsync(
[
    new DeveloperChatMessage("You are a helpful assistant"),
    new UserChatMessage("Explain the theory of relativity")
], options);

Azure AI Search 集成(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("What health plans are available?")],
    options);

ChatMessageContext context = completion.GetMessageContext();
if (context?.Intent is not null)
{
    Console.WriteLine($"Intent: {context.Intent}");
}
foreach (ChatCitation citation in context?.Citations ?? [])
{
    Console.WriteLine($"Citation: {citation.Content}");
}

嵌入

using OpenAI.Embeddings;

EmbeddingClient embeddingClient = azureClient.GetEmbeddingClient("text-embedding-ada-002");

OpenAIEmbedding embedding = await embeddingClient.GenerateEmbeddingAsync("Hello, world!");
ReadOnlyMemory<float> vector = embedding.ToFloats();

Console.WriteLine($"Embedding dimensions: {vector.Length}");
批量嵌入
List<string> inputs = new()
{
    "First document text",
    "Second document text",
    "Third document text"
};

OpenAIEmbeddingCollection embeddings = await embeddingClient.GenerateEmbeddingsAsync(inputs);

foreach (OpenAIEmbedding emb in embeddings)
{
    Console.WriteLine($"Index {emb.Index}: {emb.ToFloats().Length} dimensions");
}

图像生成(DALL-E)

using OpenAI.Images;

ImageClient imageClient = azureClient.GetImageClient("dall-e-3");

GeneratedImage image = await imageClient.GenerateImageAsync(
    "A futuristic city skyline at sunset",
    new ImageGenerationOptions
    {
        Size = GeneratedImageSize.W1024xH1024,
        Quality = GeneratedImageQuality.High,
        Style = GeneratedImageStyle.Vivid
    });

Console.WriteLine($"Image URL: {image.ImageUri}");

音频(Whisper)

转录
using OpenAI.Audio;

AudioClient audioClient = azureClient.GetAudioClient("whisper");

AudioTranscription transcription = await audioClient.TranscribeAudioAsync(
    "audio.mp3",
    new AudioTranscriptionOptions
    {
        ResponseFormat = AudioTranscriptionFormat.Verbose,
        Language = "en"
    });

Console.WriteLine(transcription.Text);
文本转语音
BinaryData speech = await audioClient.GenerateSpeechAsync(
    "Hello, welcome to Azure OpenAI!",
    GeneratedSpeechVoice.Alloy,
    new SpeechGenerationOptions
    {
        SpeedRatio = 1.0f,
        ResponseFormat = GeneratedSpeechFormat.Mp3
    });

await File.WriteAllBytesAsync("output.mp3", speech.ToArray());

函数调用(工具)

ChatTool getCurrentWeatherTool = ChatTool.CreateFunctionTool(
    functionName: "get_current_weather",
    functionDescription: "Get the current weather in a given location",
    functionParameters: BinaryData.FromString("""
        {
            "type": "object",
            "properties": {
                "location": {
                    "type": "string",
                    "description": "The city and state, e.g. San Francisco, CA"
                },
                "unit": {
                    "type": "string",
                    "enum": ["celsius", "fahrenheit"]
                }
            },
            "required": ["location"]
        }
        """));

ChatCompletionOptions options = new()
{
    Tools = { getCurrentWeatherTool }
};

ChatCompletion completion = await chatClient.CompleteChatAsync(
    [new UserChatMessage("What's the weather in Seattle?")],
    options);

if (completion.FinishReason == ChatFinishReason.ToolCalls)
{
    foreach (ChatToolCall toolCall in completion.ToolCalls)
    {
        Console.WriteLine($"Function: {toolCall.FunctionName}");
        Console.WriteLine($"Arguments: {toolCall.FunctionArguments}");
    }
}

关键类型参考

类型用途
AzureOpenAIClientAzure OpenAI 的顶层客户端
ChatClient聊天补全
EmbeddingClient文本嵌入
ImageClient图像生成(DALL-E)
AudioClient音频转录/TTS
ChatCompletion聊天响应
ChatCompletionOptions请求配置
StreamingChatCompletionUpdate流式响应分块
ChatMessage基础消息类型
SystemChatMessage系统提示词
UserChatMessage用户输入
AssistantChatMessage助手响应
DeveloperChatMessage开发者消息(推理模型)
ChatTool函数/工具定义
ChatToolCall工具调用请求

最佳实践

  1. 在生产环境中使用 Entra ID — 避免使用 API 密钥;使用 DefaultAzureCredential
  2. 重复使用客户端实例 — 创建一次,供多个请求共享
  3. 处理速率限制 — 对 429 错误实现指数退避
  4. 对较长的响应使用流式处理 — 使用 CompleteChatStreamingAsync 改善用户体验
  5. 设置适当的超时时间 — 较长的补全可能需要延长超时时间
  6. 使用结构化输出 — JSON schema 可确保响应格式一致
  7. 监控令牌用量 — 跟踪 completion.Usage 以管理成本
  8. 验证工具调用 — 执行前始终验证函数参数

错误处理

using System.ClientModel;

try
{
    ChatCompletion completion = await chatClient.CompleteChatAsync(messages);
}
catch (System.ClientModel.ClientResultException ex) when (ex.Status == 429)
{
    Console.WriteLine("Rate limited. Retry after delay.");
    await Task.Delay(TimeSpan.FromSeconds(10));
}
catch (System.ClientModel.ClientResultException ex) when (ex.Status == 400)
{
    Console.WriteLine($"Bad request: {ex.Message}");
}
catch (System.ClientModel.ClientResultException ex)
{
    Console.WriteLine($"Azure OpenAI error: {ex.Status} - {ex.Message}");
}

相关 SDK

SDK用途安装
Azure.AI.OpenAIAzure OpenAI 客户端(此 SDK)dotnet add package Azure.AI.OpenAI
OpenAIOpenAI 兼容性dotnet add package OpenAI
Azure.Identity身份验证dotnet add package Azure.Identity
Azure.Search.Documents用于 RAG 的 AI Searchdotnet add package Azure.Search.Documents

参考链接

资源URL
NuGet 软件包https://www.nuget.org/packages/Azure.AI.OpenAI
API 参考https://learn.microsoft.com/dotnet/api/azure.ai.openai
迁移指南(1.0→2.0)https://learn.microsoft.com/azure/ai-services/openai/how-to/dotnet-migration
快速入门https://learn.microsoft.com/azure/ai-services/openai/quickstart
GitHub 源代码https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/openai/Azure.AI.OpenAI

适用场景

此技能适用于执行概述中描述的工作流或操作。

限制

  • 仅当任务明确符合上述范围时,才使用此技能。
  • 不要将输出视为可替代特定环境的验证、测试或专家审核。
  • 如果缺少必需的输入、权限、安全边界或成功标准,请停下并寻求澄清。

示例是相互独立的片段,并非可编译的应用;请添加所需的导入、变量和特定模型的部署名称。聊天、音频、图像功能和选项因部署/API 版本而异:Whisper 转录和语音生成通常需要不同的部署。在建立索引前检查拒绝情况、结束原因和内容数量;结构化输出并不保证响应成功且未被拒绝。将检索到的文本/工具参数视为不可信内容,并独立授权副作用。限制重试次数并遵循重试提示;只休眠一次不算重试循环。不要记录包含敏感数据的提示词、引用或原始服务错误。此处的模型名称、软件包版本和预览版 API 仅为历史示例,并不代表当前可用性。

评论

支持 Markdown