1. 主要ページへ移動
  2. メニューへ移動
  3. ページ下へ移動

QES ブログ

記事公開日

【Copilot Studio】応答をカスタマイズすると出典が消える?載せ直す方法を解説!

  • このエントリーをはてなブックマークに追加

この記事のポイント

Copilot Studioで応答をカスタマイズしたときに、引用をメッセージに載せる方法をまとめます。

  • 応答をカスタマイズすると、引用は自動で付かない:
    引用を自分で取り出して表示する必要があります。
  • 筆者が確認した取り方は2つ:
    生成応答ノードから取る Topic.Answer.Text.CitationSources と、エージェントの応答から取る System.Response.Citations です。
  • リンクには Url 列を使う:
    引用はテーブルで返るので、Url 列などからリンクを組み立てます。

こんにちは!DXソリューション営業本部の大和矢です。

Copilot Studioで社内文書を参照するエージェントを作ったとき、「回答に出典リンクを付けたい」と思ったことはありませんか?
社内の規程やマニュアルを根拠に回答するなら、「どの規程に書いてあるのか」を示せないと、利用者は回答の精度を信頼できません。
反対に、根拠をすぐに開けるエージェントなら、利用者も安心して回答を使えます。

標準のまま使えば、引用はエージェントが自動で表示してくれます。
一方で、応答をカスタマイズしたい場面もあります。
Microsoft Learn では、たとえば次のような例が紹介されています。

  • 回答を変数に保存して、アダプティブカードに載せる
  • 回答の書式を後処理で整える、生のURLを分かりやすいリンクに置き換える
  • AIが作成した回答を、独自のメッセージで上書きする
  • エージェントが作成した回答に承認のステップを挟み、マネージャーに確認してもらう

出典:Microsoft Learn「回答生成ノードを追加する」(1つ目)、「生成オーケストレーション機能を適用する」(2〜4つ目)

筆者が関わったエージェントでも、生成した回答をそのまま利用者に返さず、担当部署の確認・修正を経てから、上書きした回答を返す構成にしました。
上の3つ目と4つ目を組み合わせた使い方です。

ところが、応答をカスタマイズすると、引用は自動では付かなくなります(詳細は後半の「引用を扱うときの注意点」で紹介します)。
せっかくの出典が、利用者の目に届かなくなるわけです。
自分で引用を取り出そうにも、どこに何が入っているのかが分かりにくく、筆者もやや手こずりました。

本記事では、引用がどの変数に入っているのか、どう取り出して表示するのかを、公式の記載とPower Fxのサンプルつきで解説します。
読み終えるころには、カスタマイズした応答にも、迷わず出典リンクを付けられるはずです。
(仕様・挙動は2026年10月時点の確認です。テキストチャネルを対象とし、音声エージェントは扱いません)

引用はどの変数に入っているのか

筆者が確認した範囲では、引用の取り出し方は回答をどこで受け止めるかによって2通りあります。
ほかの取り方がある可能性もありますが、本記事ではこの2つを扱います。

取り方 参照する変数 メモ
① 生成応答ノードから取る Topic.Answer.Text.CitationSources Microsoft Learnに手順とYAMLのサンプルがある。ノードの詳細設定を1つ変えると使えるようになる
② エージェントの応答から取る System.Response.Citations MicrosoftのCopilot Studio CATチームのブログや、Microsoft公式のサンプルで使われている。筆者環境の式エディターでは IconUrl / Id / Name / Text / Url の5列を確認。応答を送信直前に受け止める構成で使う

どちらも引用はテーブル(行の集まり)で返ります。
次の章から順に見ていきます。

取り方①:生成応答ノードから取る

トピックの中で「生成応答を作成する」ノードを使って回答を作る場合は、こちらです。
公式が手順を示しているので、要件が許すならこの方法が素直です。

手順は2つだけです。

