메시지 처리

Agent 365 SDK를 사용하여, 에이전트는 설치 및 제거와 같은 플랫폼 활동 이벤트를 처리하고 한 턴 내에 여러 개의 개별 메시지를 보낼 수 있습니다. 이 문서에서는 에이전트가 요청을 처리하는 동안 사용자에게 답변하고 정보를 제공하는 주요 패턴을 설명합니다.

에이전트 설치 및 제거 이벤트 처리

사용자가 Teams 또는 기타 Agent 365가 호스팅하는 채널에서 에이전트를 설치하거나 제거하면, 플랫폼은 InstallationUpdate 활동(또는 agentInstanceCreated 이벤트라고도 함)을 전송합니다. 에이전트는 설치 시 환영 메시지, 제거 시 작별 메시지를 보내도록 이러한 이벤트를 처리할 수 있습니다.

액션 설명
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 인스턴스입니다.

여러 개의 개별 메시지를 보내세요

Agent 365 에이전트는 단일 사용자 프롬프트에 응답하여 여러 개의 개별 메시지를 보낼 수 있습니다. 이를 위해 한 턴 내에서 SendActivityAsync (.NET), send_activity (Python), 또는 sendActivity (JavaScript)를 여러 번 호출하세요.

중요

Teams는 에이전트 정체성에 대한 스트리밍 응답을 지원하지 않습니다. SDK는 에이전트 정체성(agentic identity)을 감지하고 스트림을 단일 메시지로 버퍼링합니다. SendActivityAsync, send_activity, 및 sendActivity를 직접 사용하여 사용자에게 즉각적이고 개별적인 메시지를 보내십시오.

다음 예시들은 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)

샘플은 on_message (host_agent_server.py)에서 LLM 응답 전에 즉시 확인 메시지를 보내는 패턴을 보여줍니다.

sendActivity, send_activitySendActivityAsync를 각각 호출할 때마다 별도의 메시지가 생성됩니다. 진행 상황 업데이트, 부분 결과, 또는 최종 답변을 보내기 위해 필요한 만큼 호출할 수 있습니다.

입력 표시기

타이핑 인디케이터는 Teams에서 ... 진행 애니메이션을 보여줍니다:

  • 약 5초의 시각적 타임아웃이 내장되어 있고, 4초마다 반복해서 새로고침해야 합니다.
  • 이들은 1:1 채팅과 소규모 그룹 채팅에서만 볼 수 있으며, 채널에서는 보이지 않습니다.

에이전트는 LLM이 요청을 처리하는 동안 ... 애니메이션을 유지하기 위해 4초마다 반복 타이핑 표시를 보냅니다:

# 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