發表文章

目前顯示的是 2025的文章

在Azure DevOps中建立共用的Yaml Pipeline Template

圖片
為何有這種需求 最近在上 Azure DevOps 課程,下課後,一群學員突然跑來問了個問題。 「老師,我們公司有三十幾個 Azure DevOps 專案,每個專案都有自己的 repo,每個 repo 都有自己的 pipeline yaml 檔…」他頓了一下,臉上帶著某種「歷盡滄桑」的表情,「有沒有辦法讓這些 pipeline 共用同一份 template?改一次就全部生效的那種?」 我其實急著下課,並沒有聽得很仔細,腦袋裡還在糾結:「為何要讓所有的 repo 都共用同一份 yaml template,每個開發專案不是應該有自己的 pipeline design 嗎?為何要為了統一控管搞得這麼複雜?」 於是我追問:「為什麼會有這種需求呢?」 他苦笑著說「每當公司想要在 pipeline 裡加入一些共用的步驟,比如說安全掃描、程式碼品質檢查、部署前的驗證等等,我們就得一個一個 repo 去改 pipeline yaml 檔。三十幾個專案,每個專案又可能會有好幾個 repo,改起來超級累人。」 教室裡其他學員也紛紛露出「我懂我懂」的表情。這種痛,做 DevOps 的人應該都瞭。 更慘的是,當你好不容易改完三十幾份檔案,過兩個月主管又說:「欸,我們現在還要加入程式碼品質檢查。」然後你又要再改一輪。如果哪天發現其中一個步驟寫錯了,想改?好啊,三十幾個 repo 再巡一次。 這就像是複製貼上了三十幾份同樣的食譜,結果發現鹽放太多了,然後你得把三十幾本筆記本都翻出來,一本一本改。真的累。 「所以…」學員問,「有沒有辦法讓這些 pipeline 共用同一份 template?改一次就全部生效?」 我當下趕著回家,沒多想,也來不及具體回答。 但回家後仔細思量:「這個問題其實挺實際的,應該是有解決方案的吧?」稍微翻了一下,果然發現 Azure DevOps pipeline 原本就支援引用外部的 yaml template。 如何實現? Azure DevOps 其實早就想到這個問題了。它提供了一個機制,讓你可以把 pipeline 的某些步驟抽出來,放到另一個 repo 裡當作「模板」,然後其他專案的 pipeline 就可以「引用」這個模板。 聽起來很簡單對吧?但實際上第一次設定的時候,總會有那種「欸這樣寫對嗎?」的不確定感。 我也是這樣,看著官方...

.net conf Taiwan 2025 Recap

圖片
11/29 ,我在 .net conf Taiwan 2025 的分享,題目是 『變革👉面對變革』,主要想談的是 LLM 在軟體開發領域(SDLC)中,這三年所帶來的改變。以及,如何面對。 關於『如何面對』這個部分,因人而異,我也就不想在這邊多說些什麼了。 但從 2022/11/30,一直到今天(2025/11/30),AI對軟體開發帶來哪些改變,我倒是整理出了一些影片,也是我在這次會場中分享的部分內容,做為這一季也是 .net conf 2025 我自己場次的小總結,也分享給大家。 有些影片沒有聲音,原因是那是用來配合我在在講台上的講解所錄製,大多不長,讀者可以自己腦補體會一下。 我想表達的是, LLM在SDLC的每一個階段,都已經留下了深刻而無法抹滅的痕跡。不管你願不願意,未來AI都會與你一起開發系統,沒有例外。 開發階段AI帶來的改變(AI輔助開發): 這一段我想說的是,從2023年到2025年,AI在程式碼撰寫這個領域,介入的愈來愈深,愈來愈廣。從『只是這樣?』,到『原來可以這樣』… 2023年盛行的 Code Suggestion(程式碼片段生成或建議) https://youtu.be/gPGE-Tze_sk 2024年盛行的 Agent Mode(IDE內的大範圍生成) https://youtu.be/v6PI9Fbt7Oo 2025年開始的 CLI(命令列模式大範圍修改或生成) https://www.youtube.com/watch?v=MnbEhg3JWq4 當天做的一個現場小調查,你會發現,在今天,軟體開發就等同於AI輔助軟體開發,幾乎沒有例外: 需求設計階段AI帶來的改變: 如果你願意,AI也可以產生需求規格。甚至,從產生需求規格一路自動到完成開發… User Story/AC 自動生成 https://www.youtube.com/watch?v=AxtYwBUMIyM 搭配MCP,從規格自動完成功能開發 https://www.youtube.com/watch?v=Yp9UImcfWfs CI階段AI帶來的改變: AI的大幅度介入,將會讓人類成為開發的瓶頸,而有趣的是解決這個瓶頸的鑰匙,也是AI。現在透過AI,可以協助人類做 code review,在測試左移(shift ...

