【Microsoft編】Azure OpenAI × Power Automateで実装する、エンタープライズ向け堅牢ワークフロー

AI
スポンサーリンク

みなさん、こんにちは!業務ハックLabのようです。

はい、前回はGASを使って「コードベース」での爆速開発を行いましたね! 今回は、Microsoft 365環境での実装です。

年末年始に会社のシステムをアップグレードしようと考えている方、必見の内容ですよ!

はじめに:なぜ企業は「ノーコード」を選ぶのか?

前回はGASを使って「コードベース」での爆速開発を行いました。

今回、Microsoft 365環境で目指すのは「速さ」ではなく、「堅牢性(Stability)」と「ガバナンス(Governance)」です。

Power AutomateとAzure OpenAI Serviceを組み合わせることで、認証情報がセキュアに管理され、処理フローが可視化された、まさに「企業の業務システム」としてふさわしい実装を行います。

(Googleが「個人の武器」だとしたら、Microsoftは「組織の基盤」って感じですよね)

アーキテクチャ図解

まず、全体像を整理しましょう。

Trigger: Outlook(新しいメールが届いたとき V3)

Brain: Azure OpenAI Service(GPT-5.2-chat)

Logic: Power Automate(クラウドフロー)

Database: SharePoint Lists

Notification: Microsoft Teams(アダプティブカード)

はい、すべてがMicrosoftのエコシステム内で完結していますね!

これが企業にとって重要なポイントで、すべてのサービスが同じセキュリティポリシーの下で管理されるんです。


事前準備:Azure OpenAI Serviceのセットアップ

Microsoft環境での実装には、Azure OpenAI Serviceが必要です。

