2026年4月25日 星期六

Gemini CLI 學習筆記 : OpenSpec 初體驗 (一)

最近幾天上完 TibaMe 的規格驅動開發 (SDD) 課程, 準備找一個小專案 (計算器) 用 Gemini CLI 來跑一下 OpenSpec 交作業. 

本系列全部測試文章參考 : 


關於 SDD 我已看完高見龍老師的部落格文章, 摘要整理在這篇 : 



1. Gemini CLI 升版 :

距離上次測試已經過了快三個月了, Gemini CLI 版本應該也演進了不少, 所以先來升版. 開啟 PS 視窗, 輸入下列指令查詢目前本機版本 :

PS D:\gemini> gemini --version  
0.26.0

用下列指令升到最新版 : 

PS D:\gemini> npm install -g @google/gemini-cli@latest   

added 1 package, removed 609 packages, and changed 6 packages in 3m
npm notice
npm notice New minor version of npm available! 11.6.2 -> 11.13.0
npm notice Changelog: https://github.com/npm/cli/releases/tag/v11.13.0
npm notice To update run: npm install -g npm@11.13.0
npm notice
PS D:\gemini> gemini --version
0.39.1   

哇, 一季不見已從 0.26.0 跳到 0.39.1 版. npm 也有新版, 順便也升版 :

PS D:\gemini> npm install -g npm@11.13.0   

removed 60 packages, and changed 90 packages in 9s
PS D:\gemini> npm --version   
11.13.0


2. 安裝 OpenSpec :

OpenSpec 是一款由 Fission AI 研發的開源輕量級規格驅動開發 (SDD) 工具, 是一套讓 AI 程式助理 (coding agents) 遵循規格的工作流程與 CLI 工具, 目前支援 20 種以上 AI 工具, 它的目標是讓工程師與 AI 在開發軟體之前先對規格達成共識, 減少 vibe coding 常見的偏題與反覆修改弊病, 並且能留下規格紀錄與決策脈絡備查, 提高軟體可維護性. 

安裝 OpenSpec 須有 Node v20.19.0 以上執行環境, 先檢視 Node 版本 :

PS D:\gemini> node --version  
v25.2.1

我的 Node 是利用 Scoop 安裝 Node 的, 可管理多版本的 Node, 參考 : 


這樣就可以在 PS 視窗安裝 OpenSpec 了 : 

PS D:\gemini> npm -g install @fission-ai/openspec@latest   

added 74 packages in 34s

這樣就完成 OpenSpec 安裝了. 


3. 用 uv 建立專案目錄 & 加入版控 :

由於作業要求用 OpenSpe 做三次迭代, 我打算用 OpenSpec 來實作一個網頁計算器專案, 第一次迭代要實作基本的四則運算計算機, 第二次迭代添加次方與開根號功能; 第三次迭代則添加對數, 指數, 與三角函數. 

首先用 uv init 指令建立一個專案目錄 : 

PS D:\gemini> uv init calculator-project     
Initialized project `calculator-project` at `D:\gemini\calculator-project`

然後切換到專案目錄下 : 

PS D:\gemini> cd calculator-project     

對此專案進行版本控制, 先檢視 Git 是否已安裝 : 

PS D:\gemini\calculator-project> git --version   
git version 2.52.0.windows.1

關於 Git 安裝與用法參考 :


在專案目錄下用 git init 初始化版控 : 

PS D:\gemini\calculator-project> git init   
Reinitialized existing Git repository in D:/gemini/calculator-project/.git/

版控資訊會儲存在隱藏目錄 .git 底下. 


4. 初始化 OpenSpec :   

接著用 openspec init 指令為此專案做 OpenSpec 的初始化 :

PS D:\gemini\calculator-project> openspec init 

這時會出現 OpenSpec 歡迎畫面 :




按 Enter 會出現 AI 程式代理工具選單, 可以按上下鍵移動指標來選擇要用的 AI 工具, 按 Space 鍵選擇要使用的代理工具 (可複選, 目前已支援 28 種 AI 程式代理工具), 此處我只選 Gemini CLI :




選定的工具名稱會被列在上方的 Selected : 後面




選完後按 Enter 退出 OpenSpec 初始化畫面回到 PS 終端機, 可見已為 Gemini CLI 程式代理建立了 4 個技能 (skills) 與 OpenSpeck 相關之命令 :

Note: OpenSpec collects anonymous usage stats. Opt out: OPENSPEC_TELEMETRY=0
√ Select tools to set up (28 available) Gemini CLI
▌ OpenSpec structure created
√ Setup complete for Gemini CLI

