次の方法で共有


カスタム エンジン エージェントに非同期メッセージングとプロアクティブ メッセージングを実装する

この記事では、Microsoft Bot Frameworkを使用してビルドするカスタム エンジン エージェントに非同期およびプロアクティブ メッセージング パターンを実装する方法について説明します。 これらのパターンを使用すると、エージェントは遅延後、またはユーザーが開始したメッセージなしでユーザーに応答できます。

非同期メッセージングとプロアクティブ メッセージングを使用して、カスタム エンジン エージェントで次のことができます。

  • バックグラウンド処理を続行しながら、遅延後に応答します。
  • ユーザー入力なしでメッセージを開始します (システムによってトリガーされる更新プログラムなど)。

各ユーザー クエリは、15 秒以内に最初の応答を受け取る必要があります。 実行時間の長いタスクの場合、エージェントはフォローアップ メッセージを送信できます。 ストリーミング更新の間に 45 秒のタイムアウトが適用されます。

非同期メッセージ

非同期メッセージは、エージェントがユーザーによって開始されたバックグラウンド タスクを完了した後に送信されます。 このパターンは、注文の追跡や状態の更新などのシナリオに役立ちます。

たとえば、ユーザーがノート PC を注文した場合、エージェントは要求を確認し、注文が行われたときに後でフォローアップ メッセージをユーザーに送信できます。 次の例は、 Bot Framework を使用してノート PC の注文に関する非同期メッセージを送信する方法を示しています。

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);
      });
    }
  );

次の表は、非同期メッセージ プロセスをまとめたものです。

タスク 説明
✅ 初期確認 要求を確認するメッセージを送信します。
✅ バックグラウンド処理 タスクを非同期的に実行します。
✅ フォローアップ メッセージ タスクが完了したら、ユーザーに通知します。

プロアクティブ メッセージ

プロアクティブ メッセージは、ユーザーではなくシステムによって開始されます。 これらのメッセージは、専用の会話スレッドを介して送信されます。

たとえば、エージェントは、イベントに関する通知をユーザーに送信したり、ユーザー クエリなしで更新したりできます。 次の例は、 createConversation API を使用して会話情報をフェッチし、専用スレッド経由でプロアクティブ メッセージを送信する方法を示しています。

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),
      }
    );

次の表は、プロアクティブ メッセージ プロセスをまとめたものです。

タスク 説明
✅ トークンの取得 OAuth2 を使用して認証します。
✅ 会話を作成する Bot Framework API を使用して会話を開始します。
✅ メッセージの送信 メッセージを会話に投稿します。