ステップ1:Azure OpenAI Serviceのリソース作成

  1. Azure Portalにアクセス(https://portal.azure.com)
  2. 「リソースの作成」→「Azure OpenAI」を検索
  3. リソースグループ、リージョン、名前を設定して作成
  4. デプロイが完了したら、リソースに移動

ステップ2:モデルのデプロイ

  1. 左メニューから「モデルデプロイ」を選択
  2. 「新しいデプロイ」をクリック
  3. モデル:「gpt-5.2-chat」を選択
  4. デプロイ名を設定(例:mail-triage-gpt52)
  5. デプロイを作成

ステップ3:エンドポイントとキーの取得

  1. 「キーとエンドポイント」を選択
  2. 以下の情報をメモ:
    • エンドポイント: https://あなたのリソース名.openai.azure.com/
    • キー1 または キー2: どちらか一方をコピー

はい、これで準備完了です!

(Azure OpenAIは従量課金なので、無料枠がない点だけ注意してくださいね)


Power Automateフローの構築

では、実際にフローを作っていきましょう。

Power Automate(https://make.powerautomate.com)にアクセスして、「マイフロー」→「新しいフロー」→「自動化したクラウドフロー」を選択します。

ステップ1:トリガーの設定

フロー名を入力し、トリガーとして「新しいメールが届いたとき(V3)」を選択します。

設定項目:

  • フォルダー: 受信トレイ
  • 重要度: すべて
  • 添付ファイルを含む: いいえ
  • 詳細オプション件名フィルター: (特定のキーワードがある場合はここで設定)

はい、これでメールが届くたびにフローが起動するようになりました!


最大の山場:HTTPアクションとJSONスキーマ

ここからが本番です。

Power Automateには「OpenAIコネクタ」も存在しますが、企業利用ではセキュリティやコスト管理の観点から「Azure OpenAIのエンドポイントを直接叩く」HTTPアクションの使用を推奨します。(HTTPアクションはプレミアムコネクタなので注意です!)

ステップ2:HTTPアクションの設定

「新しいステップ」→「HTTP」で検索してアクションを追加します。

設定内容:

方法: POST

URI: https://あなたのリソース名.openai.azure.com/openai/deployments/mail-triage-gpt52/chat/completions?api-version=2025-04-01-preview

ヘッダー:
  api-key: ここにAzure OpenAI APIキーを入力してください
  Content-Type: application/json

本文:
{
  "messages": [
    {
      "role": "system",
      "content": "あなたは熟練したカスタマーサポートマネージャーです。入力された「顧客からのメール」を分析し、以下のルールに従ってJSON形式で結果を出力してください。\n\n# 分析ルール\n1. **sentiment**: 顧客の感情を `positive`, `neutral`, `negative`, `severe` (激怒・法的脅迫など) の4段階で評価。\n2. **urgency**: 対応の緊急度を `high`, `medium`, `low` の3段階で評価。\n   - `high`: システム障害、セキュリティ事故、解約の示唆、激しいクレーム\n   - `medium`: 一般的な質問、見積依頼、バグ報告\n   - `low`: 営業メール、スパム、緊急性のない報告\n3. **category**: 内容を分類 (`technical_issue`, `billing`, `feature_request`, `sales_spam`, `other`)。\n4. **summary**: メールの内容を日本語50文字以内で要約。\n5. **draft_reply**: 返信メールのドラフト案(日本語)。相手の感情に配慮した丁寧な文章を作成すること。\n\n# 制約事項\n- 出力は**JSON形式のみ**とすること。Markdown記法(```json など)は含めないでください。\n- 余計な解説や挨拶文は一切不要です。"
    },
    {
      "role": "user",
      "content": "@{triggerBody()?['body']}"
    }
  ],
  "max_completion_tokens": 1000,
  "response_format": {
    "type": "json_object"
  }
}

はい、少し複雑ですね!

重要ポイント:

  • @{triggerBody()?['body']} → これが動的コンテンツで、受信したメールの本文が自動で挿入されます
  • max_completion_tokens: 1000 → 出力トークン数の上限を設定(コスト管理のため)
  • response_format: { type: "json_object" } → GPT-5.2-chatにJSON形式での出力を強制します
  • 実運用をする時はapi-keyはAzure Key Vaultを使用してくださいね。
    今回のように直接設定してしまうと見せてはいけない人にapi-keyが見られてしまう可能性が大です。

💡 GPT-5.2-chatのパラメータ仕様:

GPT-5.2-chatでは、従来のmax_tokenstemperatureパラメータはサポートされていません

代わりに下記のパラメーターが使用できます。

  • max_completion_tokens: 出力トークン数の上限(従来のmax_tokensの代替)
  • response_format: JSON出力を保証

これにより、ある程度コスト管理をしながら確実なJSON出力が可能になります。


ステップ3:JSONの解析(1回目)

ここがGASとの最大の違いです!

Power Automateでは、後続のアクション(例:条件分岐)でデータを利用するために、「データの型(スキーマ)」を事前に定義する必要があります。

「新しいステップ」→「データ操作」→「JSON の解析」を追加します。

設定内容:

コンテンツ: HTTPアクションの「本文」を選択

スキーマ:
{
  "type": "object",
  "properties": {
    "choices": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "message": {
            "type": "object",
            "properties": {
              "content": {
                "type": "string"
              }
            }
          }
        }
      }
    }
  }
}

はい、一見手間に見えますが、これにより「存在しないデータを参照してエラーになる」といった事態を未然に防ぐことができます。


ステップ4:JSONの解析(2回目)

注意点として、上記のスキーマで取得できるのはAIからの回答テキスト全体(文字列としてのJSON)です。

そのため、さらに後続のアクションで、回答テキスト自体を再度「JSONの解析」にかける2段構えの構成が必要になります。

もう一度「データ操作」→「JSONの解析」を追加します。

設定内容:

コンテンツ: @{body('JSON_の解析')?['choices']?[0]?['message']?['content']}