順 やること
1 生成応答ノードのプロパティ →「詳細」→ 「LLM の応答を保存」を「完了 (推奨)」に変える。これで引用のメタデータまで変数に入る
2 コードエディターで SendActivity ノードに citationEntities を追加し、引用テーブルを渡す
生成応答ノードの詳細設定で「LLM の応答を保存」が「完了 (推奨)」に設定されている画面

手順1:生成応答ノードの「詳細」で「LLM の応答を保存」を「完了 (推奨)」に変える

公式に載っているYAMLのサンプルがこちらです(Microsoft Learn)。

- kind: SearchAndSummarizeContent
  id: search-content
  latencyMessageSettings:
    allowLatencyMessage: false
  autoSend: false
  variable: Topic.Answer
  userInput: =System.Activity.Text
  responseCaptureType: FullResponse

- kind: SendActivity
  id: sendActivity_SnMFMq
  activity:
    text:
      - "{Topic.Answer.Text.Content}"
    citationEntities: =Topic.Answer.Text.CitationSources

ポイントは citationEntities です。
これは、メッセージに引用を添えるための設定項目です。
回答本文は text に、引用テーブルは citationEntities に指定します。
こうすると、本文と引用が1つのメッセージとして送られます。
引用リンクの文字列は、自分で組み立てなくて済みます。

なぜ設定変更が要るのか:
「LLM の応答を保存」が既定のままだと、変数には回答本文の文字列しか入りません。
「完了 (推奨)」に変えると変数がレコード型になり、.Text.Content(本文)と .Text.CitationSources(引用テーブル)に分かれます。
公式も、この設定が「引用のメタデータを含む完全な応答を取得する」ためのものだと説明しています。

変数選択パネルにTopic.Answer.Textがrecord型、その下のCitationSourcesがtable型、Contentがstring型として並んで表示されている画面

設定変更後は、本文(Content)と引用(CitationSources)が同じ変数の下に分かれて入る。
型も表示されるため、CitationSourcesがテーブルであることもここで分かる

取り方②:エージェントの応答から取る

もう1つは、エージェント本体が作った応答を、送信される直前に受け止める方法です。
トピックのトリガーに「AI の応答が生成されました」を選ぶと、このタイミングに処理を挟めます。
(公式ドキュメントでは「AI によって生成された応答が送信されようとしています」、YAMLでは OnGeneratedResponse と表記されています)

このトリガーのトピックでは、応答の本文と引用がシステム変数に入っています。

変数 中身
System.Response.FormattedText 整形済みの回答本文(文字列)
System.Response.Citations 引用のテーブル。IconUrl / Id / Name / Text / Url の5列

本文の変数 Response.FormattedText は、トリガーの解説ページに名前が出てきます(Microsoft Learn)。
引用の変数 System.Response.Citations は、MicrosoftのCopilot Studio CATチームのブログで紹介されています(Copilot Studio CAT Blog)。
Microsoft公式のサンプル集「Copilot Studio Samples」の「Citation Swap」でも、このトリガーと変数が使われています(Copilot Studio Samples)。

記載:
Response.FormattedText システム変数を使用して、生成された応答を確認します。(Microsoft Learn)
System.Response.Citations — a table of citations with Name, Url, and Text columns(Copilot Studio CAT Blog)
(System.Response.Citations — Name、Url、Text の列を持つ引用のテーブル)

公式ガイダンスにも、このトリガーで「回答やその引用をプログラム的に修正する機会が得られます」と書かれています(Microsoft Learn)。

変数そのものは、変数選択パネルの「システム」タブで見つかります。

変数選択パネルのシステムタブでCitationを検索し、Response.Citationsがtable型として1件だけ表示されている画面

変数自体はパネルで見つかる。
ただし表示されるのは変数までで、テーブルの中身は分からない

列名は式エディターで確認します。
筆者の環境では、System.Response.Citations. と直接打つとエラーになりました。
そこで、First() で1行(レコード)を取り出します。
First(System.Response.Citations). と打つと、入力候補に列名が並びます。