OpenSpec Setup Complete

Created: Gemini CLI
4 skills and 4 commands in .gemini/
Config: openspec/config.yaml (schema: spec-driven)

Getting started:
  Start your first change: /opsx:propose "your idea"

Learn more: https://github.com/Fission-AI/OpenSpec
Feedback:   https://github.com/Fission-AI/OpenSpec/issues

Restart your IDE for slash commands to take effect.

做完上面初始化後, 用 tree /f 指令檢視專案目錄 :

PS D:\gemini\calculator-project> tree /f   
列出磁碟區 新增磁碟區 的資料夾 PATH
磁碟區序號為 1258-16B8
D:.
│  .gitignore
│  .python-version
│  main.py
│  pyproject.toml
│  README.md
├─.gemini
│  ├─commands
│  │  └─opsx
│  │          apply.toml
│  │          archive.toml
│  │          explore.toml
│  │          propose.toml
│  │
│  └─skills
│      ├─openspec-apply-change
│      │      SKILL.md
│      │
│      ├─openspec-archive-change
│      │      SKILL.md
│      │
│      ├─openspec-explore
│      │      SKILL.md
│      │
│      └─openspec-propose
│              SKILL.md
└─openspec
    │  config.yaml
    │
    ├─changes
    │  └─archive
    └─specs

可見 OpenSec 初始化時已在


5. 安裝專案所需套件 :   

雖然對一個計算器專案來說, 只需要純前端 (HTML/CSS/JavaScript) 技術就能完成所有功能, 但為了模擬真實軟體架構常見的前後端搭配組態, 我打算將計算功能邏輯交給後端 Flask 框架來完成, 所以必須先用 uv 工具安裝 Flask, 這樣當 AI 生成程式碼後就可以叫 Gemini CLI  用 uv run 執行專案與驗證結果, 不需要再跳出來處理環境問題. 其次, 在使用 /opsx:verify 進行自動化檢查或測試時, 系統會依賴現有的虛擬環境, 如果環境未就緒 (例如缺少 Flask 套件), 驗證步驟可能會出錯. 

PS D:\gemini\calculator-project> uv add flask   
Using CPython 3.12.1 interpreter at: C:\Users\tony1\AppData\Local\Programs\Python\Python312\python.exe
Creating virtual environment at: .venv
Resolved 9 packages in 758ms
Prepared 7 packages in 466ms
░░░░░░░░░░░░░░░░░░░░ [0/8] Installing wheels...                                                                         warning: Failed to hardlink files; falling back to full copy. This may lead to degraded performance.
         If the cache and target directories are on different filesystems, hardlinking may not be supported.
         If this is intentional, set `export UV_LINK_MODE=copy` or use `--link-mode=copy` to suppress this warning.
Installed 8 packages in 98ms
 + blinker==1.9.0
 + click==8.3.3
 + colorama==0.4.6
 + flask==3.1.3
 + itsdangerous==2.2.0
 + jinja2==3.1.6
 + markupsafe==3.0.3
 + werkzeug==3.1.8

安裝完後用 tree /f 檢視專案目錄, 會多出一個 .venv 隱藏子目錄, 裡面有包含 Flask 與所依賴的 Jinjia 等套件 :

├─.venv
│  │  .gitignore
│  │  .lock
│  │  CACHEDIR.TAG
│  │  pyvenv.cfg
│  │
│  ├─Lib
│  │  └─site-packages
│  │      │  _virtualenv.pth
│  │      │  _virtualenv.py
│  │      │
│  │      ├─blinker
│  │      │      base.py
│  │      │      py.typed
│  │      │      _utilities.py
│  │      │      __init__.py

... (略) ...

│  │      ├─flask
│  │      │  │  app.py
│  │      │  │  blueprints.py
│  │      │  │  cli.py
│  │      │  │  config.py
│  │      │  │  ctx.py
│  │      │  │  debughelpers.py
│  │      │  │  globals.py
│  │      │  │  helpers.py
│  │      │  │  logging.py
│  │      │  │  py.typed
│  │      │  │  sessions.py
│  │      │  │  signals.py
│  │      │  │  templating.py
│  │      │  │  testing.py
│  │      │  │  typing.py
│  │      │  │  views.py
│  │      │  │  wrappers.py
│  │      │  │  __init__.py
│  │      │  │  __main__.py

... (略) ...


6. 編輯專案語境檔 GEMINI.md : 