為何想做CI的你,根本不該使用 Gitflow?

圖片
今天在 Build School 上課時發生了一件事,讓我想了想之後,還是決定寫篇文。 事情是這樣的。 上課時,我問學員:「如果有一個敏捷團隊,裡面大概 5-7 位成員,在一個迭代中同時開發 3-5 張需求卡片,你們覺得應該切幾個 feature branch?」 本來以為會聽到各種答案。 有人會按功能切、會按人頭切、或是按模組切…,因為我曾經聽過各式各樣的回答。 結果,他們所有人異口同聲:「只切一個分支。」 我愣了一下。「只切一個?」 「對,一個。」 這群學員才剛學 Git 沒多久,怎麼得出這個『違反常理』的結論的?上了這麼多年課,每次談到這個議題,學員都還可以跟我糾結半天,討論到底要不要用 Git Flow。 後來,助教跟我解釋,原來他們之前讓學員自己做了實驗。 什麼實驗? 實驗很簡單,因為反正要做專題,所以把學員幾個人分一組,讓他們用不同的分支策略跑幾個迭代。有些組按人切分支,有些按功能切,有些混著切。然後看看哪種方式最順。 結果呢? 用多分支的組,第一個迭代還算順利,大家各寫各的,感覺井然有序。但整合的時候就開始出事了。功能 A 做完了,但要等 B 跟 C 才能 merge。有人幾天沒事做,只能坐著等。 到第二個迭代,問題更大。大家在自己的分支上寫了一段時間,最後 merge 時才發現衝突一堆。有些衝突好解,但有些是邏輯上的衝突,或是使用了同樣功能的不同套件,兩個人改了同一個模組的不同地方,單獨看都沒問題,合起來就爆了。 第三個迭代,有人開始崩潰。明明功能做完、測試也過了,但因為流程卡在 release branch,要等到迭代結束才能部署。一個小 bug 改了五分鐘,卻要三天才能上線。更慘的是,有人說:「程式碼寫完過了很久才整合,開始忘記當初為什麼要這樣寫了。」 最後,讓他們自己試試看:如果大家都在同一個分支上開發會怎樣? 結果出乎所有人的意料之外。 衝突變少了(其實是變多了,但因為每天都在整合,有問題馬上發現,立刻解決,所以花在解決衝突的時間反而變少了)。部署變快了,一個小功能做完,就能立刻上線。整個團隊的節奏順暢很多,不用再有人乾等。 助教說:「他們自己體驗過就懂了,不用我們特別去教。」 聽完之後,我想了很久。 DORA 指標 其實他們體驗到的,就是 Google 研究出來的 DORA 指標在講的事情。 ...

在軟體開發的 PR 流程中,與 AI 工程師一同協作

圖片
開場 去年在 DevOps Days Taipei 研討會中,我有分享過類似的概念,當時我還無法實現。而且我覺得當時我提出這個想法的時候,很多現場聽眾目光裡閃爍著的,其實是略帶懷疑的眼神。 什麼概念呢? 我一直希望,能不能在 PR 過程中,Reviewer 只要寫下 Comment,就能有個 AI 工程師在背景直接幫我們改 code? 或是能有一個夜班的 AI 工程師,可以隨時待命,接手白天人類的工作,在晚上完成一些例行性的任務。 現在,這個夢想終於實現了。而且比我想像的還要好用。 讓我們先聊聊 Git 版控時的 PR 流程。如果你有再用 Git 做團隊開發,我相信你一定知道 Pull Request 是整個開發協作的核心。開發者提交程式碼、reviewer 進行逐行檢查、留下 comment、來回討論、最後 approve 或是 request changes。這個流程很務實,也很必要。 但一直有一個問題。 不知道你有沒有算過,從 reviewer 在 PR 上留下 comment,到開發者真正動手修改,中間會經過多久時間? 有時候是幾小時(如果大家都很閒),有時候是一整天(因為有會議、或其他工作),有時候甚至會拖到一兩天(可能是 Developer 沒收信、甚至根本是單純忘了上去看)。這段時間,PR 就這樣卡在那裡,什麼都不能做。CI/CD pipeline 也只能乾等。 更煩的是,有時候那些 comment 其實都是些「小修改」:改個函示名稱、加個錯誤處理、調整一下格式、補個註解。這種事情,說難不難,但要開發者停下手邊的工作、重新進入 context、再去改這些小東西,說實話,挺浪費時間的。 所以我一直覺得: 如果可以讓 AI 先做初步修改呢? 那會如何? 主要不是為了取代開發人員,而是在 reviewer 提出建議後,讓 AI 先試著去處理那些「機械性」的修改。再由人類負責審核、判斷、給建議;AI 負責執行、修改、產出結果。這不是挺完美的分工嗎? 實際操作 好,概念介紹完畢,來看看實際上如何運作。 假設今天有個 PR,reviewer 檢查後發現了一些需要改進的地方。就像平常一樣,在程式碼旁邊留個 comment。可能是「AI: 這一段應該要加上錯誤處理或Log」、「AI: 這個OOO變數名稱不夠明確」、「AI: 請加上OOO的...