スキーマ:
{
  "type": "object",
  "properties": {
    "sentiment": {
      "type": "string"
    },
    "urgency": {
      "type": "string"
    },
    "category": {
      "type": "string"
    },
    "summary": {
      "type": "string"
    },
    "draft_reply": {
      "type": "string"
    }
  }
}

はい、これでやっと各フィールドが使えるようになりました!

(このあたりの構造理解が、Power Automate上達の鍵なんですよね)



SharePoint Listsへのデータ保存

次に、分析結果をSharePoint Listsに保存します。

事前準備:SharePoint Listの作成

SharePointサイトで新しいリストを作成し、以下の列を追加:

  • タイトル(テキスト) – デフォルトで存在
  • 受信日時(日付と時刻)
  • 送信者(テキスト)
  • 件名(テキスト)
  • 感情スコア(選択肢: positive, neutral, negative, severe)
  • 緊急度(選択肢: high, medium, low)
  • カテゴリ(選択肢: technical_issue, billing, feature_request, sales_spam, other)
  • AI要約(複数行テキスト)
  • 返信ドラフト(複数行テキスト)

フローの設定

「新しいステップ」→「SharePoint」→「項目の作成」を追加します。

設定内容:

サイトのアドレス: あなたのSharePointサイトを選択
リスト名: 作成したリスト名を選択

タイトル: @{triggerBody()?['subject']}
受信日時: @{triggerBody()?['receivedDateTime']}
送信者: @{triggerBody()?['from']}
件名: @{triggerBody()?['subject']}
感情スコア: @{body('JSONの解析_1')?['sentiment']}
緊急度: @{body('JSONの解析_1')?['urgency']}
カテゴリ: @{body('JSONの解析_1')?['category']}
AI要約: @{body('JSONの解析_1')?['summary']}
ドラフト返信: @{body('JSONの解析_1')?['draft_reply']}

はい、これでデータが自動で蓄積されていきます!


Teamsへの通知:アダプティブカードでリッチに

最後に、緊急度が高い場合にTeamsへ通知を送ります。

ステップ5:条件分岐の追加

「新しいステップ」→「条件」を追加します。

設定内容:

左辺: @{body('JSONの解析_1')?['urgency']}
演算子: 次の値に等しい
右辺: high

ステップ6:Teamsへの通知

「はいの場合」のブランチに「新しいステップ」を追加し、「Microsoft Teams」→「チャットまたはチャネルでメッセージを投稿する」を選択します。

設定内容:

投稿者: フロー ボット
投稿先: チャネル
チーム: あなたのチームを選択
チャネル: 通知を送りたいチャネルを選択

メッセージ:
🚨 **緊急クレーム検知** 🚨

件名: @{triggerBody()?['subject']}
送信者: @{triggerBody()?['from']}
受信日時: @{triggerBody()?['receivedDateTime']}

AI要約:
@{body('JSON_の解析_1')?['summary']}

カテゴリ: @{body('JSON_の解析_1')?['category']}
感情スコア: @{body('JSON_の解析_1')?['sentiment']}

[SharePointで詳細を確認]

はい、これで完成です!



アダプティブカードでさらにリッチに

ただのテキスト通知ではなく、「アダプティブカード(Adaptive Card)」を使うと、もっとリッチな通知が作れます。

「チャットまたはチャネルでメッセージを投稿する」の代わりに、「チャットやチャネルにカードを投稿する」を使います。

アダプティブカードのJSON例:

{
  "type": "AdaptiveCard",
  "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
  "version": "1.4",
  "body": [
    {
      "type": "TextBlock",
      "text": "🚨 緊急クレーム検知",
      "weight": "Bolder",
      "size": "Large",
      "color": "Attention"
    },
    {
      "type": "FactSet",
      "facts": [
        {
          "title": "件名:",
          "value": "@{triggerBody()?['subject']}"
        },
        {
          "title": "送信者:",
          "value": "@{triggerBody()?['from']}"
        },
        {
          "title": "AI要約:",
          "value": "@{body('JSON_の解析_1')?['summary']}"
        },
        {
          "title": "緊急度:",
          "value": "@{body('JSON_の解析_1')?['urgency']}"
        }
      ]
    }
  ],
  "actions": [
    {
      "type": "Action.OpenUrl",
      "title": "SharePointで確認",
      "url": "https://あなたのSharePointサイトURL"
    }
  ]
}