在之前使用 Vibe coding 的進階方式開發時, 我們透過事先編輯好的專案語境檔 GEMINI.md 一次將專案需求與結構, 程式風格, 任務模板, 限制和偏好等資訊一口氣描述好, 當啟動 Gemini CLI 時它便能了解專案內容, 從而減少來回問答的次數. 這種語境檔因為要交待較多訊息, 所以內容比較冗長, 參考 :


如果使用 OpenSpec 做 SDD 開發, GEMINI.md 就會比較簡短, 例如下面的通用模板 :

# Project Global Guidelines (GEMINI.md)

## 1. AI 角色設定 (通用)
你是一位資深的 [Python 後端與全端] 開發專家,精通 [Flask 框架與現代前端技術],並具備極高的軟體工程素養。

## 2. 技術棧與環境配置 (專案特製)
* 核心語言:Python 3.12+ (嚴格使用 `uv` 進行依賴與環境管理)
* 後端框架:[Flask]
* 前端技術:[Vanilla JS, HTML5, CSS3]
* 其他工具:[若無則免,例如 SQLite, 特定硬體 SDK 等]

## 3. 開發流程與規格遵循 (通用,針對 OpenSpec 用戶)
* 本專案嚴格遵循 Fission AI 的 OpenSpec 工作流 (`/opsx` 指令集)。
* 你的所有實作必須以 `specs/` 目錄下的文件與 `tasks.md` 為「唯一真相來源 (Single Source of Truth)」。
* 絕對禁止在未經使用者同意且未更新 Spec 的情況下,自行發明、擴充或竄改 API 規格與業務邏輯。

## 4. 程式碼風格守則 (通用,Python 標準)
* 必須包含 Type Hints (型別提示) 與清楚的 Docstrings。
* 遵守 PEP 8 命名規範 (變數與函式使用 `snake_case`,類別使用 `PascalCase`)。
* 保持模組化,避免單一檔案過於龐大。

其中專案特製部分視專案而異, 括號 [] 內容需要手動修改, 其他通用部分則適用於任何用 OpenSpec 開發的專案. GEMINI.md 的角色是專案的憲法, 負責告訴 AI 我們這個專案要用甚麼 approach 來做 (How), 而專案的需求 (what) 會放在 /opsx: propose 指令來交待.  

在 PS 視窗的專案目錄下輸入 notepad GEMINI.md :

PS D:\gemini\calculator-project> notepad GEMINI.md  

這時 PS 發現專案目錄下並無 GEMINI.md 檔, 就彈出詢問是否新建此檔, 按是就會開啟記事本 :




