整理這些技術筆記真的很花時間,如果你願意 關閉 Adblock 支持我,我會把這份感謝轉換成更多「踩坑轉避坑」的內容給你!ヽ(・∀・)ノ
淺談 AI Vibe Coding 當今主流的 BDD 與 SDD
.png?alt=media&token=82e1948d-156e-467d-959b-b55f6af538c6)
前言
基本上只要你有使用過 AI 來開發任何一個產品或者功能,你應該或多或少都聽過 AI 程式碼生成等詞彙。在這裡,我將這種「直接用自然語言來描述功能,由 AI 生成程式碼」的模式,稱為「Vibe Coding (直覺式開發)」。
Vibe Coding
首先 Vibe Coding 直接翻譯成中文我認為滿奇怪的,但我覺得翻成「直覺式開發」比翻譯成「憑感覺開發」來的好很多,因為 Vibe Coding 的意思就是「直接用直覺來開發」,也就是說你不需要去寫程式碼,你只需要用自然語言來描述你想要的功能,然後 AI 就會幫你生成程式碼。
除此之外 Vibe Coding 也有一些核心精隨:
- 自然語言描述: 使用自然語言來描述功能,而不是人為地撰寫程式碼。
- 不在意實作細節: 使用者不需要關心是用 Python 還是 JavaScript,也不用管分號要不要加,全由 AI 處理。
- 專注業務邏輯: 使用者可以專注於業務邏輯的描述,而不需要關心技術細節。這使得開發者可以快速驗證想法的可行性,將精力放在「解決什麼問題」而非「如何寫程式」。
- 即時回饋與迭代: 當程式碼 or 功能不符合預期時,可以請 AI 來修改而不是人工調整。
- 門檻解除: 許多開發者對於寫程式充滿著畏懼,但 Vibe Coding 可以讓這些人也能夠參與開發,因為 Vibe Coding 只需要自然語言描述就可以了,實現真正的「人人都可以創造」。
以我自己來講,我也用 Vibe Coding 做了不少小工具,甚至套用到工作上。
Vibe Coding 隱藏的問題
完全依賴「直覺」與 AI 溝通來產生程式碼,在專案變大的時候,也會開始有一些明顯的瓶頸出現:
- 不夠精確(Ambiguity): 這是自然語言描述本身就有的模糊性,尤其中文博大精深,同樣一句話可能有多種解釋。
- 舉例:「請幫我寫一個可以計算兩個數字相加的程式」。
- 對於 AI 來講:你到底是想要做「浮點數相加」還是「整數相加」呢?因為「數字」這個詞本身就不夠精確
- 風格不一致(Inconsistency): 開發者為了「未來的維護性」通常會有一套嚴謹的 Code Style,然而 Vibe Coding 生成的程式碼,往往都有可能不同,若人工介入就會失去 Vibe Coding 的意義。
- 功能缺陷(Bugs): AI 生成的程式碼都有細微的邏輯錯誤,對於一名非技術人員來說,這些錯誤可能很難被發現 or 邊界案例(Corner Cases)無法被完整涵蓋。
- 資安疑慮(Security): 可能會有一些安全性問題,例如 SQL Injection、XSS 等等,這些問題需要使用者自己去處理。
Note
邊界案例是指在特定條件下,系統可能會出現異常行為的情況,這些情況通常是比較少見或極端的,但卻可能導致系統崩潰或錯誤。
這些都是很明顯的 Vibe Coding 的缺點,所以接下來我就要來介紹 BDD 與 SDD,這兩個方法可以幫助我們解決 Vibe Coding 的一些問題。
BDD 與 SDD:讓 AI 更聽話的框架
BDD 全名是 「行為驅動開發」(Behavior-Driven Development) ,而 SDD 全名是 「規格驅動開發」(Specification-Driven Development) ,這兩個方法都是用來幫助我們更好地描述需求和行為,從而生成更精確和一致的程式碼。
這兩個東西並不是多新潮的東西,以 BDD 來說,它其實跟 TDD(Test-Driven Development)有很大的關係,TDD 核心精髓在於 「先寫測試,後寫程式碼」 ,但 BDD 則是 「先描述行為,後寫程式碼」 。
「TDD 不適合用於 Vibe Coding 嗎?」你可能這樣問。
我認為這是一個好問題,並不是 TDD 不適合用於 Vibe Coding,而是 TDD 本身就是一個比較技術性的東西,對於非技術人員來說,TDD 可能會有一些門檻,對於一個普通人來說很難理解什麼是「測試」,更不用說他們連「程式碼」可能都不知道是什麼東西了。
而 BDD 則是很剛好的與 Vibe Coding 的理念相符,因為 BDD 是用自然語言來描述行為,這正好符合 Vibe Coding 的「自然語言描述」的特性,其實也是在強迫使用者用結構化的的方式來描述需求。
那…SDD 呢?簡單來講,SDD 就是一份詳細的需求規格文件,這份文件詳細的說明了系統應該要有什麼功能、行為以及限制條件,這樣 AI 在生成程式碼時就可以參考這份文件,從而生成更符合需求的程式碼。
所以接下來我將會拆分兩個部分來介紹,以及說明如何應用在 Vibe Coding 上。
BDD 在 Vibe Coding 的應用實戰:講述故事
BDD 的運作通常圍繞著三個核心步驟,而在 AI 開發中,我們主要專注於第一步:
- 行為描述(Given-When-Then): 使用者用自然語言來描述系統的行為,通常會使用「Given-When-Then」的格式來描述
- 實現行為的測試(Test Implementation): 根據行為描述來實現測試,這些測試可以用來驗證系統是否符合行為描述
- 生成程式碼(Code Generation): 最後基於測試案例來生成程式碼
那什麼是 Given-When-Then 呢?
- Given(前提條件): 描述系統的初始狀態或背景。例如:「Given 使用者已經登入系統」
- When(行為觸發): 描述使用者或系統所執行的動作。例如:「When 使用者點擊 ‘新增商品’ 按鈕」
- Then(預期結果): 描述系統應該要達到的結果。例如:「Then 系統應該顯示 ‘商品已新增’ 訊息」
舉例來說,假設我們要開發一個簡單的購物車功能,我們可以用 BDD 來描述這個功能:
1 | |
了解了 BDD 的基本概念後,在這邊我要將 BDD 稍微調整一下,也就是變成以下:
- 行為描述(Given-When-Then): 使用 Given-When-Then 來描述系統的行為
- 實現行為的測試(Test Implementation): 由 AI 根據行為描述來實現測試
- 生成程式碼(Code Generation): 最後由 AI 根據測試案例來生成程式碼
所以其實你真正要專注的點還是在於「行為描述」這個部分,而不是其他兩個部分,因為其他兩個部分都是由 AI 來處理的。
結合 User Story (使用者故事) 提升 AI 理解力
單純的行為描述有時會缺乏上下文(Context),因此我強烈建議搭配 User Story。
Note
對於 AI 來講,如果有明確的上下文(Context),它會更容易理解使用者的需求,從而生成更符合需求的程式碼。
User Story 的公式如下:
1 | |
舉例來說,假設我們要開發一個購物車功能,我們可以這樣描述 User Story:
1 | |
透過前面簡單介紹,我們可以知道 Use Story 可以幫助我們更好地理解使用者的需求,而不是單純的功能面,那為什麼要特別提到 User Story 呢?因為你可以搭配 User Story + BDD 組合成一個給 AI 完美的 Prompt。
如果你直接跟 AI 說你想要做購物車功能,AI 肯定會亂做,但如果你今天是這樣寫:
1 | |
你會發現這邊我用了 Requirements 來跟 AI 說明接下來都是一個需求清單,並且搭配了 Markdown 的標題來區分階級,這樣 AI 就可以更好地理解整體的結構,並且生成符合需求的程式碼。
了解完 BDD 後,接下來我們來看看 SDD 怎麼幫助我們解決 Vibe Coding 的問題。
SDD 在 Vibe Coding 的應用:定義骨架
如果說 BDD 是在故事的話,那麼 SDD 就是在畫藍圖,也就是告訴 AI 資料該長什麼樣子、該用什麼技術、有哪些開發規範。
對於一般開發者來講,應該最熟悉的就是 SDD,畢竟 SDD 就是需求規格文件 (Software Design Document) 的縮寫,而需求規格文件通常會包含以下內容:
- 系統架構(System Architecture): 描述系統的整體架構,包括前端、後端、資料庫等。
- 資料結構(Data Structures): 定義系統中使用的資料結構,例如資料庫的表格結構、API 的資料格式等。
- 技術選型(Technology Stack): 指定系統使用的技術,例如程式語言、框架、工具等。
- 開發規範(Development Standards): 定義程式碼風格、命名規則、測試標準等。
- 非功能需求(Non-Functional Requirements): 包括效能、安全性、可擴展性等方面的需求。
舉例來講,我們可能會建立一個 Markdown 文件,內容如下:
1 | |
你會發現這些細節相較於 BDD 來說,更加技術性,對於非技術人員來講其實滿不友善的,但對於 AI 跟開發者來講,這些細節卻是非常重要的,也相對容易理解。
建立完 design.md 之後,接著還會建立一個 specs.md,內容如下:
1 | |
你會發現上面這些內容根本就是等價於程式碼,對於 AI 來講,它也能產出相對應的程式碼,其準確度是非常的高。
如果你用 SDD 寫到這麼細的話,AI 要發生幻覺的機會基本上是很低的,因為它不需要去猜「庫存不足要幹嘛?」,也不用猜「重複加入是要新增一筆還是數量 +1?」,因為你都透過規格文件告訴它了。
所以到底該選 BDD 還是 SDD?
看到這邊應該會充滿著一個疑惑:
「那這樣我該選 BDD 還是 SDD 呢?」
其實兩者是可以混在一起使用的,因為 BDD 側重於「行為描述」,而 SDD 側重於「技術細節」,兩者可以互補。但對於非相關專業人員來說,我會建議先從 BDD 開始,因為 BDD 更符合自然語言的描述方式,對於非技術人員來說更容易上手。
如果本身是有開發經驗的人,那麼就會比較側重於 SDD,畢竟 SDD 可以幫助我們更好地定義系統的技術細節,從而生成更符合需求的程式碼。
當然如果想要 BDD + SDD 混合使用也是可以的,這樣可以同時兼顧「行為描述」與「技術細節」,從而生成更精確和一致的程式碼,而這個範例大概就會變成像這樣:
1 | |
其實混用並不困難,就是把 BDD 的行為描述放在前面,然後接著 SDD 的技術細節,這樣 AI 就可以同時理解「我要做什麼」以及「我要怎麼做」,從而生成更符合需求的程式碼。
結論
當你這些文件都撰寫的很好的話,你就可以直接下以下 Prompt 給 AI:
1 | |
接著 AI 就會依照你的需求來生成程式碼,而不是亂七八糟的東西。
所以工程師有因此變的輕鬆嗎?我認為沒有,除了維護程式碼之外,還要維護一大票的文件。
整理這些技術筆記真的很花時間,如果你願意 關閉 Adblock 支持我,我會把這份感謝轉換成更多「踩坑轉避坑」的內容給你!ヽ(・∀・)ノ