我按照此视频演练设置了 Azure OpenAI API 管理服务。然后,使用
Azure.AI.OpenAI 2.0.0-beta.2
,我尝试调用位于 API 管理实例后面的 gpt-4o
部署的聊天完成端点 - 但不能。
最初,我按照 AzureOpenAI-with-APIM 文档中出现的示例进行操作(请注意,那里的 Nuget 版本是
1.0.0-beta.5
,比我的更早),其中表示 url 应采用以下格式:
var url = $"{apim_url}/deployments/gpt-4o/chat/completions?api-version=2024-02-01";
但这会导致
404 Not Found
错误。查看我的 APIM 日志,我发现实际使用的 url 是错误的 - chat/completion
部分是由客户端重复的。
所以我将其更改为以下代码中的格式,这成功地阻止了
404
错误,但我现在收到 401
错误:
// apim_url is taken from my apim overview page
var apim_url = "redacted";
// subscription_key is taken from the subscriptions key page
var subscription_key = "redacted";
var url = $"{apim_url}/deployments/gpt-4o?api-version=2024-02-01";
var openAIClient = new OpenAIClient(
credential: new System.ClientModel.ApiKeyCredential(subscription_key),
options: new OpenAIClientOptions() { Endpoint = new Uri(url) }
);
var chatClient = openAIClient.GetChatClient("gpt-4o");
// this results in 401 error
var completion = chatClient.CompleteChat(new ChatMessage[] {
new SystemChatMessage("You are a helpful assistant that talks like a pirate."),
new UserChatMessage("Hi, can you help me?"),
});
所以看起来
subscription_key
没有被使用。我知道它应该作为 api-key
标头传递,但我该怎么做?
[自我回答]
有两种方法可以将订阅密钥添加为
api-key
标头:
解决方案编号。 1 - 手动添加
api-key
标题
// apim_url is taken from my apim overview page
var apim_url = "redacted";
// note this is not the "official" url mentioned in the documentation
var url = $"{apim_url}/deployments/gpt-4o?api-version=2024-02-01";
// subscription_key is taken from the subscriptions key page
var subscription_key = "redacted";
// create an httpClient and set subscription_key in an 'api-key' header
var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Add("api-key", subscription_key);
var clientOptions = new OpenAIClientOptions
{
Endpoint = new Uri(url),
Transport =
// For Azure.AI.OpenAI 2.0.0, use:
new System.ClientModel.Primitives.HttpClientPipelineTransport(httpClient)
// For Azure.AI.OpenAI 1.0.0, use this instead:
// new Azure.Core.Pipeline.HttpClientTransport(httpClient)
};
var openAIClient = new OpenAIClient(
credential: new System.ClientModel.ApiKeyCredential(subscription_key), // still required!
options: clientOptions
);
var chatClient = openAIClient.GetChatClient("gpt-4o");
var completion = chatClient.CompleteChat(new ChatMessage[] {
new SystemChatMessage("You are a helpful assistant that talks like a pirate."),
new UserChatMessage("Hi, can you help me?"),
});
解决方案编号。 2 - 实现一个“policy”类,并在其中设置
api-key
标头
Azure.AI.OpenAI 2.0.0
:实施
PipelinePolicy
:
public class ApiKeyPolicy : PipelinePolicy
{
private readonly string _apiKey;
public ApiKeyPolicy(string apiKey)
{
_apiKey = apiKey;
}
public override void Process(PipelineMessage message, IReadOnlyList<PipelinePolicy> pipeline, int currentIndex)
{
message.Request.Headers.Add("api-key", _apiKey);
ProcessNext(message, pipeline, currentIndex);
}
public override ValueTask ProcessAsync(PipelineMessage message, IReadOnlyList<PipelinePolicy> pipeline, int currentIndex)
{
message.Request.Headers.Add("api-key", _apiKey);
return ProcessNextAsync(message, pipeline, currentIndex);
}
}
然后:
// apim_url is taken from my apim overview page
var apim_url = "redacted";
// note this is not the "official" url mentioned in the documentation
var url = $"{apim_url}/deployments/gpt-4o?api-version=2024-02-01";
// subscription_key is taken from the subscriptions key page
var subscription_key = "redacted";
// create an apiKeyPolicy and set clientOptions with it
var apiKeyPolicy = new ApiKeyPolicy(subscription_key);
var clientOptions = new OpenAIClientOptions
{
Endpoint = new Uri(url),
Transport = new System.ClientModel.Primitives.HttpClientPipelineTransport(new HttpClient())
};
clientOptions.AddPolicy(apiKeyPolicy, PipelinePosition.PerCall);
var openAIClient = new OpenAIClient(
credential: new System.ClientModel.ApiKeyCredential(subscription_key), // still required!
options: clientOptions
);
var chatClient = openAIClient.GetChatClient("gpt-4o");
var completion = chatClient.CompleteChat(new ChatMessage[] {
new SystemChatMessage("You are a helpful assistant that talks like a pirate."),
new UserChatMessage("Hi, can you help me?"),
});
Azure.AI.OpenAI 1.0.0
:实施
HttpPipelinePolicy
:
public class ApiKeyPolicy : HttpPipelinePolicy
{
private readonly string _apiKey;
public ApiKeyPolicy(string apiKey)
{
_apiKey = apiKey;
}
public override void Process(HttpMessage message, ReadOnlyMemory<HttpPipelinePolicy> pipeline)
{
message.Request.Headers.Add("api-key", _apiKey);
ProcessNext(message, pipeline);
}
public override ValueTask ProcessAsync(HttpMessage message, ReadOnlyMemory<HttpPipelinePolicy> pipeline)
{
message.Request.Headers.Add("api-key", _apiKey);
return ProcessNextAsync(message, pipeline);
}
}
然后:
// ... same code as above ...
var clientOptions = new OpenAIClientOptions
{
Endpoint = new Uri(url),
Transport = new Azure.Core.Pipeline.HttpClientTransport(new HttpClient())
};
clientOptions.AddPolicy(apiKeyPolicy, HttpPipelinePosition.PerCall);
// ... same code as above ...