ラボ BTA3 - ユーザー エクスペリエンスの向上
このラボでは Powered by AI、つまり Teams AI ライブラリが提供する一連の機能について学び、それらをカスタム エンジン エージェントに組み込んでユーザー エクスペリエンスを向上させます。
このラボで行うこと:
- Powered by AI 機能について学習する
 - Feedback Loop を有効化してユーザー フィードバックを収集する
 - Adaptive Cards で引用をカスタマイズする
 - Generated by AI ラベルを有効化する
 - Sensitivity ラベルを有効化する
 
Azure OpenAI と Teams AI library を使用してカスタム AI モデルとオーケストレーションを備えた Custom エンジン エージェントを構築したい場合は、これらの ラボ を実施してください
はじめに
Powered by AI とは?
Powered by AI とは、Teams AI ライブラリが提供する機能群で、カスタム エンジン エージェントとの対話をより魅力的かつユーザー フレンドリーにします。主な機能は次のとおりです。
- 
Feedback Loop: ユーザーは AI 応答に対してサムズアップまたはサムズダウンで評価できます。このフィードバックは AI の精度と有用性を継続的に向上させます。
 - 
Citations: AI が情報源を参照として提示し、透明性と信頼性を確保します。
 - 
Generated by AI: AI システムが生成したメッセージに「AI generated」ラベルが表示され、ユーザーは AI と人間による応答を区別できます。
 - 
Sensitivity Information: 共有する情報が機密性を含む場合、感度ラベルが表示され、組織外に共有可能かどうかを示します。
 
前の演習では Retrieval-Augmented Generation (RAG) とそのカスタム エンジン エージェントへの統合を学習しました。本演習では Powered by AI 機能を活用してユーザー エクスペリエンスをさらに高めます。実施内容:
- Feedback Loop の実装
 - 引用のカスタマイズ
 - AI 生成メッセージのラベル付け
 - Sensitivity 情報の表示
 
Powered by AI 機能を組み込むことで、カスタム エンジン エージェントをより透明性が高く、信頼性があり、ユーザー フレンドリーにできます。
Exercise 1: Feedback Loop を有効化する
この演習では、前のラボで作成したソース コードをそのまま利用します。
Step 1: アプリに Feedback Loop を統合する
プロジェクトの src/app/app.ts を開き、アプリケーション インスタンスを見つけて ai プロパティの中に enable_feedback_loop: true を追加します。更新後のアプリケーション インスタンスは次のようになります。
const app = new Application({
  storage,
  ai: {
    planner,
    //feedback loop is enabled
    enable_feedback_loop: true
  },
});
フィードバック応答を処理するために、src/app/app.ts に次のコード スニペットを追加します。
app.feedbackLoop(async (_context, _state, feedbackLoopData) => {
  if (feedbackLoopData.actionValue.reaction === 'like') {
      console.log('👍' + ' ' + feedbackLoopData.actionValue.feedback!);
  } else {
      console.log('👎' + ' ' + feedbackLoopData.actionValue.feedback!);
  }
});
Step 2: Feedback Loop 機能をテストする
Feedback Loop 機能を備えた Career Genie をテストしてみましょう。Visual Studio Code の Run and Debug タブから Debug in Teams (Edge) または Debug in Teams (Chrome) を選択しデバッグを開始します。ブラウザーで Microsoft Teams が開き、アプリの詳細が表示されたら Add を選択してチャットを開始します。
Tip: この演習をローカルでテストする
これまでアプリに実装したいくつかの Teams AI ライブラリ機能は Teams App Test Tool では動作が完全でない場合があります。必ず Teams でローカル デバッグしてください。
Feedback Loop を確認するには、まず「Hi」や「Suggest me .NET developers who can speak Spanish.」のように入力します。カスタム エンジン エージェントの応答の左下にサムズアップ/ダウンのボタンが表示されるはずです。
![]()
次に Feedback Loop をテストしてみましょう。サムズアップまたはサムズダウンをクリックすると、フィードバック カードが表示されます。テキスト フィールドにフィードバックを入力し Submit をクリックします。

フィードバックが記録されたか確認するには、Visual Studio Code に戻りターミナルを確認します。サムズアップ/ダウンの結果とコメントが表示されているはずです。

