通过


处理消息

重要

需要成为 Frontier 预览计划的一部分,才能获得 抢先体验Microsoft Agent 365。 Frontier将你直接连接到Microsoft最新的人工智能创新。 Frontier 预览版受客户协议中现有预览条款的约束。 由于这些功能仍在开发中,其可用性和功能可能会随时间而变化。

通过使用代理 365 SDK,代理可以处理平台活动事件,例如安装和卸载,并在单个轮次内发送多个离散消息。 本文介绍在代理处理请求时响应用户并确保用户知情的关键模式。

处理代理安装和卸载事件

当用户在 Teams 或其他代理 365 托管频道中安装或卸载代理时,平台会发送活动 InstallationUpdate (也称为 agentInstanceCreated 事件)。 代理可以处理这些事件,以在安装时发送欢迎消息,并在卸载时发送告别消息。

Action 说明
add 用户安装代理
remove 用户卸载代理

与通知处理程序不同,处理程序 InstallationUpdate 不需要身份验证,因为安装或卸载事件在用户具有活动会话之前或之后触发。

注册安装和卸载处理程序

在代理的初始化中为 InstallationUpdate 活动类型注册活动处理程序:

@agent_app.activity("installationUpdate")
async def on_installation_update(context: TurnContext, state: TurnState):
    action = context.activity.action
    from_prop = context.activity.from_property
    logger.info(
        "InstallationUpdate received — Action: '%s', DisplayName: '%s', UserId: '%s'",
        action or "(none)",
        getattr(from_prop, "name", "(unknown)") if from_prop else "(unknown)",
        getattr(from_prop, "id", "(unknown)") if from_prop else "(unknown)",
    )
    if action == "add":
        await context.send_activity("Thank you for hiring me! Looking forward to assisting you in your professional journey!")
    elif action == "remove":
        await context.send_activity("Thank you for your time, I enjoyed working with you.")

Activity.action 是在安装代理或"add"卸载代理时设置为"remove"的字符串。 Activity.from_property 是包含用户标识的 ChannelAccount 实例。

发送多条消息

代理 365 代理可以发送多个离散消息,以响应单个用户提示。 为此,请多次在单个轮次内调用 SendActivityAsync (.NET)、 send_activity (Python)或 sendActivity (JavaScript)。

重要

Teams 不支持代理标识的流式处理响应。 SDK 将检测代理标识并将流缓冲到单个消息中。 使用 SendActivityAsyncsend_activitysendActivity 直接向用户发送即时离散消息。

以下示例演示了在 LLM 响应之前发送即时确认的模式:

@agent_app.activity("message")
async def on_message(context: TurnContext, state: TurnState):
    # Message 1: immediate ack — reaches the user right away
    await context.send_activity("Got it — working on it…")

    # ... LLM processing ...

    # Message 2: the LLM response
    await context.send_activity(response)

此示例通过在 LLM 响应之前发送即时确认来演示 (on_message) 中的此模式。

每次调用sendActivitysend_activitySendActivityAsync时,都会创建一条单独的消息。 可以根据需要多次调用它来发送进度更新、部分结果或最终答案。

正在输入指示

输入指示器在 Teams 中显示 ... 进度动画:

  • 它们有一个大约 5 秒的内置视觉超时,并且必须在一个循环中每隔 4 秒刷新一次。
  • 它们仅在一对一聊天和小组聊天中可见,不在频道中。

代理每隔四秒循环发送键入指示器,以维持 ... 动画的活动状态,同时 LLM 处理请求。

# Message 1: immediate ack — reaches the user right away
await context.send_activity("Got it — working on it…")

# Send typing indicator immediately (awaited so it arrives before the LLM call starts).
await context.send_activity(Activity(type="typing"))

# Background loop refreshes the "..." animation every ~4s (it times out after ~5s).
async def _typing_loop():
    try:
        while True:
            await asyncio.sleep(4)
            await context.send_activity(Activity(type="typing"))
    except asyncio.CancelledError:
        pass  # Expected on cancel.

typing_task = asyncio.create_task(_typing_loop())
try:
    response = await agent.process_user_message(...)
    await context.send_activity(response)
finally:
    typing_task.cancel()
    try:
        await typing_task
    except asyncio.CancelledError:
        pass