Implementar mensajería asincrónica y proactiva en agentes de motor personalizados

En este artículo se describe cómo implementar patrones de mensajería asincrónica y proactiva en agentes de motor personalizados que se compilan con Microsoft Bot Framework. Estos patrones permiten a los agentes responder a los usuarios después de un retraso o sin un mensaje iniciado por el usuario.

Puede usar mensajería asíncrona y proactiva para permitir que los agentes de motor personalizados:

  • Responda después de un retraso mientras continúa con el procesamiento en segundo plano.
  • Iniciar mensajes sin la intervención del usuario (por ejemplo, actualizaciones desencadenadas por el sistema).

Cada consulta de usuario debe recibir una respuesta inicial en un plazo de 15 segundos. Para tareas de larga ejecución, los agentes pueden enviar mensajes de seguimiento. Se aplica un tiempo de espera de 45 segundos entre actualizaciones de streaming.

Mensajes asíncronos

Los mensajes asincrónicos se envían después de que el agente completa una tarea en segundo plano iniciada por el usuario. Este patrón es útil para escenarios como el seguimiento de pedidos o las actualizaciones de estado.

Por ejemplo, si un usuario pide un portátil, el agente puede confirmar la solicitud y enviar más tarde un mensaje de seguimiento al usuario cuando se realice el pedido. En el ejemplo siguiente se muestra cómo usar Bot Framework para enviar un mensaje asincrónico con respecto al pedido del portátil.

app.message(

    CustomMessageTypes.orderLaptopSelected.toString(),
    async (context: TurnContext, _state) => {
      return new Promise(async (resolve) => {
        await context.sendActivity({
          text: "Thank you for order laptop. I will keep you posted with updates.",
        });

        setTimeout(async () => {
          await context.sendActivity({
            text: "Great! I have successfully placed your order #1292. I'll notify you when it's delivered.",
            attachments: [
              {
                contentType: "application/vnd.microsoft.card.adaptive",
                content: deliveredCard,
              },
            ],
          });
          resolve();
        }, 10 * 1000);
      });
    }
  );

En la tabla siguiente se resume el proceso de mensajes asíncronos.

Tarea Descripción
✅ Confirmación inicial Enviar un mensaje para confirmar la solicitud.
✅ Procesamiento en segundo plano Realice la tarea de forma asincrónica.
✅ Mensaje de seguimiento Notifique al usuario cuando se complete la tarea.

Mensajes proactivos

Los mensajes proactivos los inicia el sistema, no el usuario. Estos mensajes se envían a través de una conversación dedicada.

Por ejemplo, el agente puede enviar una notificación a un usuario sobre un evento o una actualización sin una consulta de usuario. En el ejemplo siguiente se muestra cómo usar la API createConversation para capturar la información de la conversación y enviar mensajes proactivos a través de un subproceso dedicado.

export async function getToken() {
  const url =
    "https://login.microsoftonline.com/botframework.com/oauth2/v2.0/token";
  const params = new URLSearchParams();
  params.append("grant_type", "client_credentials");
  params.append("client_id", config.MicrosoftAppId);
  params.append("client_secret", config.MicrosoftAppPassword);
  params.append("scope", "https://api.botframework.com/.default");

  const response = await fetch(url, {
    method: "POST",
    headers: {
      "Content-Type": "application/x-www-form-urlencoded",
    },
    body: params.toString(),
  });

  if (!response.ok) {
    throw new Error(`Error! status: ${response.status}`);
  }

  const data = await response.json();
  return data;
}

  let accessToken;
    try {
      accessToken = getToken();
      if (!accessToken) {
        console.log("No access token found, fetching a new one");
        const tokenResponse = await getToken();
        accessToken = tokenResponse.access_token;
        if (!accessToken) {
          throw new Error("Failed to obtain access token");
        }
        setAccessToken(accessToken);
      }
    } catch (error) {
      console.error("Error retrieving access token:", error);
      await context.sendActivity(
        "Failed to send proactive message due to authentication error"
      );
      return;
    }

    const createConversationBody = {
      members: [{ id: context.activity.from.aadObjectId }],
      tenantId: context.activity.conversation.tenantId,
      channelData: {
        productContext: "Copilot",
        conversation: {
          conversationSubType: "AgentProactive",
        },
      },
    };

    const createConversationResponse = await fetch(
      "https://canary.botapi.skype.com/teams/v3/conversations",
      {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${accessToken}`,
        },
        body: JSON.stringify(createConversationBody),
      }
    );

    const createConversationResponseData =
      await createConversationResponse.json();
    console.log("Create conversation response", createConversationResponseData);
    const body = {
      text: "Hello proactive world",
      type: "message",
    };

    const response = await fetch(
      `https://canary.botapi.skype.com/teams/v3/conversations/${createConversationResponseData.id}/activities`,
      {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${accessToken}`,
        },
        body: JSON.stringify(body),
      }
    );

En la tabla siguiente se resume el proceso de mensajes proactivos.

Tarea Descripción
✅ Adquirir token Use OAuth2 para autenticarse.
✅ Crear conversación Use la API de Bot Framework para iniciar una conversación.
✅ Enviar mensaje Publicar un mensaje en la conversación.