はじめに
ChatGPTライクなインターフェースを使用して企業の社内文書を検索するアプリケーションが構築できると聞いて実際に試してみました。
デモアプリのソースはGitHubに公開されています。セットアップガイド付き。
こちらを参考にすれば すぐに Chat+社内文書検索デモアプリが構築できる!
...と思いきや、いろいろ試行錯誤したので、その内容の備忘録です。
余談ですが、トライアンドエラーは「Try & Error」ではなく「Trial & Error」みたいですね。
Azure CloudShellで構築するよ
セットアップガイドにいろいろと事前準備の記載がありますが、すぐに試せる環境が良いのでAzure CloudShellを使います。Azure CloudShellでのセットアップガイドもあります。
さっそく、やってみる!
概要
構成はこちら。(こちらより参照。)
- ユーザインタフェースのアプリデプロイにAzure App Services
- ChatのやりとりにAzure OpenAI
- Chatの会話を保存するためにAzure Cosmos DB
- 社内文書を保存するためにAzure Blob Storage
- 社内文書を検索するためにAzure AI Search
手順はこちら。(こちらより参照。)
- 事前準備 - 環境変数設定
- 事前準備 - 権限確認
- 事前準備 - コード取得
- Azureのリソース作成
- アプリケーションコードのビルドとデプロイ - フロントエンドのビルド
- アプリケーションコードのビルドとデプロイ - Pythonコードのデプロイ
- アプリケーションコードのビルドとデプロイ - Create and assign Cosmos DB data actions roles
- データの投入(data配下のPDFを利用して Search Index を作成) - 環境変数の設定
- データの投入(data配下のPDFを利用して Search Index を作成) - スクリプト実行用にCosmosDB権限付与
- データの投入(data配下のPDFを利用して Search Index を作成) - Run prepdocs.py
Trial & Error
ここからは私がつまずいた点を書いていきます。
"The subscription does not have QuotaId/Feature required by SKU 'S0' from kind 'OpenAI' or contains blocked QuotaId/Feature."
{"code": "SpecialFeatureOrQuotaIdRequired", "message": "The subscription does not have QuotaId/Feature required by SKU 'S0' from kind 'OpenAI' or contains blocked QuotaId/Feature."}
手順4において、az deployment sub create --name $ENV:DEP_NAME --location $ENV:LOC --template-file main.bicep --parameters principalId=$ENV:AZURE_PRINCIPAL_ID environmentName=$ENV:AZURE_ENV_NAME location=$ENV:LOC
を実行すると上記のエラーメッセージが出ました。
使用しているサブスクリプションでAzure OpenAIが利用できないようです。
Azure OpenAIの利用申請をします。
Azure OpenAIの作成画面で、赤枠の中のリンクをクリックすると、申請Formに遷移します。
必要事項を入力し申請すれば です。(半日程度で申請が通ります。(2024/6月時点))
"Subscription XXX has a quota of 20 for resources of type PublicIpAddress with sku SkuNotSpecified. Subscription currently has 20 resources and the template contains 1 new resources of the this type which exceeds the quota. Please contact support to increase the quota for resource type PublicIpAddress"
{"code": "ResourceCountExceedsLimitDueToTemplate", "message": "Subscription XXX has a quota of 20 for resources of type PublicIpAddress with sku SkuNotSpecified. Subscription currently has 20 resources and the template contains 1 new resources of the this type which exceeds the quota. Please contact support to increase the quota for resource type PublicIpAddress"}
手順4において、az deployment sub create --name $ENV:DEP_NAME --location $ENV:LOC --template-file main.bicep --parameters principalId=$ENV:AZURE_PRINCIPAL_ID environmentName=$ENV:AZURE_ENV_NAME location=$ENV:LOC
を実行すると上記のエラーメッセージが出ました。
使用しているサブスクリプションでパブリックIPアドレスの使用上限に引っかかっているようです。
パブリックIPアドレスの使用上限を緩和します。
サブスクリプションの使用量+クォータ画面で「プロバイダ:Networking」を選択し、下図の赤枠の アイコンから上限緩和申請します。(すぐに設定されます。)
※下図はすでに上限緩和した後の図です。
"This operation require 120 new capacity in quota Tokens Per Minute (thousands) - GPT-35-Turbo, which is bigger than the current available capacity 60. The current quota usage is 240 and the quota limit is 300 for quota Tokens Per Minute (thousands) - GPT-35-Turbo."
{"code": "InsufficientQuota", "message": "This operation require 120 new capacity in quota Tokens Per Minute (thousands) - GPT-35-Turbo, which is bigger than the current available capacity 60. The current quota usage is 240 and the quota limit is 300 for quota Tokens Per Minute (thousands) - GPT-35-Turbo."}
手順4において、az deployment sub create --name $ENV:DEP_NAME --location $ENV:LOC --template-file main.bicep --parameters principalId=$ENV:AZURE_PRINCIPAL_ID environmentName=$ENV:AZURE_ENV_NAME location=$ENV:LOC
を実行すると上記のエラーメッセージが出ました。
使用しているサブスクリプションでAzure OpenAIの利用上限に引っかかっているようです。
このときは、一度最初から作り直すため、リソースグループから削除してもう一度やり直していました。
リソースグループからすべてのリソースを削除したはずなのに、、、。
原因は、Azure OpenAIのリソースがまだ完全に削除されていなかったためでした。
Azure OpenAIは一時的に「削除されたリソースの管理」に移動します。
すぐに削除する場合は、「削除されたリソースの管理」で削除します。
Document intelligenceも同様です。
"SKU 'standard' cannot be provisioned in 'XXX' at this time RequestId: XXX"
{"code": "DeploymentFailed", "target": "/subscriptions/XXX/resourceGroups/XXX/providers/Microsoft.Resources/deployments/search-searvice"}
{"code": "StampNotFound", "message": "SKU 'standard' cannot be provisioned in 'XXX' at this time RequestId: XXX"}
手順4において、az deployment sub create --name $ENV:DEP_NAME --location $ENV:LOC --template-file main.bicep --parameters principalId=$ENV:AZURE_PRINCIPAL_ID environmentName=$ENV:AZURE_ENV_NAME location=$ENV:LOC
を実行すると上記のエラーメッセージが出ました。
Search Services(AI Search)でSKU 'standard' のデプロイに失敗しているようです。
AzureのコンソールからリソースAI SearchでSKU 'standard' を作成しようとしたところ同じエラーが出ました。
今回はデモアプリのためSKUは 'standard' ではなく 'basic' で対応することにします。
(なぜSKU 'standard' で作成できないのかはわかっていません。)
以下のソースを修正します。
5.internal-document-search/infra/main.bicep
+ param searchServiceSkuName string = 'basic'
- param searchServiceSkuName string = 'standard'
The subscription is not registered to use namespace 'Microsoft.AlertsManagement'.
The subscription is not registered to use namespace 'Microsoft.AlertsManagement'. See XXX for how to register subscriptions. (コード: MissingSubscriptionRegisteration、ターゲット: Microsoft.AlertsManagement)
手順4において、az deployment sub create --name $ENV:DEP_NAME --location $ENV:LOC --template-file main.bicep --parameters principalId=$ENV:AZURE_PRINCIPAL_ID environmentName=$ENV:AZURE_ENV_NAME location=$ENV:LOC
を実行後、デプロイログを確認すると上記のエラーメッセージが出ました。
使用しているサブスクリプションでAlerts Managementが登録されていないようです。
Alerts Managementを登録します。
リソースプロバイダーの画面でAlerts Managementを選択し、登録します。
※下図はすでに登録した後の図です。
その後、失敗したデプロイだけ再実行すれば です。
Container XXX didn't respod to HTTP pings on port: 8000, failing site start.
Deployment failed because the site failed to start within 10mins.
Error: Deployment for site 'XXX' with DeploymentId 'XXX' failed because the worker process failed to start within the allotted time.
Please check the runtime logs for more info : https://[App Servicesの名前].scm.azurewebsites.net/api/logs/docker
手順6において、az webapp deployment source config-zip --resource-group $ENV:AZURE_WEBAPP_RESOURCE_GROUP --name $ENV:WEBAPP_NAME --src ./app.zip
を実行すると上記のエラーメッセージが出ました。
10分以内にデプロイができずに失敗しているようです。
なんでや、、、。
ログのURLにアクセスすると詳細のログが確認できます。
ERROR - Container XXX didn't respond to HTTP pings on port: 8000, failing site start.
どうやらポート8000をリッスンしていないようです。
Webアプリの環境変数画面で環境変数を追加します。
「WEBSITE_PORT」「8000」を追加して、「適用」をクリック。
(Forbidden) Request blocked by Auth XXX : Request is blocked because principal [XXX] does not have required RBAC permissions to perform action [Microsoft.DocumentDB/databaseAccounts.readMetadata] on resource [/].
Deployment failed because the site failed to start within 10mins.
Error: Deployment for site 'XXX' with DeploymentId 'XXX' failed because the worker process failed to start within the allotted time.
Please check the runtime logs for more info : https://[App Servicesの名前].scm.azurewebsites.net/api/logs/docker
手順6において、az webapp deployment source config-zip --resource-group $ENV:AZURE_WEBAPP_RESOURCE_GROUP --name $ENV:WEBAPP_NAME --src ./app.zip
を実行すると上記のエラーメッセージが出ました。
10分以内にデプロイができずに失敗しているようです。
なんでや、、、。(2回目)
ログのURLにアクセスすると詳細のログが確認できます。
azure.cosmos.exceptions.CosmosHttpResponseError: (Forbidden) Request blocked by Auth XXX : Request is blocked because principal [XXX] does not have required RBAC permissions to perform action [Microsoft.DocumentDB/databaseAccounts.readMetadata] on resource [/].
どうやらAzure Cosmos DBへのアクセスに失敗しているようです。
Azure Cosmos DBへのアクセス設定は、次の手順(手順7)のようですが、先に実施した方が良さそうです。
手順7の後、手順6を実施します。
Chatできるよ
手順7まで実施してApp ServiceのURL(https://[App Servicesの名前].azurewebsites.net)にアクセスすると、無事Chatができるデモアプリが表示されました。
まずはここまで。手順8以降でつまずきがあったら、後日追記します。
[2024/06/14 追記]
ManagedIdentityCredential.get_token failed: (invalid_request) Timeout waiting for token from portal.
Code: invalid_request
Message: Timeout waiting for token from portal. Audience: https://storage.azure.com/
ManagedIdentityCredential.get_token failed: (invalid_request) Timeout waiting for token from portal. Audience: https://storage.azure.com/
手順10において、Start-Process -FilePath $venvPythonPath -ArgumentList "./scripts/prepdocs.py $cwd/data/* --storageaccount $env:AZURE_STORAGE_ACCOUNT --container $env:AZURE_STORAGE_CONTAINER --searchservice $env:AZURE_SEARCH_SERVICE --searchkey $env:AZURE_SEARCH_KEY --index $env:AZURE_SEARCH_INDEX --formrecognizerservice $env:AZURE_FORMRECOGNIZER_SERVICE --formrecognizerkey $env:AZURE_FORMRECOGNIZER_KEY -v --managedidentitycredential" -Wait -NoNewWindow
を実行すると上記のエラーメッセージが出ました。
ストレージへの認証に失敗しているようです。
実行するprepdocs.pyを確認すると、ストレージアカウントのキーを取得していない場合、うまく処理できないようです。
ストレージアカウントのキーを指定します。
変数$env:AZURE_STORAGE_KEY
にストレージアカウントのキーを指定し、手順10のコマンドを以下に変更。(--storagekey $env:AZURE_STORAGE_KEY
を追加しています。)
Start-Process -FilePath $venvPythonPath -ArgumentList "./scripts/prepdocs.py $cwd/data/* --storageaccount $env:AZURE_STORAGE_ACCOUNT --container $env:AZURE_STORAGE_CONTAINER --searchservice $env:AZURE_SEARCH_SERVICE --searchkey $env:AZURE_SEARCH_KEY --index $env:AZURE_SEARCH_INDEX --formrecognizerservice $env:AZURE_FORMRECOGNIZER_SERVICE --formrecognizerkey $env:AZURE_FORMRECOGNIZER_KEY --storagekey $env:AZURE_STORAGE_KEY -v --managedidentitycredential" -Wait -NoNewWindow
社内文書検索できるよ
全ての手順を実施してApp ServiceのURL(https://[App Servicesの名前].azurewebsites.net)にアクセスすると、無事社内文書検索ができるデモアプリが表示されました。
なお、社内文書検索の対象を追加する場合は、
5.internal-document-search/infra/main.bicep/data/直下にファイルを追加して
再度手順10を実行します。
さいごに
- 手順4において、プライベートな環境に構築するかどうかが選択できます。
プライベートな環境を選択すると、オープンな環境に比べて、プライベートエンドポイントやVMのリソースが追加でデプロイされます。 - つまずくことがなければ1時間くらいで構築できるかも。
- 少しでもみなさんの参考になりますように!