以往要開發程式,多少會寫一些工具來幫忙自己開發更快更準確,如偵測 DB table 欄位資訊再透過動態類別與微軟的System.Reflection 組件來幫忙自動產生程式,因為欄位可能多達數十個,手動與肉眼建立model很耗時。
現在似乎有更快更直接的方式,那就是利用目前釋出的大語言模型API。
身邊一直聽到有人或有老闆一個人把整個專案、ERP寫好,就覺得老闆下海寫程式是想不開嗎還是怎樣。
後來想想不對,老闆都是很聰明的每秒幾十萬上下,應該是有方法,了解後就是利用這些API。
於是就動手來測試看看,是不是可以幫忙coding更快一些。
(有先測過股票程式如一目均衡表等等,確實真的產出且正確且畫圖出來,跟自己寫的差不多。)
假設文件寫的清楚,要替文件寫程式,且透過套件存取資料庫,這邊先以呼叫store procedure來代替複雜的SQL邏輯。
目前是請模型先實行 PG 角色,如果有底層設計與其它架構則是由真人來擔任架構師或者 PA 以上的職務,額外對模型描述要求,此先不試這些部分。
也就是實際人類去請電腦寫程式,並且依照SA寫好的文件開發撰寫。
(之後的測試程式、測試報告甚至弱掃建議,是另外再建立描述)
開始實行,先找到公開的測試目標文件:
其公開文件查看網址:
公開的API文件網址
開始實際呼叫API來測試。
1. Google Gemini
溝通的Python程式碼: (文件第2~5頁以圖檔方式讓模型讀取)
from google import genai
from google.genai import types
import PIL.Image
import requests
image1 = PIL.Image.open(r'C:\Users\XXX\Desktop\self Coding by AI\Step2-Spec1.jpg')
image2 = PIL.Image.open(r'C:\Users\XXX\Desktop\self Coding by AI\Step3-Spec2.jpg')
image3 = PIL.Image.open(r'C:\Users\XXX\Desktop\self Coding by AI\Step4-Spec3.jpg')
image4 = PIL.Image.open(r'C:\Users\XXX\Desktop\self Coding by AI\Step5-Spec4.jpg')
client = genai.Client(api_key="ABCDEF888KKKLLLGGG666XFFWFGGDFAEWFEWEFW")
MODEL_ID = "gemini-2.0-flash"
user_req = "產生C# Web MVC API 程式 "
proj_name = "DigitalDevProj"
data_service = f"使用 'dapper' 套件存取 'MS SQL SERVER' , SQL語法部分為執行名稱為 FetchData 的 'store procedure' \
對應欄位跟規格提供的名稱一樣。 dapper用法可參考網址內容 'https://dappertutorial.net/' 。"
system_prompt = f"成為一個專業的 'C# Web MVC API' 程式開發者, \
我需要你的協助產生程式碼, 只需要依照使用者需求內容來產生程式碼。只給我程式碼與相關的註解就好。"
prompt = f"需求為 {user_req} 。 \
任務是依照提供的圖片內容為規格,開發C# Web MVC API,需要提供 controller、model與對應資料存取的 service 為 {data_service}。 \
回覆應包含「C# Web MVC API controller 、 model and Data Service 」 代碼,並排除任何不相關的內容、註解與資訊文字。 \
專案名稱為 {proj_name} 。"
response = client.models.generate_content(
model=MODEL_ID,
contents=[prompt, image1, image2, image3, image4 ],
config=types.GenerateContentConfig(
system_instruction=system_prompt
)
)
print(response.text)
產生的程式:
// Model
namespace DigitalDevProj.Models
{
public class SmsSendRequest
{
public string orderNo { get; set; }
public string packageNo { get; set; }
public int packageCnt { get; set; }
public string timeUp { get; set; }
public string responseUrl { get; set; }
public string smsTitle { get; set; }
public List<SmsBody> smsBody { get; set; }
}
public class SmsBody
{
public string uid { get; set; }
public string mobile { get; set; }
public string smsText { get; set; }
}
public class SmsSendResponse
{
public string msgId { get; set; }
public string status { get; set; }
public string statusMsg { get; set; }
public string orderNo { get; set; }
public string packageNo { get; set; }
public int packageCnt { get; set; }
public List<ErrorUid> errorUids { get; set; }
}
public class ErrorUid
{
public string uid { get; set; }
public string uidStatus { get; set; }
public string uidStatusMsg { get; set; }
}
}
// Service
namespace DigitalDevProj.Services
{
using Dapper;
using Microsoft.Extensions.Configuration;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Threading.Tasks;
using DigitalDevProj.Models;
public interface ISmsSendService
{
Task<SmsSendResponse> FetchData(SmsSendRequest request);
}
public class SmsSendService : ISmsSendService
{
private readonly string _connectionString;
public SmsSendService(IConfiguration configuration)
{
_connectionString = configuration.GetConnectionString("DefaultConnection");
}
public async Task<SmsSendResponse> FetchData(SmsSendRequest request)
{
using (var connection = new SqlConnection(_connectionString))
{
connection.Open();
var parameters = new DynamicParameters();
parameters.Add("@orderNo", request.orderNo);
parameters.Add("@packageNo", request.packageNo);
parameters.Add("@packageCnt", request.packageCnt);
parameters.Add("@timeUp", request.timeUp);
parameters.Add("@responseUrl", request.responseUrl);
parameters.Add("@smsTitle", request.smsTitle);
var smsBodyTable = new DataTable();
smsBodyTable.Columns.Add("uid", typeof(string));
smsBodyTable.Columns.Add("mobile", typeof(string));
smsBodyTable.Columns.Add("smsText", typeof(string));
foreach (var body in request.smsBody)
{
smsBodyTable.Rows.Add(body.uid, body.mobile, body.smsText);
}
parameters.Add("@smsBody", smsBodyTable.AsTableValuedParameter("dbo.SmsBodyType"));
return await connection.QueryFirstOrDefaultAsync<SmsSendResponse>(
"FetchData",
parameters,
commandType: CommandType.StoredProcedure);
}
}
}
}
// Controller
namespace DigitalDevProj.Controllers
{
using Microsoft.AspNetCore.Mvc;
using DigitalDevProj.Models;
using DigitalDevProj.Services;
using Microsoft.AspNetCore.Authorization;
[ApiController]
[Route("api/[controller]")]
public class SmsSendController : ControllerBase
{
private readonly ISmsSendService _smsSendService;
public SmsSendController(ISmsSendService smsSendService)
{
_smsSendService = smsSendService;
}
[HttpPost("SmsSend")]
[Authorize]
public async Task<IActionResult> SmsSend([FromBody] SmsSendRequest request)
{
var response = await _smsSendService.FetchData(request);
return Ok(response);
}
}
}
2. Gork
這次把圖檔改成url連結,以減少token數目。
溝通的Python程式碼: (描述訊息有先mark掉一段,等等會說明差異)
from openai import OpenAI
import PIL.Image
import requests
XAI_API_KEY = "xai-fsfjjre3l3jiojflks34t9sdfslk9fssfjjljlkjlkl"
uri_doc1 = "https://pouch.jumpshare.com/preview/fgAKFdHoyMQIxK986_cCVJyV9i60pqYyXhDIyP-irR1Zch46a5IeuNUBiVCQD-ilzcIv_ajoO5ObdvvMdN6lLCXu4DUqlp4Owv51xUVLIKs"
uri_doc2 = "https://pouch.jumpshare.com/preview/kdKEMmKTFCAao5u3YqHUEVD2mtm7GeApAGDqUEabc4357GlR3GB1DtWPxDMN2xbzAuLIvJA4UcmmPrm04w0iNvvEnRojmgCTkFmWDkZ8ETk"
uri_doc3 = "https://pouch.jumpshare.com/preview/QBv3Yua9oyjrH7S_ly-VPJTo8TLH95P7JXSO5yQKE5uz-E_ief61HaSerhpfGqnbAuLIvJA4UcmmPrm04w0iNkQ80KIOjNuaj92cz6SaUto"
uri_doc4 = "https://pouch.jumpshare.com/preview/H6RNFukmqhCAWqm1cRa4XXkVPGYgZZF1CjebFSR43hD7PEe1ybdJW8X04hZjDdLhAuLIvJA4UcmmPrm04w0iNvdVD6i__n8oqnkbPErdWro"
MODEL_ID = "grok-2-vision-latest" #"grok-3-latest"
user_req = "產生C# Web MVC API 程式 "
proj_name = "DigitalDevProj"
data_service = f"使用 'dapper' 套件存取 'MS SQL SERVER' , SQL語法部分為執行名稱為 FetchData 的 'store procedure' \
對應欄位跟規格提供的名稱一樣。 dapper用法可參考網址內容 'https://dappertutorial.net/' 。"
system_prompt = f"成為一個專業的 'C# Web MVC API' 程式開發者, \
我需要你的協助產生程式碼, 只需要依照使用者需求內容來產生程式碼。只給我程式碼與相關的註解就好。"
prompt = f"需求為 {user_req} 。 \
任務是依照提供的網頁內容為規格,開發C# Web MVC API。提供的網頁內容試圖檔,請協助解析內容。然後回覆程式,為 controller、model與對應資料存取的 service 為 {data_service}。 \
回覆應包含「C# Web MVC API controller 、 model and Data Service 」 代碼,並排除任何不相關的內容、註解與資訊文字。 \
專案名稱為 {proj_name} 。 只需要提供SmsSend這部分即可。"
#另外要注意的是,欄位 smsBody 是一個物件集合,集合的每個元素物件的成員描述在接下來的描述。"
client = OpenAI(
api_key=XAI_API_KEY,
base_url="https://api.x.ai/v1",
)
completion = client.chat.completions.create(
model= MODEL_ID ,
messages=[
{ "role": "system", "content": system_prompt },
{ "role": "user", "content":
[
{
"type": "image_url",
"image_url": {
"url": uri_doc1
}
},
{
"type": "image_url",
"image_url": {
"url": uri_doc2
}
},
{
"type": "image_url",
"image_url": {
"url": uri_doc3
}
},
{
"type": "image_url",
"image_url": {
"url": uri_doc4
}
},
{
"type": "text",
"text": prompt
}
]
},
],
)
print(completion.choices[0].message.content)
產生的程式:
// Controller: SmsSendController.cs
using Microsoft.AspNetCore.Mvc;
using DigitalDevProj.Models;
using DigitalDevProj.Services;
namespace DigitalDevProj.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class SmsSendController : ControllerBase
{
private readonly ISmsSendService _smsSendService;
public SmsSendController(ISmsSendService smsSendService)
{
_smsSendService = smsSendService;
}
[HttpPost]
public async Task<IActionResult> SendSms(SmsSendRequest request)
{
var result = await _smsSendService.SendSms(request);
return Ok(result);
}
}
}
// Model: SmsSendRequest.cs
using System.ComponentModel.DataAnnotations;
namespace DigitalDevProj.Models
{
public class SmsSendRequest
{
[Required]
[StringLength(36)]
public string orderNo { get; set; }
[Required]
[StringLength(5)]
public string packageNo { get; set; }
[Required]
[StringLength(4)]
public string packageCut { get; set; }
[Required]
[StringLength(12)]
public string timeUp { get; set; }
[Required]
[StringLength(256)]
public string responseUrl { get; set; }
[Required]
[StringLength(30)]
public string smsTitle { get; set; }
[Required]
[StringLength(20)]
public string uid { get; set; }
[Required]
[StringLength(10)]
public string mobile { get; set; }
[Required]
[StringLength(333)]
public string smsText { get; set; }
}
}
// Model: SmsSendResponse.cs
namespace DigitalDevProj.Models
{
public class SmsSendResponse
{
public string msgId { get; set; }
public int status { get; set; }
public string statusMsg { get; set; }
public string orderNo { get; set; }
public string packageNo { get; set; }
public string packageCut { get; set; }
public string errorIds { get; set; }
public string uid { get; set; }
}
}
// Service: ISmsSendService.cs
using System.Threading.Tasks;
using DigitalDevProj.Models;
namespace DigitalDevProj.Services
{
public interface ISmsSendService
{
Task<SmsSendResponse> SendSms(SmsSendRequest request);
}
}
// Service: SmsSendService.cs
using System.Threading.Tasks;
using Dapper;
using System.Data.SqlClient;
using DigitalDevProj.Models;
namespace DigitalDevProj.Services
{
public class SmsSendService : ISmsSendService
{
private readonly string _connectionString;
public SmsSendService(string connectionString)
{
_connectionString = connectionString;
}
public async Task<SmsSendResponse> SendSms(SmsSendRequest request)
{
using (var connection = new SqlConnection(_connectionString))
{
var parameters = new DynamicParameters();
parameters.Add("@orderNo", request.orderNo);
parameters.Add("@packageNo", request.packageNo);
parameters.Add("@packageCut", request.packageCut);
parameters.Add("@timeUp", request.timeUp);
parameters.Add("@responseUrl", request.responseUrl);
parameters.Add("@smsTitle", request.smsTitle);
parameters.Add("@uid", request.uid);
parameters.Add("@mobile", request.mobile);
parameters.Add("@smsText", request.smsText);
var result = await connection.QueryFirstOrDefaultAsync<SmsSendResponse>(
"FetchData",
parameters,
commandType: System.Data.CommandType.StoredProcedure
);
return result;
}
}
}
}
在 model 部分似乎有解析錯誤,物件欄位沒判斷到。
溝通程式碼將註解解除後再執行一次,也就是溝通得再詳細一點,就可以了。
再次產生的程式: (有好一點,但回傳部分仍有一點錯誤)
// Controller: SmsSendController.cs
using Microsoft.AspNetCore.Mvc;
using DigitalDevProj.Models;
using DigitalDevProj.Services;
namespace DigitalDevProj.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class SmsSendController : ControllerBase
{
private readonly ISmsSendService _smsSendService;
public SmsSendController(ISmsSendService smsSendService)
{
_smsSendService = smsSendService;
}
[HttpPost]
public async Task<IActionResult> SendSms(SmsSendRequest request)
{
var response = await _smsSendService.SendSmsAsync(request);
return Ok(response);
}
}
}
// Model: SmsSendRequest.cs
namespace DigitalDevProj.Models
{
public class SmsSendRequest
{
public string orderNo { get; set; }
public string packageNo { get; set; }
public string packageCnt { get; set; }
public string timeUp { get; set; }
public string responseUrl { get; set; }
public string smsTitle { get; set; }
public List<SmsBody> smsBody { get; set; }
}
public class SmsBody
{
public string uid { get; set; }
public string mobile { get; set; }
public string smsText { get; set; }
}
}
// Model: SmsSendResponse.cs
namespace DigitalDevProj.Models
{
public class SmsSendResponse
{
public string msgId { get; set; }
public string status { get; set; }
public string statusMsg { get; set; }
public string orderNo { get; set; }
public string packageNo { get; set; }
public string packageCnt { get; set; }
public List<SmsBodyResponse> smsBody { get; set; }
}
public class SmsBodyResponse
{
public string uid { get; set; }
public string status { get; set; }
public string statusMsg { get; set; }
}
}
// Service: ISmsSendService.cs
using DigitalDevProj.Models;
using System.Threading.Tasks;
namespace DigitalDevProj.Services
{
public interface ISmsSendService
{
Task<SmsSendResponse> SendSmsAsync(SmsSendRequest request);
}
}
// Service: SmsSendService.cs
using Dapper;
using Microsoft.Data.SqlClient;
using System.Threading.Tasks;
using DigitalDevProj.Models;
namespace DigitalDevProj.Services
{
public class SmsSendService : ISmsSendService
{
private readonly string _connectionString;
public SmsSendService(string connectionString)
{
_connectionString = connectionString;
}
public async Task<SmsSendResponse> SendSmsAsync(SmsSendRequest request)
{
using (var connection = new SqlConnection(_connectionString))
{
var parameters = new DynamicParameters();
parameters.Add("@orderNo", request.orderNo);
parameters.Add("@packageNo", request.packageNo);
parameters.Add("@packageCnt", request.packageCnt);
parameters.Add("@timeUp", request.timeUp);
parameters.Add("@responseUrl", request.responseUrl);
parameters.Add("@smsTitle", request.smsTitle);
parameters.Add("@smsBody", request.smsBody);
var result = await connection.QueryFirstOrDefaultAsync<SmsSendResponse>("FetchData", parameters, commandType: System.Data.CommandType.StoredProcedure);
return result;
}
}
}
}
3. Anthropic
溝通的Python程式碼::
import anthropic
api_key = "sk-ant-sdf332mlkrl39dfsfkslfjs8fsesefjlsfsk3dhdh5hj6rj67nhhk7"
uri_doc1 = "https://pouch.jumpshare.com/preview/fgAKFdHoyMQIxK986_cCVJyV9i60pqYyXhDIyP-irR1Zch46a5IeuNUBiVCQD-ilzcIv_ajoO5ObdvvMdN6lLCXu4DUqlp4Owv51xUVLIKs"
uri_doc2 = "https://pouch.jumpshare.com/preview/kdKEMmKTFCAao5u3YqHUEVD2mtm7GeApAGDqUEabc4357GlR3GB1DtWPxDMN2xbzAuLIvJA4UcmmPrm04w0iNvvEnRojmgCTkFmWDkZ8ETk"
uri_doc3 = "https://pouch.jumpshare.com/preview/QBv3Yua9oyjrH7S_ly-VPJTo8TLH95P7JXSO5yQKE5uz-E_ief61HaSerhpfGqnbAuLIvJA4UcmmPrm04w0iNkQ80KIOjNuaj92cz6SaUto"
uri_doc4 = "https://pouch.jumpshare.com/preview/H6RNFukmqhCAWqm1cRa4XXkVPGYgZZF1CjebFSR43hD7PEe1ybdJW8X04hZjDdLhAuLIvJA4UcmmPrm04w0iNvdVD6i__n8oqnkbPErdWro"
MODEL_ID = "claude-opus-4-20250514"
user_req = "產生C# Web MVC API 程式 "
proj_name = "DigitalDevProj"
data_service = f"使用 'dapper' 套件存取 'MS SQL SERVER' , SQL語法部分為執行名稱為 FetchData 的 'store procedure' \
對應欄位跟規格提供的名稱一樣。 dapper用法可參考網址內容 'https://dappertutorial.net/' 。"
system_prompt = f"成為一個專業的 'C# Web MVC API' 程式開發者, \
我需要你的協助產生程式碼, 只需要依照使用者需求內容來產生程式碼。只給我程式碼與相關的註解就好。"
prompt = f"需求為 {user_req} 。 \
任務是依照提供的網頁內容為規格,開發C# Web MVC API。提供的網頁內容試圖檔,請協助解析內容。然後回覆程式,為 controller、model與對應資料存取的 service 為 {data_service}。 \
回覆應包含「C# Web MVC API controller 、 model and Data Service 」 代碼,並排除任何不相關的內容、註解與資訊文字。 \
專案名稱為 {proj_name} 。 只需要提供SmsSend這部分即可。 "
#另外要注意的是,欄位 smsBody 是一個物件集合,集合的每個元素物件的成員描述在接下來的描述。"
client = anthropic.Anthropic(api_key = api_key)
message = client.messages.create(
model= MODEL_ID,
max_tokens=3000,
temperature=1,
system= system_prompt,
messages=[
{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "url",
"url": uri_doc1,
},
},
{
"type": "image",
"source": {
"type": "url",
"url": uri_doc2,
},
},
{
"type": "image",
"source": {
"type": "url",
"url": uri_doc3,
},
},
{
"type": "image",
"source": {
"type": "url",
"url": uri_doc4,
},
},
{
"type": "text",
"text": prompt,
},
]
}
]
)
print(message.content[0].text)
產生的程式: (未把註解解除,似乎就有正確把欄位結構對應好)
// Models/SmsSendRequest.cs
using System.Collections.Generic;
namespace DigitalDevProj.Models
{
public class SmsSendRequest
{
public string orderNo { get; set; }
public string packageNo { get; set; }
public int packageCnt { get; set; }
public string timeUp { get; set; }
public string responseUrl { get; set; }
public string smsTitle { get; set; }
public List<SmsBodyItem> smsBody { get; set; }
}
public class SmsBodyItem
{
public string uid { get; set; }
public string mobile { get; set; }
public string smsText { get; set; }
}
}
// Models/SmsSendResponse.cs
namespace DigitalDevProj.Models
{
public class SmsSendResponse
{
public string msgId { get; set; }
public string status { get; set; }
public string statusMsg { get; set; }
public string orderNo { get; set; }
public string packageNo { get; set; }
public int? packageCnt { get; set; }
public List<ErrorUid> errorUids { get; set; }
}
public class ErrorUid
{
public string uid { get; set; }
public string uidStatus { get; set; }
public string uidStatusMsg { get; set; }
}
}
// Services/SmsSendService.cs
using System.Data;
using System.Threading.Tasks;
using Microsoft.Data.SqlClient;
using Dapper;
using DigitalDevProj.Models;
using Microsoft.Extensions.Configuration;
namespace DigitalDevProj.Services
{
public interface ISmsSendService
{
Task<SmsSendResponse> SendSmsAsync(SmsSendRequest request);
}
public class SmsSendService : ISmsSendService
{
private readonly string _connectionString;
public SmsSendService(IConfiguration configuration)
{
_connectionString = configuration.GetConnectionString("DefaultConnection");
}
public async Task<SmsSendResponse> SendSmsAsync(SmsSendRequest request)
{
using (var connection = new SqlConnection(_connectionString))
{
var parameters = new DynamicParameters();
parameters.Add("@orderNo", request.orderNo);
parameters.Add("@packageNo", request.packageNo);
parameters.Add("@packageCnt", request.packageCnt);
parameters.Add("@timeUp", request.timeUp);
parameters.Add("@responseUrl", request.responseUrl);
parameters.Add("@smsTitle", request.smsTitle);
parameters.Add("@smsBody", Newtonsoft.Json.JsonConvert.SerializeObject(request.smsBody));
var result = await connection.QueryFirstOrDefaultAsync<SmsSendResponse>(
"FetchData",
parameters,
commandType: CommandType.StoredProcedure
);
return result;
}
}
}
}
// Controllers/SmsSendController.cs
using System;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using DigitalDevProj.Models;
using DigitalDevProj.Services;
namespace DigitalDevProj.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class SmsSendController : ControllerBase
{
private readonly ISmsSendService _smsSendService;
public SmsSendController(ISmsSendService smsSendService)
{
_smsSendService = smsSendService;
}
[HttpPost]
public async Task<IActionResult> SmsSend([FromBody] SmsSendRequest request)
{
if (!IsAuthorized())
{
return Unauthorized();
}
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
try
{
var response = await _smsSendService.SendSmsAsync(request);
return Ok(response);
}
catch (Exception ex)
{
return StatusCode(500, new { error = ex.Message });
}
}
private bool IsAuthorized()
{
string authHeader = Request.Headers["Authorization"];
if (authHeader != null && authHeader.StartsWith("Basic"))
{
string encodedUsernamePassword = authHeader.Substring("Basic ".Length).Trim();
Encoding encoding = Encoding.GetEncoding("UTF-8");
string usernamePassword = encoding.GetString(Convert.FromBase64String(encodedUsernamePassword));
int seperatorIndex = usernamePassword.IndexOf(':');
var username = usernamePassword.Substring(0, seperatorIndex);
var password = usernamePassword.Substring(seperatorIndex + 1);
return true;
}
return false;
}
}
}
// Startup.cs (Add to ConfigureServices)
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<ISmsSendService, SmsSendService>();
}
結論:
個人覺得以現在這個時間點,效果排名: Anthropic >= Gemini >> Gork
一樣的文件,Anthropic 似乎可以一次就看懂文件並完成程式(要付費)。Gemini也不錯(免費)。
但 Gork , 卻要再描述更詳細一點,才會比較正確(他要付費...),不過可能原因是url為參數方式目前只能用
"grok-2-vision-latest", 而 "grok-3-latest" 此時間點還未支援url為參數方式讀圖。
至於直接讀文件檔案方式,試過效果有一些出入,就先略過這部分的比較。不過讀檔可以直接請模型只寫某段API程式,這是大部分模型可以實現的。
大致上測試這三款,為何不測試 Open Api (chatGPT) 出的 model? 因為太熱門且要付費,應該可參考其它國內外的分享即可。
那 DeepSeek 則是有空再當作業測試看看。