次の方法で共有


GitHub Copilot Chat を使用して WinUI 3/Windows アプリ SDK 開発ワークフローを合理化する

この攻略ガイドは、Visual Studio の Github Copilot Chat を使用して WinUI 3/Windows アプリ SDK アプリケーション開発ワークフローを合理化する必要のあるデスクトップ アプリケーション開発者を対象としています。

まず GitHub Copilot Chat を使用して 1 つのプロンプトで "Hello world" アプリを構築してから、GitHub Copilot Chat を使用して、サーバー側のモック コンポーネントからの応答を表示するチャット インターフェイスを追加する方法を説明します。

前提条件

プロンプトの手法

この攻略ガイドの目的は、求める結果を最小限の労力で生み出すボキャブラリプロンプト手法を提供することです。 主な手法として、チャット ウィンドウを使用したプロンプトと、インライン チャットを使用したプロンプトの 2 つがあります。

[Copilot Chat] ウィンドウを使用したプロンプト

Visual Studio で、[表示] > [GitHub Copilot Chat] を選択します。

Copilot Chat が選択された状態を示すスクリーンショット

これにより、Visual Studio ウィンドウの左側に [GitHub Copilot Chat] ウィンドウが開きます。 このチャット ウィンドウを使用して、コードに関するヘルプを Copilot に求めることができます。 この手法は、複数のファイルで作業しており、変更が必要なファイルを明示的に指定してもかまわない場合に便利です。この攻略ガイドでは、この手法に焦点を当てます。

インラインの Copilot Chat を使用したプロンプト

任意のファイルのエディター ウィンドウで右クリックして [Copilot に質問する] を選択すると、エディター自体に Copilot Chat のインライン チャット ビューが表示されます。

右クリックをしてインラインの Copilot Chat が表示される様子を示すスクリーンショット

これにより、インライン チャット ウィンドウが表示され、現在作業中のファイルを支援するよう Copilot に指示することができます。 これを使用するのは、1 つのファイルのコンテキスト内で作業している場合です。

新しい WinUI 3 プロジェクトを作成する

[Copilot Chat] ウィンドウに次のように入力します。

Get me started with a blank WinUI 3 / WinAppSDK project

手順が表示されます。

[空の WinUI 3/WinAppSDK プロジェクトの使用を開始する] に対する応答のスクリーンショット

これは、"この記事の執筆時点では、Chat 拡張機能では新しいプロジェクトやファイル構造を作成できませんが、詳細な手順の提供は可能である" という、承知しておくべき制限事項を強調しています。 新しいプロジェクトを作成するには、次の手順に従います。

"Hello, world!" メッセージを表示する

新しいプロジェクトが作成されたら、[Copilot Chat] ウィンドウに次のように入力します。

Update my app to display a "Hello, world!" message

Copilot の応答は、開発コンテキストを認識していないことを示している可能性があります。

[アプリを更新して表示...] に対する応答のスクリーンショット

[Copilot Chat] ウィンドウは、コンテキストを明示的に指定しなくても、既定で追加のコンテキストを含めずに基になる LLM (大規模言語モデル) をプロンプトできる、実際上、便利なインターフェイスです。

これに対処するには、スラッシュ コマンドハッシュ参照を使用して、関連するコンテキストを Copilot に明示的に提供します。 詳細については、「Visual Studio で GitHub Copilot Chat のコンテキストを設定し、より適切な回答を得る」を参照してください。

Chat ウィンドウに次のように入力します。

Update #MainWindow.xaml and #MainWindow.xaml.cs to display "Hello, world!" when the app starts. Directly modify the existing files. Do not explain yourself. Do not generate new files.

Copilot が、MainWindow.xaml および MainWindow.xaml.cs とラベル付けされたコード ブロック内に必要なコードを生成することが確認できるはずです。 これらのコード ブロックには、Insert in new filePreview という 2 つのオプションがそれぞれ表示されます。 ターゲット ファイルでカーソルがアクティブになっている Preview をクリックして 変更をステージングして受け入れます。

