Microsoft Copilot Studioで会話を設計するとき、最初に理解したい単位が「トピック」です。トピックは単なる回答文の置き場ではなく、会話が始まる条件、質問、入力値の保存、条件分岐、終了までをひとまとまりにした対話フローです。
この記事では、Microsoft Learnの公式ドキュメントをもとに、初心者が小さなトピックを組み立てる手順と、最初につまずきやすい設計ポイントを整理します。
結論:最初は5種類の要素で組み立てる
| 要素 | 役割 | 最初に決めること |
|---|---|---|
| Trigger | トピックを開始する | どんな相談をこのトピックが受け持つか |
| Message | エージェントが説明する | ユーザーに何を伝えるか |
| Question | ユーザーから情報を集める | 何を、どの型で受け取るか |
| Variable | 回答を後続処理で再利用する | 内容が分かる名前を付ける |
| Condition | 回答に応じて経路を分ける | どの条件をどの順番で評価するか |
最小構成は次のように考えると分かりやすくなります。
Trigger
↓
Message(何を案内するか説明)
↓
Question(必要な情報を質問)
↓
Variable(回答を保存)
↓
Condition(回答によって分岐)
├─ 条件A → Message → End
└─ その他 → Message → End
最初から多数の分岐や外部ツール連携を加えるより、まずこの一本道と1つの分岐をテストし、期待どおりに動いてから広げるのが安全です。
トピックは「会話の一部分」を担当する
Microsoftの公式ドキュメントでは、トピックはエージェントの会話がどのように進むかを定義するものと説明されています。トピック内には複数のノードがあり、メッセージの送信、質問、条件分岐、別トピックへの移動、ツールの呼び出しなどを並べて会話経路を作ります。
ここで重要なのは、1つのトピックにエージェントの全機能を詰め込まないことです。たとえば「利用方法の案内」と「問い合わせの受付」は目的が違うため、別のトピックに分けたほうが変更箇所を追いやすくなります。
トピック名は、機能名ではなく会話の目的が分かる名前にします。
分かりにくい例: 質問処理1
分かりやすい例: 利用方法を案内する
Microsoftは、トピック名にピリオド(.)を使うと、そのトピックを含むソリューションをエクスポートできないと注意しています。命名時点で避けておくと、後からの修正を減らせます。
Triggerで「いつ始まるか」を決める
トピックの先頭にはTriggerノードがあります。どのように起動条件を定義するかは、エージェントのオーケストレーション方式によって異なります。
| 方式 | 既定の考え方 | 設計で重視する項目 |
|---|---|---|
| 生成オーケストレーション | エージェントがトピックを選ぶ | トピック名と説明 |
| クラシックオーケストレーション | ユーザー発話とフレーズを照合する | トリガーフレーズ |
生成オーケストレーションでは、トピック名とTriggerノードに設定した説明が選択判断に使われます。説明を「質問に答える」のように広く書くと、ほかのトピックと役割が重なりやすくなります。「製品の基本操作について、手順を案内する」のように、対象と目的を具体化します。
クラシックオーケストレーションでは、ユーザーが入力しそうな言い方をトリガーフレーズとして登録します。完全一致だけを狙うのではなく、同じ意図を別の言い方で表した例を用意します。
使い方を教えて
基本操作を知りたい
最初の設定方法は?
トピックの対象範囲が重なるフレーズを複数のトピックへ登録すると、意図しないトピックが選ばれる原因になります。フレーズを増やす前に、各トピックの担当範囲を一文で区別できるか確認します。
QuestionとVariableで入力を受け取る
Questionノードを追加すると、ユーザーへの質問と回答の受け取りを1か所で定義できます。Copilot Studioは、Questionノードの出力を保存する変数を自動で作成します。
質問を作るときは、文章だけでなく「どんな情報として識別するか」も決めます。選択肢、文字列、数値など、後続の条件で扱いたい型に合わせます。型が曖昧なままだと、条件分岐で文字列と数値を比較するような不整合が起きやすくなります。
自動生成された変数名は、そのまま使わず意味のある名前へ変更します。
分かりにくい例: Var1
分かりやすい例: selectedGuideType
変数にはユーザーの回答を保存できるため、後続のMessageノードで内容を表示したり、Conditionノードで分岐したりできます。別トピックへリダイレクトするときは、入力値を渡したり、呼び出し先から出力値を受け取ったりすることも可能です。
ただし、何でもグローバル変数にする必要はありません。まずはトピック内だけで使う変数を基本とし、複数トピックで本当に共有する値だけ受け渡すと、どこで値が変わったか追跡しやすくなります。
Conditionで回答ごとの経路を作る
Conditionノードは、変数と値を比較して会話を分岐させます。追加直後は、条件が成立する経路と、それ以外を受ける経路の2つが作られます。
たとえば、案内の種類を選んでもらう場合は次のように分けられます。
selectedGuideType = "初期設定"
→ 初期設定の手順を案内
selectedGuideType = "基本操作"
→ 基本操作の手順を案内
All Other Conditions
→ 選び直しを案内
条件は上から順番に評価され、最初に真になった分岐が実行されます。似た条件を並べる場合は、より具体的な条件を先に置きます。また、どの条件にも一致しない場合の経路を空にしないことが大切です。想定外の入力が来ても、ユーザーが次に何をすればよいか分かるメッセージを返します。
大きくなったら別トピックへ分ける
1つのトピックが長くなったら、Redirectノードで別トピックを呼び出せます。呼び出し先が終わると、既定では元のトピックへ戻って会話を続けます。共通の入力確認や、複数の会話から使う案内を別トピックへ切り出すと、重複を減らせます。
分割するときは、呼び出し先の入力と出力を明確にします。
| 確認項目 | 例 |
|---|---|
| 呼び出し先に渡す値 | 選択された案内種別 |
| 呼び出し先から返す値 | 案内が完了したか |
| 終了後に戻る場所 | 次の選択肢を表示するノード |
リダイレクトを追加したら、Test agentペインで呼び出し先へ移動し、完了後に元のトピックへ戻ることまで確認します。
実装チェックリスト
- トピックの目的を一文で説明できる
- 生成オーケストレーションでは、名前と説明がほかのトピックと重複していない
- クラシックオーケストレーションでは、同じ意図の異なる言い方を用意した
- Questionノードの回答型を後続処理に合わせた
- 自動生成された変数に意味のある名前を付けた
- Conditionの各分岐にユーザー向けメッセージがある
- All Other Conditionsの経路を空にしていない
- 別トピックへ移動する場合は、入力・出力・戻り先を確認した
- 正常系だけでなく、曖昧な入力と想定外の入力もテストした
失敗パターン
トピックの目的が広すぎる → 対策:1トピック1目的に近づけ、名前と説明で担当範囲を明示する。
Questionノードの回答型を意識しない → 対策:後続のConditionで何と比較するかを先に決め、回答の識別方法と変数型を合わせる。
正常系の分岐だけ作る → 対策:未入力、想定外の回答、どの条件にも一致しない場合の案内を用意する。
長い会話を1トピックへ詰め込む → 対策:再利用できる部分を別トピックへ切り出し、受け渡す変数を最小限にする。
保存できたので完成と考える → 対策:Test agentペインで、起動、質問、全分岐、リダイレクト後の復帰まで順番に確認する。
参考リンク
- Create and edit topics - Microsoft Copilot Studio
- Set topic triggers - Microsoft Copilot Studio
- Work with variables - Microsoft Copilot Studio
- Add conditions to topics - Microsoft Copilot Studio
- Manage topics - Microsoft Copilot Studio
この記事を書いた人✏️@YushiYamamoto
ITPRODX.com代表 / AIアーキテクト
Next.js / TypeScript / n8nを活用した自律型アーキテクチャ設計を専門としています。
日々の自動化の検証結果や、ビジネス側の視点(ROI等)に関するより深い考察は、以下の公式サイトおよびnoteで発信しています。
