Microsoft 365 Copilotのカスタムエンジンエージェントで、ステータスや承認結果などを表示するAdaptive Cardが古いまま残り、利用者にエージェント全体の再読み込みを求めていたケースは少なくありません。
2026年7月29日付のMicrosoft 365 Copilotリリースノートで、Web版のカスタムエンジンエージェントがAdaptive Card refreshに対応しました。カードにrefreshとAction.Executeを実装し、エージェント側で更新要求を処理すれば、エージェント全体を再読み込みせずに表示中のカードを新しい内容へ差し替えられます。(Microsoft Learn)
ただし、既存のAdaptive Cardが自動的に更新対応へ切り替わるわけではありません。カード側の更新アクションと、エージェント側の処理の両方が必要です。また、チャットを開き直したときに更新後の状態が保持されない既知の制限もあるため、業務データの保存方法まで含めて設計する必要があります。
カスタムエンジンエージェントのAdaptive Card更新で何が変わったのか
今回の更新で変わったのは、Microsoft 365 CopilotのWeb画面に表示されたAdaptive Cardが、更新アクションを通じて最新データを再取得し、表示内容を差し替えられるようになった点です。
従来と更新後の違いを整理すると、次のようになります。
| 項目 | 従来 | 2026年7月29日以降 |
|---|---|---|
| 表示中カードの更新 | カスタムエンジンエージェントでは未対応 | WebでAdaptive Card refreshに対応 |
| 最新データの反映 | 新しいメッセージを送る、またはエージェントを再読み込み | 更新アクションからカードを差し替え可能 |
| カード側の実装 | 通常のAdaptive Cardだけでも表示可能 | refreshとAction.Executeが必要 |
| エージェント側の実装 | 通常のメッセージ処理 | 更新要求を受け取り、新しいカードを返す処理が必要 |
| チャット再表示後の状態 | 元のメッセージを表示 | 更新後の内容が保持されず、元のカードに戻る場合がある |
Microsoftのリリースノートでは、更新アクションをサポートするAdaptive Cardを追加し、カード更新を実行する手順が示されています。一方、更新アクションを持たない既存カードを、設定変更だけで自動更新対応にする方法は案内されていません。(Microsoft Learn)
Adaptive Card refreshの仕組み
Adaptive Card refreshは、単に画面上の文字を書き換える機能ではありません。カードからエージェントへ更新要求を送り、エージェントが最新データを取得して、新しいAdaptive Cardを返す仕組みです。
基本的な処理の流れは次のとおりです。
- エージェントがAdaptive Cardを表示する
- Microsoft 365 Copilotのホストがカードの更新アクションを実行する
- エージェントが
Action.Executeの要求を受け取る - エージェントが業務システムやデータベースから最新情報を取得する
- 最新情報を含む新しいAdaptive Cardを返す
- 表示中のカードが新しいカードへ差し替わる
Adaptive Cardsの仕様では、refreshはスキーマバージョン1.4で導入されました。refresh.actionにはAction.Executeを指定します。クライアントは更新アクションを自動実行する場合もあれば、利用者が押せる更新操作を表示する場合もあります。(Microsoft Learn)
重要なのは、Adaptive Card refreshが常時プッシュ通知や一定間隔の自動ポーリングと同じではないことです。ホストが更新アクションを実行したタイミングで、エージェントへ最新カードを要求する仕組みとして考える必要があります。
CopilotカスタムエンジンエージェントでAdaptive Cardを自動更新する方法
Adaptive Cardのスキーマを1.4以上にする
refreshとAction.Executeを使用するには、Adaptive Cardのversionを原則として1.4以上にします。
{
"$schema": "https://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.4"
}
古いスキーマバージョンを指定したままrefreshやAction.Executeを追加すると、ホストによっては更新機能が無視されたり、アクション自体が表示されなかったりする可能性があります。(Microsoft Learn)
カードにrefresh.actionを追加する
次に、カードのルートにrefreshを追加します。
以下は、申請番号REQ-2026-0042の承認状況を更新する例です。
{
"$schema": "https://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.4",
"refresh": {
"action": {
"type": "Action.Execute",
"verb": "refreshApprovalStatus",
"data": {
"requestId": "REQ-2026-0042"
}
},
"userIds": [
"<対象ユーザーID>"
]
},
"body": [
{
"type": "TextBlock",
"text": "申請状況",
"weight": "Bolder",
"size": "Medium"
},
{
"type": "FactSet",
"facts": [
{
"title": "申請番号",
"value": "REQ-2026-0042"
},
{
"title": "現在の状態",
"value": "承認待ち"
},
{
"title": "最終確認",
"value": "2026年8月4日 13:00"
}
]
}
]
}
各プロパティの役割は次のとおりです。
| プロパティ | 役割 |
|---|---|
refresh | カードの更新方法を定義する |
refresh.action | 更新時に実行するアクション |
type | Action.Executeを指定する |
verb | エージェント側で処理を識別する名前 |
data | 申請番号やチケット番号など、更新対象の識別情報 |
userIds | 自動更新の対象となるユーザーをホストへ伝える |
userIdsはAdaptive Cardsのスキーマ上では省略可能ですが、一部のクライアントでは、指定されていないと自動実行せず、手動更新の操作だけを表示することがあります。実際に指定するIDの形式は、利用しているSDKや受信アクティビティから取得できるユーザー情報に合わせてください。(Microsoft Learn)
必要に応じて手動更新ボタンも用意する
自動更新だけに依存せず、利用者が任意のタイミングで最新状態を確認できるボタンを追加する設計も有効です。
{
"type": "ActionSet",
"actions": [
{
"type": "Action.Execute",
"title": "最新状態を確認",
"verb": "refreshApprovalStatus",
"data": {
"requestId": "REQ-2026-0042"
},
"fallback": {
"type": "Action.Submit",
"title": "最新状態を確認",
"data": {
"action": "refreshApprovalStatus",
"requestId": "REQ-2026-0042"
}
}
}
]
}
fallbackを設定しておくと、Action.Executeを処理できないクライアントでAction.Submitへ切り替えられる場合があります。ただし、Action.Submitから現在のカードを直接差し替えられるとは限りません。フォールバック時は新しいメッセージで結果を返すなど、機能を限定した動作を用意するのが安全です。
エージェント側でAction.Executeを処理する
カードへrefreshを追加するだけでは更新されません。エージェント側でAction.ExecuteのInvoke要求を受け取り、最新のAdaptive Cardを返す必要があります。
更新要求では、概念的に次の情報を確認します。
{
"name": "adaptiveCard/action",
"value": {
"action": {
"type": "Action.Execute",
"verb": "refreshApprovalStatus",
"data": {
"requestId": "REQ-2026-0042"
}
},
"trigger": "automatic"
}
}
value.triggerには、自動更新ならautomatic、利用者による操作ならmanualが設定されます。エージェントはvalue.action.verbを確認し、対応する更新処理を実行します。(Microsoft Learn)
フレームワークに依存しない疑似コードで表すと、次のようになります。
if activity.name == "adaptiveCard/action":
action = activity.value.action
if action.verb == "refreshApprovalStatus":
requestId = action.data.requestId
利用者がrequestIdを閲覧できるか確認する
最新の承認状況を業務システムから取得する
最新データを含むAdaptive Cardを生成する
Adaptive Card形式のInvokeレスポンスを返す
Microsoft 365 Agents SDKの.NET APIには、Adaptive CardのAction.Executeイベントを処理するためのハンドラーが用意されています。具体的な登録方法はSDKの言語やバージョンで異なるため、既存のメッセージ処理とは分けて実装すると管理しやすくなります。(Microsoft Learn)
更新後のAdaptive Cardをレスポンスで返す
更新処理が成功した場合は、新しいAdaptive CardをInvokeレスポンスとして返します。
{
"statusCode": 200,
"type": "application/vnd.microsoft.card.adaptive",
"value": {
"$schema": "https://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.4",
"refresh": {
"action": {
"type": "Action.Execute",
"verb": "refreshApprovalStatus",
"data": {
"requestId": "REQ-2026-0042"
}
},
"userIds": [
"<対象ユーザーID>"
]
},
"body": [
{
"type": "TextBlock",
"text": "申請状況",
"weight": "Bolder",
"size": "Medium"
},
{
"type": "FactSet",
"facts": [
{
"title": "申請番号",
"value": "REQ-2026-0042"
},
{
"title": "現在の状態",
"value": "承認済み"
},
{
"title": "承認者",
"value": "営業部 部長"
},
{
"title": "最終確認",
"value": "2026年8月4日 13:05"
}
]
}
]
}
}
ここで見落としやすいのが、更新後のカードにもrefreshを残すことです。
最初のカードにはrefreshがあっても、差し替え後のカードからrefreshが消えていると、次回以降の更新要求を実行できなくなります。更新前後で共通のカード生成関数を使い、常に更新定義を含める方法が確実です。
更新アクションを実装していない既存カードはどうなるのか
今回の変更は、Microsoft 365 Copilot側がAdaptive Card refreshを処理できるようになったものです。既存カードのJSONへ自動的に更新処理が追加されるわけではありません。
既存カードに次の要素がなければ、原則として改修が必要です。
version: "1.4"以上refresh.actionAction.Execute- 処理を識別する
verb - 更新対象を識別するデータ
- エージェント側のAction.Executeハンドラー
- 最新カードを返すレスポンス処理
Microsoftのリリースノートでは、更新アクションを実装していないカード向けの別の修正手順は公表されていません。そのため、対象カードを洗い出し、カード定義とエージェント処理を個別に改修する必要があります。(Microsoft Learn)
実装前に知っておきたい制限
チャットを開き直すと元のカードが表示される場合がある
Microsoftの既知の問題では、Action.Executeによって更新したAdaptive Cardの内容は、チャットを閉じて再度開いたときに保持されず、元のカードが表示されると説明されています。
また、Microsoft 365 Copilotのカスタムエンジンエージェントでは、メッセージが変更不可であり、updateActivity APIもサポートされていません。(Microsoft Learn)
この制限を踏まえ、カードの表示内容を業務上の確定記録として扱わないことが重要です。
承認結果や処理結果を確実に残す必要がある場合は、次の設計を組み合わせます。
- 承認状態はデータベースや業務システムに保存する
- 処理完了時に新しいフォローアップメッセージを送る
- カード内に「最終取得日時」を表示する
- 重要な結果は履歴画面や詳細画面でも確認できるようにする
- カード再表示時に最新状態を取得できる操作を用意する
「すべての動的カード機能が対応した」とは限らない
2026年7月29日付のリリースノートではAdaptive Card refreshへの対応が案内されていますが、同時期の既知の問題ページには、カスタムエンジンエージェントで「Dynamic Adaptive Card refresh」が未対応という記載も残っています。
そのため、今回の更新を「Adaptive Cardsの動的機能がすべて解禁された」と解釈するのは避けるべきです。現時点では、Web版でrefreshとAction.Executeを使用して表示中のカードを更新する機能として範囲を限定し、自社テナントで挙動を確認するのが安全です。(Microsoft Learn)
Web以外のクライアントは別に確認する
リリースノートの対象プラットフォームには[Web]と記載されています。Teamsやモバイルアプリなど、別のクライアントでも同じタイミング、同じ条件で動作するとは限りません。(Microsoft Learn)
複数クライアントでエージェントを提供している場合は、少なくとも次の組み合わせを分けてテストします。
| テスト対象 | 確認内容 |
|---|---|
| Microsoft 365 Copilot Web | 今回の更新対象として正常に差し替わるか |
| Teams | 自動更新、手動更新、フォールバックの違い |
| 複数ユーザー | ユーザーごとに適切な内容が表示されるか |
| チャット再表示 | 更新後の状態が保持されるか |
| 古いクライアント | Action.Executeが表示されるか |
| 権限の異なるユーザー | 他人の申請やチケットを取得できないか |
段階的なロールアウトを考慮する
Microsoft 365 Copilotの機能は、安全な展開モデルによってテナント内の一部ユーザーから段階的に提供されることがあります。そのため、リリースノート掲載直後にすべてのユーザーで同じ挙動になるとは限りません。(Microsoft Learn)
一部ユーザーだけ更新できない場合は、実装ミスと判断する前に、次の点を確認してください。
- 同じテナント内でユーザーごとの差があるか
- Microsoft 365 Copilot Webで試しているか
- ブラウザを再起動しても差が続くか
- 開発環境と本番環境で展開状況が異ならないか
- Microsoft 365管理センターのメッセージや既知の問題に追加情報がないか
Adaptive Card refreshが向いている活用例
承認状況の確認
稟議、購入申請、休暇申請などの状態を、同じカード上で「承認待ち」から「承認済み」へ更新できます。
ただし、正式な承認記録はカードではなく、承認システム側に保存します。
サポートチケットや障害対応の状況表示
チケット番号をカードのdataへ持たせ、担当者、優先度、対応状況、最終更新日時を再取得できます。
「調査中」「対応中」「解決済み」といった変化を確認する用途に適しています。
バッチ処理や生成処理の進捗確認
時間のかかる処理を開始したあと、カードから現在の進捗を取得できます。
ただし、Adaptive Card refreshだけで完了通知が自動配信されるとは限りません。完了を確実に知らせる必要がある場合は、別の通知経路やフォローアップメッセージも検討します。
在庫、空き枠、予約状況の確認
在庫数や予約可能枠など、短時間で変わる情報を再取得できます。
この用途では、カード内に最終取得日時を表示し、表示値がリアルタイム保証ではないことを分かるようにしておくと、利用者の誤解を防げます。
実装時に起きやすい問題と確認ポイント
| 症状 | 主な原因 | 確認する場所 |
|---|---|---|
| カードがまったく更新されない | refreshがない、スキーマが古い | カードJSON |
| 更新要求がエージェントへ届かない | Action.Executeが認識されていない | Invokeログ |
| 別の処理が実行される | verbの不一致 | カードとハンドラー |
| 更新時にエラーになる | レスポンス形式が不正 | statusCode、type、value |
| 一度しか更新できない | 更新後カードにrefreshがない | カード生成処理 |
| 手動更新しか表示されない | userIds未指定、ホスト側の挙動 | カード定義と対象クライアント |
| 他人の情報が表示される | requestIdだけを信用している | 認可処理 |
| チャットを開き直すと古い | 現時点の既知の制限 | 永続化設計 |
| Teamsでは動くがCopilotでは動かない | ホストごとの対応差、段階展開 | Web版での実機テスト |
特に危険なのは、カードから送られたrequestIdやチケット番号だけを信用してデータを返す実装です。利用者がカードのデータを変更して送信する可能性を考え、更新処理では必ず次の順序で確認します。
- 呼び出し元ユーザーを特定する
- 対象データへの閲覧権限を確認する
- 最新データをサーバー側で取得する
- 表示してよい項目だけでカードを生成する
- 更新日時をカードへ含める
本番展開前のチェックリスト
- Adaptive Cardのスキーマを1.4以上にした
- カードのルートに
refreshを追加した refresh.action.typeをAction.Executeにした- 用途ごとに重複しない
verbを設定した - 更新対象のIDを
dataに含めた - エージェント側で
adaptiveCard/actionを処理した - 呼び出しユーザーの認可を実装した
- 新しいAdaptive Cardを正しいレスポンス形式で返した
- 更新後のカードにも
refreshを残した - 自動更新と手動更新の両方を確認した
- Microsoft 365 Copilot Webでテストした
- 複数ユーザーで表示内容を確認した
- チャットを閉じて再表示するテストを行った
- 更新後の状態が消えても業務データが失われない設計にした
- 更新失敗時のメッセージや再試行方法を用意した
既存カードを棚卸しして段階的に更新する
今回のAdaptive Card refresh対応により、Microsoft 365 Copilotのカスタムエンジンエージェントでは、承認状況やチケット状態などを表示中のカードへ反映しやすくなりました。
一方で、既存カードが自動的に更新対応になるわけではありません。まず、動的な情報を表示しているAdaptive Cardを一覧化し、refresh、Action.Execute、更新ハンドラーの有無を確認してください。
改修後は、Microsoft 365 Copilot Webの少人数ユーザーで先行検証し、更新直後だけでなく、チャットの再表示、複数ユーザー、権限エラー、更新失敗まで確認します。重要な処理結果はカードだけに保持せず、業務システムへの保存やフォローアップメッセージを組み合わせることが、現時点で最も安全な実装方針です。

コメント