エージェントの対話には、テキスト、音声、画像、またはビデオを使用できます。 ユーザーの入力を処理して要求を理解し、入力を評価して関連するタスクを実行します。 エージェントは、情報を要求したり、サービスへのアクセスを有効にしたりして、ユーザーに応答します。
エージェント スコープ
Microsoft Teams のエージェントは、1 対 1 の会話、グループ チャット、またはチーム内のチャネルに参加できます。 各スコープは、会話型エージェントに固有のオポチュニティと課題を提供します。
| チャネル |
グループ チャット |
1 対 1 のチャット |
| 大規模なリーチ |
減少したメンバー |
従来の方法 |
| 簡潔な個々のやり取り |
@mention エージェントへ |
Q&A エージェント |
|
@mention エージェントへ |
チャネルと同様 |
冗談を言ったりメモを取ったりするエージェント |
チャネル
チャネルには、複数のユーザー (最大 2000 人) 間のスレッド形式の会話が含まれます。 これにより、エージェントに大規模なリーチが与えられる可能性がありますが、個々のやり取りは簡潔でなければなりません。 従来の複数ターンの操作は機能しません。 代わりに、対話型のカードやダイアログ (TeamsJS v1.x ではタスク モジュールと呼ばれていました) を使用するか、会話を 1 対 1 の会話に移動して、多くの情報を収集する必要があります。 エージェントは、 @mentionedされているメッセージにのみアクセスできます。 Microsoft Graph および組織レベルのアクセス許可を使用して会話から追加のメッセージを取得できます。
次の場合、エージェントはチャネルでより適切に機能します。
- ユーザーが追加情報を取得するための対話型カードを提供する通知。
- 投票やアンケート調査などのフィードバック シナリオ。
- 単一の要求または応答サイクルは対話を解決し、結果は複数のメンバーで会話をする場合に役立ちます。
- 素晴らしい猫の画像を取得したり、ランダムに勝者を選んだりするソーシャル エージェントまたは楽しいエージェント。
グループ チャット
グループ チャットは、3 人以上のユーザー同士で行われる非スレッドの会話です。 チャネルよりもメンバーは少なく、一時的な会話が多いのが特徴です。 チャネルと同様に、エージェントは直接 @mentioned されたメッセージにのみアクセスできます。
チャネルでより適切に機能するエージェントは、グループ チャットでもより適切に機能します。
1 対 1 のチャット
1 対 1 のチャットは、会話型エージェントがユーザーと対話するための従来の方法です。 1 対 1 の会話エージェントの例をいくつか示します。
- Q&A エージェント
- 他のシステムでワークフローを開始するエージェント。
- ジョークを言うエージェント。
- メモを取るエージェント。
1 対 1 のエージェントを作成する前に、会話ベースのインターフェイスが機能を提示するための最良の方法であるかどうかを検討してください。
アクティビティ ハンドラーとエージェント ロジック
ニーズを満たすエージェント アプリを作成するには、Microsoft Teams アクティビティ ハンドラーとエージェント ロジックを理解することが不可欠です。 これら 2 つの重要なコンポーネントが連携して会話ロジックを整理します。
Teams アクティビティ ハンドラー: チャネルの作成、チーム メンバーの追加、Teams 環境に固有のその他のアクションなど、Teams 固有のイベントと相互作用を処理します。 Teams SDK v2 では、ハンドラーはクラス継承を介してではなく、 App インスタンスに直接登録されます。
エージェント ロジック: App オブジェクトにはエージェントの会話ロジックが格納され、ユーザー入力に基づいて意思決定を行う責任があります。 受信アクティビティは、アクティビティー・タイプとオプションのパターン・マッチングに基づいて、適切なハンドラーにルーティングされます。
Teams アクティビティ ハンドラー
アクティビティ ハンドラーはエージェントの機能の中核であり、ユーザー操作を管理および処理します。 Teams SDK v2 の場合:
-
App オブジェクトをインスタンス化し、ハンドラーを登録します。
- ハンドラーは、型指定されたコンテキスト オブジェクト (TypeScript で
IActivityContext 、C# で IContext<TActivity> 、Python で ActivityContext[TActivity] ) を受け取ります。
- 応答とプロアクティブ メッセージは、
ctx.reply() または ctx.send() 経由で送信されます。
Teams エージェントがアクティビティを受信すると、SDK は登録済みハンドラーを介してアクティビティをルーティングします。 Teams 固有のイベント (チャネルのライフサイクル、メンバーの変更など) は個別の名前付きイベントとして表示されるため、手動で channelData.eventType を調べる必要はありません。
注:
エージェント アクティビティの処理に 15 秒以上かかる場合、Teams はエージェント エンドポイントに再試行要求を送信するため、重複する要求が表示される可能性があります。
アクティビティ ハンドラー コード スニペット
次のスニペットは、チャネルおよびチームのライフサイクル イベントの Teams アクティビティ ハンドラーを示しています。
エージェントは、 Microsoft.Teams.Apps パッケージを使用してビルドされます。
OnMessage()、OnChannelCreated() などの拡張メソッドを使用して、Appとチェーン ハンドラーの登録をインスタンス化します。すべてのハンドラーは IContext<TActivity> オブジェクトを受け取ります。
OnChannelCreated
using Microsoft.Teams.Apps;
WebApplicationBuilder builder = WebApplication.CreateSlimBuilder(args);
builder.Services.AddTeamsBotApplication();
WebApplication app = builder.Build();
TeamsBotApplication teams = app.UseTeamsBotApplication();
teams.OnChannelCreated(async (context, cancellationToken) =>
{
var channel = context.Activity.ChannelData.Channel;
var team = context.Activity.ChannelData.Team;
// Code logic here
});
OnChannelDeleted
teams.OnChannelDeleted(async (context, cancellationToken) =>
{
// Code logic here
});
OnChannelRenamed
teams.OnChannelRenamed(async (context, cancellationToken) =>
{
// Code logic here
});
OnTeamRenamed
teams.OnTeamRenamed(async (context, cancellationToken) =>
{
// Code logic here
});
OnMembersAdded
teams.OnMembersAdded(async (context, cancellationToken) =>
{
foreach (var member in context.Activity.MembersAdded)
{
// Code logic here
}
});
OnMembersRemoved
teams.OnMembersRemoved(async (context, cancellationToken) =>
{
foreach (var member in context.Activity.MembersRemoved)
{
// Code logic here
}
});
OnMessageUpdate / OnMessageDelete
メッセージの編集は OnMessageUpdate 経由で処理されます。 論理的な削除は OnMessageDelete を使用して処理されます。
teams.OnMessageUpdate(async (context, cancellationToken) =>
{
// Code logic here
});
teams.OnMessageDelete(async (context, cancellationToken) =>
{
// Code logic here
});
エージェントは、 Microsoft.Teams.Apps パッケージを使用してビルドされます。
OnMessage()、OnChannelCreated() などの拡張メソッドを使用して、Appとチェーン ハンドラーの登録をインスタンス化します。すべてのハンドラーは IContext<TActivity> オブジェクトを受け取ります。
OnChannelCreated
using Microsoft.Teams.Apps;
var app = new App();
app.OnChannelCreated(async context => {
var channel = context.Activity.ChannelData.Channel;
var team = context.Activity.ChannelData.Team;
// Code logic here
});
OnChannelDeleted
app.OnChannelDeleted(async context => {
// Code logic here
});
OnChannelRenamed
app.OnChannelRenamed(async context => {
// Code logic here
});
OnTeamRenamed
app.OnTeamRenamed(async context => {
// Code logic here
});
OnMembersAdded
app.OnMembersAdded(async context => {
foreach (var member in context.Activity.MembersAdded) {
// Code logic here
}
});
OnMembersRemoved
app.OnMembersRemoved(async context => {
foreach (var member in context.Activity.MembersRemoved) {
// Code logic here
}
});
OnMessageUpdate / OnMessageDelete
メッセージの編集は OnMessageUpdate 経由で処理されます。 論理的な削除は OnMessageDelete を使用して処理されます。
app.OnMessageUpdate(async context => {
// Code logic here
});
app.OnMessageDelete(async context => {
// Code logic here
});
エージェントは、 @microsoft/teams.apps パッケージを使用してビルドされます。
Appをインスタンス化し、ハンドラーを app.on(eventName, handler) に登録します。 SDK は、イベント名の文字列に基づいて、アクティビティを正しいハンドラーにルーティングします。
channelCreated
import { App } from '@microsoft/teams.apps';
const app = new App();
app.on('channelCreated', async ({ activity }) => {
const channel = activity.channelData.channel; // { id, name }
const team = activity.channelData.team; // { id, name }
// Code logic here
});
channelDeleted
app.on('channelDeleted', async ({ activity }) => {
// Code logic here
});
channelRenamed
app.on('channelRenamed', async ({ activity }) => {
// Code logic here
});
teamRenamed
app.on('teamRenamed', async ({ activity }) => {
// Code logic here
});
membersAdded / membersRemoved
app.on('membersAdded', async ({ activity, send }) => {
for (const member of activity.membersAdded) {
await send(`Welcome, ${member.name}!`);
}
});
app.on('membersRemoved', async ({ activity }) => {
// Code logic here
});
messageUpdate / messageDelete
メッセージの編集内容は、 messageUpdateとして表示されます。 論理的な削除は messageDelete として表示され、 activity.channelData.eventType は 'softDeleteMessage'されます。
app.on('messageUpdate', async ({ activity }) => {
// Code logic here
});
app.on('messageDelete', async ({ activity }) => {
// activity.channelData.eventType === 'softDeleteMessage' for soft deletes
// Code logic here
});
エージェントは、 microsoft-teams-apps パッケージを使用してビルドされます。 ハンドラーは、 App インスタンス上のデコレーターを使用して登録されます。 各ハンドラーは、ActivityContext[TActivity] オブジェクトを受け取る async 関数です。
on_channel_created
from microsoft_teams.apps import App, ActivityContext
from microsoft_teams.api.activities import ConversationUpdateActivity
app = App()
@app.on_channel_created
async def handle_channel_created(ctx: ActivityContext[ConversationUpdateActivity]):
channel = ctx.activity.channel_data.channel
team = ctx.activity.channel_data.team
# Code logic here
on_channel_deleted
@app.on_channel_deleted
async def handle_channel_deleted(ctx: ActivityContext[ConversationUpdateActivity]):
# Code logic here
on_channel_renamed
@app.on_channel_renamed
async def handle_channel_renamed(ctx: ActivityContext[ConversationUpdateActivity]):
# Code logic here
on_team_renamed
@app.on_team_renamed
async def handle_team_renamed(ctx: ActivityContext[ConversationUpdateActivity]):
# Code logic here
on_conversation_update (メンバーの追加/削除)
メンバーの追加および削除イベントは、 on_conversation_updateを介して処理されます。
ctx.activity.members_addedとctx.activity.members_removedを検査します。
@app.on_conversation_update
async def handle_conversation_update(ctx: ActivityContext[ConversationUpdateActivity]):
if ctx.activity.members_added:
for member in ctx.activity.members_added:
await ctx.send(f"Welcome, {member.name}!")
if ctx.activity.members_removed:
# Code logic here
on_edit_message / on_soft_delete_message / on_undelete_message
@app.on_edit_message
async def handle_edit_message(ctx: ActivityContext):
# Code logic here
@app.on_soft_delete_message
async def handle_soft_delete_message(ctx: ActivityContext):
# Code logic here
@app.on_undelete_message
async def handle_undelete_message(ctx: ActivityContext):
# Code logic here
エージェント アクティビティ ハンドラーの例
次のコードは、エージェント アクティビティの例を示しています。
using Microsoft.Teams.Apps;
WebApplicationBuilder builder = WebApplication.CreateSlimBuilder(args);
builder.Services.AddTeamsBotApplication();
WebApplication app = builder.Build();
TeamsBotApplication teams = app.UseTeamsBotApplication();
teams.OnMessage(async (context, cancellationToken) =>
{
var senderName = context.Activity.From.Name;
await context.SendAsync($"Hello <at>{senderName}</at>.", cancellationToken);
});
app.Run();
using Microsoft.Teams.Apps.Activities;
using Microsoft.Teams.Apps.Extensions;
using Microsoft.Teams.Plugins.AspNetCore.DevTools.Extensions;
using Microsoft.Teams.Plugins.AspNetCore.Extensions;
var builder = WebApplication.CreateBuilder(args);
builder.AddTeams().AddTeamsDevTools();
var app = builder.Build();
var teams = app.UseTeams();
teams.OnMessage(async (context, cancellationToken) =>
{
var senderName = context.Activity.From.Name;
await context.Send($"Hello <at>{senderName}</at>.", cancellationToken);
});
app.Run();
import { App } from '@microsoft/teams.apps';
const app = new App();
app.on('message', async ({ activity, reply }) => {
const senderName = activity.from.name;
await send(`Hello <at>${senderName}</at>.`);
});
app.start().catch(console.error);
import asyncio
from microsoft_teams.apps import App, ActivityContext
from microsoft_teams.api import MessageActivity
app = App()
@app.on_message
async def handle_message(ctx: ActivityContext[MessageActivity]):
sender_name = ctx.activity.from_property.name
await ctx.send(f"Hello <at>{sender_name}</at>.")
if __name__ == "__main__":
asyncio.run(app.start())
エージェント ロジック
エージェント ロジックには、エージェントのアクションと相互作用を指示する基本的なルールと意思決定フレームワークが組み込まれています。 エージェントがユーザー入力を解釈し、応答を作成し、会話に参加する方法の概要を示します。
Teams SDK v2 では、エージェント ロジックは 1 つ以上のエージェント チャネルからの着信アクティビティを処理し、発信アクティビティを生成します。 すべてのアクティビティのルーティングは App インスタンスによって処理されます。ハンドラーを登録すると、SDK はそれらにアクティビティを自動的にディスパッチします。
コア アクティビティ ハンドラー
App クラスは、ハンドラーを登録するための拡張メソッドを公開します。 メソッドは Fluent チェーンの App を返します。
| イベント |
延長方法 |
説明 |
| 任意のアクティビティの種類を受信しました |
OnActivity(handler) |
すべてのアクティビティに対して呼び出される Catch-all ハンドラー。 |
| メッセージ アクティビティを受信しました |
OnMessage(handler) |
着信テキスト メッセージを処理します。 パターン マッチングの最初の引数として正規表現文字列を渡します。 |
| 会話の更新を受信した |
OnConversationUpdate(handler) |
未加工の会話更新アクティビティ。 |
| 非エージェント メンバーが参加済み |
OnMembersAdded(handler) |
MembersAdded.Length > 0時に発生します。 |
| エージェント以外のメンバーが残りました |
OnMembersRemoved(handler) |
MembersRemoved.Length > 0時に発生します。 |
| インストールが追加されました |
OnInstall(handler) |
エージェントがインストールされました。 |
Teams 固有のアクティビティ ハンドラー
| イベント |
延長方法 |
説明 |
| チャネルを作成しました |
OnChannelCreated(handler) |
Teams チャネルが作成されました。 |
| チャネルが削除されました |
OnChannelDeleted(handler) |
Teams チャネルが削除されました。 |
| チャネルの名前が変更されました |
OnChannelRenamed(handler) |
Teams チャネルの名前が変更されました。 |
| チャットの名前が変更されました |
OnTeamRenamed(handler) |
チーム名が変更されました。 |
| 編集されたメッセージ |
OnMessageUpdate(handler) |
メッセージが編集されました。 |
| メッセージが論理的に削除されました |
OnMessageDelete(handler) |
メッセージが論理的に削除されました。 |
Teams の呼び出しアクティビティ
| 呼び出しの種類 |
延長方法 |
説明 |
CardAction.Invoke |
OnExecuteAction(handler) |
カード アクション呼び出しアクティビティが受信されました。 |
task/fetch |
OnTaskFetch(handler) |
ダイアログ (タスク モジュール) がフェッチされました。 |
task/submit |
OnTaskSubmit(handler) |
ダイアログ (タスク モジュール) が送信されました。 |
fileConsent/invoke |
OnFileConsent(handler) |
ファイル同意カード アクティビティが受信されました。 |
signin/verifyState |
SDK によって自動的に処理されます (OAuth フロー) |
サインイン 状態の確認アクティビティ。 |
コア アクティビティ ハンドラー
app.on() でサポートされているイベント名の一覧は次のとおりです。
| イベント |
イベント名文字列 |
説明 |
| 任意のアクティビティの種類を受信しました |
'activity' |
すべてのアクティビティに対して呼び出される Catch-all ハンドラー。 |
| メッセージ アクティビティを受信しました |
'message' |
着信テキスト メッセージを処理します。 正規表現の照合には app.message(pattern, handler) を使用します。 |
| 会話の更新を受信した |
'conversationUpdate' |
未加工の会話更新アクティビティ。 |
| インストールが追加されました |
'install.add' |
エージェントがインストールされました。 |
| インストールが削除されました |
'install.remove' |
エージェントがアンインストールされました。 |
| メンバーが追加されました |
'membersAdded' |
1 人以上のメンバーが会話に参加しました。 |
| 削除されたメンバー |
'membersRemoved' |
1 人以上のメンバーが会話から退出しました。 |
| 編集されたメッセージ |
'messageUpdate' |
会話内のメッセージが編集されました。 |
| メッセージが論理的に削除されました |
'messageDelete' |
メッセージが論理的に削除されました (activity.channelData.eventType === 'softDeleteMessage')。 |
| 開封確認メッセージを受信しました |
'readReceipt' |
開封確認メッセージを受信しました。 |
Teams 固有のイベント ハンドラー
app.on() は、次の Teams 固有のイベント名文字列をサポートします。
| イベント |
イベント名文字列 |
説明 |
channelCreated |
'channelCreated' |
Teams チャネルが作成されました。 |
channelDeleted |
'channelDeleted' |
Teams チャネルが削除されました。 |
channelRenamed |
'channelRenamed' |
Teams チャネルの名前が変更されました。 |
channelRestored |
'channelRestored' |
Teams チャネルが復元されました。 |
channelMemberAdded |
'channelMemberAdded' |
メンバーがチャネルに追加されました。 |
channelMemberRemoved |
'channelMemberRemoved' |
メンバーがチャネルから削除されました。 |
teamRenamed |
'teamRenamed' |
チーム名が変更されました。 |
teamArchived |
'teamArchived' |
チームはアーカイブされました。 |
teamDeleted |
'teamDeleted' |
チームは削除されました。 |
teamRestored |
'teamRestored' |
チームが復元されました。 |
| 会議開始 |
'meetingStart' |
会議が開始されました。 |
| 会議が終了しました |
'meetingEnd' |
会議が終了しました。 |
| 参加者が参加しました |
'meetingParticipantJoin' |
参加者が会議に参加しました。 |
| 参加者が左 |
'meetingParticipantLeave' |
参加者が会議を退出しました。 |
Teams の呼び出しアクティビティ
次の表に、 app.on()経由で使用できるアクティビティ ハンドラーの呼び出しを示します。
| 呼び出しの種類 |
イベント名文字列 |
説明 |
CardAction.Invoke |
'card.action' |
カード アクション呼び出しアクティビティが受信されました (adaptiveCard/action)。 |
signin/verifyState |
SDK によって自動的に処理されます (OAuth フロー) |
サインイン 状態の確認アクティビティ。 |
task/fetch |
'dialog.open' |
ダイアログ (タスク モジュール) がフェッチされました。 |
task/submit |
'dialog.submit' |
ダイアログ (タスク モジュール) が送信されました。 |
コア アクティビティ ハンドラー
App クラスは、デコレーター スタイルのハンドラー登録を公開します。
| イベント |
デコレーター |
説明 |
| 受信したアクティビティ |
@app.on_activity |
すべてのアクティビティの包括的なハンドラー。 |
| 受信したメッセージ |
@app.on_message |
着信テキスト メッセージを処理します。 |
| パターンのあるメッセージ |
@app.on_message_pattern(re.compile(...)) |
正規表現パターンに一致するメッセージを処理します。 |
| 会話の更新 |
@app.on_conversation_update |
生の会話の更新;チェック members_added / members_removed。 |
| インストールが追加されました |
@app.on_install_add |
エージェントがインストールされました。 |
| インストールが削除されました |
@app.on_install_remove |
エージェントがアンインストールされました。 |
Teams 固有のアクティビティ ハンドラー
| イベント |
デコレーター |
説明 |
| チャネルを作成しました |
@app.on_channel_created |
Teams チャネルが作成されました。 |
| チャネルが削除されました |
@app.on_channel_deleted |
Teams チャネルが削除されました。 |
| チャネルの名前が変更されました |
@app.on_channel_renamed |
Teams チャネルの名前が変更されました。 |
| チャットの名前が変更されました |
@app.on_team_renamed |
チーム名が変更されました。 |
| 編集されたメッセージ |
@app.on_edit_message |
メッセージが編集されました。 |
| メッセージが論理的に削除されました |
@app.on_soft_delete_message |
メッセージが論理的に削除されました。 |
| メッセージが削除されない |
@app.on_undelete_message |
削除されたメッセージが復元されました。 |
| 会議開始 |
@app.on_meeting_start |
会議が開始されました。 |
| 会議が終了しました |
@app.on_meeting_end |
会議が終了しました。 |
| 参加者が参加しました |
@app.on_meeting_participant_join |
参加者が会議に参加しました。 |
| 参加者が左 |
@app.on_meeting_participant_leave |
参加者が会議を退出しました。 |
Teams の呼び出しアクティビティ
| 呼び出しの種類 |
デコレーター |
説明 |
CardAction.Invoke |
@app.on_card_action |
カード アクション呼び出しアクティビティが受信されました。 |
task/fetch |
@app.on_dialog_open |
ダイアログ (タスク モジュール) がフェッチされました。 |
task/submit |
@app.on_dialog_submit |
ダイアログ (タスク モジュール) が送信されました。 |
fileConsent/invoke |
@app.on_file_consent |
ファイル同意カード アクティビティが受信されました。 |
signin/verifyState |
SDK によって自動的に処理されます (OAuth フロー) |
サインイン 状態の確認アクティビティ。 |
エージェント アクティビティ ハンドラーについて理解を深めたので、エージェントが会話や送受信するメッセージによってどのように動作するかを見てみましょう。
推奨事項
エージェントとユーザーの間の広範な対話は、タスクを完了するための遅くて複雑な方法です。 過剰なコマンド、特に広範囲のコマンドをサポートするエージェントは、成功しないか、ユーザーから肯定的に見られません。
チャットでの複数ターン エクスペリエンスを避ける 長時間のダイアログでは、開発者は状態を維持する必要があります。 この状態を終了するには、ユーザーがタイムアウトするか、 キャンセルを選択する必要があります。 また、このプロセスは面倒です。 たとえば、次の会話シナリオを参照してください。
ユーザー: Megan との会議をスケジュールして。
エージェント: 200件の結果が見つかりました。これには名と姓が含まれています。
ユーザー: Megan Bowen との会議をスケジュールして。
エージェント:わかりました、ミーガン・ボーウェンと会いたいのは何時ですか?
ユーザー: 午後 1 時に。
エージェント:どの日に?
6 つ以下のコマンドをサポートする 現在のエージェント メニューには表示されるコマンドが 6 つしかないため、それ以上のコマンドがどの頻度でも使用される可能性は低いです。 幅広いアシスタントになろうとするのではなく、特定の分野に深く入り込むエージェントは、よりうまく働き、うまくいきます。
より迅速な対話のためにサポート情報のサイズを最適化する エージェントの欠点の 1 つは、ランク付けされていない応答で大規模な検索サポート情報を維持するのが難しいことです。 エージェントは、短く迅速な対話に最適であり、長いリストで答えを探し回ることはありません。
注:
Teams プラットフォームは、トランスポート層セキュリティ (TLS) バージョン 1.2 のみをサポートします。 それに応じてエージェント環境を構成してください。
その他のエージェント機能を調べる
従来のエージェント機能に加えて、Teams エージェント アプリで利用できる高度な機能を調べることもできます。
コード サンプル
| サンプルの名前 |
説明 |
TypeScript |
C# |
Python |
| Teams 会話エージェント |
このアプリは、基本的なエージェント イベントを示します。 |
表示 |
表示 |
表示 |