在Visual Studio 2022使用提示檔協助開發-3
本文是本站《在Visual Studio 2022使用提示檔協助開發》系列文章的第三篇,介紹如何在Visual Studio 2022開發工具中,使用指示檔(instruction file)與提示檔案(Prompt files)跟Github Copilot溝通的互動步驟。
延續本站《在Visual Studio 2022使用提示檔協助開發》系列文章的第一篇、第二篇建立的專案、指示檔(instruction file)與提示檔案(Prompt files)互動步過程如下:
加入提示檔案(Promptfiles)
從Visual Studio 2022開發工具「Solution Explorer」視窗方案名稱上方按滑鼠右鍵,從快捷選單選擇「Add」>「Existing Item」項目,選取提示檔(Prompt files),它也是一個文字檔,以本文使用的「my.prompt.md」範例為例,它是一個檔案名稱後綴「.prompt」字串且副檔名為「md」的Markdown格式檔。
目前檔案內容如下列表,其中包含本文要設計專案的提示,提示檔案分為兩大區塊,表頭與內容。
l 「---」符號:是 YAML Front Matter 的開始標記,常用於 Markdown 文件的開頭,定義一些metadata
l 「mode: 'agent'」:指定執行模式為「agent」模式,代表這份指令是給自動化代理人(GitHub Copilot)使用。
l 「model: GPT-4.1」:指定要使用的 AI 模型版本為 GPT-4.1。
l 「description: 」:提供這份檔案的描述,說明這是 Copilot 的指令步驟設計檔,目的是讓 Copilot 依照步驟逐步完成程式開發。
l 「---」符號:YAML Front Matter 的結束標記。
檔案剩餘部分為提示內容,表列如下:
my.prompt.md
---
mode:
'agent'
model:
GPT-4.1
description:
本檔案為 Copilot 指令步驟設計,請依步驟逐步完成程式開發。
---
你是高效且自主的代理人,你肯定能獨立解決問題,無需每次都向使用者詢問。
請花時間仔細思考每一個步驟 - 記得嚴格檢查你的解決方案,你必須不斷迭代直到問題被解決。且所有待辦事項皆已勾選。
不要在未完成所有步驟且確認一切運作良好之前結束回合。當你說「接著我要做 X」或「現在我要做 Y」或「我要做 X」時,你必須真的去做,而非僅說說而已。
接下來請使用繁體中文回應我。
#建立待辦事項Todo清單
- 根據我提供的`程式設計步驟`建立待辦事項Todo清單。
- 每一個步驟都要成為一個待辦事項。
- 每一步驟開始之前都要列出所有待辦事項。
- 建立 Markdown 格式代辦清單以追蹤。
- 每完成一項用 `[x]` 標示。
- 每次標示完成都顯示更新清單給我。
- 完成每一項目,暫停執行,確認程式碼能夠正確編譯,然後等我確認,待我回應 OK,才可進行下一步。
使用以下格式建立待辦事項Todo清單,務必使用Markdown 格式
```markdown
- [
] 步驟1:第一步描述
- [
] 步驟2:第二步描述
- [
] 步驟3:第三步描述
```
## 程式設計步驟
- 請花時間仔細思考每一個程式設計步驟,記得嚴格檢查你的解決方案,是否符合微軟Asp.net Core 9 版的框架,要符合SOLID軟體設計原則,使用DI等設計模式。
- 思考專案與專案之間的相互參考關係,思考是否正確引用命名空間。
- 是否需要額外安裝套件以協助開發。
- 必要時利用網路搜尋相關文件、文章及論壇,研究問題。
- 每一步驟完成,列出更動的程式碼,供我參考。
### Step 1
在 `CopilotWeb` 專案設計一個
`VacationDaysCalculator` 服務,包含一個 C# 方法,輸入月份,回傳特休日數,規則如下:
1. 6個月以上1年未滿者,3日。
2. 1年以上2年未滿者,7日。
3. 2年以上3年未滿者,10日。
4. 3年以上5年未滿者,每年14日。
5. 5年以上10年未滿者,每年15日。
6.
10年以上者,每1年加給1日,加至30日為止。
#### 範例
| 勞工服務年資特別休假天數 | 天數 |
|--------------------------|------|
| 6個月至未滿1年 | 3 |
| 滿第1年 | 7 |
| 滿第2年 | 10 |
| 滿第3年 | 14 |
| 滿第4年 | 14 |
| 滿第5年 | 15 |
| 滿第6年 | 15 |
| 滿第7年 | 15 |
| 滿第8年 | 15 |
| 滿第9年 | 15 |
| 滿第10年 | 16 |
| 滿第11年 | 17 |
| 滿第12年 | 18 |
| 滿第13年 | 19 |
| 滿第14年 | 20 |
| 滿第15年 | 21 |
| 滿第16年 | 22 |
| 滿第17年 | 23 |
| 滿第18年 | 24 |
| 滿第19年 | 25 |
| 滿第20年 | 26 |
| 滿第21年 | 27 |
| 滿第22年 | 28 |
| 滿第23年 | 29 |
| 滿第24年 | 30 |
| 滿第25年 | 30 |
---
### Step 2
在
`VacationDaysCalculator.Tests` 專案中,加入一個測試 `VacationDaysCalculator` 服務的程式碼。 並進行單元測試,確認所有測試案例都通過。
---
### Step 3
在 `CopilotWeb` 專案設計一個適用 .NET 9 的 Web API,名為VacationController,使用DI,利用 `VacationDaysCalculator` 服務計算特休日數並傳回。
---
### Step 4
在 `CopilotWeb` 專案加入 Swagger 功能來測試 Web API。 自行安裝相關套件。
---
### Step 5
在 `CopilotWeb` 專案註冊 Razor Page 功能,然後加入一個 Razor Page 網頁,名為Index,使用完整類別名稱存取Index對應的IndexModel
使用 Bootstrap 5.3.3 版美化畫面。
在 Razor Page 網頁加入一個文字方塊輸入月數,還有一個按鈕。
按下按鈕利用 fetch 送 httpget 請求,傳入文字方塊的值為參數,從 Step 3 設計的 Web API 取得特休天數,顯示在按鈕下方。
使用指示檔案(Instruction files)與指示檔(Prompt files)
在「Github Copilot Chat」視窗從下方的下拉式清單方塊中,選取「Agent」模式,筆者選用泛用性高的最新OpenAI旗艦模型「GPT-4.1」來執行任務。
在「Github
Copilot Chat」視窗加入指示檔案(Instruction files),點選「Reference」>「File」,請參考下圖所示:
圖 1:加入指示檔案(Instruction files)
圖 2:選取指示檔(Instruction files)
加入與執行提示檔案
在「Github
Copilot Chat」視窗加入提示檔案(Prompt
files),點選「Reference」>「Prompts」,請參考下圖所示:
圖 3:加入提示檔案(Prompt files)
選取提示檔案(Prompt files),請參考下圖所示:
圖 4:選取提示檔案(Prompt files)
接著按下執行按鈕送出提示,請參考下圖所示:
圖 5:送出提示
由於生成式AI每次的回應都不太一樣,你的操作畫面可能會與本文描述的不相同,以下為筆者測試時Github Copilot的回應,首先它會根據提示的要求,建立「程式設計步驟」待辦事項清單,請參考下圖所示:
步驟一
待筆者回覆「OK」之後,Github Copilot便開始執行「步驟一」,並撰寫了一個新的「VacationDaysCalculator.cs」檔案,請參考下圖所示:
圖 7: Github Copilot的回應
為了驗證它寫出的程式有符合我們的設計要求,筆者在當下的「Github Copilot Chat」視窗下達提示進行複驗:
照目前邏輯滿第20年會休幾天
務必確認Github Copilot的回應結果是正確的,請參考下圖所示:
圖 8: Github Copilot的回應
若回應不正確,可以持續與Github Copilot溝通,請它修訂程式碼來符合需求。若複驗沒問題,可以按下「Keep」按鈕接受變更,請參考下圖所示:
圖 9: Github Copilot的回應
以下列表是Github
Copilot產出的程式碼,從程式中可以看到Github Copilot根據我們的指示檔(Instruction files)中要求的的風格來撰寫程式碼,例如:「 為每個函式撰寫清楚且簡潔的註解」。
VacationDaysCalculator.cs
using System;
namespace
CopilotWeb.Services
{
/// <summary>
/// 計算特休日數的服務。
/// </summary>
public class VacationDaysCalculator :
IVacationDaysCalculator
{
/// <summary>
/// 根據工作月數計算特休日數。
/// </summary>
/// <param
name="months"> 工作月數 </param>
/// <returns> 特休日數 </returns>
/// <exception cref="ArgumentOutOfRangeException">
當月數小於0時拋出 </exception>
public int GetVacationDays( int months )
{
if ( months < 0 )
{
throw new
ArgumentOutOfRangeException( nameof(months), "月數不可為負值。" );
}
if ( months < 6 )
{
return 0;
}
if ( months < 12 )
{
return 3;
}
int years = months / 12;
if ( years == 1 )
{
return 7;
}
if ( years == 2 )
{
return 10;
}
if ( years >= 3 && years
< 5 )
{
return 14;
}
if ( years >= 5 && years
< 10 )
{
return 15;
}
if ( years >= 10 )
{
int days = 15 + ( years – 9 );
return days > 30 ? 30 :
days;
}
return 0;
}
}
/// <summary>
/// 特休日數計算服務介面。
/// </summary>
public interface IVacationDaysCalculator
{
/// <summary>
/// 根據工作月數計算特休日數。
/// </summary>
/// <param
name="months"> 工作月數 </param>
/// <returns> 特休日數 </returns>
int GetVacationDays( int months );
}
}
步驟二
當「步驟一」順利完成後,我們就可以請Github Copilot進行下一個步驟,在「Github
Copilot Chat」視窗下提示,進行下一個步驟:
OK進行Step 2
第二步驟要求Github Copilot撰寫單元測試程式碼,請參考下圖所示:
圖 10: Github Copilot的回應
我們只要扮演複驗程式是否正確的角色,繼續與Github Copilot溝通,然後接受它產出的程式碼,請參考下圖所示:
圖 11: Github Copilot的回應
在這個步驟中產生的「VacationDaysCalculatorTests.cs」測試程式如下列表:
VacationDaysCalculatorTests.cs
using
CopilotWeb.Services;
using Xunit;
namespace
CopilotWeb.Tests
{
/// <summary>
/// VacationDaysCalculator 單元測試。
/// </summary>
public class VacationDaysCalculatorTests
{
private readonly
IVacationDaysCalculator _calculator = new VacationDaysCalculator();
[Theory]
[InlineData( 0, 0 )]
[InlineData( 5, 0 )]
[InlineData( 6, 3 )]
[InlineData( 11, 3 )]
[InlineData( 12, 7 )]
[InlineData( 23, 7 )]
[InlineData( 24, 10 )]
[InlineData( 35, 10 )]
[InlineData( 36, 14 )]
[InlineData( 47, 14 )]
[InlineData( 48, 14 )]
[InlineData( 59, 14 )]
[InlineData( 60, 15 )]
[InlineData( 119, 15 )]
[InlineData( 120, 16 )]
[InlineData( 132, 17 )]
[InlineData( 144, 18 )]
[InlineData( 156, 19 )]
[InlineData( 168, 20 )]
[InlineData( 180, 21 )]
[InlineData( 192, 22 )]
[InlineData( 204, 23 )]
[InlineData( 216, 24 )]
[InlineData( 228, 25 )]
[InlineData( 240, 26 )]
[InlineData( 252, 27 )]
[InlineData( 264, 28 )]
[InlineData( 276, 29 )]
[InlineData( 288, 30 )]
[InlineData( 300, 30 )]
public void
GetVacationDays_ReturnsExpectedDays( int months, int expectedDays )
{
var result =
_calculator.GetVacationDays (months );
Assert.Equal( expectedDays, result );
}
[Fact]
public void
GetVacationDays_NegativeMonths_ThrowsException()
{
Assert.Throws<ArgumentOutOfRangeException>( () =>
_calculator.GetVacationDays( -1 ) );
}
}
}
步驟三
在「Github
Copilot Chat」視窗下提示,進行下一個步驟:
OK
執行結果請參考下圖所示:
圖 12: Github Copilot的回應
這階段產生的「VacationController.cs」程式碼參考如下:
VacationController.cs
using
Microsoft.AspNetCore.Mvc;
using
CopilotWeb.Services;
namespace CopilotWeb.Controllers
{
/// <summary>
/// 提供特休日數查詢的
API。
/// </summary>
[ApiController]
[Route( "api/[controller]" )]
public class VacationController :
ControllerBase
{
private readonly
IVacationDaysCalculator _calculator;
/// <summary>
/// 建構子,注入特休日數計算服務。
/// </summary>
/// <param
name="calculator"> IVacationDaysCalculator 實例 </param>
public VacationController( IVacationDaysCalculator
calculator )
{
_calculator = calculator;
}
/// <summary>
/// 根據工作月數取得特休日數。
/// </summary>
/// <param
name="months"> 工作月數 </param>
/// <returns> 特休日數 </returns>
[HttpGet]
public ActionResult<int> GetVacationDays(
[FromQuery] int months )
{
try
{
var days =
_calculator.GetVacationDays( months );
return Ok( days );
}
catch ( ArgumentOutOfRangeException
ex )
{
return BadRequest( ex.Message );
}
}
}
}
這階段產生的「Program.cs」程式碼參考如下,叫用「AddScoped<T>」方法註冊服務:
Program.cs
var builder =
WebApplication.CreateBuilder( args );
// Add services to the
container.
builder.Services.AddControllers();
// 註冊特休日數計算服務(DI)
builder.Services.AddScoped<CopilotWeb.Services.IVacationDaysCalculator,
CopilotWeb.Services.VacationDaysCalculator>();
// Learn more about
configuring OpenAPI at https://aka.ms/aspnet/openapi
builder.Services.AddOpenApi();
var app =
builder.Build();
// Configure the HTTP
request pipeline.
if ( app.Environment.IsDevelopment()
)
{
app.MapOpenApi();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
步驟四
在「Github
Copilot Chat」視窗下提示,進行下一個步驟:
OK
執行結果請參考下圖所示:
圖 13: Github Copilot的回應
在這個階段中Github Copilot自動安裝了「Swashbuckle.AspNetCore」套件,並在「Program.cs」程式碼中註冊Swagger服務,參考如下:
Program.cs
var builder =
WebApplication.CreateBuilder( args );
// Add services to the
container.
builder.Services.AddControllers();
// 註冊特休日數計算服務(DI)
builder.Services.AddScoped<CopilotWeb.Services.IVacationDaysCalculator,
CopilotWeb.Services.VacationDaysCalculator>();
// Swagger/OpenAPI 註冊
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app =
builder.Build();
// Configure the HTTP
request pipeline.
if ( app.Environment.IsDevelopment()
)
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
我們可以執行這個網站,手動驗證看看是否一切符合需求,按CTRL+F5執行目前網站,預設Visual Studio 2022開發工具會啟動開發階段的Web伺服器動態給一個埠號,請參考下圖所示:
圖 14: Github Copilot的回應
開啟瀏覽器,輸入網站所在URL,後綴「Swagger」,例如:
https://localhost:7234/swagger
執行結果請參考下圖所示:
圖 15:驗證Swagger
使用Swagger圖型介面測試特休功能是否正常,請參考下圖所示:
圖 16: 使用Swagger測試Web API
步驟五
在「Github
Copilot Chat」視窗下提示,進行下一個步驟:
OK
執行結果請參考下圖所示:
圖 17: Github Copilot的回應
這階段產生的「Index.cshtml」程式碼參考如下:
Index.cshtml
@page
@model
CopilotWeb.Pages.IndexModel
@{
ViewData["Title"] = "特休日數查詢";
}
<!DOCTYPE html>
<html
lang="zh-Hant">
<head>
<meta charset="utf-8" />
<meta name = "viewport"
content = "width=device-width, initial-scale=1" />
<title> @ViewData["Title"] </title>
<link href = "https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
rel = "stylesheet" crossorigin = "anonymous">
</head>
<body>
<div class = "container
py-5">
<h1 class = "mb-4"> 特休日數查詢 </h1>
<div class = "mb-3">
<label for = "monthsInput"
class = "form-label"> 請輸入工作月數: </label>
<input type = "number"
class = "form-control" id = "monthsInput" min = "0"
placeholder = "例如:48">
</div>
<button id = "queryBtn"
class = "btn btn-primary mb-3"> 查詢特休日數 </button>
<div id = "result" class =
"mt-3"> </div>
</div>
<script>
document.getElementById( 'queryBtn' ).addEventListener(
'click', async function () {
const months =
document.getElementById( 'monthsInput' ).value;
const resultDiv =
document.getElementById( 'result' );
resultDiv.innerHTML = '';
if (!months || months < 0) {
resultDiv.innerHTML = '<div
class="alert alert-warning">請輸入有效的月數。</div>';
return;
}
try {
const response = await fetch( `/api/vacation?months=${months}`
);
if ( response.ok ) {
const days = await
response.json();
resultDiv.innerHTML =
`<div class="alert alert-success">特休日數:<strong>${days}</strong>
天</div>`;
} else {
const msg = await
response.text();
resultDiv.innerHTML =
`<div class="alert alert-danger">${msg}</div>`;
}
} catch (e) {
resultDiv.innerHTML = '<div
class="alert alert-danger">查詢失敗,請稍後再試。</div>';
}
});
</script>
</body>
</html>
網站目前已經開發完成,按CTRL+F5執行目前網站,預設將顯示網站首頁,請參考下圖所示:
圖 18: 特休查詢網站
總結
在Visual Studio 2022開發工具 中運用提示檔(prompt file)與指示檔(instruction
file)來整合生成式 AI,不僅能讓開發過程更快速、更有條理,也能確保專案的長期品質與一致性。這樣的方式讓AI真正從「輔助工具」進化為「開發流程的一部分」,使得開發者能更專注於解決核心業務問題,而不是浪費時間在重複性或低層次的工作上。隨著這項整合方式的成熟與普及,它勢必將成為未來軟體開發中不可或缺的利器。

0 意見:
張貼留言