📊

Microsoft 365 Copilot の宣言型エージェントで API にデータを POST する

2024/12/03に公開

はじめに

生成 AI を使った RAG の主流はデータ検索です。Microsoft 365 Copilot では Microsoft Graph を使った RAG が組み込まれており、Microsoft 365 のデータを AI に回答させることができます。また Microsoft 365 Copilot を拡張して外部のデータを取り込むこともできます。RAG を使った検索は一般化しているのですが、さらに今後は、生成 AI にデータを渡して何かしらの処理をさせることがポイントになります。

Microsoft 365 Copilot の宣言型エージェントでは、API プラグインに対して GET または POST の呼び出しができます。POST ができるということは、任意のデータを渡すことができるということになります。今回は、施設予約をする API を呼び出す宣言型エージェントを作成してみます。

サンプル コード

https://github.com/karamem0/samples/tree/main/microsoft-365-copilot-api-plugins

実行手順

API の中身は大したことないので割愛します。

manifest.json

スキーマのバージョンは 1.19 である必要があります。現時点で開発者ポータルがサポートする最新バージョンは 1.17 なので注意してください。宣言型エージェントとして declarativeAgent.json を指定します。

{
  "$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.19/MicrosoftTeams.schema.json",
  "version": "1.0.0",
  "manifestVersion": "1.19",
  "id": "bfbec615-0b1d-4129-95d1-eb27522ce881",
  "name": {
    "short": "施設予約システム",
    "full": "施設予約システム"
  },
  "developer": {
    "name": "karamem0",
    "mpnId": "",
    "websiteUrl": "https://github.com/karamem0/samples",
    "privacyUrl": "https://github.com/karamem0/samples",
    "termsOfUseUrl": "https://github.com/karamem0/samples"
  },
  "description": {
    "short": "施設を予約または検索できます。",
    "full": "社内の会議室やブースの施設を予約できます。"
  },
  "icons": {
    "outline": "outline.png",
    "color": "color.png"
  },
  "accentColor": "#FFFFFF",
  "copilotAgents": {
    "declarativeAgents": [
      {
        "id": "350b7c19-59e4-4b2f-8923-477c318ce39f",
        "file": "declarativeAgent.json"
      }
    ]
  },
  "validDomains": []
}

declarativeAgent.json

declarativeAgent.json は宣言型エージェントの機能を指定する JSON ファイルです。アクションとして apiPlugin.json を指定します。

{
  "$schema": "https://developer.microsoft.com/json-schemas/copilot/declarative-agent/v1.0/schema.json",
  "version": "v1.0",
  "name": "社内施設予約システム",
  "description": "社内の会議室やブースの施設を予約できます。",
  "instructions": "あなたは Microsoft 365 Copilot の宣言型エージェントです。あなたはユーザーからの指示にしたがって社内施設の予約を行います。予約できる施設は社内の会議室やブースです。予約は日単位で行うことができます。過去の日付は予約できません。",
  "conversation_starters": [
    {
      "text": "明日101会議室を予約してください。",
      "title": "社内施設を予約する"
    }
  ],
  "actions": [
    {
      "id": "5829823a-d960-453e-b7b5-71741fc412a1",
      "file": "apiPlugin.json"
    }
  ]
}

apiPlugin.json

apiPlugin.json は API プラグインの機能を指定する JSON ファイルです。OpenAPI 仕様として openApi.json を指定します。

{
  "$schema": "https://developer.microsoft.com/json-schemas/copilot/plugin/v2.1/schema.json",
  "schema_version": "v2.1",
  "name_for_human": "社内施設予約システム",
  "description_for_human": "社内の会議室やブースの施設を予約できます。",
  "namespace": "reservation",
  "functions": [
    {
      "name": "postReserve",
      "description": "ログインしているユーザーの代わりに社内施設を予約します。",
      "capabilities": {
        "response_semantics": {
          "data_path": "$",
          "properties": {
            "title": "$.location",
            "subtitle": "$.date"
          }
        }
      }
    }
  ],
  "runtimes": [
    {
      "type": "OpenApi",
      "auth": {
        "type": "None"
      },
      "spec": {
        "url": "openApi.json"
      },
      "run_for_functions": [
        "postReserve"
      ]
    }
  ]
}

openApi.json

openApi.json は API の仕様を指定する JSON ファイルです。ここで重要なのは operationId で、POST 操作をするときには operationIdpost を含めたほうがよいようです。post を含めないと GET 操作になってしまいます。

{
  "openapi": "3.0.1",
  "info": {
    "title": "施設予約システム",
    "description": "施設予約システムの API です。",
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "https://{{servername}}/api"
    }
  ],
  "paths": {
    "/Reserve": {
      "post": {
        "summary": "社内施設を予約します。",
        "description": "社内施設を予約します。",
        "operationId": "postReserve",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/reservation"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Payload of Reservation",
            "content": {
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/reservation"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "reservation": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "location": {
            "type": "string"
          },
          "date": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      }
    }
  }
}

実行結果

実際に呼び出してみます。いきなり実行されるわけではなくデータを渡してよいかどうかの確認をされます。

実際に呼び出して登録されることがわかります。

開発者モードでも API が呼び出されたことを確認できます。

おわりに

GET か POST を operationId から判断しているのは意外でした。もしうまくいかない場合は、開発者モードを有効にして、API がどのように呼び出されているかを確認してみてください。

https://zenn.dev/karamem0/articles/2024_11_12_090000

Discussion