複製上面的語境檔通用範本貼到 GEMINI.md 後存檔 (此處我將 ## 2 的其他工具內容改為 [無]) : 




再次用 tree /s 檢視專案目錄下已有此 GEMINI.md 檔了 :

PS D:\gemini\calculator-project> tree /f   
列出磁碟區 新增磁碟區 的資料夾 PATH
磁碟區序號為 1258-16B8
D:.
│  .gitignore
│  .python-version
│  GEMINI.md
│  main.py
│  pyproject.toml
│  README.md
│  uv.lock
├─.gemini
│  ├─commands
│  │  └─opsx
│  │          apply.toml
│  │          archive.toml
│  │          explore.toml
│  │          propose.toml
│  │
│  └─skills
... (略) ...


7. 啟動 Gemini CLI 進行初次迭代  : 

完成上面準備工作後, 終於要開啟 Gemini CLI 開始用 OpenSpec 幹活了. 在專案目錄下輸入 gemini 指令 : 

PS D:\gemini\calculator-project> gemini    

詢問是否信任此目錄, 當然要選 1. Trust folder (calculator-project) 才會進入 Gemini CLI 介面 :





出現 > 提示號表示 AI 已經讀取了 GEMINI.md 內容知道自己是誰, 也知道這個資料夾裡有 OpenSpec 環境, 這樣就可以開始用 OpenSpec 的 斜線指令集 /opsx 進行 SDD 開發了. 

如上所述, 這個專案作業要求至少進行三次開發迭代, 第一次迭代是要做出一個基本的四則運算計算器, 由於較簡單, 此處會使用快轉模式, 直接用 /opsx: ff 指令一鍵生成完成專案規劃與程式碼生成與測試, 整個工作流只需要的指令如下 (依序) :
  • /opsx:new <iteration_name> (建立迭代之專屬的工作區)
  • /opsx:ff <requirements> (依需求快轉生成設計文件與程式碼並完成測試)
  • /opsx:archive (迭代完成歸檔)
其中 iteration_name 是自訂的, 為了專案的易讀性以及讓 AI 能隱約猜到任務方向, 通常會遵循以下命名最佳實踐來取名 :
  • 使用 Kebab-case (連字號命名法) :
    全小寫英文, 單字之間用連字號 - 隔開, 避免使用空格, 大寫或特殊符號. 
  • 具備語意 (Semantic) : 名稱要能直接反映這次迭代的核心目的.
初次迭代我選用 cals-basic 作為工作區名稱. 


(1). 建立迭代之專屬工作區 : 

這會在專案目錄下建立此次迭代之專屬工作區, 例如迭代名稱是 calc-basic 的話就建立對應的資料夾 specs/changes/calc-basic/ 來收納這次迭代的所有相關討論與設計文件. 

系統會自動生成標準 SDD 流程所需的空文件或帶有基礎標題的模板, 例如空的 proposal.md, spec.md, design.md 以及 tasks.md, 此階段相當於是買了一本有分類索引標籤 (提案, 規格, 設計, 任務) 的空白筆記本, 以便在後續工作流中依需求來填空或修改. 

輸入下列指令並於一連串授權詢問時一律選擇預設的 Allow once :

/opsx:new calc-basic  



... (略) ...



工作區建完後, 專案所需的 OpenSpec 模板文件也都已建好, 但它們目前只是空洞的骨架而已, 接下來的工作流 (/opsx:ff 或 /opsx:continue) 就會根據需求來填寫這些標準 SSD 流程的四份核心文件模板 (proposal.md, spec.md, design.md 以及 tasks.md), 如果需求較複雜, 可能也會生成額外的 spec-xxx.md 文件, 相當於是在骨架中進行靈魂注入. 


(2). 依需求快轉 (ff) 生成設計文件與程式碼 : 

此階段 OpenSpec 會根據我們提供的專案需求, 透過 AI 去修改或填空上一個指令 (/opsx: new) 生出的四份核心文件 proposal.md (提案), spec.md (介面規格), design.md (架構設計) 與 tasks.md (任務清單), 並且據此生成程式碼同時完成測試, 可說是集成了 /opsx:propose, /opsx:continue, /opsx: apply, 以及 /opsx: verify 這四個指令的功能於一身, 一氣呵成完成專案實作. 

輸入如下指令來進行快轉 : 

> /opsx:ff "請幫我規劃一個基礎四則運算計算機軟體, 後端使用 Flask 提供 POST API, 前端使用純 HTML/JS, 並提供基本的使用者介面."   



... (略) ...



同樣地, 在它修改生成檔案與依此生成整個專案程式碼過程中會不斷要求授權, 我都選預設的 Allow once, 這樣可以一步步觀察 OpenSpec 做了哪些事, 過程中會顯示生成的程式碼與單元測試檔, 完成後結果如下 :  




這時可以另開一個命令提示字元或 PS 視窗, 切到專案目錄下, 用 python main.py 或 uv run main.py 執行此專案, 然後開啟瀏覽器訪問 http://127.0.0.1:5000 : 

PS D:\gemini> cd calculator-project   
PS D:\gemini\calculator-project> uv run main.py
 * Serving Flask app 'main'
 * Debug mode: on
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on http://127.0.0.1:5000
Press CTRL+C to quit
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 125-928-819
127.0.0.1 - - [25/Apr/2026 16:44:54] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [25/Apr/2026 16:44:54] "GET /static/style.css HTTP/1.1" 200 -
127.0.0.1 - - [25/Apr/2026 16:44:54] "GET /static/script.js HTTP/1.1" 200 -
127.0.0.1 - - [25/Apr/2026 16:44:54] "GET /favicon.ico HTTP/1.1" 404 -
127.0.0.1 - - [25/Apr/2026 16:45:11] "POST /api/multiply HTTP/1.1" 200 -
127.0.0.1 - - [25/Apr/2026 16:45:23] "POST /api/divide HTTP/1.1" 400 -

果然顯示了四則運算計算器頁面, 測試計算功能正常 (7 * 8=56, 1 除以 0 顯示 Error ) :





(3). 歸檔結案 : 

完成以上功能驗證後, 就可以用 /opsx: archive 指令檢查所有的 Artifacts 是否齊全, 是的話將此次迭代的所有紀錄, 文件, 與過程收整, 並移動到 archive 資料夾收存 :

> /opsx:archive

同樣地會有一連串的授權請求, 一律選擇預設的 Allow once : 




... (略) ...




可見所有此次迭代的紀錄文件都已歸檔於 openspec/changes/archive/2026-04-25-calc-basic/ 資料夾底下, 這些都是未來維護軟體的重要資料. 好啦! 終於完成初次迭代. 

沒有留言 :