アダプティブカードを使うと、背景色を変えたり、ボタンを配置したりと、高度なUI/UXもノーコードで実現できるんですよね!

(これがPower Platformの醍醐味ですw)


実際に動かしてみよう

では、テストメールを送って動作確認してみましょう。

テスト1:緊急クレーム

自分宛(またはテスト用メールアドレス)に以下のようなメールを送ります。(前回のGoogle編で使った文章と同じものですね)

件名: 至急対応願います
本文: 
御社のシステムが3時間も停止しており、業務に重大な支障が出ています。
このままでは損害賠償を請求せざるを得ません。
すぐに責任者から連絡をください

フローが起動し…

  1. Azure OpenAIで分析
  2. SharePoint Listsに保存
  3. Teamsに通知

という一連の流れが自動で実行されます!

はい、初めて動いたときの達成感、たまらないですよね!


テスト2:営業メール

次は、営業メールで試してみます。

件名: 新サービスのご案内
本文: 
この度、弊社では新しいクラウドサービスをリリースいたしました。
貴社のビジネスにお役立ていただけると存じます。
詳細は添付の資料をご覧ください。

こちらは urgency: low と判定され、Teams通知は飛ばずにSharePoint Listsにだけ記録されました。

はい、完璧ですね!

トラブルシューティング

実装中によくあるエラーと対処法をまとめておきます。

エラー1:「HTTPアクションが401エラーで失敗する」

APIキーが正しく設定されていない可能性があります。 ヘッダーの api-key に正しいキーが入っているか確認してください。

エラー2:「JSONの解析でエラーが発生する」

Azure OpenAIが “`json というマークダウン記法を付けて返している可能性があります。 システムプロンプトで「Markdown記法は含めないでください」と明示しているか確認してください。

エラー3:「動的コンテンツが選択できない」

前のアクションで「JSONの解析」を追加していないと、動的コンテンツとして選択肢に表示されません。 フローの順序を確認してください。


Google vs Microsoft:どちらを選ぶべきか?

3回にわたって両者の実装を比較してきました。

最後に、選択の指針をまとめておきます。

特徴Google Workspace × Gemini (GAS)M365 × Azure OpenAI (Power Platform)
開発スタイルスクリプト(Pro-code)ビジュアル(Low-code)
学習曲線JavaScript知識が必要プログラミング不要
開発速度圧倒的に速い慣れるまで時間がかかる
コスト無料枠が充実従量課金(APIコストに注意)
メンテナンス性属人化しやすいフローが可視化されているので引き継ぎやすい
セキュリティ個人アカウント依存組織アカウントで一元管理
拡張性柔軟にカスタマイズ可能コネクタの範囲内で拡張
推奨シーン個人利用、プロトタイプ、エンジニア主体全社システム、機密情報扱い、非エンジニア主体

重要なのは、どちらが優れているかではなく、「解決したい課題の規模」と「組織のフェーズ」に合わせて使い分けることです。


まとめ

はい、いかがでしたでしょうか?

3回のシリーズを通じて、AIによるメール自動トリアージシステムを、設計 → Google実装 → Microsoft実装という流れで解説してきました。

最大のポイントは、「人間の判断基準を言語化」し、「JSONという構造化データ」でAIに返答させることで、システムによる自動化を実現したことでした。

ぜひ、あなたの組織に合った方法で、AIによる業務変革(DX)への第一歩を踏み出してみてください!

年末年始休暇中に、こっそり作ってみるのもいいかもしれませんねw

それでは皆さん、良い業務ハックライフを~

コメント