記事公開日
最終更新日
【Copilot for Microsoft 365】Copilot拡張プラグインを作成してみた!④

本記事では、Copilot for Microsoft 365の拡張プラグインを作成します。
今回は、第4回目となります。
これまでの記事については以下リンクをご参照ください。
【Copilot for Microsoft 365】Copilot拡張プラグインを作成してみた!①
【Copilot for Microsoft 365】Copilot拡張プラグインを作成してみた!②
【Copilot for Microsoft 365】Copilot拡張プラグインを作成してみた!③
前回の記事では検索処理部は、ユーザー情報を固定応答としていましたが、今回は「Azure AI Search」を使用して実際に検索部も実装してみます。
検索データの準備
Azure AI Searchを用意し、検索対象ドキュメントを取り込みます。
検索対象ドキュメントは、インターネットに出回っていない資料の方が本当にそのデータが使用されているか分かりやすいとは思いますが、丁度良いドキュメントが手元に無かったため、マイクロソフト様の「Microsoft Azure 利用ガイド.pdf」を利用させていただきます。
このドキュメントの内容に対して、Copilot に調べてもらい回答を得られるかを試してみます。
データの取り込み方法は、以前ご紹介させていただいた「Azure AI Search の統合ベクトル化を試してみた」と同様の方法で試します。ここでは詳しく紹介しませんので、興味のある方は過去ブログをご参照ください。
作成されたインデックスは、このような形になりました。
![]() |
![]() |
検索処理の実装
プログラムは、前回までと同様の名前で「CopilotExApp4」というプロジェクトでメッセージ拡張機能のカスタム検索コードをベースとしています。検索処理部分を拡張し、以下のように Azure AI Searchを検索するようにしました。ハイブリッド+セマンティックランカー検索になります。public async Task<SearchResults> Search(string query) { var searchCredential = new AzureKeyCredential(key); var indexClient = new SearchIndexClient(new Uri(serviceEndpoint), searchCredential); var searchClient = indexClient.GetSearchClient(indexName); var queryEmbeddings = await GenerateEmbeddings(query); var searchOptions = new SearchOptions { VectorSearch = new() { Queries = { new VectorizedQuery(queryEmbeddings.ToArray()) { KNearestNeighborsCount = 3, Fields = { "text_vector" } } } }, SemanticSearch = new() { SemanticConfigurationName = "vector-ragtest-semantic-configuration", QueryCaption = new(QueryCaptionType.Extractive), QueryAnswer = new(QueryAnswerType.Extractive), }, QueryType = SearchQueryType.Semantic, Size = 3, Select = { "title", "chunk" }, }; SearchResults response = await searchClient.SearchAsync(query, searchOptions); return response; }
メッセージ拡張機能で呼ばれた部分から以下のような形で Azure AI Searchを検索する処理を呼び出し、前回同様アダプティブカードとして応答を返します。
protected override async Task OnTeamsMessagingExtensionQueryAsync(ITurnContext turnContext, MessagingExtensionQuery query, CancellationToken cancellationToken) { var templateJson = await System.IO.File.ReadAllTextAsync(_adaptiveCardFilePath, cancellationToken); var template = new AdaptiveCards.Templating.AdaptiveCardTemplate(templateJson); var text = query?.Parameters?[0]?.Value as string ?? string.Empty; var hybridResponse = await _aiSearch.Search(text); var attachments = new List(); await foreach (SearchResult result in hybridResponse.GetResultsAsync()) { Debug.WriteLine($"Title: {result.Document["title"]}"); Debug.WriteLine($"Content: {result.Document["chunk"]}\n"); var previewCard = new HeroCard { Title = result.Document["title"].ToString(), Text = result.Document["chunk"].ToString() }; var adaptiveCardJson = template.Expand(new { chunk = result.Document["chunk"], title = result.Document["title"]}); var adaptiveCard = AdaptiveCard.FromJson(adaptiveCardJson).Card; var attachment = new MessagingExtensionAttachment { ContentType = AdaptiveCard.ContentType, Content = adaptiveCard, Preview = previewCard.ToAttachment() }; attachments.Add(attachment); } return new MessagingExtensionResponse { ComposeExtension = new MessagingExtensionResult { Type = "result", AttachmentLayout = "list", Attachments = attachments } }; }
実行してみる
実装ができたので、試してみます。「Microsoft Azure 利用ガイド」に記載されている内容で質問してみます。
【質問】Azureのライセンス契約形態の種類について教えて
拡張処理には、以下のような検索ワードが渡されていました。このワードで、Azure AI Searchを検索する形になります。![]() |
Copilotの回答は、このようになりました。
![]() |
![]() |
【質問】Azureのサポートについて調べて
以下のような回答が得られました。![]() |
メッセージ拡張機能で生成されたアダプティブカードが情報ソースとなっているのですが、ここの設定された本文データは、ドキュメント取込み時に自動的に分割されたチャンクデータがそのまま表示されています。そのまま見えてしまうのは微妙(※PDFファイルからのテキスト抽出したままで、レイアウトも微妙)な感じもしますが、この内容と元となったPDFを比較すると検索された結果であることは分かります。ここでは、実際の引用元へのリンクにはなっていないので、社内文書等を検索した場合でも引用元へのリンクとなるようにカスタマイズしても良いかと思います。
回答の元ネタを返してあげれば、もともとの質問と AI Searchの検索結果から Copilotがいい感じに回答を生成してくれるというRAG構成が出来上がります。
検索結果としての精度を上げるには、インデックス作成時のチャンクサイズの調整や AI Search へのクエリ方法や応答本数の調整などをしていく必要がありそうです。
まとめ
いかがだったでしょうか。前回は、固定で応答するダミーの検索でしたが、今回は実際に検索処理を実装して試すことができました。メッセージ拡張機能だけでも、アイデアさえあれば、いろいろ活用できそうです。
また、Copilot for Microsoft 365 の具体的な活用方法等のブログもたくさんありますのでご覧ください!
QUICK E-Solutionsでは、「AIチャットボット構築サービス」をはじめとして、各AIサービスを利用したシステム導入のお手伝いをしております。それ以外でも QESでは様々なアプリケーションの開発・導入を行っております。提供するサービス・ソリューションにつきましては こちら に掲載しております。
システム開発・構築でお困りの問題や弊社が提供するサービス・ソリューションにご興味を抱かれましたら、是非一度 お問い合わせ ください。
※このブログで参照されている、Microsoft、Microsoft 365、Microsoft Copilot for Microsoft 365、Microsoft Teams、Azure OpenAI、その他のマイクロソフト製品およびサービスは、米国およびその他の国におけるマイクロソフトの商標または登録商標です。
※その他の会社名、製品名は各社の登録商標または商標です。