デバッグで Feedback Loop を深掘り
コードをデバッグして動作を理解しましょう。app.feedbackLoop にブレークポイントを設定し、サムズアップ/ダウンをクリックして実行すると、feedbackLoopData.actionValue.reaction にリアクションが、feedbackLoopData.actionValue.feedback にテキスト フィードバックが格納されていることが分かります。
Exercise 2: Adaptive Cards で引用をカスタマイズする
カスタム エンジン エージェントでデータ ソースを定義すると、Teams AI ライブラリは関連ドキュメントを参照する引用を自動で有効にします。現在のエクスペリエンスを確認するために、「Suggest me .NET developers who can speak Spanish.」のように質問してみてください。引用マークにカーソルを合わせるとドキュメントの冒頭が表示されます。

この演習では、この引用エクスペリエンスをさらにカスタマイズし、Adaptive Cards を用いて引用の表示方法を変更します。
Step 1: 引用用の Adaptive Card を作成する
src/app/ フォルダーに card.ts という新しいファイルを作成し、次のコード スニペットを追加します。
import { AdaptiveCard, Message, Utilities } from '@microsoft/teams-ai';
/**
 * Create an adaptive card from a prompt response.
 * @param {Message<string>} response The prompt response to create the card from.
 * @returns {AdaptiveCard} The response card.
 */
//Adaptive card to display the response and citations
export function createResponseCard(response: Message<string>): AdaptiveCard {
    const citationCards = response.context?.citations.map((citation, i) => ({
            type: 'Action.ShowCard',
            title: `${i+1}`,
            card: {
                type: 'AdaptiveCard',
                body: [
                    {
                        type: 'TextBlock',
                        text: citation.title,
                        fontType: 'Default',
                        weight: 'Bolder'
                    },
                    {
                        type: 'TextBlock',
                        text: citation.content,
                        wrap: true
                    }
                ]
            }
        }));
    const text = Utilities.formatCitationsResponse(response.content!);
    return {
        type: 'AdaptiveCard',
        body: [
            {
                type: 'TextBlock',
                text: text,
                wrap: true
            },
            {
                type: 'TextBlock',
                text: 'Citations',
                wrap: true,
                fontType: 'Default',
                weight: 'Bolder'
            },
            {
                type: 'ActionSet',
                actions: citationCards
            }
        ],
        $schema: 'http://adaptivecards.io/schemas/adaptive-card.json',
        version: '1.5'
    };
}
この Adaptive Card は Action.ShowCard ボタンとして引用を一覧表示し、クリックすると詳細を表示します。また、引用ボタンとともに応答のメイン コンテンツを表示します。ユーザーが詳細を確認したい場合は、ボタンをクリックして全文を閲覧できます。
Step 2: PredictedSayCommand で引用エクスペリエンスをカスタマイズする
PredictedSayCommand とは?
PredictedSayCommand は AI システムが実行する応答ディレクティブです。PredictedSayCommand をカスタマイズすることで、引用や Feedback Loop など Powered by AI 機能をエージェントのアクティビティへ細かく統合でき、AI 応答をアプリ要件に合わせて調整できます。
src/app/app.ts を開き、先ほど作成した Adaptive Card をインポートするために次のスニペットをコード冒頭に追加します。
import { createResponseCard } from './card';
botbuilder のインポートに CardFactory を追加し、更新後は次のようになります。
import { CardFactory, MemoryStorage, MessageFactory, TurnContext } from "botbuilder";
"@microsoft/teams-ai" のインポートに AI と PredictedSayCommand を追加し、更新後は次のようになります。
import { Application, ActionPlanner, OpenAIModel, PromptManager, AI, PredictedSayCommand} from "@microsoft/teams-ai";
引用をカスタマイズするために src/app/app.ts に次の PredictedSayCommand アクションを追加します。
app.ai.action<PredictedSayCommand>(AI.SayCommandActionName, async (context, state, data, action) => {
  let activity;
  if (data.response.context && data.response.context.citations.length > 0 ) {
      const attachment = CardFactory.adaptiveCard(createResponseCard(data.response));
      activity = MessageFactory.attachment(attachment);
  }
  else {
      activity = MessageFactory.text(data.response.content);
  }
  activity.entities = [
    {
        type: "https://schema.org/Message",
        "@type": "Message",
        "@context": "https://schema.org",
        "@id": ""
    }
  ];
  activity.channelData = {
    feedbackLoopEnabled: true
  };
  await context.sendActivity(activity);
  return "success";
});
Step 3: カスタマイズした引用エクスペリエンスをテストする
カスタマイズした引用エクスペリエンスを備えた Career Genie をテストしましょう。Visual Studio Code の Run and Debug タブから Debug in Teams (Edge) または Debug in Teams (Chrome) を選択します。ブラウザーで Microsoft Teams が開いたら、アプリの詳細で Add を選択してチャットを開始します。
Tip: この演習をローカルでテストする
これまでアプリに実装した Teams AI ライブラリの機能は Teams App Test Tool では完全に動作しない場合があります。必ず Teams でローカル デバッグしてください。
まず「Hi」や「Hello」と挨拶し、その後「Can you suggest any candidates for a senior developer position with 7+ year experience that requires Japanese speaking?」のように質問してみてください。

