중요
Microsoft 에이전트 365에 대한 초기 액세스를 얻으려면 프론티어 미리 보기 프로그램의 일부여야 합니다. 프론티어는 Microsoft의 최신 AI 혁신과 직접 연결합니다. 프론티어 미리 보기에는 고객 계약의 기존 미리 보기 조건이 적용됩니다. 이러한 기능은 아직 개발 중이므로 가용성 및 기능은 시간이 지남에 따라 변경 될 수 있습니다.
알림 모듈을 사용하면 개발자가 Microsoft 365 애플리케이션의 이벤트 및 알림에 응답할 수 있는 에이전트를 빌드할 수 있습니다. 알림 지원을 통해 에이전트는 사용자가 이메일, 문서 주석 또는 기타 공동 작업 시나리오를 통해 상호 작용할 때 경고를 수신하고 처리할 수 있습니다.
알림 워크플로
이 워크플로에 따라 AI 에이전트 애플리케이션에 대한 알림을 사용하도록 설정합니다.
알림 패키지를 설치합니다.
알림 구성 요소 가져오기
- 알림 클래스 및 처리기 가져오기
- 활동 유형 및 채널 식별자 가져오기
알림 처리기 등록
- 알림 처리기 메서드를 사용하여 경로 등록
- 특정 알림 유형에 대한 처리기 구성(예: 전자 메일, Word, Excel, PowerPoint)
에이전트 코드에서 알림 처리
- 에이전트가 Microsoft 365 애플리케이션에서 알림을 받습니다.
- 들어오는 알림을 처리하고 적절하게 응답
알림 유형
는 다음 알림 유형을 지원합니다.
| 알림 형식 |
설명 |
하위 채널 ID |
|
Email |
에이전트가 언급되거나 주소가 지정된 전자 메일을 받습니다. |
email |
|
단어 |
Word 문서의 메모에 에이전트가 언급되어 있습니다. |
word |
|
Excel |
Excel 문서의 메모에 에이전트가 언급되어 있습니다. |
excel |
| 및 PowerPoint |
PowerPoint 문서의 메모에 에이전트가 언급됨 |
powerpoint |
| 수명 주기 이벤트 |
에이전트 수명 주기 알림(사용자 ID 생성, 워크로드 온보딩, 사용자 삭제) |
사용 불가 |
에이전트 수명 주기 이벤트
에이전트 수명 주기 이벤트를 사용하면 에이전트가 에이전트 사용자 ID 관리와 관련된 특정 시스템 이벤트에 응답할 수 있습니다. SDK는 현재 세 가지 수명 주기 이벤트를 지원합니다.
| 이벤트 유형 |
이벤트 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: 강력한 형식의 알림 데이터를 사용하여 알림 활동을 구문 분석합니다. 알림 관련 메타데이터(
wpxCommentNotificationID, 대화 세부 정보, 문서 참조)와 같은 emailNotification 속성 포함
-
NotificationType: 알림 유형 열거형(
Unknown, , EmailNotificationWpxComment, 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: 강력한 형식의 알림 데이터로 활동을 래핑합니다. 알림 관련 메타데이터(
WpxCommentNotificationID, 대화 세부 정보, 문서 참조)와 같은 EmailNotification 속성 포함
-
NotificationTypeEnum: 지원되는 알림 유형 열거형(
Unknown, , WpxCommentEmailNotification, 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" }
);
테스트 및 모니터
알림을 사용하여 에이전트 테스트
알림 처리기를 구현한 후 에이전트를 테스트하여 다른 알림 유형을 올바르게 수신하고 처리하는지 확인합니다. 테스트 가이드에 따라 환경을 설정한 다음, 주로 알림 작업으로 테스트 섹션에 집중하여 에이전트 인증을 사용하여 알림의 유효성을 검사합니다.
알림 처리 모니터링
관찰 기능을 추가하여 에이전트의 알림 처리를 모니터링합니다. 알림 처리, 응답 시간 및 오류 비율을 추적하여 에이전트 성능을 이해합니다.
추적 및 모니터링 구현에 대해 자세히 알아보기