TL;DR: 我請 AI 幫我寫一個能從 Claude Code 裡呼叫 OpenAI Codex CLI 的 skill,它給我 13 行 markdown。看起來小到不像個東西。但這 13 行不是 skill 的全部——真正讓它變成 skill 而不是 prompt 的,是它指過去的那一份比較厚的東西。Skill 是契約的形狀,不是指令的形狀。


前三篇我談過 skill 是什麼。一個 AI Skill 和 Prompt 到底差在哪 把它放進 stack 裡的某一層, Skill 邊界設計 講為什麼邊界比能力重要, Skill Design as Interface Design 是英文版用 API 設計的角度寫的。

這篇換個角度:真的拿一個給你看。

/codex-cli 這個 skill,因為它小到適合當教材。它在我那邊的工作是:從 Claude Code 想把某個任務丟給 OpenAI 的 codex CLI 去跑,我打 /codex-cli 修 README 的 typo,它就接手。

13 行長這樣

我請 AI 幫我寫第一版的時候,它給我這個:

# /codex-cli

Execute the canonical workflow: `.agent/workflows/codex-cli.md`

## Execution

Follow every step in `.agent/workflows/codex-cli.md` sequentially.
The user's task description is: $ARGUMENTS

- [OPTIONAL MODULE] Requires globally installed `codex` CLI
  (`npm install -g @openai/codex`).
- If CLI is unavailable, inform the user and fall back to native execution.
- End response with ⚡ ACX.

就這樣。13 行。沒有複雜的 prompt engineering, 沒有冗長的 system message, 沒有 chain-of-thought 模板。第一次看到的時候我有點疑惑:這就是一個 skill?

是。然後不是。

這 13 行做了什麼

最上面 /codex-cli 是觸發詞——在 Claude Code 裡打那個 slash 命令,這個檔就被載入。$ARGUMENTS 是個 placeholder,我打的「修 README 的 typo」會被代進去, 成為這個 skill 真正要處理的 input。下面那兩條 bullet, 是 fallback 條款:工具不在的時候怎麼辦。

到這裡, 它做完了一個 skill 該做的事——接到一個輸入, 告訴 AI 去執行哪一份 protocol, 並且講清楚如果工具不在的話退路是什麼。

但它不是 prompt。Prompt 是「你扮演一個資深工程師,請幫我…」這種把指令塞滿的東西。Skill 比較像 dispatcher——它指向別的地方, 自己只負責定義契約。

但 13 行不是全部

那 13 行裡有一句很安靜的話:

Execute the canonical workflow: .agent/workflows/codex-cli.md

被指過去的這個 workflow 檔, 比那 13 行厚很多。/codex-cli 自己很瘦, 因為它把厚的東西外包出去了。

打開那份 workflow, 裡面寫的大概是這幾類東西:codex 真的能不能用要先確認一次, 不能用就退回去。任務丟過去之前要先包一份護欄上去——「不要動指定範圍以外的檔案、不要重構沒被要求的程式碼、如果不確定範圍就停下來問」。等 codex 跑完, 還要拉一次 git diff 看它有沒有越界, 越界就回滾。

這才是 skill 跟 prompt 真正的分水嶺。Prompt 給你的是「請小心」, skill 給你的是「跑完幫我比對, 超出範圍就回滾」。

一個我必須講的疤痕

回到最前面那句:「我請 AI 幫我寫」。

AI 寫得很好。看起來很專業, 該有的環節都有。我看了一眼覺得不錯, 直接合進去。

跑起來才發現問題:那些 codex CLI 的旗標, 有幾個是 AI 編出來的。

不是它故意騙我, 是它根據訓練資料裡 codex CLI 的「應該長什麼樣」推測出來。但我那時候用的版本根本沒有那幾個旗標。前前後後修了兩三次, 跑一次 codex --help, 把實際存在的東西對回去, 才把這份 workflow 校準到真的能跑。

這就是我要寫這篇的原因。網路上很多在教「怎麼讓 AI 幫你寫 skill」, 沒人講事後看會發現什麼。我看到的是:AI 很會生 skill 的形狀, 但它對外部工具的真實 API 是用猜的。

那我學到什麼?不是「不要讓 AI 寫 skill」。寫得快, 結構也對。我學到的是 boundary 該畫在哪——agent 起稿結構沒問題, 我要做的是 verify 它生出來的東西對不對得上現實。Skill 的 dispatcher 部分 AI 寫沒問題, 被它指過去的那份 protocol, 特別是真實工具的旗標, 一定要對著 --help 校過再用。

Skill 是契約的形狀

回到主題。一個 skill 最小可以多小?13 行。但那 13 行只是一張請帖, 真正的契約寫在它指過去的地方。

第一版讓 AI 寫沒關係, 它對形狀的直覺很好。要記得補的是 fallback 條款——「工具不在的時候怎麼辦」這條, 是讓它變成 skill 而不是 prompt 的最低門檻。然後任何指向外部工具的旗標, 親自跑一次 --help 對。AI 不會故意騙你, 但它會用很有把握的口氣猜。

老實說, 寫 skill 這件事我還在摸索。每次重看自己舊的 skill 都會發現邊界又該收一點。但有一件事我蠻確定:skill 是契約形狀的東西, 不是指令形狀的——這個區別比任何 prompt engineering 技巧都重要。

下一篇會拆 ask-openrouter——那是我自己寫的一個 repo, 把 OpenRouter 包成一個 repo-aware 的 CLI。它在這個系列裡的位置剛好相反:不是包外部工具的 dispatcher, 是那個被 skill 包起來的工具本身。同一條 boundary, 從反方向看。

最後一句重要的話:如果你準備自己動手寫一個 skill, 記得每個工具的慣例都不一樣 ——Claude Code 官方 skills 文件OpenAI Codex CLI docs、Cursor 的 .cursor/rules、AGENTS.md 規範, 各自有自己的形狀。寫之前對著官方文件再確認一次, 包括這篇——blog 文會過期, 官方文件不會等你。

Agentic OS 是開源專案:github.com/KbWen/agentic-os


延伸閱讀