重要
Microsoft Agent 365 の早期アクセスを利用するには、フロンティア プレビュープログラムに参加する必要があります。 フロンティアは、Microsoft の最新の AI イノベーションと直接接続します。 Frontier のプレビューは、お客様の契約書に記載されている既存のプレビュー利用規約に従います。 これらの機能は現在開発中であるため、提供状況や機能は今後変更される可能性があります。
通知モジュールにより、開発者は Microsoft 365 アプリケーションからのイベントや通知に応答できるエージェントを構築できます。 通知機能により、エージェントはユーザーがメール、ドキュメント コメント、その他の共同作業シナリオを通じてやり取りした際にアラートを受信して処理できます。
通知のワークフロー
このワークフローに従って、AI エージェント アプリケーションの通知を有効にします。
通知パッケージをインストールします。
通知コンポーネントのインポート
- 通知クラスとハンドラーをインポートする
- 活動の種類とチャネル識別子をインポートする
通知ハンドラーを登録する
- 通知ハンドラー メソッドの使用によりルートを登録する
- 特定の通知の種類 (電子メール、Word、Excel、PowerPoint など) のハンドラーを構成する
エージェント コードで通知を処理する
- エージェントはMicrosoft 365 アプリケーションから通知を受け取ります
- 受信通知を処理し、適切に応答します
通知の種類
Agents 365 SDK は以下の通知タイプをサポートしています:
| 通知のタイプ |
プロパティ |
サブチャネル ID |
|
電子メール |
エージェントは、自身にメンションされている、または宛先として指定されているメールを受信します |
email |
|
Word |
エージェントは Word ドキュメントのコメントでメンションされている |
word |
|
Excel |
エージェントは Excel ドキュメントのコメントでメンションされている |
excel |
|
PowerPoint |
エージェントは PowerPoint ドキュメントのコメントでメンションされている |
powerpoint |
|
ライフサイクル イベント |
エージェント ライフサイクル通知 (作成されたユーザー ID、ワークロード オンボード、ユーザー削除) |
N/A |
エージェントのライフサイクル イベント
エージェントのライフサイクル イベントにより、エージェントはエージェント型ユーザー ID 管理に関連する特定のシステム イベントに対応できます。 SDK では現在、次の 3 つのライフサイクル イベントがサポートされています:
| イベント タイプ |
イベント ID |
プロパティ |
|
作成されたユーザー ID |
agenticUserIdentityCreated |
エージェント ユーザー ID が作成された際にトリガーされます |
|
ワークロード オンボードの更新 |
agenticUserWorkloadOnboardingUpdated |
エージェント ユーザーのワークロード オンボード状態が更新された際にトリガーされます |
|
削除されたユーザー |
agenticUserDeleted |
エージェント ユーザー ID が削除された際にトリガーされます |
これらのイベントを使用すると、エージェントは、ユーザーのライフサイクルの変更に応じて、初期化タスク、クリーンアップ操作、または状態管理を実行できます。
エージェントに通知を追加する
既存のエージェントで通知処理を有効にするには、次の手順に従います:
通知コンポーネントのインポート
エージェント ファイルに次のインポートを追加します:
from microsoft_agents_a365 import AgentApplication
from microsoft_agents_a365.notifications import (
AgentNotification,
AgentNotificationActivity,
NotificationTypes
)
from microsoft_agents.activity import ChannelId
from microsoft_agents.hosting.core import Authorization, TurnContext
-
AgentApplication: Agent365 アプリケーション構築のための基底クラスです。アクティビティのルーティング、状態管理、リクエスト処理のコア機能を提供します
-
AgentNotification: 通知ハンドラーをデコレーター メソッドに登録するクラス。
on_agent_notification()、on_email()、on_word()、その他の便利なデコレーターを提供します
-
AgentNotificationActivity: 解析済み通知データを含むラッパーです。
email_notification や wpx_comment_notification などの型指定されたプロパティを持ち、通知固有のメタデータ (ID、会話詳細、ドキュメント参照) を含みます
-
NotificationTypes: サポートされている通知の種類 (
EMAIL_NOTIFICATION、 WPX_COMMENT、 AGENT_LIFECYCLE) の列挙型
-
ChannelId: 通知チャネルを指定するために使用されます (
ChannelId(channel="agents", sub_channel="*") など)
-
承認: 通知を処理する承認コンテキスト
-
TurnContext: エージェントSDKからの現在の会話ターンのコンテキスト
import { AgentApplication, TurnContext, TurnState } from '@microsoft/agents-hosting';
import { ActivityTypes } from '@microsoft/agents-activity';
import {
AgentNotificationActivity,
NotificationType
} from '@microsoft/agents-a365-notifications';
-
AgentApplication: Agent365 アプリケーション構築の基底クラスです。アクティビティのルーティング、状態管理、リクエスト処理のコア機能を提供します。
onAgentNotification() を使用してハンドラーを登録する
-
AgentNotificationActivity: 厳密に型指定された通知データを含む解析された通知アクティビティ。
emailNotification や wpxCommentNotification などのプロパティには、通知固有のメタデータ (ID、会話の詳細、ドキュメント参照) が含まれています
-
NotificationType: 通知の種類の列挙型 (
Unknown、WpxComment、EmailNotification、AgentLifecycleNotification)
-
TurnContext: 現在の会話のターン コンテキスト
-
TurnState: 会話の状態管理
using Microsoft.Agents.Hosting;
using Microsoft.Agents.A365.Notifications;
using Microsoft.Agents.A365.Notifications.Extensions;
using Microsoft.Agents.A365.Notifications.Models;
-
AgentApplication: Agent365 アプリケーション構築の基底クラスです。アクティビティのルーティング、状態管理、リクエスト処理のコア機能を提供します。
OnAgentNotification() を使用してハンドラーを登録する
-
AgentNotificationActivity: アクティビティを型指定された通知データでラップします。
EmailNotification や WpxCommentNotification などのプロパティには、通知固有のメタデータ (ID、会話の詳細、ドキュメント参照) が含まれています
-
NotificationTypeEnum: サポートされている通知の種類の列挙 (
Unknown、WpxComment、EmailNotification、AgentLifecycleNotification)
-
ITurnContext: 現在の会話ターン コンテキストを表すインターフェイス
-
ITurnState: 会話状態管理のためのインターフェイス
エージェントに通知ハンドラーを登録する
エージェントの初期化に通知ハンドラーを追加します:
class YourAgent(AgentApplication):
def __init__(self, app):
# Create notification handler
agent_notification = AgentNotification(app)
# Register handler for all notifications
@agent_notification.on_agent_notification(
ChannelId(channel="agents", sub_channel="*")
)
async def handle_all_notifications(context, state, notification):
# Route based on notification type
if notification.notification_type == NotificationTypes.EMAIL_NOTIFICATION:
await self.handle_email_notification(context, state, notification)
elif notification.notification_type == NotificationTypes.WPX_COMMENT:
await self.handle_comment_notification(context, state, notification)
else:
await context.send_activity('Notification type not yet implemented.')
export class YourAgent extends AgentApplication {
constructor() {
super();
// Register notification handler
this.onAgentNotification("*", async (context, state, notification) => {
await this.handleAgentNotificationActivity(context, state, notification);
});
}
async handleAgentNotificationActivity(context, state, notification) {
// Route based on notification type
switch (notification.notificationType) {
case NotificationType.EmailNotification:
await this.handleEmailNotification(context, state, notification);
break;
case NotificationType.WpxComment:
await this.handleCommentNotification(context, state, notification);
break;
default:
await context.sendActivity('Notification type not yet implemented.');
}
}
}
public class YourAgent : AgentApplication
{
public YourAgent()
{
// Register notification handler
this.OnAgentNotification(
"*",
HandleNotificationAsync
);
}
private async Task HandleNotificationAsync(
ITurnContext turnContext,
ITurnState turnState,
AgentNotificationActivity activity,
CancellationToken cancellationToken)
{
// Route based on notification type
switch (activity.NotificationType)
{
case NotificationTypeEnum.EmailNotification:
await HandleEmailNotificationAsync(turnContext, turnState, activity,
cancellationToken);
break;
case NotificationTypeEnum.WpxComment:
await HandleCommentNotificationAsync(turnContext, turnState, activity,
cancellationToken);
break;
default:
await turnContext.SendActivityAsync("Notification type not yet implemented.",
cancellationToken: cancellationToken);
break;
}
}
}
特定の通知ハンドラーを実装する
通知の種類ごとにハンドラー メソッドを追加します:
class YourAgent(AgentApplication):
# ... __init__ from above ...
async def handle_email_notification(self, context, state, notification):
"""Handle email notifications"""
email = notification.email_notification
if not email:
await context.send_activity('No email data found')
return
# Process the email
await context.send_activity(
f'Received email notification. Email ID: {email.id}'
)
# Your email processing logic here
async def handle_comment_notification(self, context, state, notification):
"""Handle document comment notifications"""
comment = notification.wpx_comment_notification
if not comment:
await context.send_activity('No comment data found')
return
# Process the comment
await context.send_activity(
f'Received comment notification. Document ID: {comment.document_id}'
)
# Your comment processing logic here
async handleEmailNotification(context, state, notification) {
const email = notification.emailNotification;
if (!email) {
await context.sendActivity('No email data found');
return;
}
// Process the email
await context.sendActivity(`Received email notification. Email ID: ${email.id}`);
// Your email processing logic here
}
async handleCommentNotification(context, state, notification) {
const comment = notification.wpxCommentNotification;
if (!comment) {
await context.sendActivity('No comment data found');
return;
}
// Process the comment
await context.sendActivity(`Received comment. Document ID: ${comment.documentId}`);
// Your comment processing logic here
}
private async Task HandleEmailNotificationAsync(
ITurnContext turnContext,
ITurnState turnState,
AgentNotificationActivity activity,
CancellationToken cancellationToken)
{
var email = activity.EmailNotification;
if (email == null)
{
await turnContext.SendActivityAsync("No email data found",
cancellationToken: cancellationToken);
return;
}
// Process the email
await turnContext.SendActivityAsync(
$"Received email notification. Email ID: {email.Id}",
cancellationToken: cancellationToken
);
// Your email processing logic here
}
private async Task HandleCommentNotificationAsync(
ITurnContext turnContext,
ITurnState turnState,
AgentNotificationActivity activity,
CancellationToken cancellationToken)
{
var comment = activity.WpxCommentNotification;
if (comment == null)
{
await turnContext.SendActivityAsync("No comment data found",
cancellationToken: cancellationToken);
return;
}
// Process the comment
await turnContext.SendActivityAsync(
$"Received comment. Document ID: {comment.DocumentId}",
cancellationToken: cancellationToken
);
// Your comment processing logic here
}
特殊な通知ハンドラー
基本通知ルーティングを設定した後で、特殊なハンドラー メソッドを使用してより詳細な制御を行います。 これらのメソッドにより、次のことが可能になります。
- 同じ通知の種類に対して複数のハンドラーを登録する
- 順位付けを使用してハンドラーの優先順位を設定する
- ハンドラーごとの自動認証を構成する
注意
ほとんどのユース ケースでは、汎用ハンドラー パターンで十分です。 高度なルーティングや、同じ通知タイプに対して複数のハンドラーが必要な場合に、これらの専用ハンドラーを使用します。
すべての通知に特化されたハンドラー
すべての種類の通知を処理するハンドラーをさらに登録します。
from microsoft_agents_a365.notifications import (
AgentNotification,
NotificationTypes
)
from microsoft_agents.activity import ChannelId
# Create notification handler
agent_notification = AgentNotification(app)
# Register handler for all notifications
@agent_notification.on_agent_notification(
ChannelId(channel="agents", sub_channel="*")
)
async def handle_all_notifications(context, state, notification):
if notification.notification_type == NotificationTypes.EMAIL_NOTIFICATION:
if notification.email_notification:
await context.send_activity(f"Received email: {notification.email_notification.id}")
elif notification.notification_type == NotificationTypes.WPX_COMMENT:
if notification.wpx_comment_notification:
await context.send_activity(f"Received comment: {notification.wpx_comment_notification.comment_id}")
import '@microsoft/agents-a365-notifications';
// Register handler for all notifications
app.onAgentNotification('*', async (context, state, notification) => {
const { notificationType, emailNotification, wpxCommentNotification } = notification;
switch (notificationType) {
case NotificationType.EmailNotification:
if (emailNotification) {
console.log('Email ID:', emailNotification.id);
await context.sendActivity('Processing your email...');
}
break;
case NotificationType.WpxComment:
if (wpxCommentNotification) {
console.log('Comment ID:', wpxCommentNotification.commentId);
await context.sendActivity('Responding to your comment...');
}
break;
}
});
using Microsoft.Agents.A365.Notifications;
using Microsoft.Agents.A365.Notifications.Extensions;
using Microsoft.Agents.A365.Notifications.Models;
// Register handler for all notifications (wildcard)
this.OnAgentNotification(
"*",
AgentNotificationActivityAsync
);
private async Task AgentNotificationActivityAsync(
ITurnContext turnContext,
ITurnState turnState,
AgentNotificationActivity activity,
CancellationToken cancellationToken)
{
switch (activity.NotificationType)
{
case NotificationTypeEnum.EmailNotification:
var email = activity.EmailNotification;
if (email != null)
{
await turnContext.SendActivityAsync(
$"Received email: {email.Id}",
cancellationToken: cancellationToken
);
}
break;
case NotificationTypeEnum.WpxComment:
var comment = activity.WpxCommentNotification;
if (comment != null)
{
await turnContext.SendActivityAsync(
$"Received comment: {comment.CommentId}",
cancellationToken: cancellationToken
);
}
break;
}
}
メールの通知に特化されたハンドラー
メール通知用にさらに多くのハンドラを登録します:
from microsoft_agents_a365.notifications import AgentNotification
from microsoft_agents.activity import ChannelId, AgentSubChannel
# Create notification handler
agent_notification = AgentNotification(app)
# Use the convenience method for email notifications
@agent_notification.on_email()
async def handle_email(context, state, notification):
email = notification.email_notification
if not email:
await context.send_activity('No email found')
return
# Process the email
email_id = email.id
conversation_id = email.conversation_id
# Send response
await context.send_activity('Thank you for your email!')
app.onAgenticEmailNotification(async (context, state, notification) => {
const email = notification.emailNotification;
if (!email) {
await context.sendActivity('No email found');
return;
}
// Process the email
console.log('Email ID:', email.id);
console.log('Conversation ID:', email.conversationId);
// Send a response
await context.sendActivity('Thank you for your email!');
});
// Register handler for email notifications
this.OnAgenticEmailNotification(HandleEmailNotificationAsync);
private async Task HandleEmailNotificationAsync(
ITurnContext turnContext,
ITurnState turnState,
AgentNotificationActivity activity,
CancellationToken cancellationToken)
{
var email = activity.EmailNotification;
if (email == null)
{
await turnContext.SendActivityAsync("No email found",
cancellationToken: cancellationToken);
return;
}
// Process email
var emailId = email.Id;
var conversationId = email.ConversationId;
// Send response
await turnContext.SendActivityAsync(
"Thank you for your email!",
cancellationToken: cancellationToken
);
}
Word、Excel、PowerPoint のコメント通知用に、より多くのハンドラーを登録します:
from microsoft_agents_a365.notifications import AgentNotification
# Create notification handler
agent_notification = AgentNotification(app)
# Use convenience methods for document notifications
@agent_notification.on_word()
async def handle_word(context, state, notification):
comment = notification.wpx_comment_notification
if comment:
document_id = comment.document_id
comment_id = comment.comment_id
await context.send_activity(f'Processing Word comment: {comment_id}')
@agent_notification.on_excel()
async def handle_excel(context, state, notification):
comment = notification.wpx_comment_notification
if comment:
await context.send_activity('Processing Excel comment')
@agent_notification.on_powerpoint()
async def handle_powerpoint(context, state, notification):
comment = notification.wpx_comment_notification
if comment:
await context.send_activity('Processing PowerPoint comment')
// Handle Word notifications
app.onAgenticWordNotification(async (context, state, notification) => {
const comment = notification.wpxCommentNotification;
if (comment) {
console.log('Word comment:', comment.commentText);
await context.sendActivity('Processing your Word comment...');
}
});
// Handle Excel notifications
app.onAgenticExcelNotification(async (context, state, notification) => {
const comment = notification.wpxCommentNotification;
if (comment) {
await context.sendActivity('Processing your Excel comment...');
}
});
// Handle PowerPoint notifications
app.onAgenticPowerPointNotification(async (context, state, notification) => {
const comment = notification.wpxCommentNotification;
if (comment) {
await context.sendActivity('Processing your PowerPoint comment...');
}
});
// Register handlers for document notifications
this.OnAgenticWordNotification(HandleWordNotificationAsync);
this.OnAgenticExcelNotification(HandleExcelNotificationAsync);
this.OnAgenticPowerPointNotification(HandlePowerPointNotificationAsync);
private async Task HandleWordNotificationAsync(
ITurnContext turnContext,
ITurnState turnState,
AgentNotificationActivity activity,
CancellationToken cancellationToken)
{
var comment = activity.WpxCommentNotification;
if (comment != null)
{
await turnContext.SendActivityAsync(
$"Processing Word comment: {comment.CommentText}",
cancellationToken: cancellationToken
);
}
}
private async Task HandleExcelNotificationAsync(
ITurnContext turnContext,
ITurnState turnState,
AgentNotificationActivity activity,
CancellationToken cancellationToken)
{
var comment = activity.WpxCommentNotification;
if (comment != null)
{
await turnContext.SendActivityAsync(
"Processing Excel comment",
cancellationToken: cancellationToken
);
}
}
private async Task HandlePowerPointNotificationAsync(
ITurnContext turnContext,
ITurnState turnState,
AgentNotificationActivity activity,
CancellationToken cancellationToken)
{
var comment = activity.WpxCommentNotification;
if (comment != null)
{
await turnContext.SendActivityAsync(
"Processing PowerPoint comment",
cancellationToken: cancellationToken
);
}
}
ライフサイクル イベント用の特殊なハンドラー
ユーザー ID の作成、ワークロードのオンボード、ユーザーの削除など、エージェント ライフサイクル イベントのハンドラーをさらに登録します。
from microsoft_agents_a365.notifications import AgentNotification
# Create notification handler
agent_notification = AgentNotification(app)
# Handle all lifecycle events
@agent_notification.on_agent_lifecycle_notification("*")
async def handle_lifecycle(context, state, notification):
lifecycle_notification = notification.agent_lifecycle_notification
if lifecycle_notification:
event_type = lifecycle_notification.lifecycle_event_type
if event_type == "agenticUserIdentityCreated":
await context.send_activity('User identity created')
elif event_type == "agenticUserWorkloadOnboardingUpdated":
await context.send_activity('Workload onboarding completed')
elif event_type == "agenticUserDeleted":
await context.send_activity('User identity deleted')
// Handle all lifecycle notifications
app.onLifecycleNotification(async (context, state, notification) => {
await context.sendActivity('Lifecycle event received');
});
// Handle specific lifecycle events
app.onAgenticUserCreatedNotification(async (context, state, notification) => {
await context.sendActivity('User identity created');
});
app.onAgenticUserWorkloadOnboardingNotification(
async (context, state, notification) => {
await context.sendActivity('Workload onboarding completed');
}
);
app.onAgenticUserIdentityDeletedNotification(
async (context, state, notification) => {
await context.sendActivity('User identity deleted');
}
);
// Register lifecycle notification handlers
this.OnLifecycleNotification(HandleAllLifecycleEventsAsync);
this.OnAgenticUserIdentityCreatedNotification(HandleUserCreatedAsync);
this.OnAgenticUserWorkloadOnboardingNotification(HandleWorkloadOnboardingAsync);
this.OnAgenticUserDeletedNotification(HandleUserDeletedAsync);
private async Task HandleAllLifecycleEventsAsync(
ITurnContext turnContext,
ITurnState turnState,
AgentNotificationActivity activity,
CancellationToken cancellationToken)
{
await turnContext.SendActivityAsync(
"Lifecycle event received",
cancellationToken: cancellationToken
);
}
private async Task HandleUserCreatedAsync(
ITurnContext turnContext,
ITurnState turnState,
AgentNotificationActivity activity,
CancellationToken cancellationToken)
{
await turnContext.SendActivityAsync(
"User identity created",
cancellationToken: cancellationToken
);
}
private async Task HandleWorkloadOnboardingAsync(
ITurnContext turnContext,
ITurnState turnState,
AgentNotificationActivity activity,
CancellationToken cancellationToken)
{
await turnContext.SendActivityAsync(
"Workload onboarding completed",
cancellationToken: cancellationToken
);
}
private async Task HandleUserDeletedAsync(
ITurnContext turnContext,
ITurnState turnState,
AgentNotificationActivity activity,
CancellationToken cancellationToken)
{
await turnContext.SendActivityAsync(
"User identity deleted",
cancellationToken: cancellationToken
);
}
高度な構成
このセクションでは、通知ハンドラーを微調整する高度な構成オプションについて説明します。 これらの構成により、ハンドラーの実行順序の制御、認証要件の管理、複雑なシナリオにおける通知処理を最適化できます。
ハンドラーの優先順位とランク付け
複数の専用ハンドラを使用する場合、ランク値を使用して優先順位を指定できます。 ランク値が低いほど、優先度が高いことを示します。
from microsoft_agents_a365.notifications import AgentNotification
from microsoft_agents.activity import ChannelId, AgentSubChannel
# Create notification handler
agent_notification = AgentNotification(app)
# Higher priority handler (processed first)
@agent_notification.on_email(rank=100)
async def high_priority_email(context, state, notification):
# Handle with high priority
pass
# Lower priority handler (processed after higher priority)
@agent_notification.on_email(rank=200)
async def low_priority_email(context, state, notification):
# Handle with lower priority
pass
// Higher priority handler (lower rank number)
app.onAgenticEmailNotification(
async (context, state, notification) => {
// Handle email with high priority
},
100 // rank
);
// Lower priority handler
app.onAgenticEmailNotification(
async (context, state, notification) => {
// Handle email with lower priority
},
200 // rank
);
// Higher priority handler (lower rank number)
this.OnAgenticEmailNotification(
HighPriorityEmailHandlerAsync,
rank: 100
);
// Lower priority handler
this.OnAgenticEmailNotification(
LowerPriorityEmailHandlerAsync,
rank: 200
);
認証ハンドラー
認証が必要な通知に対して自動サインイン ハンドラーを構成する:
from microsoft_agents_a365.notifications import AgentNotification
from microsoft_agents.activity import ChannelId, AgentSubChannel
# Create notification handler
agent_notification = AgentNotification(app)
# Handler with automatic authentication
@agent_notification.on_email(auto_sign_in_handlers=['agentic'])
async def authenticated_email(context, state, notification):
# Authentication is handled automatically
pass
app.onAgenticEmailNotification(
async (context, state, notification) => {
// Handler with automatic authentication
},
32767, // rank (default)
['agentic'] // autoSignInHandlers
);
this.OnAgenticEmailNotification(
HandleAuthenticatedEmailAsync,
rank: 32767,
autoSignInHandlers: new[] { "agentic" }
);
テストと監視
通知でエージェントをテストする
通知ハンドラーを実装した後は、テストを実施してエージェントが異なる通知タイプを正しく受信し処理できることを確認してください。
テスト ガイドに従って環境を設定し、その後通知アクティビティを使用したテストセクションに焦点を当て、エージェント認証を使用して通知を検証します。
通知処理の監視
監視機能を追加することで、エージェントの通知処理を監視します。 通知処理、応答時間、エラー率を追跡し、エージェントのパフォーマンスを把握します。
トレースと監視の実装の詳細