Power Fxの式エディターでFirst(System.Response.Citations)の後に列名(IconUrl、Id、Name、Text、Url)が入力候補として表示されている画面

First()で1行取り出すと、入力候補に5つの列名が並ぶ

この方法を選ぶ場面:
エージェント本体の回答を、送信する前に加工したり、別の処理に渡したりしたいときの方法です。
ただし公式は、このトリガーについて「このトリガーの多用は、メイン命令に含まれていた可能性のあるロジックを示している可能性があります。必要に応じて細かい制御に使ってください」と案内しています(Microsoft Learn)。
単に引用を表示したいだけなら、標準の表示や取り方①で足ります。

サンプル:Power Fxで引用リンクを組み立てる

ここからは、取り方②で受け取った引用テーブルを自分でリンク文字列に組み立てるサンプルです。
(取り方①で citationEntities に渡す場合は、この加工は不要です)

引用テーブルの列は、前章の入力候補で確認した IconUrl / Id / Name / Text / Url の5つです。
CATブログや公式サンプルのコードで使われているのは、このうち Name・Url・Text の3つです。
Text は、PDFのページ番号の目印(<page value=…>)を取り出すために使われています。
リンクを作るには、表示する名前とリンク先が要ります。
そこで、このサンプルでは Name と Url を使います。

今回は、Markdown形式とHTML形式の両方で出力できるようにしました。

// Markdown形式のリンク一覧にする
Concat(
  Distinct(System.Response.Citations, "[" & Name & "](" & Url & ")"),
  Value,
  Char(10)
)
// 得られる文字列の例(1件ごとに改行が入る)
// [01_就業規則抜粋.docx](文書のURL)
// [02_年次有給休暇規程.docx](文書のURL)

