ラボ E4 - API とプラグインの強化
このラボでは、API に追加の REST 呼び出しを実装し、それらを API プラグイン パッケージに追加して Copilot から呼び出せるようにします。この過程で、API を Copilot で使用するために定義すべき箇所を学習します。
Microsoft 365 が AI モデルとオーケストレーションを提供する宣言型エージェントを構築したい場合は、これらのラボを実施してください。
- 🏁 はじめに
- 🔧 セットアップ
- 🧰 宣言型エージェントの基礎
- 🛠️ API をゼロから構築して統合する
- 🔐 認証
- 🔌 統合
Exercise 1: /projects リソースの追加
この演習では Trey Research API に /projects リソースを追加します。これにより、GET 要求でプロジェクト情報を取得し、POST 要求でコンサルタントをプロジェクトに割り当てることができます。その過程で、appPackage/trey-plugin.json と trey-definition.json を修正して新しい projects API 呼び出しを追加する方法を学びます。
手順 1: Azure Function のコードを追加
まず、ソリューションの /src/functions フォルダーに projects.ts という新しいファイルを作成します。次に こちらのコードをコピー してください。
これにより Trey Research のプロジェクトへアクセスする新しい Azure Function が実装されます。
手順 2: Azure Function のコードを確認 (任意)
コードを簡単に確認してみましょう。
これはバージョン 4 の Azure Function で、NodeJS の従来の Express コードに近い構造です。projects クラスは HTTP トリガーを実装しており、「/projects」パスにアクセスされたときに呼び出されます。その後、メソッドとルートを定義するインライン コードが続きます。現状ではアクセスは匿名で、認証を追加する予定です。認証の方法については こちら をご覧ください。
export async function projects(
req: HttpRequest,
context: InvocationContext
): Promise<Response> {
// ...
}
app.http("projects", {
methods: ["GET", "POST"],
authLevel: "anonymous",
route: "projects/{*id}",
handler: projects,
});
クラスには GET と POST を処理する switch 文が含まれ、URL パス (プロジェクト ID)、クエリ文字列 (?projectName=foo などの GET)、およびリクエスト本文 (POST の場合) からパラメーターを取得します。その後、開始済みソリューションに含まれている ProjectApiService を使用してプロジェクト データへアクセスします。また、各リクエストのレスポンスを送信し、デバッグ コンソールへログを出力します。
手順 3: HTTP テスト リクエストを追加
次に、新しいリクエストを http/treyResearchAPI.http ファイルへ追加し、動作を試します。ファイルを開き、末尾に以下のテキストを追加して保存してください。または 更新済みファイルをコピー しても構いません。
########## /api/projects - working with projects ##########
### Get all projects
{{base_url}}/projects
### Get project by id
{{base_url}}/projects/1
### Get project by project or client name
{{base_url}}/projects/?projectName=supply
### Get project by consultant name
{{base_url}}/projects/?consultantName=dominique
### Add consultant to project
POST {{base_url}}/projects/assignConsultant
Content-Type: application/json
{
"projectName": "contoso",
"consultantName": "sanjay",
"role": "architect",
"forecast": 30
}
手順 4: 新しいリソースのテスト
アプリが前のラボから実行中の場合はデバッガーを停止して再起動してください。あるいは通常どおりデバッガーを開始し、アプリの起動を待ちます。準備が整うと、Agents Toolkit が Microsoft 365 へのログインを求めるブラウザーを表示します。最小化して構いませんが、閉じるとデバッガーが停止するので注意してください。
新しいリクエストを送信すると、Trey Research のプロジェクト詳細を確認したり、POST リクエストで新しいコンサルタントをプロジェクトに割り当てたりできます。