使用 ADO Coding Agent 套件,在 Pipeline 中讓 AI Agent 自動運行各種任務

圖片
前言 你可能有聽過 GitHub Copilot Coding Agent ,它是一個可以搭配 GitHub Action,在背景自動執行 AI 任務的工具。甫一推出,就讓開發者們眼睛一亮,因為它讓 AI 能夠在 PR 或 CI/CD Pipeline 流程中,自動化地幫助我們完成許多重複性任務。 可惜的是,它目前只能在 GitHub Repo 上使用。 因此,我試著開發了 ADO Coding Agent 套件。 簡單來說,ADO Coding Agent 就像是 GitHub Copilot Coding Agent 的 Azure DevOps 版本 - 它可以在 Azure DevOps Pipeline 中自動執行你給 AI 的提示詞 (背後是 GitHub Copilot CLI),將 AI 的強大能力與 CI/CD 工作流程無縫整合。 我之前也 Demo 過,如何在 Azure Pipeline 中運行 GitHub Copilot CLI,我對這議題一直很有興趣,因為這讓 AI 驅動的自動化開發變成可能。這意味著,我們未來可能不再需要手動執行重複性的程式碼修改工作,而是可以在每次程式碼提交、或 PR 被觸發時,透過 Pipeline 讓 AI 來執行這些自動化工作。 無論是自動化 Code Review、自動生成單元測試、自動撰寫文件、自動修復 Bugs、或是進行程式碼重構,ADO Coding Agent 都能夠在背景完成,並且把結果直接寫回 Repo 中,這已經不只是效率的提升,而是我一直期待的 24h 自動化 AI 開發團隊的逐漸成形。 具體使用方法: 在 Pipeline 中添加 ADO Coding Agent Task (套件安裝位置: https://marketplace.visualstudio.com/items?itemName=tw-developer.ado-coding-agent )。 在 GitHub 站台上申請一個具有 Copilot Requests 權限的 PAT (申請位置: https://github.com/settings/personal-access-tokens/new ),這是因為該 task 主要是在 Pipeline 中調用 GitHub Copilot CLI ...

使用 Managed Identity 讓 WebApp 毋須帳密直接存取 KeyVault

圖片
你有沒有過這種經驗?把資料庫密碼寫在設定檔裡,commit 之後才驚覺「慘了!」然後開始瘋狂 Google「如何從 Git 歷史紀錄中永久刪除檔案」。 或者更糟的是,一時偷懶把 API Key 硬寫在程式碼裡,結果被同事在 Code Review 時抓包,尷尬地說「我只是暫時測試用的啦」(但其實已經在 Production 跑了三個月)。 歡迎來到~密碼管理地獄。😈 然而你可能不知道,Azure 提供了一個叫做 Managed Identity(受控識別) 的機制,可以跟本性的解決這類問題。 Managed Identity 是 Azure AD 中的一種應用身分(Service Principal),它就像是幫你的應用程式辦了一張「雲端身分證」。有了這張身分證,你的 WebApp 可以直接向 Azure 的各種服務(像是 Key Vault、Storage、Database)亮出證件說:「嘿,我是合法的!讓我進去!」 同時完全不需要在程式碼裡寫任何帳號密碼。 😲 這就像是住在有門禁管理的大樓,你不需要每次都掏出鑰匙,因為管理員認識你的臉。系統會自動幫你驗證身份,既方便又安全。 為什麼這麼做會讓老闆和資安長都笑開懷?那你得先知道,究竟使用 Managed Identity 的好處有多少? 1. 零密碼外洩風險 💪 當你的程式碼裡 完全沒有 密碼時,就算有人偷看你的 GitHub Repository、翻遍你的設定檔、甚至把整個專案下載回去,也拿不到任何可以用來入侵的憑證。因為根本就不存在!這就像是你家的保險箱沒有鑰匙孔,只能透過虹膜辨識開啟,小偷就算把保險箱搬走也沒用。 2. 不用再煩惱密碼輪替(Rotate) 🔄 傳統做法中,如果要定期更換密碼(資安政策通常要求 90 天換一次),你常常得改設定檔檔、重新部署、還要確保所有環境都同步更新。一個不小心,Production 就掛了。但使用 Managed Identity,Azure 會在背後自動處理所有的憑證更新,就像是有個超敬業的助理幫你處理所有煩人的行政工作。 3. 精準的權限管理 🎯 透過 Azure 的 IAM(Identity and Access Management),你可以精確控制「 誰 」可以「 對什麼資源 」做「 哪些操作 」。想讓 WebApp ...

漸漸消失的信任

圖片
我有兩次非常不好的用餐經驗。嗯…或許,該說是一次半。🤔 某天假日,一時興起想吃個早午餐,到了知名的連鎖店之後,點了看起來頗可口的漢堡。過程一切順利,餐點非常迅速的上桌,我迫不及待地品嘗一口,溫度適中,口感極好。一切都非常的完美… 直到…桌上放醬料的籃子旁,突然出現一隻蟑螂,會動的。靠~ 我不動聲色,伸手攔截了剛好從我座位旁經過的服務人員,他一臉驚訝地望著我(我猜他是在想,我為何突然伸手襲擊他!?)。 我什麼都沒說,隨即給了他一個眼色。 他朝我的目光望去,臉上的驚訝轉為慌張。 但,他也不動聲色(厲害!),朝著目標前進,居然用手一巴掌把目標物給抓了起來,隨即往廚房走去,就好像什麼事情都沒發生過一樣。 另一次,一天早晨,我到了一個過去不曾來過的地點,因為剛好有一段不長不短的時間(等人),所以我就沿著大街閒逛,突然看到一家老麵包子店,正愁沒吃早餐,因此我就隨便點肉包菜包各一份,想說試試看。 沒想到,非常之好吃 ! 我對包子是很挑的,我覺得全台灣好吃的包子只有三家,而我今天吃到的這家,居然可以媲美我心中第二名,這讓我內心的包子排行榜大大的洗牌了。 回到家之後,立刻把這包子跟家人分享。 然後我也很疑惑,這麼好吃的店怎麼從來沒有聽到過呢? 上網查。 一查不得了,Google 評價非常兩極。 翻了幾頁都還無所謂,直到我看到一個評價,除了文字還附上了一張照片。 文字是這麼寫的:『吃到腳了,有人吃到頭嗎?』 然後照片是包子裡面一節蟑螂的腳。 靠~ 又來。 你猜,我後來還有去這兩家店嗎? 再也沒有,一次都沒有。 這兩家店不好吃嗎? 不會,其實都很好吃。 但我不會去了,因為我對這兩家店完全失去信心。 (那怕其中一家根本不是親身經驗) 上面是第一段故事。 接著,我要講另一段我前幾天在課堂上說的故事。 我有一個朋友(不是我),他從小喜歡外文,也常常看外文書籍,雖然都是自學,但也因此遍覽群書,自從有了 AI 之後,他樂翻了。 透過 AI 的翻譯,他開始閱讀過去不曾讀過的語言,剎那間全世界的浩瀚,都在他的眼前。由於他常常在網路上分享他讀過的書,因此出版社就開始找他作書籍翻譯,他也很開心能夠把不同語言的書籍介紹給更多有興趣的人。 但因為他畢竟都是靠自學和 AI 翻譯,所以對於比較艱澀少見的文字較難掌握,不過整個大方向他是 OK 的,他用極...

Too Fast to Think 快到來不及思考:AI 時代開發者的腦力透支危機

圖片
上週四晚十一點,有位工作上的夥伴 Eric 在 Teams 上貼出了一段訊息:「剛剛用 Claude 一口氣寫了三個功能,感覺效率爆表!」文末還配上了一個肌肉的 emoji 💪。 隔天,早上九點,我看著他頂著熊貓眼進會議室,手裡拿著第三杯咖啡。「怎麼了?」我問。 「昨晚那幾個功能…有兩個邏輯不對,一個測試全掛…我從半夜改到剛剛。」他苦笑著說「AI 寫得太快了,我根本來不及想清楚就繼續下一個,結果…」 這種場景,你是不是也開始很熟悉? AI 讓我們變成了「高速公路上的疲勞駕駛」 還記得沒有 AI 的年代嗎?(對,我知道那好像已經是上個世紀的事了,雖然才過了兩年) 以前寫程式是這樣的: 思考需求(泡杯咖啡,先想個 15 分鐘) 設計架構(畫畫白板,跟同事討論一下) 開始寫 code(一行一行慢慢敲) 測試除錯(找問題,修 bugs) 提交上版(長舒一口氣) 現在呢? 有了 Claude、GitHub Copilot、Cursor 這些開發神器後,開始有所不同: 在 Prompt 輸入方格裡描述需求(30 秒) AI 給你三種架構方案(10 秒) 選一個,AI 自動生成程式碼(20 秒) 複製貼上,改改參數(1 分鐘) 跑不過?問 AI 為什麼(30 秒) AI 給你修正版本(20 秒) 能動,結束。那…繼續下一個功能… 看起來超讚的對吧?效率提升十倍!老闆眉開眼笑,專案進度超前! 但問題來了:我們的大腦跟上了嗎? 「認知債」:比技術債更可怕的東西 技術債大家都知道,就是為了趕進度寫出來的爛 code,將來要花更多時間來償還。 但現在我們面對的是一種新型態的債務: 認知債 。 什麼是認知債?就是 當 AI 生成程式碼的速度,遠超過你理解這些程式碼的速度時,累積下來的「理解負債」 。 舉個例子。 某天 AI 幫你生成了一個看起來「完美」的 .NET 8 Web API 專案:用 Minimal APIs 搭配 依賴注入 (DI) 、全域 Exception Handling Middleware 、 EF Core (含 UnitOfWork 與 Repository 模式)、 MediatR 指令/查詢分離、 FluentValidation 、 AutoMapper 、背景作業用 IHos...

在 ADO Pipeline 中使用 GitHub Copilot CLI:實現全天候24h開發的夢想

圖片
我跟你說,我夢想著實現這個功能很久了✌ 我一直希望能夠在 CI/CD Pipeline 中加入 LLM 的力量。 我一直想透過 CLI 讓 LLM 在 Pipeline 中自動處理重複性任務。例如,在晚上讓 AI 自動幫我找 bugs、自動做 Code Review、甚至自動撰寫說明文件或一部分程式碼… 然後,我夢寐以求的 “兩班制全天候24h開發團隊” 就可以實現了!!! 白天,由 Developer 搭配 AI 進行開發。 晚上,由 AI 自己去做比較不需要人監督或無傷大雅的工作,像是寫文件,找 bugs 之類的。 然後隔天早上工程師上班之後,就可以繼續接手 AI 昨晚產出的成果,接著進行開發。 嘿嘿,這樣是不是太完美了? 想想都覺得興奮。 緣起 在現代軟體開發中,效率與自動化是不可或缺的要素。 GitHub Copilot CLI 的出現,為我們提供了一個強大的工具,能夠在開發過程中自動生成程式碼、撰寫技術文件,甚至協助除錯。 假設我能將這項工具整合到 Azure DevOps 的 Pipeline 中,自動在晚上運行,就可以實現我之前說的 全天候的開發流程 。(以前是把程式碼發包給印度的工程師,現在 AI 就是我的夜班工程師!!!) 嘗試在 Azure DevOps Pipeline 中使用 GitHub Copilot CLI 想要將 GitHub Copilot CLI 整合到 Azure DevOps Pipeline 中,有幾個關鍵步驟。 首先,你要能夠在 Build Agent 上安裝 GitHub Copilot CLI。要這麼做不難,只需透過底下這個 bash script 指令就可以完成安裝 。 npm install -g @github/copilot 只是,你得先確定 Node.js 已經安裝在你的 Agent 上,且是最新版本。 因此,我們會在 pipeline 中,先用一個 step 來安裝 Node.js。 steps : - task : NodeTool@0 displayName : 'Use Node 22.x' inputs : versionSpec : 22.x 接著,我們就可以安裝 GitHub Copilot CLI 了...

使用ADO MCP搭配Chrome DevTools MCP享受E2E自動化UI測試

圖片
這支影片展示了如何透過 Azure DevOps (ADO) 的 Model Context Protocol (MCP) 整合 Chrome DevTools MCP ,實現端到端(E2E)的自動化 UI 測試流程。 影片中展示了如何讓測試腳本的運行不再倚賴人工,開發者只需要在 GitHub Copilot 中下達提示指令,MCP 代理便能自動呼叫瀏覽器、執行互動測試、檢查運行結果並回報測試通過或失敗,還能順手撰寫完整的測試報告。 整個流程結合了 AI Agent + Chrome DevTools + Azure DevOps Test Case 的強大能力,實現真正的「零人工自動化測試」: 由 PM/SA/PO 負責描述測試路徑 (例如登入流程、輸入數據、按鈕執行…etc.) 由 Chrome DevTools MCP 負責具體執行並檢查測試結果 由 GitHub Copilot 負責記錄與撰寫測試結果 這樣的整合大幅提升測試效率與速度。 未來,或許每位工程師都能「像喝咖啡一樣輕鬆地跑完自動化測試」。 看完之後,來 FB 留言分享一下你的感想~ https://www.facebook.com/DotNetWalker/posts/pfbid02qnBruy8mJLnoCswoXnNRQvAqoyAhnXMEA9dqcun3M3rSMx1rv3NovvAZWmJBFqwBl 我很好奇大家的看法。

有趣比有意義重要

圖片
日前參加 DevDays 2025 大會,和幾位 MVP 講師在台上 live 接受學員們的提問。問題五花八門,既有技術細節,也有宏觀趨勢。會後又和社群朋友閒聊,回到家,還收到幾則來自學員與老友的 LINE 訊息。 和大夥閒聊和互動的過程中讓我更感受到,似乎還是有不少開發人員對 Vibe Coding 以及最近這陣子以來,AI所帶來的改變感到焦慮~ 技術變化如此快速,我們究竟該緊跟不放,還是先按兵不動? 到底該持續follow,還是讓子彈飛一會兒? 不只是個人,企業也急於導入 AI,卻總是找不到真正有意義的場景與能發揮價值施力點。 大家隱約知道 AI 開始改變了許多事情,但心中又有一絲不安:自己該怎麼辦?該如何面對? 在一個半小時的時間裡,我還真無法給一個面面俱到的答案。 最後主持人請我做個總結,但其實我心裡想講的是,在資訊產業當中,面對變革早已不是一天兩天的事情了。2022 年底 ChatGPT 初現時,我滿懷興奮與期待;到了 2023 年中,焦慮與疑惑席捲而來;2024 年底,我逐漸找回自己的節奏,直到今天。 回想自己整個歷程, DevDays 2025 大會的最後,我分享給大家我自己面對 AI 時的三個心態與轉折… 接觸:直球對決 直到今天,仍有不少人對 AI 避之唯恐不及,甚至認為它只是一場即將破滅的泡沫。這樣的想法很可以理解,當市場上各種 AI 課程、話題氾濫,它走向泡沫並不令人意外。但請注意,那是對投資人而言。而我們來說,則大大不同。還記得2001年 .com 泡沫化之後發生的事情嗎?真正的改變,那時才剛剛開始。 AI帶來的影響已無庸置疑,這個階段,你的各種的接觸都是好事(是的,包含可能帶來風險的 Vibe Coding ),各種嘗試都是加分,不要躲避,去面對這個改變,直球對決,這是第一件事情,也是最重要的一件。 體驗:唯有親身嘗試,才會生出洞見 接著是體驗,我是指你自己親身的體驗。不只是去聽聽課,或只是上網玩玩圖片生成、與ChatGPT聊聊天而已。 昨天提到,光是 Vibe Coding 這個詞,十個人就能說出十一種不同的解釋。我自己在 2022 到 2025 年間,就歷經至少四種不同型態的 AI 輔助開發,而 Vibe Coding 這個詞到了2025年初才開始出現。其實每種方式在碰到不同的情境時(專案大小、團隊...

Responsible Vibe Coding

圖片
昨天 “恰巧” 碰上了洗版全台的 vibe coding 事件,所以很多人以為我說 Responsible Vibe Coding 是玩笑話 ​ 不~我是認真的。 你拿 Responsible Vibe Coding 這個字去網路上搜尋,就會發現,早已經有太多人在討論 Vibe Coding 帶來的風險以及如何因應。 特別是對於原本不在軟體開發領域的開發新手而言,有許多需要注意的事情,甚至已經有人針對 Responsible Vibe Coding 列出了 guidelines… LLM確實讓進入軟體開發的門檻大幅下降,甚至有人用了 democracy 這個詞來形容(意味著過去被少數人壟斷的專有能力,如今已釋放給所有人…),但這也是 吳恩達(Andrew Ng) 不喜歡 vibe coding 這個詞彙的原因 讓人誤以為軟體開發從此就變得人人可做了。 然而其實不是的。 因為,專業 與 非專業 的差異,其實不只是能力,而是 『態度』。 專業不只是因為能力比較強,或是比較有經驗,也是因為願意去做那些流程中看似無聊和瑣碎的雜事,以至於我們的成品可以在安全性和品質上得到保障。 寫程式,或許變得容易了(反正都是AI寫嘛),但寫出高品質的好程式,則依舊是專業人士才能作到的事情。 新手面對 Vibe Coding 到底該注意些什麼,如何才能兼顧品質、安全、和效率? 我把相關資訊,放在底下: https://vibe-coding-manifesto.com/ https://medium.com/@harsz89/from-heads-down-to-hands-off-a-journey-into-responsible-vibe-coding-3d81a1c5634c https://www.businessinsider.com/andrew-ng-vibe-coding-unfortunate-term-exhausting-job-2025-6 針對 vibe-coding-manifesto 這份給開發人員的 Responsible Vibe Coding 建議,整理如下: Rules for AI-Assisted PR Submissions(AI 輔助的 PR 提交規則) 這一部分主要在講:如果你用 AI 幫忙產生程式碼,當...

LINE Imagemap 陷阱:baseUrl 原來不是一張圖!

圖片
在最近的某個專案當中,客戶希望在 LINE 官方帳號的互動中,使用 Imagemap 訊息格式。 Imagemap 可以讓使用者點擊圖片上的不同區塊,以便於觸發不同的行為,例如導向不同的網頁、回傳不同的文字訊息,非常適合設計互動式選單或導覽。 例如,假設你用底下這張圖當作Imagemap: 則可以設定成,如果用戶點選左邊,則會出現 鶯歌 的簡介,點右邊,則會出現八德的簡介。 我的 team member 馬上動手實作,照著文件寫下程式碼,其中一則 Imagemap 訊息的json代碼類似底下這樣: { "type" : "imagemap" , "baseUrl" : "https://example.com/images/sample.png" , "altText" : "選單" , "baseSize" : { "width" : 1040 , "height" : 1040 } , "actions" : [ { "type" : "uri" , "linkUri" : "https://example.com/page1" , "area" : { "x" : 0 , "y" : 0 , "width" : 520 , "height" : 520 } } ] } 但是,不管怎麼設定,圖片就是顯示不出來。總是出現類似底下這樣的錯誤訊息: debug 了好一陣子,毫無頭緒。 同仁跑來問我時,我看了一眼,突然想起以前也踩過這個坑。 其實, baseUrl 並不是一張圖片的 URL ! 此參數之所以叫做「baseUrl」,是因為它代表的是 圖片的基底路徑 。(而非圖片的路徑) LINE Imagemap 為了要在不同裝置(例如手機解析度不同)都能有合適的圖...

在LINE Bot中使用MemoryCache保存Semantic Kernel的對談記憶

圖片
在開發 LINE Bot 的 AI Agent 或客服機器人時,最重要的功能之一就是 記憶 。 使用者永遠會預期機器人應該要能「記得上一句話」,並能依照上下文繼續對話。 在 Semantic Kernel 中,提供了 ChatHistory 物件來維護對話脈絡。這個物件會記錄 system / user / assistant 的訊息序列,當傳給大語言模型 (LLM) 時,就能讓模型在上下文中產生更自然的回覆。 但是,有一個問題: LINE Bot 的 Webhook API 是 Stateless 的 ,這意味著,每一次訊息事件進來,Controller 都是新的,不會自動幫你保存之前的 ChatHistory 。 因此,如果我們要讓 Semantic Kernel 記住對話,就需要額外設計一個「記憶儲存機制」。 短期記憶的解決方案:MemoryCache 方法有很多,但如果你的應用場景是: AI Agent / QA 客服 一次對話通常會在 半小時內結束 這時候就不需要複雜的資料庫,只要使用 .NET 內建的 MemoryCache 就能搞定。 MemoryCache 的特點 存放在伺服器記憶體中 可以設定 滑動到期時間 (SlidingExpiration) → 長時間沒互動就清掉 可以設定 絕對到期時間 (AbsoluteExpiration) → 即使一直互動,最多存活多久(避免高費用或token爆掉) 效能快。但也因為是存放在伺服器端記憶體中,應用程式重啟或多台伺服器作HA架構時,資料會消失,重新佈署應用程式時,也會消失。 還算是適合「短期記憶」的應用場景。 專案架構 底下示範如何在 LINE Bot WebAPI 專案中,整合該機制,我們建立了三隻程式: Controllers/LineBotChatGPTWebHookController.cs (處理 LINE Webhook) Controllers/ChatCompletion.cs (使用Semantic Kernel 生成 AI 對話) Controllers/ChatHistoryMemoryStore.cs (短期對談記憶保存) 完整程式碼我放在: https://github.com/isdaviddo...

C# 格式化(formatter)在 VS Code 中的選擇

圖片
程式碼的世界裡,有一個古老的爭論: 大括號 { 到底該放在同一行,還是獨立成一行? 這不只是排版問題,有時甚至會演變成團隊會議上的「宗教戰爭」。而我自己也有喜歡的 indent style ,如果看到團隊中其他人的寫法和我不同,雖不至於惱怒,但總覺得有些彆扭。有一種衝動很想把它全部改成自己習慣的方式。 你大概可以想像,當有一天,我發現 VS Code 升級到新版之後,排版和對齊方式竟然變成和我喜歡的不同,那時候我有多麼的震驚,一整天都想要把它給改回來。 怎麼做? 今天我們就來談談,如何在 VS Code 裡改設定,讓 { 的排版聽話。 兩種常見風格 先來看看範例: 1. K&R (大括號跟在同一行) public class HelloWorld { public void SayHello ( ) { if ( true ) { Console . WriteLine ( "Hello, world!" ) ; } } } 2. Allman Style(大括號獨立一行) public class HelloWorld { public void SayHello ( ) { if ( true ) { Console . WriteLine ( "Hello, world!" ) ; } } } 先問問,你喜歡哪一種? 各自的優缺點 同一行風格 (K&R) ✔ 節省垂直空間,檔案比較短。 ✔ 很多 C# 官方範例和文件都是這種格式。 ✘ 有人覺得程式「擠在一起」,閱讀時容易忽略最末端的 { 。 獨立一行風格 (Allman) ✔ 大括號醒目,結構一眼就能看出來。 ✔ 不容易漏掉對應的 { 與 } 。 ✘ 程式會「莫名變長」,多佔好幾行。 👉 簡單說:前者像極簡主義,後者像穿寬鬆衣服,空間感十足。 你是哪一派呢? 在 VS Code 裡如何調整? 方法一: .editorconfig (推薦) 在專案或解決方案根目錄新增 .editorconfig 檔案: root = true [*...

開發者的肌肉記憶

圖片
前陣子,網路上出現一支很轟動的受訪影片, 原因不只是它的長度驚人👉整整六小時: 更重要的是,受訪者是 DHH。 如果你不熟悉他是誰,DHH 全名是 David Heinemeier Hansson,他是 Basecamp 的創辦人,更是 Ruby on Rails 框架的建立者。在開發者的江湖裡,他是那種推一句話就可能引發社群爭論、寫一篇 blog 就可能改變許多開發者的那種人。 訪談中,他談到一個很多人都有那麼點感覺的主題: AI 與 Vibe Coding 對開發者帶來的影響。 他坦言,自從頻繁使用 Auto Complete 與 AI code generation 之後,開始感受到一種「技能退化」的跡象。(有鑑於他的開發能力與背景,我相信他說的,遠多過於其他那些早已不寫 Code 的業界大佬) 一些原本熟練的 API 名稱,突然要多想一下; 思考邏輯的節奏被打斷,肌肉記憶也逐漸消失。 你知道我個人對 AI 輔助開發一直以來的看法, 在絕大部分的情況下,我支持使用 AI 輔助開發遠高於其他人。 為何是「在絕大部分的情況下」呢? 因為,身為一位稍有年資的開發者,我依稀覺得有某個地方怪怪的,但又一直說不上來是哪裡。 直到這次聽到 DHH 的分享,他是第一個明確說出我一直講不出來的那種感受的人,深思後我不得不同意他的觀點。 大量使用 AI輔助開發,特別是最近很紅的 CLI 那種,確實有可能失去開發者特有的 「肌肉記憶」,不只是敲鍵盤的準確度而已,而是某種鍵盤跟大腦之間獨特的聯繫。 如今,大量使用 AI 輔助開發的人, 大多都認為未來開發者的角色將逐漸改變。 從一個「敲打鍵盤的人」,變成一個「溝通者」或「監工者」。 與 AI 溝通、審視 AI 產出、並且進行判斷與修正。 但這樣的轉變,是否也像極了過去許多技術人員,逐漸離開技術轉型成主管的過程? 看似升級,實則在過程中逐漸失去對技術本身的感知與掌握。 當我們不再自己動手,久而久之,是否也會失去「能動手」的能力? DHH 說,那些「自己一行行鑿刻程式碼」的過程,恰好是開發工作樂趣的來源。 當我們在鍵盤上敲下每一個詞彙時,大腦同時也在構建一種獨特的神經迴路 – 那正是開發者創造力與思考能力的來源。 他並不反對 Vibe Coding,只是用一個開發人員的角度給出了提醒...

Junior Developers 在 Vibe Coding 時的問題與挑戰

圖片
最近有個發生在我們專案上的真實案例。 一位初階開發人員用 AI 一口氣生出 前端註冊表單 以及 後端驗證與寫入資料庫 的程式碼。建置沒錯、可以運行、AI 自我檢查後也說了聲沒問題,但是一跑, 前端的資料就是進不到後端模型 ,驗證當然也就永遠失敗。 這位 Junior Developer 卡在這邊三小時(生成這段程式碼的時間其實只有5分鐘),直到下班前,一票老傢伙看不下去,在旁邊盯著把前後端程式碼一一對起來後才發現,問題居然只需要改一個字母而已。 現場重現:前端 AJAX 送這個 劇情其實很簡單,前端把使用者輸入後的資料,包裹成類似底下這樣的 JSON,透過 AJAX 丟到後端 Controller: { "UserName" : "Rick" , "Email" : "rick@example.com" , "Password" : "P@ssw0rd!" , "PhoneNumber" : "0987123456" } 產出上面的這段 JSON 的程式碼是 AI 寫的。 而接著 ASP.NET Core 的 Controller 大概長底下這樣: [ ApiController ] [ Route ( "api/[controller]" ) ] public class AuthController : ControllerBase { [ HttpPost ( "register" ) ] public IActionResult Register ( [ FromBody ] RegisterRequest input ) { // input 的屬性全是 null -> 驗證失敗 if ( input is null || string . IsNullOrWhiteSpace ( input . username ) ) return BadRequest ( "payload invalid." ) ; /...