// HTML形式のリンク一覧にする
Concat(
  Distinct(System.Response.Citations, "<a href=""" & Url & """>" & Name & "</a>"),
  Value,
  "<br>"
)
// 得られる文字列の例
// <a href="文書のURL">01_就業規則抜粋.docx</a><br><a href="文書のURL">02_年次有給休暇規程.docx</a>

式のポイントは3つです。

  • Distinct:
    同じ文字列(同じ Name と Url)が複数回出てきたときに、重複を除きます。
  • Value:
    Distinctは結果を Value という単一列のテーブルで返すため、Concatの第2引数には Value を指定します。
  • ダブルクォート3つ:
    Power Fxでは文字列内の " を2つ重ねて書くため、HTML側は """ という見慣れない並びになります。

筆者の環境では、引用が1件も無い回答でも、式はエラーにならず、結果は空になりました。

サンプル:カードとTeamsメッセージに載せる

組み立てた文字列を、実際に表示するところまで通します。
ここでは一例として、トピックからPower Automateのフローを呼び、フローがカードとTeamsのメッセージを送る構成で説明します。

順 場所 やること
1 トピックの「変数の設定」ノード Markdown用とHTML用の変数を作り、前章の式を入れる
2 フローを呼び出すノード 2つの変数をフローの入力に渡す。入力は「任意」にする
3 カードのJSON Markdown版を TextBlock の text に入れる
4 Teamsへの投稿アクション HTML版をメッセージ本文に入れる

手順2で入力を「任意」にするのがコツです。
引用が付かない回答では変数が空になるため、トリガー入力を必須にしていると FlowActionBadRequest で失敗します。
しかも筆者の環境では、フロー自体が呼ばれず、実行履歴に何も残りませんでした。
「動かないのにログがない」という調べにくい形になるので、先に任意にしておくのがおすすめです。

任意入力にしたら、フロー側では ? を付けて参照します。
? を付けると、値が無い場合でも、エラーにならず null が返ります。
あわせて、empty() で空かどうかを確かめ、引用が無いときに見出しだけが残らないようにします。

// カードのTextBlock(引用が無いときは何も表示しない)
{
  "type": "TextBlock",
  "text": "@{if(empty(triggerBody()?['text_5']), '', concat('参照:', decodeUriComponent('%0A'), triggerBody()?['text_5']))}",
  "wrap": true
}

// Teamsのメッセージ本文(HTML版を使う)
@{if(empty(triggerBody()?['text_6']), '', concat('<br><br><strong>【参照資料】</strong><br>', triggerBody()?['text_6']))}

decodeUriComponent('%0A') は、改行文字を入れるための書き方です。
参照名が text_5 / text_6 なのは、このフローにはほかの入力もあり、内部名が順番に振られているためです(本記事では、ほかの入力は使っていません)。
式では、表示名ではなく、この内部名で参照します。

回答本文の下に参照元ファイル名のリンクが3件表示されているアダプティブカードの画面

組み立てた引用リンクをカードに表示した例(Copilot Studioのテストパネル。文書は動作確認用のサンプル規程)

引用を扱うときの注意点

最後に、公式ドキュメントに書かれている注意点を3つ紹介します。
いずれも先に知っておくと遠回りを避けられます。

1. 指示で引用の「書式」を指定しない

エージェントの指示(instructions)で引用の書き方を指定するのは避けるよう、公式が明記しています(Microsoft Learn)。

公式の記載:
システム定義の引用形式や動作を変更、オーバーライド、または干渉しないでください。
引用文献の生成、構造化、表示方法("引用文献" や "参照" などの用語を含む)を変更しようとする命令は避けてください。
引用文献を変更または非表示にした場合、オーケストレーターは引用文献を認識せず、応答をモデルナレッジとして扱い、……有効な出力が破棄され、システムが機能していないように見える可能性があります。

ややこしいのは、「出典を引用してほしい」と促すこと自体はむしろ推奨されている点です。
ナレッジソースの解説ページには、引用を安定させる方法として、「エージェントの指示では、モデルに必ず出典を明記するよう指示してください」と書かれています(Microsoft Learn)。

2つを合わせると、「引用して」と促すのはOK、「こう書け」と書式を決めるのはNGという線引きになります。
筆者は「本文の末尾に『参照: 文書名』の形で書く」という書式指定を入れており、これを削除した後は引用が安定しました(1行を戻して再現させる対照実験まではしていないため、断定はできません)。

2. 引用が付かないと、回答そのものが消えることがある

エージェントの設定「根拠のない応答を許可する」(Allow ungrounded responses)をオフにすると、ナレッジソース由来の回答は本文中に引用が含まれている場合にだけ返されます(Microsoft Learn)。
日本語版では、agent が「担当者」と訳されているため、次は英語版の原文を引用します。

公式の記載(英語版の原文):
Occasionally, the model generates a correct answer from a knowledge source but doesn't include a citation for it. When that happens, the agent withholds the answer and responds as though it didn't find any information. Because models don't always include citations, this behavior can be intermittent.
(モデルがナレッジソースから正しい回答を生成しても、その引用を付けないことがあります。
その場合、エージェントは回答を出力せず、情報が見つからなかったかのように応答します。
モデルは常に引用を付けるとは限らないため、この動作は断続的に起こることがあります)

「回答に役立つ情報は見つかりませんでした」が繰り返し出るとき、検索の失敗とは限りません。
回答は生成されていて、引用が付かなかったために出力されていない可能性があります。

3. 応答をカスタマイズすると、引用は自動で付かない

そもそも本記事のように自前で引用を扱う必要があるのは、公式が次のように明記しているためです(Microsoft Learn)。

公式の記載(英語版の原文):
If you customize the generative answer response, citations aren't added automatically. For example, if you clear a Message node and render the answer yourself through a variable or an Adaptive Card, you need to include citation rendering yourself. In Teams, citation links are returned automatically only for answers that aren't customized.
(生成された回答をカスタマイズした場合、引用は自動では追加されません。
たとえば、メッセージノードを空にして、変数やアダプティブカードで自分で回答を表示する場合は、引用の表示も自分で組み込む必要があります。
Teams では、引用リンクは、カスタマイズされていない回答にだけ自動で返されます)

つまり自分で引用を表示するのは回避策ではなく、カスタマイズする構成では必要な作業ということです。

よくある質問

Q. 引用テーブルの列名は、どこで確認するのが確実ですか?

式エディターで First(System.Response.Citations). と打つと、入力候補に列名が並びます。
変数そのものは変数選択パネルの「システム」タブでも見つかりますが、テーブルの中の列名までは表示されません。
筆者の環境では System.Response.Citations. と直接打つとエラーになったため、First() で1行取り出しています。

Q. 取り方①と②は、どちらを選べばよいですか?

トピック内の生成応答ノードで回答を作り、その場で送るなら①です。
公式が手順を示しており、citationEntities に引用テーブルを渡すだけで済みます。
エージェント本体の回答を送信直前に受け止めて、加工したり別の処理に渡したりする必要がある場合は②になります。
ただし公式は、②のトリガーについて「必要に応じて細かい制御に使ってください」と案内しています。

Q. 引用の付与率を上げるために、指示で「出典を必ず書くように」と書いてもよいですか?

「出典を引用してほしい」と促すだけなら問題ありません。
公式も、引用を安定させる方法として指示で出典を求めることを挙げています。
避けるべきなのは書式や表示方法の指定です。
公式は「引用文献」「参照」などの用語で引用の生成・構造化・表示方法を変えようとする指示を避けるよう明記しています。

Q. 引用が1件も付かない回答では、どうなりますか?

筆者の環境では、本記事の Concat の式は、引用が無くてもエラーにならず、結果は空になりました。
ただし、その値をフローに渡す場合は、トリガー入力を「任意」にしてください。
筆者の環境では、必須のままだと FlowActionBadRequest で失敗し、フロー自体が呼ばれないため実行履歴にも残りませんでした。

まとめ

Copilot Studioで引用を取り出すポイントは3つです。

  • 筆者が確認した取り方は2つ:
    生成応答ノードから取るなら、Topic.Answer.Text.CitationSources を citationEntities に渡します(Microsoft Learnの手順)。
    エージェントの応答から取るなら、System.Response.Citations を使います(MicrosoftのCopilot Studio CATチームのブログと公式サンプルで紹介)。
  • 列名は式エディターで確かめる:
    引用はテーブルで返り、変数選択パネルには列名までは出ません。
    First() で1行取り出すと、入力候補で列名を確認できます。
  • 自分で表示するなら、Url 列からリンクを組み立てる:
    本記事では Name と Url を Concat と Distinct でつなぐ例を紹介しましたが、組み立て方はほかにもあります。

社内文書を根拠に回答するエージェントでは、出典の提示がそのまま信頼性につながります。
まずは式エディターで引用テーブルの中身を1回のぞいてみてはいかがでしょうか。


QUICK E-Solutionsでは、Copilot Studio / Power Platform 環境のセキュリティ・ガバナンス設計から、エージェント開発のPoC・本番構築、運用・継続改善まで一貫して支援しています。
以下のリンクからご提供しているサービスの詳細をご確認いただけます。

※このブログで参照されている、Microsoft、Microsoft Copilot Studio、Power Platform、Power Automate、Power Fx、SharePoint、Microsoft Teams は、米国およびその他の国におけるMicrosoft Corporationの商標または登録商標です。

  • このエントリーをはてなブックマークに追加

お問い合わせ

Contact

ご質問やご相談、サービスに関する詳細など、何でもお気軽にご連絡ください。下記のお問い合わせフォームよりお気軽に送信ください。

お問い合わせ

資料ダウンロード

Download

当社のサービスに関する詳細情報を掲載した資料を、下記のページよりダウンロードいただけます。より深く理解していただける内容となっております。ぜひご活用ください。

資料ダウンロード