コードビハインド ファイル操作時の [プレビュー] ボタンのスクリーンショット

マークアップ ファイル操作時の [プレビュー] ボタンのスクリーンショット

これは、"Copilot にファイルの変更を指示するには、変更する必要があるファイルを知っている必要がある" という重要な考慮事項を強調しています。 このパターンは、開発ワークフローの残りの部分で使用します。

これは、プロジェクト構造をシンプルかつ適切に整理された状態に保てば、Copilot での作業が効率化される可能性があることを示唆しています。

変更する必要のあるファイルがわからない場合は、#Solution ハッシュ参照を使用して Copilot Chat に尋ねることができます。

What files should I change in my #Solution in order to achieve <desired outcome>?

ボタンを削除する

Chat ウィンドウに次のように入力します。

Update #MainWindow.xaml and #MainWindow.xaml.cs to display ONLY "Hello, world!" when the app starts, removing extraneous buttons and their codebehind functionality as-needed. Directly modify the existing files. Do not explain yourself. Do not generate new files.

推奨される変更を受け入れます。 ボタンが UI から削除され、対応するコードがコードビハインド ファイルから削除されていることを確認できるはずです。 アプリケーションを実行して、"Hello, world!" メッセージのみが表示されることを確認します。

hello world の結果のスクリーンショット

チャット インターフェイスを構築する

次に、テキストを入力してモック応答を生成できるシンプルなチャット インターフェイスを構築します。 Chat ウィンドウに次のように入力します。

Update #MainWindow.xaml and #MainWindow.xaml.cs to build a chat interface with the following layout and functionality, step by step:

 1. A **horizontally centered input** at the bottom of the window
 2. A **vertically scrolling list of messages and responses** directly above the input
 3. A **ProgressBar** to indicate when the app is waiting for a response, directly above the input, below the list of messages and responses
 4. The latest message should be visible at the bottom of the list, with older messages above it, eventually becoming hidden as the list grows
 5. When I click the Send button, display the input text in a TextBlock, and update the ProgressBar to indicate that the app is waiting for a response. Mock the code that generates a response with a delay of 2 seconds, and then display a response that echoes the input text above the input.
 6. Ensure that **TextBlock** text wraps to the next line when it reaches the edge of the window.

Remove extraneous code as-needed. Directly modify the existing files. Do not explain yourself. Do not generate new files. Ensure that every single numbered requirement is accounted for in the end result. Ensure that both the markup and codebehind files are updated to produce a fully functional chat interface that builds and meets the above-stated requirements. Take your time. Reveal only two code blocks representing the end result, one for each file.

次に、すべての要件を 1 つのプロンプトで提供するワンショット プロンプトの例を示します。 これは、何を構築したいのかが明確で、その要件を満たすコードを Copilot が生成するのを確認する必要がある場合に便利かもしれませんが、要件を完全に満たしていないコードを Copilot が生成する可能性も高くなります。

これは、"Copilot は正確な要件を与えられると、その要件を満たすために必要なコードを生成できる" という重要な考慮事項を強調しています。 これは、開発ワークフロー内で Copilot を活用する強力な方法ですが、構築する機能の要件を正確に定義する技術的なボキャブラリを使用してプロンプトを構築する必要があります。

この記事の執筆時点では、上記の入力によって次の出力が生成されました。

using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using System;
using System.Collections.ObjectModel;
using System.Threading.Tasks;

namespace ImageGenerator
{
    public sealed partial class MainWindow : Window
    {
        public ObservableCollection<string> Messages { get; } = new ObservableCollection<string>();

        public MainWindow()
        {
            this.InitializeComponent();
            MessageTextBox.KeyDown += (sender, e) =>
            {
                if (e.Key == Windows.System.VirtualKey.Enter && !string.IsNullOrWhiteSpace(MessageTextBox.Text))
                {
                    SendButton_Click(sender, e);
                }
            };
        }

