はじめに
Copilot Studio の自律型エージェントには、「ファイルが作成されたとき (プロパティのみ)」というトリガーが用意されています。このトリガーを使えば、SharePoint にファイルがアップロードされたタイミングで自律型エージェントを起動させることができます。
今回は、このトリガーを使って「見積書ファイルがアップロードされたら、エージェントが自動で内容を抽出して構造化データとして出力する」という処理を実現できるか検証してみました。
結論から申し上げると、現時点(2026/03)ではこのトリガーからファイルのコンテンツ自体をエージェントに渡すことはまだ確立されていないという認識です。本記事では、検証の過程と判明した課題、そして代替案について共有します。
今回やりたかったこと
今回作ろうとした自律型エージェントの処理フローは以下の通りです。
- SharePoint のフォルダーに見積書(PDF)がアップロードされる
- エージェントがファイルの内容を読み取り、OCR でテキスト抽出する
- 見積書番号、日付、顧客名、明細、金額等の情報を JSON 形式で構造化する
- 金融機関コード・支店コードをナレッジ検索で照合し、金融機関名・支店名を補完する
- 最終的な JSON を Teams チャットで通知する
エージェントの指示文には、上記の処理ステップやエラーハンドリング、出力形式等を詳細に記載しました。
# 目的
このエージェントは、トリガーで渡された見積書ファイル(画像・PDF等)から必要情報を抽出し、JSON形式で構造化します。
さらに、抽出した金融機関コードおよび支店コードを基にナレッジ検索を実行し、対応する金融機関名・支店名を取得してJSONに追加します。
最終結果はチャット返信せず、指定されたツール(例:チャット投稿ツール)を使用して通知します。
# 一般ガイドライン
- 推測は行わず、ファイルに記載されている内容のみを抽出します。
- 情報が存在しない場合は null を設定します。
- 金融機関名・支店名はナレッジ検索結果に基づいて追加します。
- 数値は数値型で出力し、通貨記号やカンマは除去します。
- 最終的な出力はメッセージとして返さず、必ずツールを使用します。
- エージェントの通常応答としてJSONを直接表示しません。
# スキル
- OCRによる画像・PDFからのテキスト抽出
- 構造化データ生成(JSON整形)
- ナレッジ検索の実行
- コードをキーにしたデータ照合
- ツール呼び出しによる通知
# ステップバイステップ手順
1. ファイル解析
- トリガーで渡された見積書ファイルを読み取ります。
- OCRまたはテキスト解析を実行します。
2. 情報抽出
以下の項目を抽出します:
- 見積書番号
- 日付
- 顧客名
- 明細(品目コード、品目名、数量、単価、金額)
- 小計
- 消費税
- 合計
- 金融機関コード
- 支店コード
3. JSON構造化
以下の形式でJSONオブジェクトを生成します:
{
"quotation_number": "",
"date": "",
"customer_name": "",
"items": [
{
"item_code": "",
"item_name": "",
"quantity": 0,
"unit_price": 0,
"amount": 0
}
],
"subtotal": 0,
"tax": 0,
"total": 0,
"bank_info": {
"bank_code": "",
"bank_name": "",
"branch_code": "",
"branch_name": ""
}
}
4. ナレッジ検索
- 抽出した金融機関コードおよび支店コードを使用してナレッジ検索を実行します。
- 一致する金融機関名・支店名を取得します。
5. 情報補完
- 取得した金融機関名・支店名をJSON内の bank_info に追加します。
- ナレッジに存在しない場合は null を設定します。
6. ツール通知(必須)
- 完成したJSONを文字列化します。
- 指定されたツール( チャットまたはチャネルでメッセージを投稿する )を呼び出します。
- 投稿内容は生成したJSONのみとします。
- 通常のチャット応答は行いません。
# エラーハンドリングと制約
- OCRで読み取れない項目は null を設定します。
- ナレッジ検索で一致しない場合は bank_name / branch_name を null にします。
- JSON生成に失敗した場合はエラー内容をツールで通知します。
- 明細が複数ある場合は配列にすべて格納します。
# ツール利用ルール
- 最終結果は必ずツールで通知すること。
- ツール呼び出しを省略しないこと。
エージェントの構成
指示文とツールの設定
まず Copilot Studio 側でエージェントの指示文を上記の通り編集し、必要なナレッジ、ツール(Teams チャット投稿等)を追加します。そして最後に「ファイルが作成されたとき (プロパティのみ)」トリガーを追加します。
Power Automate 側の編集が必要
ただし、このトリガーを追加しただけではエージェントは動きません。エージェント側に渡す情報について、既定では、「Use content from 本文」となっており、このままでは正しく動作しないためです。 こちらは、今回のトリガーでも同様で、基本的に、一旦トリガーを追加した後、Power Automate 側で編集作業が必要になります。
つまり、自律型エージェントを使う際は、Power Automate の知識が必要になります。
※それ以外にも、コネクタ、エージェントフローを使う際にも Power Automate の知識が必要になると思います
トリガーを追加すると、Power Automate 側に以下のようなフローが自動生成されます。
- 「ファイルが作成されたとき (プロパティのみ)」トリガー
- 「Sends a prompt to the specified copilot for processing」アクション
この「Sends a prompt to the specified copilot for processing」アクションの詳細パラメーターを開くと、以下のような項目があります。
- テキスト フィールドのコンテンツを表す BCP-47 ロケール名
- 添付ファイルのリスト
- 会話 ID
- 環境 ID
- Body/message
検証①:Body/message にファイルコンテンツを渡す
仮説
今回の目的はアップロードされたファイル自体をエージェントに渡すことです。そのため、まず以下の仮説を立てました。
「ファイル コンテンツの取得」アクションを間に追加し、その結果を Body/message に渡せば、エージェントがファイルの中身を解読してくれるのではないか。
フローの構成
フローを以下のように構成しました。
- ファイルが作成されたとき (プロパティのみ)
- ファイル コンテンツの取得(追加)
- Sends a prompt to the specified copilot for processing
Body/message にはプロンプトテキスト + ファイルコンテンツの取得の結果を入れて渡しました。
※なお、[ファイルコンテンツの取得] アクションを追加すると、[For each] アクションが追加されました。そのため、「Sends a prompt to the specified copilot for processing」も [For each] の中にいれました
結果
フロー自体は正常に実行されました。
しかし、Copilot Studio 側の活動ログを確認すると、トリガーの入力にPDFのバイナリデータがそのままテキストとして流れ込んでいることがわかりました。
この場合、エージェントはこれを読み取ることができず、以下のような応答が返ってきました。
「申し訳ございません、お問い合わせ内容を理解できません。別の言い方をお試しください。」
結果として出力された JSON は全項目が null となってしまいました。
つまり、ファイルコンテンツの取得で得られるバイナリデータをそのまま Body/message に渡しても、エージェントは PDF の中身を解読してくれないようです
検証②:添付ファイルのリストを使う
添付ファイルパラメーターの存在
詳細パラメーターにある「添付ファイルのリスト」を使ってみます。
こちらは、Bot Framework の Activity.Attachments の仕様に基づいた項目で、以下のフィールドが用意されているようです。
- ContentType:MIME タイプ
- ContentUrl:ファイルの取得 URL
- Content:インラインコンテンツ
- Name:ファイル名
- ThumbnailUrl:サムネイル URL
項目としてはファイルを渡せそうな構造になっています。
試行 1:Content フィールドに直接ファイルコンテンツを入れる
まず ContentType に application/pdf を設定し、Content フィールドにファイル コンテンツの取得の結果を直接入れてみました。
しかし、フローを保存しようとするとエラーが発生しました。
エラーメッセージの内容としては、「body/attachments/0/content に String/binary 型の値を入れているが、Object 型に変換できない」というものです。Content フィールドは単純なバイナリ文字列ではなく、オブジェクト構造を期待しているようです。
試行 2:JSON 形式で構造化して渡す
そこで、添付ファイルのリスト全体を JSON 形式で記述してみました。
[
{
"contentType": "application/pdf",
"name": "@{triggerOutputs()?['body/{FilenameWithExtension}']}",
"content": {
"$content-type": "application/pdf",
"$content": "@{body('ファイル_コンテンツの取得')}"
}
}
]
この方法ではフローの保存自体は成功し、実行も正常に完了しました。
しかし、Copilot Studio 側でエージェントのトリガーのテストを実行しても、エージェントが何の反応も示さなくなりました。 エラーも出ず、ただ沈黙するという状態です。
個人的には、attachments の形式がエージェント側の想定と合わない場合にサイレントに失敗するのではないかと考えています。
Apply to each/For each が自動で追加される件について
一つ補足があります。Power Automate を普段から触っている方にとっては疑問に感じるかもしれない点があります。
通常、「ファイルが作成されたとき (プロパティのみ)」トリガーの後に「ファイル コンテンツの取得」を行っても、配列形式ではないため Apply to each/For each(繰り返し処理)は自動で追加されないはずです。Power Automate 単体でフローを作る場合はそのような挙動になります。
しかし、自律型エージェントのトリガーとして使う場合は、Apply to each/For each が自動的に付与されます。
これは Copilot Studio 側のエージェントが添付ファイルを扱う際のデータ型が attachments(配列構造) になっているためです。トリガーでアップロードされたファイルが 1 つであっても、配列として扱われるため Apply to each/For each が自動で追加されます。
つまり、Power Automate で扱うファイルトリガーのデータ型と、Copilot Studio のエージェント側の添付ファイルを扱うデータ型が異なるということです。Power Automate 単体で作ったときとは異なる動作となるため、この点はやや戸惑う方もいるのではないかと思います。
現時点での結論と代替案
結論
現時点(2026/03)では、自律型エージェントのファイルアップロードトリガーからファイルのコンテンツ自体をエージェントに渡して処理させることは、まだ確立されていないという認識です。
具体的には以下の課題があります。
- Body/message にファイルコンテンツを渡しても、PDF のバイナリデータがそのまま文字列として渡されるだけで、エージェントは解読できない
- 添付ファイルのリストのパラメーターは存在するが、Bot Framework の Activity.Attachments の仕様に合わせた JSON 構造で記述する必要があり、市民開発者にとっては難易度が高い
- 仮に正しい形式で渡せたとしても、エージェント側がサイレントに失敗する不安定さがある
代替案:AI Builder で事前にテキスト抽出する
現時点での代替案としては、Power Automate のフロー内で AI Builder の AI プロンプトを使い、ファイルからテキスト情報を事前に抽出する方法が考えられます。
- ファイルが作成されたとき (プロパティのみ)
- ファイル コンテンツの取得
- AI Builder の AI プロンプトでファイルからテキスト抽出 → JSON 形式で出力
- Sends a prompt to the specified copilot for processing → Body/message に 抽出済み JSON テキストを渡す
この方法であれば、エージェントにはテキストとして JSON が渡されるため、エージェント側で受け取った JSON を解読して後続の処理(ナレッジ検索による情報補完、Teams 通知等)を実行できます。
以下は修正したプロンプトです。
# 目的
このエージェントは、トリガーで渡された見積書のJSON形式テキストを受け取り、金融機関コードおよび支店コードを基にナレッジ検索を実行し、対応する金融機関名・支店名を取得してJSONに追加します。
最終結果はチャット返信せず、指定されたツール(チャット投稿ツール)を使用して人間が読みやすい形式で通知します。
# 一般ガイドライン
- 受け取ったJSONの内容を改変・推測しないこと。
- 金融機関名・支店名はナレッジ検索結果に基づいて追加します。
- 最終的な出力はメッセージとして返さず、必ずツールを使用します。
- エージェントの通常応答としてJSONを直接表示しません。
# スキル
- JSON解析
- ナレッジ検索の実行
- コードをキーにしたデータ照合
- ツール呼び出しによる通知
# ステップバイステップ手順
1. JSON受け取り
- トリガーから渡されたメッセージをJSON形式として解析します。
- JSONの解析に失敗した場合はエラーとして処理します。
2. ナレッジ検索
- JSON内の bank_info.bank_code を使用してナレッジ検索を実行し、金融機関名を取得します。
- JSON内の bank_info.branch_code を使用してナレッジ検索を実行し、支店名を取得します。
3. 情報補完
- 取得した金融機関名を bank_info.bank_name に設定します。
- 取得した支店名を bank_info.branch_name に設定します。
- ナレッジに存在しない場合は null を設定します。
4. ツール通知(必須)
- 補完済みの情報を以下のフォーマットで整形します。
- 指定されたツール( チャットまたはチャネルでメッセージを投稿する )を呼び出します。
- 通常のチャット応答は行いません。
# 通知メッセージフォーマット
以下の形式で出力すること。値がnullの場合は「―」と表示すること。
📄 見積書情報
- 見積書番号:{quotation_number}
- 日付:{date}
- 顧客名:{customer_name}
📦 明細
(items配列を以下の形式で1件ずつ出力)
【{No.}】{item_name}({item_code})
- 数量:{quantity}
- 単価:{unit_price}円
- 金額:{amount}円
💰 金額
- 小計:{subtotal}円
- 消費税:{tax}円
- 合計:{total}円
🏦 振込先
- 金融機関:{bank_name}(コード:{bank_code})
- 支店:{branch_name}(コード:{branch_code})
# エラーハンドリングと制約
- 受け取ったメッセージがJSON形式でない場合はエラー内容をツールで通知します。
- ナレッジ検索で一致しない場合は bank_name / branch_name を null にします。
- 受け取ったJSONの bank_info 以外の値は変更しません。
# ツール利用ルール
- 最終結果は必ずツールで通知すること。
- ツール呼び出しを省略しないこと。
いい感じに動いてくれました。
まとめ
今回は、Copilot Studio の自律型エージェントで「ファイルが作成されたとき (プロパティのみ)」トリガーを使い、アップロードされたファイルのコンテンツをエージェントに渡せるか検証しました。
現時点では、ファイルのバイナリコンテンツをそのままエージェントに渡して処理させることは難しく、添付ファイルのパラメーターを使った方法も不安定という結果でした。代替案として AI Builder で事前にテキスト抽出を行い、テキストベースでエージェントに渡す方法が現実的かと思います。
個人的には、このトリガーは将来的にマルチモーダル対応でファイルを直接渡せるようになることを期待していますが、現状は「ファイルがアップロードされたというイベント通知を受け取れるだけ」という位置づけかなと感じています。
また、Power Automate 単体で作る場合と自律型エージェントのトリガーとして使う場合で Apply to each/For each の挙動が異なる点も、知っておくと混乱を防げるかと思います。
本記事が自律型エージェントのファイルトリガーを試そうとしている方のお役に立てば幸いです。私の検証の仕方が悪いだけかもなので、「こうしたらうまくいった」という情報があれば、ぜひ共有いただけると嬉しいです。



























