Azure AI 服务集成
大约 15 分钟约 4356 字
Azure AI 服务集成
简介
Azure AI Services 的价值,在于让企业团队可以在微软云体系中直接获得可用的 AI 能力,而不必从模型训练和基础设施开始自建。对于 .NET 团队来说,它尤其适合作为 Azure OpenAI、Azure AI Search、文本分析、语音服务等能力的统一接入层,并与现有的 ASP.NET Core、Identity、Key Vault、日志和监控体系自然融合。
Azure AI Services 提供了一整套从基础设施到应用层的 AI 能力堆栈:底层是 Azure OpenAI 提供的 GPT-4/3.5 等大模型能力;中间层是 Azure AI Search 提供的向量检索和语义搜索能力;上层是 Cognitive Services 提供的文本分析、语音识别、计算机视觉等垂直能力。这三层可以独立使用,也可以组合构建完整的 AI 应用。
特点
实现
Azure OpenAI:聊天与流式输出
using Azure;
using Azure.AI.OpenAI;
using OpenAI.Chat;
var endpoint = new Uri("https://your-resource.openai.azure.com");
var credential = new AzureKeyCredential("your-api-key");
var client = new AzureOpenAIClient(endpoint, credential);
var chatClient = client.GetChatClient("gpt-4o");
var messages = new List<ChatMessage>
{
new SystemChatMessage("你是一个 .NET 企业应用助手"),
new UserChatMessage("解释 ASP.NET Core 中间件和过滤器的区别")
};
var response = await chatClient.CompleteChatAsync(messages);
Console.WriteLine(response.Value.Content[0].Text);// 流式输出
await foreach (var update in chatClient.CompleteChatStreamingAsync(
[new UserChatMessage("用 C# 写一个快速排序示例")]))
{
if (update.ContentUpdate.Count > 0)
{
Console.Write(update.ContentUpdate[0].Text);
}
}企业落地时更关注:
- 模型版本
- 部署名(deployment)
- 配额与成本
- 敏感数据边界
- Prompt 与输出审计Python 调用 Azure OpenAI
from openai import AzureOpenAI
import json
# 配置 Azure OpenAI 客户端
client = AzureOpenAI(
api_key="your-api-key",
api_version="2024-02-01",
azure_endpoint="https://your-resource.openai.azure.com"
)
# 基础聊天调用
response = client.chat.completions.create(
model="gpt-4o-deployment",
messages=[
{"role": "system", "content": "你是一个技术顾问"},
{"role": "user", "content": "解释微服务架构的优缺点"}
],
temperature=0.3,
max_tokens=1000
)
print(response.choices[0].message.content)
# 流式输出
stream = client.chat.completions.create(
model="gpt-4o-deployment",
messages=[{"role": "user", "content": "用 Python 写一个快速排序"}],
stream=True
)
for chunk in stream:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="")Function Calling / Tool Use
ChatTool[] tools =
[
ChatTool.CreateFunctionTool(
functionName: "get_weather",
functionDescription: "获取指定城市天气",
functionParameters: BinaryData.FromString("""
{
"type": "object",
"properties": {
"city": { "type": "string", "description": "城市名称" }
},
"required": ["city"]
}
"""))
];
var options = new ChatCompletionOptions { Tools = tools };
var response = await chatClient.CompleteChatAsync(
[new UserChatMessage("北京今天天气怎么样?")],
options);if (response.Value.FinishReason == ChatFinishReason.ToolCalls)
{
foreach (var toolCall in response.Value.ToolCalls)
{
if (toolCall.FunctionName == "get_weather")
{
var city = JsonDocument.Parse(toolCall.FunctionArguments)
.RootElement.GetProperty("city").GetString();
var weather = $"{city}: 晴,25°C";
var followUp = await chatClient.CompleteChatAsync(
[
new UserChatMessage("北京今天天气怎么样?"),
new AssistantChatMessage(toolCall.Id, toolCall.FunctionName, toolCall.FunctionArguments),
new ToolChatMessage(toolCall.Id, weather)
]);
Console.WriteLine(followUp.Value.Content[0].Text);
}
}
}Azure AI Search:搜索与语义检索
using Azure;
using Azure.Search.Documents;
using Azure.Search.Documents.Indexes;
using Azure.Search.Documents.Indexes.Models;
var endpoint = new Uri("https://your-search.search.windows.net");
var credential = new AzureKeyCredential("your-api-key");
var indexClient = new SearchIndexClient(endpoint, credential);
var searchClient = new SearchClient(endpoint, "knowledge-index", credential);var index = new SearchIndex("knowledge-index")
{
Fields =
{
new SimpleField("id", SearchFieldDataType.String) { IsKey = true },
new SearchableField("title") { IsFilterable = true },
new SearchableField("content"),
new SimpleField("category", SearchFieldDataType.String) { IsFilterable = true, IsFacetable = true },
new SearchField("embedding", SearchFieldDataType.Collection(SearchFieldDataType.Single))
{
VectorSearchDimensions = 1536,
VectorSearchProfileName = "default"
}
},
VectorSearch = new VectorSearch
{
Profiles = { new VectorSearchProfile("default", "hnsw-config") },
Algorithms = { new HnswAlgorithmConfiguration("hnsw-config") }
}
};var options = new SearchOptions
{
QueryType = SearchQueryType.Semantic,
SemanticSearch = new SemanticSearchOptions
{
SemanticConfigurationName = "default"
}
};
var results = await searchClient.SearchAsync<SearchDocument>("微服务架构设计", options);
await foreach (var result in results.Value.GetResultsAsync())
{
Console.WriteLine(result.Document["title"]);
}AI Search 常见落地角色:
- 企业知识库检索
- FAQ 搜索
- 语义检索 + RAG 召回层
- 结构化过滤 + 语义搜索混合查询Text Analytics / Speech 等认知服务
using Azure;
using Azure.AI.TextAnalytics;
var client = new TextAnalyticsClient(
new Uri("https://your-resource.cognitiveservices.azure.com"),
new AzureKeyCredential("your-api-key")
);
var sentiment = await client.AnalyzeSentimentAsync("这个产品质量很好,物流也很快");
Console.WriteLine(sentiment.Value.Sentiment);
var phrases = await client.ExtractKeyPhrasesAsync("ASP.NET Core 支持跨平台部署到 Linux 容器");
foreach (var phrase in phrases.Value)
{
Console.WriteLine(phrase);
}using Microsoft.CognitiveServices.Speech;
var speechConfig = SpeechConfig.FromSubscription("your-api-key", "eastus");
speechConfig.SpeechSynthesisLanguage = "zh-CN";
using var synthesizer = new SpeechSynthesizer(speechConfig);
var result = await synthesizer.SpeakTextAsync("欢迎使用 Azure 语音服务");
Console.WriteLine(result.Reason);Embedding 与向量检索集成
using Azure.AI.OpenAI;
using OpenAI.Embeddings;
var embeddingClient = client.GetEmbeddingClient("text-embedding-ada-002");
// 生成文本嵌入向量
var embeddingResponse = await embeddingClient.GenerateEmbeddingAsync("微服务架构设计最佳实践");
float[] vector = embeddingResponse.Value.Vector.ToArray();
Console.WriteLine($"向量维度: {vector.Length}"); // 1536
Console.WriteLine($"前5个分量: {string.Join(", ", vector.Take(5).Select(v => v.ToString("F6")))}");// 批量生成嵌入并写入 Azure AI Search
var documents = new List<SearchDocument>
{
new() { ["id"] = "doc-001", ["title"] = "微服务入门", ["content"] = "..." },
new() { ["id"] = "doc-002", ["title"] = "Docker 部署", ["content"] = "..." },
new() { ["id"] = "doc-003", ["title"] = "CI/CD 流水线", ["content"] = "..." },
};
foreach (var doc in documents)
{
var emb = await embeddingClient.GenerateEmbeddingAsync(doc["content"].ToString());
doc["embedding"] = emb.Value.Vector.ToArray();
}
// 批量上传到索引
await searchClient.UploadDocumentsAsync(documents);
Console.WriteLine($"已上传 {documents.Count} 条文档到索引");Embedding 集成要点:
- 选择合适的嵌入模型:text-embedding-ada-002(1536维)、text-embedding-3-small(1536维)、text-embedding-3-large(3072维)
- 文本分块策略:建议 512-1024 token,带 50-100 token 重叠
- 向量维度必须与索引定义一致
- 高频查询场景考虑缓存嵌入结果内容安全与内容过滤
// Azure OpenAI 内置内容过滤配置
// 在部署时可通过 Azure Portal 配置以下过滤器:
// - 仇恨内容 (Hate)
// - 性内容 (Sexual)
// - 暴力内容 (Violence)
// - 自残内容 (Self-Harm)
// 每个类别可设置: Low/Medium/High 阈值或禁用
// 代码层面检测内容过滤结果
var response = await chatClient.CompleteChatAsync(
[new UserChatMessage("请生成一段技术文档")]);
var filterResult = response.Value.ContentFilterResult;
Console.WriteLine($"仇恨内容过滤: {filterResult.Hate?.Filtered}");
Console.WriteLine($"性内容过滤: {filterResult.Sexual?.Filtered}");
Console.WriteLine($"暴力内容过滤: {filterResult.Violent?.Filtered}");
Console.WriteLine($"自残内容过滤: {filterResult.SelfHarm?.Filtered}");// 生产环境中的内容安全封装
public class SafeChatService
{
private readonly ChatClient _chatClient;
private readonly ILogger<SafeChatService> _logger;
public SafeChatService(ChatClient chatClient, ILogger<SafeChatService> logger)
{
_chatClient = chatClient;
_logger = logger;
}
public async Task<SafeChatResult> SafeCompleteAsync(string userMessage, string systemPrompt = null)
{
try
{
var messages = new List<ChatMessage>();
if (systemPrompt != null)
messages.Add(new SystemChatMessage(systemPrompt));
messages.Add(new UserChatMessage(userMessage));
var response = await _chatClient.CompleteChatAsync(messages);
var filter = response.Value.ContentFilterResult;
// 记录过滤日志
if (filter.Hate?.Filtered == true || filter.Sexual?.Filtered == true)
{
_logger.LogWarning("内容被过滤: Hate={Hate}, Sexual={Sexual}, Violence={Violence}",
filter.Hate?.Filtered, filter.Sexual?.Filtered, filter.Violent?.Filtered);
return new SafeChatResult { IsFiltered = true, Reason = "内容不合规" };
}
return new SafeChatResult
{
IsFiltered = false,
Content = response.Value.Content[0].Text,
InputTokens = response.Value.Usage.InputTokenCount,
OutputTokens = response.Value.Usage.OutputTokenCount
};
}
catch (RequestFailedException ex) when (ex.Status == 400)
{
_logger.LogError(ex, "请求参数错误");
return new SafeChatResult { IsFiltered = true, Reason = "请求格式错误" };
}
catch (RequestFailedException ex) when (ex.Status == 429)
{
_logger.LogWarning("触发速率限制,建议重试");
return new SafeChatResult { IsFiltered = true, Reason = "速率限制" };
}
}
}
public class SafeChatResult
{
public bool IsFiltered { get; set; }
public string Reason { get; set; }
public string Content { get; set; }
public int InputTokens { get; set; }
public int OutputTokens { get; set; }
}多模态能力(视觉与图像)
// GPT-4o 多模态调用:分析图片
var imageBytes = File.ReadAllBytes("architecture-diagram.png");
var imageBinaryData = BinaryData.FromBytes(imageBytes);
var messages = new List<ChatMessage>
{
new SystemChatMessage("你是一个架构审查助手,分析系统架构图并给出改进建议。"),
new UserChatMessage(
[
ChatMessageContentPart.CreateTextPart("请分析这张系统架构图,指出潜在的单点故障和性能瓶颈:"),
ChatMessageContentPart.CreateImagePart(imageBinaryData, "image/png")
])
};
var response = await chatClient.CompleteChatAsync(messages);
Console.WriteLine(response.Value.Content[0].Text);# Python 多模态调用
from openai import AzureOpenAI
import base64
client = AzureOpenAI(
api_key="your-api-key",
api_version="2024-02-01",
azure_endpoint="https://your-resource.openai.azure.com"
)
# 方式一:使用图片 URL
response = client.chat.completions.create(
model="gpt-4o-deployment",
messages=[
{
"role": "user",
"content": [
{"type": "text", "text": "描述这张图片的内容"},
{"type": "image_url", "image_url": {"url": "https://example.com/image.png"}}
]
}
],
max_tokens=500
)
# 方式二:使用 base64 编码
with open("screenshot.png", "rb") as f:
base64_image = base64.b64encode(f.read()).decode("utf-8")
response = client.chat.completions.create(
model="gpt-4o-deployment",
messages=[
{
"role": "user",
"content": [
{"type": "text", "text": "分析这个错误截图中的异常信息"},
{"type": "image_url", "image_url": {
"url": f"data:image/png;base64,{base64_image}"
}}
]
}
]
)
print(response.choices[0].message.content)批量处理与异步调用
# Azure OpenAI 批量处理
import asyncio
from openai import AzureOpenAI
client = AzureOpenAI(
api_key="your-api-key",
api_version="2024-02-01",
azure_endpoint="https://your-resource.openai.azure.com"
)
async def process_single(client, text, semaphore):
"""带限流的单条处理"""
async with semaphore:
try:
response = client.chat.completions.create(
model="gpt-4o-deployment",
messages=[
{"role": "system", "content": "对以下文本进行摘要,不超过100字。"},
{"role": "user", "content": text}
],
temperature=0.1,
max_tokens=200
)
return {
"status": "success",
"summary": response.choices[0].message.content,
"tokens": response.usage.total_tokens
}
except Exception as e:
return {"status": "error", "error": str(e)}
async def batch_process(texts, max_concurrent=5):
"""批量处理文本列表"""
semaphore = asyncio.Semaphore(max_concurrent)
tasks = [process_single(client, text, semaphore) for text in texts]
results = await asyncio.gather(*tasks)
success_count = sum(1 for r in results if r["status"] == "success")
total_tokens = sum(r.get("tokens", 0) for r in results if r["status"] == "success")
print(f"批量处理完成: {success_count}/{len(texts)} 成功")
print(f"总消耗 Token: {total_tokens}")
return results
# 使用示例
texts_to_summarize = [
"第一篇长文本内容...",
"第二篇长文本内容...",
"第三篇长文本内容...",
]
# results = asyncio.run(batch_process(texts_to_summarize))与 ASP.NET Core / Key Vault 的工程化集成
var builder = WebApplication.CreateBuilder(args);
builder.Configuration.AddAzureKeyVault(
new Uri("https://your-key-vault.vault.azure.net/"),
new DefaultAzureCredential());
builder.Services.AddSingleton(_ =>
{
var endpoint = new Uri(builder.Configuration["AzureOpenAI:Endpoint"]!);
var key = builder.Configuration["AzureOpenAI:ApiKey"]!;
return new AzureOpenAIClient(endpoint, new AzureKeyCredential(key));
});企业项目里常见组合:
- Azure OpenAI:模型能力
- Azure AI Search:检索能力
- Key Vault:密钥治理
- Application Insights:监控与日志
- Entra ID:身份与权限RAG 架构集成
# Azure OpenAI + Azure AI Search 构建 RAG 系统
class AzureRAGSystem:
"""
使用 Azure 服务构建企业 RAG 系统
架构:用户查询 → Azure AI Search 检索 → Azure OpenAI 生成
"""
def __init__(self, openai_endpoint, search_endpoint, api_key):
self.openai_client = AzureOpenAI(
api_key=api_key,
azure_endpoint=openai_endpoint,
api_version="2024-02-01"
)
# Azure AI Search 客户端配置
self.search_endpoint = search_endpoint
def query(self, question: str, index_name: str = "knowledge-base"):
"""完整的 RAG 查询流程"""
# 1. 检索相关文档(通过 Azure AI Search)
# 2. 组装 Prompt(检索结果 + 问题)
# 3. 调用 Azure OpenAI 生成答案
prompt = f"""基于以下资料回答问题。如果资料不足,请说明"资料未覆盖"。
问题:{question}
资料:
[检索结果将在此处注入]
请给出答案并注明来源。"""
response = self.openai_client.chat.completions.create(
model="gpt-4o-deployment",
messages=[
{"role": "system", "content": "你是企业知识助手,请基于资料准确回答。"},
{"role": "user", "content": prompt}
],
temperature=0
)
return response.choices[0].message.content
print("Azure RAG 系统架构已定义")成本监控与配额管理
class AzureCostMonitor:
"""Azure AI 服务成本监控"""
def __init__(self):
self.usage_log = []
def log_usage(self, service, model, input_tokens, output_tokens, latency_ms):
"""记录每次 API 调用的使用情况"""
self.usage_log.append({
"service": service,
"model": model,
"input_tokens": input_tokens,
"output_tokens": output_tokens,
"latency_ms": latency_ms,
"timestamp": "2026-04-12T10:00:00"
})
def estimate_cost(self):
"""估算成本(以 GPT-4o 定价为例)"""
# GPT-4o: $2.5/1M input tokens, $10/1M output tokens
total_input = sum(log["input_tokens"] for log in self.usage_log)
total_output = sum(log["output_tokens"] for log in self.usage_log)
cost = (total_input / 1_000_000) * 2.5 + (total_output / 1_000_000) * 10
return {
"total_input_tokens": total_input,
"total_output_tokens": total_output,
"estimated_cost_usd": cost,
"total_calls": len(self.usage_log)
}
monitor = AzureCostMonitor()
monitor.log_usage("azure-openai", "gpt-4o", 1500, 300, 850)
monitor.log_usage("azure-openai", "gpt-4o", 800, 150, 420)
print(monitor.estimate_cost())优点
缺点
总结
Azure AI Services 更适合做企业级 AI 能力接入平台,而不是单纯调用几个 SDK。真正落地时,要把模型调用、搜索检索、配置密钥、权限边界、日志审计、评估集和成本控制一起考虑,才能让 Azure AI 从"能调 API"升级为"能稳定服务业务"。
关键知识点
- Azure OpenAI 解决模型能力,Azure AI Search 解决检索能力,它们不是同一层东西。
- 企业接入 AI 时,安全、权限、配额和成本与效果同样重要。
- RAG 场景里,检索层质量常常比单纯换模型更关键。
- SDK 接入只是最外层,真正复杂的是治理和平台化。
项目落地视角
- 企业知识助手通常是 Azure OpenAI + AI Search + Key Vault 的组合。
- 文本分析、语音服务更适合做垂直能力补充,而不是所有问题都交给大模型。
- 对高价值业务流程,必须补审计日志与失败兜底。
- 已有 Azure 基础设施的团队落地成本通常会更低。
常见误区
- 以为 Azure AI 就是 Azure OpenAI,忽略搜索、语音、文本分析等能力边界。
- 只做 PoC,不做成本预算和调用审计。
- 不区分"模型输出问题"和"检索 / 数据问题"。
- 生产环境把 API Key 写死在代码或配置文件里。
进阶路线
- 深入学习 Azure AI Search 的向量检索与语义排序。
- 将 Azure OpenAI 与 Semantic Kernel / LangChain / Agent 编排结合。
- 建立 Prompt 版本管理、RAG 评估和上线审批机制。
- 结合 Entra ID、Key Vault、Application Insights 做完整企业治理。
适用场景
- 企业知识库与问答系统。
- AI 助手、Copilot、流程辅助系统。
- 文本分析、语音识别、语音合成、语义搜索场景。
- 已有 Azure 云基础设施的企业项目。
落地建议
- 先明确每个服务负责哪一层能力,不要把所有需求都压到 OpenAI 上。
- 所有敏感配置统一放 Key Vault 或安全配置源中。
- 为模型调用、搜索调用建立独立监控与成本视图。
- 对高风险业务输出增加人工审核、拒答和回退机制。
排错清单
- 调用失败:先查 endpoint、api-key、deployment 名是否正确。
- 搜索效果差:先查索引结构、分块、Embedding 和过滤条件。
- 成本超预期:先查 Prompt 长度、召回数量和请求频次。
- 生产结果不稳定:检查 Prompt 版本、上下文来源和模型版本是否一致。
Streaming 在 ASP.NET Core 中的集成模式
// ASP.NET Core SSE 端点实现流式聊天
app.MapGet("/api/chat/stream", async (HttpContext context, ChatClient chatClient, string question) =>
{
context.Response.ContentType = "text/event-stream";
context.Response.Headers.Append("Cache-Control", "no-cache");
context.Response.Headers.Append("Connection", "keep-alive");
var messages = new List<ChatMessage>
{
new SystemChatMessage("你是企业知识助手"),
new UserChatMessage(question)
};
await foreach (var update in chatClient.CompleteChatStreamingAsync(messages))
{
if (update.ContentUpdate.Count > 0)
{
var text = update.ContentUpdate[0].Text;
var sseMessage = $"data: {System.Text.Json.JsonSerializer.Serialize(new { content = text })}\n\n";
await context.Response.WriteAsync(sseMessage);
await context.Response.Body.FlushAsync();
}
}
await context.Response.WriteAsync("data: [DONE]\n\n");
await context.Response.Body.FlushAsync();
});Token 管理与上下文窗口优化
# Token 计算与管理工具
import tiktoken
class TokenManager:
"""管理 LLM 调用的 Token 使用"""
def __init__(self, model="gpt-4o", max_context=128000):
self.model = model
self.max_context = max_context
# 选择对应的编码器
try:
self.encoding = tiktoken.encoding_for_model(model)
except KeyError:
self.encoding = tiktoken.get_encoding("cl100k_base")
def count_tokens(self, text: str) -> int:
"""计算文本的 Token 数"""
return len(self.encoding.encode(text))
def truncate_to_limit(self, text: str, max_tokens: int) -> str:
"""截断文本到指定 Token 数"""
tokens = self.encoding.encode(text)
if len(tokens) <= max_tokens:
return text
return self.encoding.decode(tokens[:max_tokens])
def build_context_window(self, system_prompt: str, history: list, new_message: str,
max_output_tokens: int = 4096) -> list:
"""构建符合上下文窗口限制的消息列表"""
available = self.max_context - max_output_tokens - self.count_tokens(system_prompt)
available -= self.count_tokens(new_message)
result_history = []
# 从最近的历史消息开始填充
for msg in reversed(history):
msg_tokens = self.count_tokens(msg.get("content", ""))
if available >= msg_tokens:
result_history.insert(0, msg)
available -= msg_tokens
else:
break
messages = [{"role": "system", "content": system_prompt}]
messages.extend(result_history)
messages.append({"role": "user", "content": new_message})
total = sum(self.count_tokens(m["content"]) for m in messages)
print(f"上下文 Token 使用: {total}/{self.max_context}")
return messages
# 使用示例
tm = TokenManager()
text = "这是一段需要计算Token的示例文本..."
print(f"Token 数: {tm.count_tokens(text)}")Token 管理最佳实践:
- 中文文本 Token 消耗通常是英文的 1.5-2 倍
- 系统提示词应精简,避免浪费上下文空间
- 历史消息采用滑动窗口或摘要压缩策略
- GPT-4o: 128K 上下文,实际可用约 120K(预留输出)
- 建议在应用层做 Token 计数,避免超出限制导致 API 报错错误处理与重试策略
// 生产级重试策略
using Polly;
using Polly.Retry;
var retryPolicy = Policy
.Handle<RequestFailedException>(ex => ex.Status == 429 || ex.Status >= 500)
.WaitAndRetryAsync(
retryCount: 3,
sleepDurationProvider: (retryAttempt, exception, context) =>
{
// 429 时优先使用 Retry-After 头
if (exception is RequestFailedException rfe && rfe.Status == 429)
{
if (rfe.Headers.TryGetValue("Retry-After", out var retryAfter))
return TimeSpan.FromSeconds(int.Parse(retryAfter));
}
return TimeSpan.FromSeconds(Math.Pow(2, retryAttempt));
},
onRetry: (exception, timeSpan, retryCount, context) =>
{
Console.WriteLine($"重试第 {retryCount} 次,等待 {timeSpan.TotalSeconds}s,原因: {exception.Exception.Message}");
});
// 带熔断的调用封装
var circuitBreaker = Policy
.Handle<RequestFailedException>(ex => ex.Status >= 500)
.CircuitBreakerAsync(
exceptionsAllowedBeforeBreaking: 5,
durationOfBreak: TimeSpan.FromSeconds(30),
onBreak: (ex, breakDelay) => Console.WriteLine($"熔断开启,等待 {breakDelay.TotalSeconds}s"),
onReset: () => Console.WriteLine("熔断恢复"));
var resilientPolicy = Policy.WrapAsync(retryPolicy, circuitBreaker);常见错误码及处理策略:
- 400 Bad Request: 检查 Prompt 格式、Token 限制、参数合法性
- 401 Unauthorized: 检查 API Key 是否有效,是否过期
- 403 Forbidden: 检查资源权限和订阅状态
- 404 Not Found: 检查 deployment 名称和 endpoint
- 429 Too Many Requests: 实施指数退避重试,检查配额
- 500/502/503: 服务端错误,重试 + 熔断保护
- Content Filter: 调整输入内容或修改过滤阈值配置Azure OpenAI 模型选择指南
模型选择决策树:
┌─────────────────────────────────────┐
│ 是否需要最高推理质量? │
│ 是 → GPT-4o / GPT-4o-mini │
│ 否 → 是否需要长上下文? │
│ 是 → GPT-4o-128K │
│ 否 → 是否需要图像理解? │
│ 是 → GPT-4o (多模态) │
│ 否 → GPT-4o-mini (性价比最优) │
└─────────────────────────────────────┘
模型对比(2024 定价参考):
| 模型 | 上下文 | Input/1M Token | Output/1M Token | 适用场景 |
|---------------|---------|---------------|-----------------|-------------------|
| GPT-4o | 128K | $2.50 | $10.00 | 复杂推理、代码生成 |
| GPT-4o-mini | 128K | $0.15 | $0.60 | 分类、摘要、简单对话 |
| GPT-3.5-Turbo | 16K/4K | $0.50 | $1.50 | 简单任务、批量处理 |
| DALL-E 3 | - | 按次计费 | - | 图像生成 |
| Whisper | - | $0.006/min | - | 语音转文字 |
| TTS | - | $15/1M字符 | - | 文字转语音 |部署与运维注意事项
生产环境部署检查清单:
1. 网络配置
- 确认 VNet / Private Endpoint 配置正确
- 检查 NSG 规则是否允许访问 Azure OpenAI 端点
- 评估是否需要 Azure Front Door / API Management 做入口管理
2. 安全基线
- API Key 通过 Key Vault 管理,禁止硬编码
- 启用 Managed Identity 替代 API Key 认证
- 配置 Content Filter 过滤策略
- 定期轮换访问密钥
3. 监控告警
- 配置 Application Insights 追踪调用链路
- 设置 Token 消耗和成本告警阈值
- 监控 429/5xx 错误率
- 记录 Prompt 和输出用于审计(注意脱敏)
4. 容量规划
- 按 TPM(Tokens Per Minute)和 RPM(Requests Per Minute)规划配额
- 多区域部署应对单区域故障
- 考虑使用 GPT-4o-mini 分流简单请求