🙆

Azure OpenAI Service でマネージド ID を使う

2023/04/20に公開

今日は .NET で マネージド ID を使用して Azure OpenAI Service を構成する方法 を試してみます。

マネージド ID を使うようにする場合は Azure SDK for .NET での依存関係の挿入 に従ってやるのが一番素直なのでそれに従ってやっていこうと思います。

プロジェクトの準備

今回は一番ライトな ASP.NET Core (空) のプロジェクトをベースにやっていきます。
プロジェクトを作成したら以下の NuGet パッケージを追加します。

  • Microsoft.Extensions.Azure
  • Azure.Identity
  • Azure.AI.OpenAI (2023/04/20 時点でプレビューパッケージです)

マネージド ID を使用して Azure OpenAI Service を構成する方法 を参考に Azure ポータルの Cloud シェルで以下のコマンドをうって開発用に自分のアカウントに Azure OpenAI Service を呼び出す権限を追加します。

export user=自分のアカウントのオブジェクトID
export myResourceGroupName=OpenAIをデプロイしているリソースグループ名
export resourceId=$(az group show -g $myResourceGroupName | jq -r .id)
az role assignment create --role "Cognitive Services OpenAI User" --assignee $user --scope $resourceId

権限が付与されたら以下のコードを書いて実行してみます。

using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Azure;
using Microsoft.Extensions.Options;

var builder = WebApplication.CreateBuilder(args);

// OpenAI のオプションを DI コンテナに登録
// appsettings.json, appsettings.Development.json, secrets.json などに以下の設定がある前提
// "OpenAIOptions": {
//   "ModelDeployName": "Azure OpenAI Service にモデルをデプロイするときに指定した名前"
// }
// Azure にデプロイした際にはアプリケーション設定に OpenAIOptions__ModelDeployName というキーで設定する
builder.Services.Configure<OpenAIOptions>(builder.Configuration.GetRequiredSection("OpenAIOptions"));

// Azure SDK を DI コンテナに登録
builder.Services.AddAzureClients(clientBuilder =>
{
    // OpenAI のクライアントを登録
    // appsettings.json, appsettings.Development.json, secrets.json などに以下の設定がある前提
    // "OpenAIClient": {
    //   "Endpoint": "https://xxxxxx.openai.azure.com/",
    // }
    // Azure にデプロイした際にはアプリケーション設定に OpenAIClient__Endpoint というキーで設定する
    clientBuilder.AddOpenAIClient(builder.Configuration.GetSection(nameof(OpenAIClient)));

    // Managed ID を使う
    clientBuilder.UseCredential(new DefaultAzureCredential());
});

var app = builder.Build();

app.MapGet("/", async (
    // クエリパラメーターでプロンプトを受け取る
    [FromQuery]string prompt,
    // DI コンテナから OpenAI のクライアントを取得
    OpenAIClient client,
    // DI コンテナから OpenAI のオプションを取得
    IOptions<OpenAIOptions> openAIOptions,
    CancellationToken cancellationToken) =>
    await client.GetCompletionsAsync(
        openAIOptions.Value.ModelDeployName,
        prompt,
        cancellationToken));

app.Run();

class OpenAIOptions
{
    public required string ModelDeployName { get; set; }
}

実行して表示された URL に ?prompt=任意のプロンプト をつけてアクセスすると JSON で結果が表示されます。

こんな URL でアクセスしてみました。

https://localhost:7057/?prompt=あなたは可愛い女性アイドルです。語尾は"""ぺこ"""になります。例えば"""こんにちはぺこ!"""や"""こんぺこ!!"""や"""今日は暑かったぺこね。"""のようになります。ファンから"""こんにちは"""と言われたので返事をします。返事は150文字以内にしてください。返事:

こんな JSON が返ってきました。ばっちりっぽいですね。

{
  "value": {
    "id": "cmpl-77GX1OqcDkxWPkxbcmGJTn0cc9QGL",
    "created": 1681966199,
    "model": "gpt-35-turbo",
    "choices": [
      {
        "text": "こんにちはぺこ!元気いっぱいの私です!今日も一日中歌って踊って最高の日になったぺこ!そんな1日を過ごすことができたのもファンの皆さんがあたたかく見守ってくださったからこそです。これからも全力で歌って踊ってみ",
        "index": 0,
        "logprobs": null,
        "finishReason": "length"
      }
    ],
    "usage": {
      "completionTokens": 100,
      "promptTokens": 110,
      "totalTokens": 210
    }
  },
  "hasValue": true
}

Azure にデプロイする場合は App Service などでマネージド ID を使うようにして Cognitive Services OpenAI User の権限を付与してアプリケーション設定に Azure OpenAI Service のエンドポイントとデプロイしたモデルの名前を設定してください。

まとめ

何故か自分の中で Azure OpenAI Service は、まだマネージド ID での認証に対応していないと思っていたのですが普通に対応してたので試してみました。
設定が必要ですが API キーがいらないので間違って機密情報を公開することもないので安心です。

Microsoft (有志)

Discussion