CLI 運作在純文字的終端機環境中,不像 GUI 擁有按鈕、視覺邊框或選單點擊等提示。使用者第一次接觸工具時,無法透過視覺預覽介面,全靠輸入命令、查詢 --help 與閱讀錯誤訊息來理解工具的運作方式。如果不同命令間的語法缺乏一致性、--help 寫得像抽象規格書、輸入錯誤時程式只拋出一句 invalid argument,或是執行破壞性動作時缺乏安全預設值,開發節奏就會被反覆打斷。
良好的 CLI 設計不在於堆疊複雜功能,而是提供可類推、可引導且安全的文字介面體驗。接下來的 Human-friendly 與 Agent-friendly CLI 設計分為以下五個層面:
在這五個層面中,文字介面的起點就是使用者輸入的第一個命令。如果命令名稱與 Flag 無法直覺推測,後續的表格輸出或選單互動再漂亮,使用者也會因為敲不對命令而無法開始。
良好的命名設計能讓使用者直接從日常工具(如 git、docker、kubectl)的經驗類推語法,不必每次切換命令都重新翻閱文件。如果一套 CLI 採用非標準或缺乏一致性的命名結構,就會打斷使用者的操作習慣。
主流 CLI 的命名語序主要分為兩種結構。第一種是 gh 採用的「資源在前、動作在後」:
gh issue list
gh pr list
gh release create
gh workflow run
kubectl 則採用「動作在前、資源在後」的結構:
kubectl get pods
kubectl get services
kubectl delete deployment api
這兩種結構各自成立,重點在於同一套 CLI 工具必須全篇保持統一。如果 mycli env list 採用了「資源在前、動作在後」,其他子命令就應寫成 mycli deploy list,不要交替改成 mycli list deploy。結構統一後,使用者只要學會一組命令,就能順暢推測出其他功能的語法。
代表相同動作的動詞如果在不同子命令中混用 list、show-all 和 get-all,使用者就必須額外記憶每個資源選用了哪個詞彙。選定 list 後,所有列舉資源的命令都應統一稱為 list;刪除動作也應在 delete 和 remove 之間固定使用一個。
命令名稱要精準反映影響範圍。真正會清理資源的命令用 delete;僅變更狀態、將資源設為停用的動作用 disable 或 archive,避免使用者從名稱誤判破壞程度。
當多個資源包含相同動作時,可以透過 Go 語言的工廠函式建立 Cobra 命令,確保語意與說明格式集中管理:
// 所有資源的列舉命令都統一使用 list。
func newListCmd(resource string, run func(cmd *cobra.Command, args []string) error) *cobra.Command {
return &cobra.Command{
Use: "list",
Short: fmt.Sprintf("列出所有 %s", resource),
RunE: run,
}
}
envCmd.AddCommand(newListCmd("env", runListEnvs))
deployCmd.AddCommand(newListCmd("deploy", runListDeploys))
修改說明文字或命令結構時,調整該工廠函式即可套用到所有子命令。寫入類命令的共用 Flag 也可以集中註冊:
func addWriteFlags(cmd *cobra.Command) {
cmd.Flags().Bool("dry-run", false, "只顯示將執行的動作,不實際執行")
cmd.Flags().BoolP("force", "f", false, "跳過確認提示")
}
Flag 名稱應沿用慣例。使用者看到 --output/-o、--force/-f、--verbose/-v 與 --dry-run,就能直接推斷用途。同一功能在所有子命令中也必須使用相同的 Flag 名稱,例如輸出格式統一用 --output,不要部分命令寫成 --format。
短 Flag(Short Flag)適合在終端機中快速手動輸入,長 Flag(Long Flag)適合寫入腳本以維護可讀性。常用 Flag 可以同時提供長短兩種形式:
cmd.Flags().StringP("output", "o", "table", "輸出格式:table、json")
--help 是終端機內最重要的說明文件。一個好的 Help 訊息應由三層結構組成:
Short:單句摘要,顯示於父命令的 Help 清單中。Long:詳細說明,交代命令預設行為、資源來源與執行限制。Example:可複製執行的具體命令,示範常見操作情境。撰寫 Example 時,應填入可執行的具體數值,不要寫成 <environment> 或 <project> 這類抽象的代碼名稱。帶有真實值的範例能讓使用者複製後直接在終端機中測試與執行:
var deployCreateCmd = &cobra.Command{
Use: "create",
Short: "建立一次部署",
Long: "將目前目錄的專案部署到指定環境,未指定環境時使用設定檔中的 default_env。",
Example: ` # 部署到預設環境
mycli deploy create
# 部署到 staging 並跳過測試
mycli deploy create --env staging --skip-tests`,
RunE: runDeployCreate,
}
當使用者執行 mycli deploy create --help 時,終端機呈現的畫面如下:
將目前目錄的專案部署到指定環境,未指定環境時使用設定檔中的 default_env。
Usage:
mycli deploy create [flags]
Examples:
# 部署到預設環境
mycli deploy create
# 部署到 staging 並跳過測試
mycli deploy create --env staging --skip-tests
Flags:
-e, --env string 目標部署環境 (預設為設定檔中的 default_env)
-h, --help 顯示 create 的說明訊息
--skip-tests 跳過單元測試與整合測試
這份輸出同時包含了短說明、預設值來源、可複製的命令範例與可用的 Flag,使用者不必離開終端機去查閱線上網頁即可完成操作。
當命令執行失敗時,僅印出 config not found 或 invalid argument 只是在宣佈失敗,沒有提供修正方向。好的錯誤訊息應明確包含三個要素:失敗的操作、相關的位置或輸入值,以及使用者接下來可以採取的具體修復步驟。
以找不到設定檔為例,錯誤訊息應標示查詢的路徑與建立設定檔的初始化命令:
$ mycli deploy create
Error: 找不到設定檔(預設路徑:~/.mycli/config.yaml)
請執行以下命令建立初始設定檔:
mycli init
當參數驗證失敗時,訊息應一併列出可用的有效值與正確語法,免去使用者再次手動輸入 --help 的過程:
$ mycli env list --output yaml
Error: 不支援輸出格式 "yaml"
可用的輸出格式:table、json
正確語法範例:
mycli env list --output json
當使用者打錯子命令時,Cobra 預設會透過編輯距離(Levenshtein distance)算法比對已註冊的命令清單,並印出最相似的名稱建議:
$ mycli deplyo create
Error: unknown command "deplyo" for "mycli"
Did you mean this?
deploy
在演算法運作上,Cobra 計算輸入字串與合法的子命令之間的編輯距離(即插入、刪除或替換字元所需的最小次數)。cobra.Command 提供了兩個屬性供控制這項行為:
DisableSuggestions(預設為 false):設定為 true 時停用拼字建議。SuggestionsMinimumDistance(預設為 2):設定允許的最大編輯距離。預設值 2 代表當輸入字串與合法命令的差異在 2 個字元以內時才會觸發 Did you mean this? 提示。var rootCmd = &cobra.Command{
Use: "mycli",
DisableSuggestions: false,
SuggestionsMinimumDistance: 2,
}
預設值能大幅減少日常操作所需的輸入量。例如 mycli logs 預設顯示最近 20 筆日誌,使用者平常直接執行即可;需要調閱更多歷史紀錄時,再用 --limit 擴充數量:
# 預設顯示最近 20 筆日誌
mycli logs
# 顯示最近 100 筆日誌
mycli logs --limit 100
設計預設值時,必須遵守以下三條原則:
--help 中;執行破壞性變更時,透過 --dry-run Flag 提前列出目標環境、資源名稱與即將執行的動作。$ mycli deploy create --env prod --dry-run
[DRY-RUN] 即將部署至環境: prod
[DRY-RUN] 目標資源: api-server
[DRY-RUN] 執行動作: 更新 image 為 registry.example.com/api:v1.2.0
[DRY-RUN] 提示: 此操作未實際執行。若要執行部署,請移除 --dry-run Flag。
可預測的命名慣例、隨手可查且帶有範例的 --help、包含修復建議的錯誤提示,以及安全的預設行為,共同建立了 CLI 在終端機文字介面中的第一道防線。
完成命令介面與基礎互動設計後,下一篇我們接著介紹 stdout 的視覺呈現與 stderr 的動態反饋。