Exercise 2: アプリケーション パッケージへ projects を追加
API プラグインのアプリケーション パッケージは zip ファイルで、Copilot が API を使用するために必要なすべての情報を含みます。
この演習では、新しい /projects リソースの情報をアプリ パッケージへ追加します。
手順 1: Open API Specification ファイルの更新
アプリ パッケージの重要な要素として Open API Specification (OAS) 定義ファイルがあります。OAS は REST API を記述する標準フォーマットを定義しており、人気のある “Swagger” 定義を基にしています。
まず /appPackage/apiSpecificationFile フォルダーの trey-definition.json を開きます。
大きな JSON を編集するのは大変なので、更新済みファイルをコピー して保存してください。以降の手順で変更内容を確認します。
手順 2: 変更内容を確認 (任意)
最初の変更点は paths コレクションへ /projects/ パスを追加したことです。
ここには /projects/ リソース取得時に利用できるクエリ文字列がデータ型と必須フィールドとともに記載されています。また、ステータス 200 (成功) と 400 (失敗) で返されるペイロードも定義されています。
"/projects/": {
"get": {
"operationId": "getProjects",
"summary": "Get projects matching a specified project name and/or consultant name",
"description": "Returns detailed information about projects matching the specified project name and/or consultant name",
"parameters": [
{
"name": "consultantName",
"in": "query",
"description": "The name of the consultant assigned to the project",
"required": false,
"schema": {
"type": "string"
}
},
{
"name": "projectName",
"in": "query",
"description": "The name of the project or name of the client",
"required": false,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Successful response",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"results": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"location": {
"type": "object",
"properties": {
"street": {
"type": "string"
},
"city": {
"type": "string"
},
"state": {
"type": "string"
},
"country": {
"type": "string"
},
"postalCode": {
"type": "string"
},
"latitude": {
"type": "number"
},
"longitude": {
"type": "number"
},
"mapUrl": {
"type": "string",
"format": "uri"
}
}
},
"role": {
"type": "string"
},
"forecastThisMonth": {
"type": "integer"
},
"forecastNextMonth": {
"type": "integer"
},
"deliveredLastMonth": {
"type": "integer"
},
"deliveredThisMonth": {
"type": "integer"
}
}
}
},
"status": {
"type": "integer"
}
}
}
}
}
},
"404": {
"description": "Project not found"
}
}
}
},
さらに、POST 要求を処理するため /projects/assignConsultant パスも追加されています。
説明は重要です!
このファイルを含むアプリ パッケージ内のすべてのファイルはインテリジェンスによって読み取られます。人工的とはいえインテリジェントなので説明を理解します!
Copilot が API を適切に利用できるよう、ここを含めすべてのアプリ パッケージ ファイルで分かりやすい名前と説明を使用してください。
手順 3: プラグイン定義ファイルへ projects を追加
/appPackage フォルダー内の trey-plugin.json を開きます。このファイルは OAS には含まれない追加情報を保持します。trey-plugin.json の内容を 更新済み JSON に置き換えてください。
手順 4: プラグイン定義ファイルの変更を確認 (任意)
プラグイン JSON ファイルには functions のコレクションがあり、それぞれが API 呼び出しの種類に対応します。Copilot は実行時にこれらの関数を選択します。
新しい trey-plugin.json には getProjects と postAssignConsultant の新規関数が含まれています。例として getProjects を見てみましょう。
{
"name": "getProjects",
"description": "Returns detailed information about projects matching the specified project name and/or consultant name",
"capabilities": {
"response_semantics": {
"data_path": "$.results",
"properties": {
"title": "$.name",
"subtitle": "$.description"
}
}
}
},
ここでは response_semantics が含まれており、Copilot のオーケストレーターにレスポンス ペイロードの解釈方法を指示します。
レスポンスの構造化データを特定のプロパティへマッピングし、レンダリングや後続処理で利用できるようにします。例えば次のようになります。
"functions": [
{
"name": "getConsultants",
"description": "Returns detailed information about consultants identified from filters like name of the consultant, name of project, certifications, skills, roles and hours available. Multiple filters can be used in combination to refine the list of consultants returned",
"capabilities": {
"response_semantics": {
"data_path": "$.results",
"properties": {
"title": "$.name",
"subtitle": "$.id",
"url": "$.consultantPhotoUrl"
}
}
}
},..]
ここで data_path は $.results で、JSON 内の主要データが results キー配下にあることを示します。また、title、subtitle、url の各プロパティへフィールドをマッピングしています。
POST 要求にも同様の関数があります。
{
"name": "postAssignConsultant",
"description": "Assign (add) consultant to a project when name, role and project name is specified.",
"capabilities": {
"response_semantics": {
"data_path": "$",
"properties": {
"title": "$.results.clientName",
"subtitle": "$.results.status"
}
},
"confirmation": {
"type": "AdaptiveCard",
"title": "Assign consultant to a project when name, role and project name is specified.",
"body": "**ProjectName**: {{function.parameters.projectName}}\n* **ConsultantName**: {{function.parameters.consultantName}}\n* **Role**: {{function.parameters.role}}\n* **Forecast**: {{function.parameters.forecast}}"
}
}
}
ここでは Adaptive Card を使用して確認カードを定義し、POST 実行前にユーザーへ確認を求めます。
さらに下へスクロールすると、runtimes オブジェクトがあります。プラグインの種類、OAS 定義ファイルの場所、関数の一覧が定義されており、新しい関数が追加されています。
"runtimes": [
{
"type": "OpenApi",
"auth": {
"type": "None"
},
"spec": {
"url": "trey-definition.json"
},
"run_for_functions": [
"getConsultants",
"getUserInformation",
"getProjects",
"postBillhours",
"postAssignConsultant"
]
}
],
最後に、プロンプト候補として表示される conversation_starters が含まれ、新しいファイルには projects に関するスターターが追加されています。
"capabilities": {
"localization": {},
"conversation_starters": [
{
"text": "What Trey projects am i assigned to?"
},
{
"text": "Charge 5 hours to the Contoso project for Trey Research"
},
{
"text": "Which Trey consultants are Azure certified?"
},
{
"text": "Find a Trey consultant who is available now and has Python skills"
},
{
"text": "Add Avery as a developer on the Contoso project for Trey"
}
]
}
Exercise 3: Copilot でプラグインをテスト
アプリケーションをテストする前に、appPackage\manifest.json ファイル内のマニフェスト バージョンを更新します。以下の手順に従ってください。
-
プロジェクトの
appPackageフォルダーにあるmanifest.jsonを開きます。 -
JSON 内の
versionフィールドを探します。例えば次のようになっています。
json "version": "1.0.0" -
バージョン番号をわずかに増やします。例:
json "version": "1.0.1" -
ファイルを保存します。
手順 1: アプリケーションを再起動
プロジェクトを停止して再起動し、アプリ パッケージを再デプロイさせます。
Copilot でエージェントとの直接チャット ウィンドウが開いている状態になります。
手順 2: Trey Genie へプロンプトを送信
「what projects are we doing for adatum?」などのプロンプトを試してください。

GET 要求でもエージェントが実行許可を求めます。「Always allow」を選択してプロジェクト詳細を表示します。

おめでとうございます!
これで API プラグインの強化が完了しました。しかしご覧のとおり、引用カードはまだ基本的なものです。次のラボでは、Adaptive Card を使用してリッチなカードの引用と応答を追加しましょう。