🤖

Teamsをもっと便利に!Azureで作るセキュアなRAGボット開発

に公開

はじめに

Microsoft Teamsは多くの企業で日常的に利用されており、業務の中心的なプラットフォームになっています。しかし、情報がチャネルやファイルに分散し、「必要な資料や決定事項がすぐに見つからない」という課題もあります。

そこで本記事では、Azureのサービス群を活用して、社内ドキュメントに関する質問に答えてくれる RAG(Retrieval-Augmented Generation)対応のTeamsボット を開発した過程を紹介します。特に、シークレット情報を持たせずにマネージドIDを用いてセキュアに認証する構成 に重点を置いています。

開発環境

今回の開発で利用した主な技術は以下の通りです。

項目 バージョン / 備考
クラウド Microsoft Azure
言語 Python 3.11+
Webフレームワーク FastAPI
Botフレームワーク Microsoft Bot Framework SDK for Python
主要Azureサービス Bot Service, App Service, ACR, AI Search, OpenAI
コンテナ Docker

アプリケーション自体は、使い慣れているPythonとFastAPIで実装することにしました。


セットアップ手順

それでは、実際の構築手順です。大まかな流れは以下のようになります。

  1. Azureリソースの作成
  2. 認証部分の実装
  3. アプリケーションのコンテナ化とデプロイ
  4. RAG用ドキュメントのインデックス作成
  5. Teamsアプリとしての登録

1. Azureリソースの作成

まずは土台となるインフラをAzure CLIで準備します。GUIで一つずつ作っても良いのですが、CLIだと再現性があって便利です。

以下のコマンド内の<...>で示されるプレースホルダーは、ご自身の環境に合わせた任意の名前に置き換えてください。

Botのアプリケーション本体をホストするApp Service、コンテナイメージを格納するAzure Container Registry (ACR)、RAGの頭脳となるAzure OpenAIAzure AI Search、そしてドキュメントを保管するAzure Storageなどを作成します。

そして、これらをつなぐ中心的な役割を担うのがBot Serviceです。Bot Serviceを作成する際には、認証方法を選択できます。今回はシークレットを使わないユーザー割り当てマネージドIDという方式を採用しました。そのために、まずマネージドIDリソースを作成しておきます。

# 変数の設定
RESOURCE_GROUP="<your-resource-group-name>"
LOCATION="japaneast"
MANAGED_IDENTITY_NAME="<your-managed-identity-name>"
BOT_NAME="<your-bot-name>"
APP_SERVICE_NAME="<your-app-service-name>"

# リソースグループの作成
az group create --name $RESOURCE_GROUP --location $LOCATION

# 認証用のIDを作成
az identity create --name $MANAGED_IDENTITY_NAME --resource-group $RESOURCE_GROUP

# IDの情報を取得
IDENTITY_RESOURCE_ID=$(az identity show --name $MANAGED_IDENTITY_NAME --resource-group $RESOURCE_GROUP --query id -o tsv)
CLIENT_ID=$(az identity show --name $MANAGED_IDENTITY_NAME --resource-group $RESOURCE_GROUP --query clientId -o tsv)

# Bot Serviceを作成時に、認証方法としてマネージドIDを指定
az bot create \
    --resource-group $RESOURCE_GROUP \
    --name $BOT_NAME \
    --app-type UserAssignedMSI \
    --appid $CLIENT_ID \
    --tenant-id $(az account show --query tenantId -o tsv) \
    --msi-resource-id $IDENTITY_RESOURCE_ID \
    --endpoint "https://$APP_SERVICE_NAME.azurewebsites.net/api/messages" \
    --location "global"

このように、Bot Serviceの作成時に認証方法を指定するのがポイントです。

2. 認証部分の実装

Botアプリケーションから他のAzureサービスへアクセスする際の認証部分のコードです。今回は認証にマネージドIDを使うと決めたので、それに合わせた実装が必要でした。

Bot FrameworkのPython SDKは、標準ではこの認証方式を直接サポートしていないようでした。そのため、azure-identityライブラリを使って少しだけ追加のコードを記述しています。

具体的には、AppCredentialsを継承したカスタムクラスを作成し、内部でManagedIdentityCredentialを呼び出してアクセストークンを取得するように実装しました。

app/auth/managed_identity_credentials.py:

from botframework.connector.auth import AppCredentials
from azure.identity import ManagedIdentityCredential

