Azure OpenAI Service を HttpClient + マネージド ID でアクセスする
はじめに
Azure OpenAI Service には API キーと ID ベースの 2 種類の認証方式があります。API キーは簡単ではあるものの、可能であればよりセキュアな ID ベースの認証を使いたいところです。Azure App Service や Azure Functions などから Azure OpenAI Service を呼び出す場合は、マネージド ID を利用することで、シークレットを意識する必要がなくなります。
Azure OpenAI Service に対してマネージド ID でアクセスするには Azure OpenAI クライアント ライブラリを使用するのが簡単です。
ただし Azure OpenAI クライアント ライブラリはプレビューでもありまだまだ使いづらいところもあります。できればより低レイヤーな HttpClient
クラスを使って Azure OpenAI Service にアクセスしたいということもあります。
サンプル コード
DefaultAzureCredential
クラスは GetToken
メソッドまたは GetTokenAsync
メソッドによってアクセス トークンを取得することができます。これらのメソッドはパラメーターとしてスコープを要求します。これは Azure OpenAI クライアント ライブラリのコードを見ると https://cognitiveservices.azure.com/.default
であることがわかります。ここまでわかればあとは簡単です。
public static class Program
{
private static readonly string[] Scopes = new[] { "https://cognitiveservices.azure.com/.default" };
private static readonly string Endpoint = "https://{{resource-name}}.openai.azure.com/openai/deployments/{{deployment-name}}/chat/completions?api-version={{api-version}}";
private static async Task Main()
{
var credential = new DefaultAzureCredential();
var token = await credential.GetTokenAsync(new TokenRequestContext(Scopes));
var httpClient = new HttpClient();
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, Endpoint)
{
Content = new StringContent(
JsonSerializer.Serialize(
new Dictionary<string, object>()
{
["messages"] = new List<Dictionary<string, object>>()
{
new Dictionary<string, object>()
{
["role"] = "system",
["content"] = "あなたは優秀なAIアシスタントです。慎重に考え自信を持って回答してください。"
},
new Dictionary<string, object>()
{
["role"] = "user",
["content"] = "日本の首都はどこにありますか?"
}
}
}
),
new MediaTypeHeaderValue("application/json"))
};
httpRequestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token.Token);
var httpResponseMessage = await httpClient.SendAsync(httpRequestMessage);
var httpResponseContent = await httpResponseMessage.Content.ReadAsStringAsync();
Console.WriteLine(httpResponseContent);
Console.ReadLine();
}
}
おわりに
DefaultAzureCredential
は Azure SDK を使う前提でしか扱ってこなかったので、GetToken
メソッドや GetTokenAsync
メソッドがあるというのは知りませんでした。何事も調べてみるべきですね。
Discussion