        private async void SendButton_Click(object sender, RoutedEventArgs e)
        {
            Messages.Add(MessageTextBox.Text);
            ProgressBar.Visibility = Visibility.Visible;
            MessageTextBox.Text = string.Empty;

            await Task.Delay(2000);
            Messages.Add($"Echo: {Messages[^1]}");
            ProgressBar.Visibility = Visibility.Collapsed;
            ScrollToBottom(); // Scroll to the end after adding a message
        }

        private void ScrollToBottom()
        {
            var scrollViewer = MessagesScrollViewer;
            if (scrollViewer != null)
            {
                scrollViewer.ChangeView(0.0f, scrollViewer.ExtentHeight, 1.0f); // Scroll to the bottom
            }
        }
    }
}
<Window
    x:Class="ImageGenerator.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>

        <!-- Message viewer area -->
        <ScrollViewer Grid.Row="0" VerticalScrollBarVisibility="Auto" x:Name="MessagesScrollViewer">
            <StackPanel VerticalAlignment="Bottom" HorizontalAlignment="Center">
                <ItemsControl ItemsSource="{x:Bind Messages, Mode=OneWay}">
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding}" TextWrapping="Wrap" HorizontalAlignment="Center" Margin="0,2" />
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
            </StackPanel>
        </ScrollViewer>

        <!-- Input area -->
        <StackPanel Grid.Row="1" VerticalAlignment="Bottom" HorizontalAlignment="Stretch">
            <ProgressBar x:Name="ProgressBar" Height="5" HorizontalAlignment="Stretch" Visibility="Collapsed" Margin="0,5,0,0" />
            <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
                <TextBox x:Name="MessageTextBox" MinWidth="200" Margin="5" AcceptsReturn="False" />
                <Button x:Name="SendButton" Content="Send" Click="SendButton_Click" />
            </StackPanel>
        </StackPanel>
    </Grid>
</Window>

そこから、次の UI が生成されました。

実際の例の UI のスクリーンショット

生成されたコードを修正して反復処理する

Copilot から受け取った出力が指定された要件を満たしていない場合、1 つのオプションとして、より正確な命令をもって元の命令を繰り返し、Copilot に "更新を続行" するよう指示して満たされていない要件を満たします。

Continue updating #MainWindow.xaml and #MainWindow.xaml.cs to build a chat interface with the following layout and functionality, step by step:

 1. A **horizontally centered input** at the bottom of the window // done
 2. A **vertically scrolling list of messages and responses** directly above the input // partially done - the list is displayed, but it doesn't scroll
 3. A **ProgressBar** to indicate when the app is waiting for a response, directly above the input, below the list of messages and responses // done
 4. The latest message should be visible at the bottom of the list, with older messages above it, eventually becoming hidden as the list grows
 5. When I click the Send button, display the input text in a TextBlock, and update the ProgressBar to indicate that the app is waiting for a response. Mock the code that generates a response with a delay of 2 seconds, and then display a response that echoes the input text above the input.
 6. Ensure that **TextBlock** text wraps to the next line when it reaches the edge of the window.

Remove extraneous code as-needed. Directly modify the existing files. Do not explain yourself. Do not generate new files. Ensure that every single numbered requirement is accounted for in the end result. Ensure that both the markup and codebehind files are updated to produce a fully functional chat interface that builds and meets the above-stated requirements. Take your time. Reveal only two code blocks representing the end result, one for each file.

あるいは、マルチショット プロンプトを使用して、さらに小さな要件に問題を分割し、一度に 1 つずつ対処して、目的の結果に向けて段階的に構築することもできます。 このアプローチが役立つ可能性があるのは、技術的な精度の高い要件を明確にする方法がわからない場合や、Copilot が、求められているコードの生成に苦労している場合です。

要点

この攻略ガイドで説明した内容は次のとおりです。

  • Visual Studio で GitHub Copilot Chat を使用して WinUI 3/Windows アプリ SDK 開発ワークフローを合理化する方法を示しました
  • 要件を満たすコードを生成するように Copilot に求めました
  • 求めているコードを生成するためには、正確な要件を Copilot に提供することが重要であるということを強調しました
  • それぞれについて、さまざまなプロンプト手法とユース ケースを特定しました