Adaptive Cards でカスタマイズされた引用エクスペリエンスでは、引用ごとにボタンが表示されます。引用ボタンをクリックしてドキュメント ビューを展開し、候補者ごとの履歴書詳細を確認してください。
Exercise 3: Generated by AI ラベルを有効化する
この演習では PredictedSayCommand を使い、ユーザーが AI と人間の応答を区別できるよう「AI generated」ラベルを表示します。
Step 1: PredictedSayCommand で Generated by AI ラベルを有効化する
src/app/app.ts を開き、PredictedSayCommand アクションを探します。activity.entities 内に次のコード スニペットを追加します。
// Generated by AI label
additionalType: ["AIGeneratedContent"]
更新後の activity.entities は次のようになります。
activity.entities = [
    {
        type: "https://schema.org/Message",
        "@type": "Message",
        "@context": "https://schema.org",
        "@id": "",
        // Generated by AI label
        additionalType: ["AIGeneratedContent"],
    },
];
Step 2: Generated by AI ラベルをテストする
Generated by AI ラベル付きの Career Genie をテストしましょう。Visual Studio Code の Run and Debug タブから Debug in Teams (Edge) または Debug in Teams (Chrome) を選択しデバッグします。ブラウザーで Microsoft Teams が開いたら、アプリの詳細で Add を選択してチャットを開始します。
Tip: この演習をローカルでテストする
これまでアプリに実装した Teams AI ライブラリの機能は Teams App Test Tool では完全に動作しない場合があります。必ず Teams でローカル デバッグしてください。
Career Genie に挨拶してみてください。最初のメッセージの上部に小さく「AI generated」ラベルが表示されます。

Exercise 4: Sensitivity ラベルを有効化する
最後の演習では PredictedSayCommand を用いて Sensitivity ラベルを有効化します。Career Genie は人事関連の機密情報を扱うことが多いため、共有情報が機密性を含む場合に Sensitivity ラベルを表示して組織外への共有可否を示します。
Step 1: PredictedSayCommand で Sensitivity ラベルを有効化する
src/app/app.ts を開き、PredictedSayCommand アクションを探します。activity.entities 内に次のコード スニペットを追加します。
// Sensitivity label
usageInfo: {
    "@type": "CreativeWork",
    name: "Confidential",
    description: "Sensitive information, do not share outside of your organization.",
}
更新後の activity.entities は次のようになります。
activity.entities = [
    {
        type: "https://schema.org/Message",
        "@type": "Message",
        "@context": "https://schema.org",
        "@id": "",
        // Generated by AI label
        additionalType: ["AIGeneratedContent"],
        // Sensitivity label
        usageInfo: {
          "@type": "CreativeWork",
          name: "Confidential",
          description: "Sensitive information, do not share outside of your organization.",
        }
    },
  ];
Step 2: Sensitivity ラベルをテストする
Sensitivity ラベル付きの Career Genie をテストしましょう。Visual Studio Code の Run and Debug タブから Debug in Teams (Edge) または Debug in Teams (Chrome) を選択します。ブラウザーで Microsoft Teams が開き、アプリの詳細が表示されたら Add を選択してチャットを開始します。
Tip: この演習をローカルでテストする
これまでアプリに実装した Teams AI ライブラリの機能は Teams App Test Tool では完全に動作しない場合があります。必ず Teams でローカル デバッグしてください。
「Hi」や「Can you suggest a candidate who is suitable for spanish speaking role that requires at least 2 years of .NET experience?」などと質問してみてください。

Career Genie のメッセージ上部で「AI Generated」ラベルの隣に Sensitivity ラベルが表示されます。Sensitivity ラベルにカーソルを合わせて、組織固有のガイダンスを確認してください。
おめでとうございます!
Lab BTA3 - Powered by AI キットによるユーザー エクスペリエンス向上ラボを完了しました。さらに探求したい場合は、このラボのソース コードを Copilot Developer Camp リポジトリ でご覧いただけます。
次は Lab BTA4 - 認証によるソリューションのセキュリティ 강화 に進みましょう。Next を選択してください。