class ManagedIdentityAppCredentials(AppCredentials):
    def __init__(self, app_id: str, **kwargs):
        super().__init__(app_id=app_id, **kwargs)
        self.credential = ManagedIdentityCredential(client_id=app_id)

    def get_access_token(self, force_refresh: bool = False) -> str:
        token = self.credential.get_token("https://api.botframework.com/.default")
        return token.token

そして、アプリケーションの初期化時に、この自作クラスをBotアダプターに設定します。

app/main.py (抜粋):

adapter_settings = BotFrameworkAdapterSettings(app_id=settings.MicrosoftAppId, app_password="")
adapter = BotFrameworkAdapter(adapter_settings)

# 認証部分を自作のクラスで上書きします
adapter._credentials = ManagedIdentityAppCredentials(app_id=settings.MicrosoftAppId)

もし従来のApp IDとパスワードで認証する場合は、この部分の実装は不要で、設定ファイルにシークレットを記述することになります。

3. アプリケーションのコンテナ化とデプロイ

アプリケーションはDockerコンテナとしてApp Serviceにデプロイします。Dockerfileは一般的なPythonアプリケーションのものです。

コンテナイメージをビルドしてACR(Azure Container Registry)にプッシュした後、App Serviceの構成でそのイメージを指定します。

4. RAG用ドキュメントのインデックス作成

Botに回答させるための知識源として、社内ドキュメント(PDFなど)をAzure AI Searchに登録します。このプロセスもPythonスクリプトで自動化しました。

  1. ドキュメントを読み込み、適度なサイズに分割(チャンキング)。
  2. Azure OpenAIの埋め込みモデルで各チャンクをベクトル化。
  3. 元のテキストとベクトルデータをAzure AI Searchのインデックスに登録。

このインデックスを検索することで、Botは質問に関連するドキュメント箇所を高速に見つけ出すことができます。

5. Teamsアプリとしての登録

最後に、manifest.jsonというファイルにBotの情報を記述し、ZIPファイルにまとめてTeams Admin Centerからアップロードします。これで、組織内のユーザーがTeams上でBotを使えるようになります。

動作確認方法

Botを構築したあとは、実際にユーザーとの会話が正しく動作するかを確認します。確認方法は大きく2種類あります。

1. Bot Emulatorでのローカルテスト

開発段階では、Bot Framework Emulator を利用すると、ローカル環境でBotの動作を確認できます。

  • Botアプリをローカルで起動した状態で、Emulatorから http://localhost:3978/api/messages のようなエンドポイントを指定すると会話をテスト可能。
  • Teamsにデプロイする前に動作確認ができるため、デバッグ効率が大幅に向上します。
  • 認証周りやRAG連携のレスポンス確認など、開発中の細かい挙動を確認する際に便利です。

2. Azure PortalのTest in Web Chat

BotをAzureにデプロイした後は、Azure Portal上の Bot Service → Test in Web Chat 機能を使って、クラウド環境にデプロイされたBotを直接テストできます。

  • 実際にTeamsに登録する前に、クラウド上で正しく応答できるかを確認可能。
  • ローカルでは再現できない認証設定やマネージドIDによる接続なども、この環境で検証できます。
  • 本番に近い環境で動作確認できるため、事前の不具合検出に役立ちます。

動作確認と所感

以上の手順を経て、無事にTeams上で動作するRAGボットが完成しました。実際に質問を投げると、AI Searchが関連ドキュメントを検索し、その内容を元にOpenAIが回答を生成して返してくれます。

今回、Azureの様々なサービスを組み合わせることで、比較的短い期間で高機能なチャットボットを構築できることを実感しました。特に認証周りは、クラウドの機能をうまく活用することで、シークレット情報をコードから排除し、セキュアな構成を実現できるのが良い点だと感じます。

一方で、RAGの回答精度は、ドキュメントの分割方法やプロンプトの作り込みに大きく依存します。このあたりは、実際に運用しながら継続的に改善していく必要がある、奥が深い領域だと改めて感じました。

まとめ

本記事では、Azureのサービス群を活用して、Teams対応のRAGチャットボットを構築した事例を紹介しました。

認証情報の管理は、アプリケーション開発における普遍的な課題ですが、クラウドネイティブな仕組みをうまく利用することで、より安全で効率的な開発が可能になると思います。今回の知見が、同じような課題を持つ方の参考になれば幸いです。

参考文献

Discussion