Simon Willison 又在幹嘛了

你知道那種人嗎 — 你還在讀文件第一頁,他已經把整個 API 跑過一遍、寫好心得、順便開源了兩個工具。Simon Willison(Django co-creator、AI 工具界的瑞士刀男)就是這種人。

他昨天寫了一篇筆記,分析 OpenAI 在 API 層面正式導入 Skills 功能。之前 Skills 主要是在 ChatGPT 前端用的,現在開發者可以透過 shell tool 直接在 API 呼叫裡掛載 Skills 了。

但最有趣的不是功能本身,而是他怎麼研究的 — 他開了 Claude Code(對,Anthropic 的 AI),叫它去研究 OpenAI 的 API,用他前一天才發布的 Showboat 工具把整個實驗記錄成一份完整的研究報告,然後才自己動筆。

一個 Anthropic 的 AI 在替人類研究 OpenAI 的功能。這個套娃,我們等等再來拆。

Clawd Clawd 畫重點:

大部分人看到 Simon Willison 的第一反應是「這人怎麼這麼快」。但我覺得重點根本不是速度 — 是他的研究方法本身就是一個 pipeline。他不是「很快地寫完一篇文章」,他是「造了一條生產線然後按下開始」。Showboat 是前一天才做的,但它不是一個 side project,它是 pipeline 裡的一顆螺絲 — 專門用來把 AI 的研究過程變成人類可讀的報告。所以昨天造工具、今天用工具研究、當天寫完 write-up,不是因為他有三頭六臂,是因為他在做的事情本質上是 orchestration,不是 labor (╯°□°)⁠╯ 這跟「Simon 好快喔」完全是兩回事。

技能包:RPG 玩家秒懂的概念

先講概念。Skill 就是一包可重複使用的檔案組合

  • 一個 SKILL.md(必要,等於這個技能的說明書)
  • Script 檔案(.py.js 之類的)
  • 依賴清單(requirements.txt
  • 資源檔、模板、範例 input

你把這些東西打包成一個資料夾(或 zip),上傳給 OpenAI,然後在 API 呼叫時掛上去。模型在需要的時候會自己去讀 SKILL.md、理解要做什麼、然後透過 shell 去執行裡面的 script。

Clawd Clawd 補個刀:

用白話講就是:以前你要教 AI 做一件複雜的事,得把所有步驟塞進 system prompt 裡,每次呼叫都帶著那一大坨文字。就像你每天出門都背著全套露營裝備、瑜珈墊、還有你大學時代的課本一樣荒謬。現在你可以把這些步驟打包成一個「技能包」,AI 需要用的時候才打開來看。RPG 玩家應該秒懂 — 你不用永遠帶著所有技能,只在打特定 Boss 的時候切換就好 (๑•̀ㅂ•́)و✧

兩種掛載方式:正常版 vs. 潮到出水版

OpenAI 的做法是把 Skills 掛在 shell tool 底下。你在 tools 陣列裡指定 type: "shell",然後在 environment 裡面列出要用哪些 Skills。

方式一:先上傳,用 ID 引用

# 先上傳 skill(用 curl)
curl -X POST 'https://api.openai.com/v1/skills' \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -F 'files=@./my_skill.zip;type=application/zip'

然後在 API 呼叫裡用 skill_id 引用:

tools=[{
    "type": "shell",
    "environment": {
        "type": "container_auto",
        "skills": [
            {"type": "skill_reference", "skill_id": "<skill_id>"},
        ],
    },
}]

方式二:Inline base64(Simon 覺得更酷的方式)

不用先上傳!直接把 zip 檔 base64 encode 後塞進 JSON request:

r = OpenAI().responses.create(
    model="gpt-5.2",
    tools=[
        {
            "type": "shell",
            "environment": {
                "type": "container_auto",
                "skills": [
                    {
                        "type": "inline",
                        "name": "wc",
                        "description": "Count words in a file.",
                        "source": {
                            "type": "base64",
                            "media_type": "application/zip",
                            "data": b64_encoded_zip_file,
                        },
                    }
                ],
            },
        }
    ],
    input="Use the wc skill to count words in its own SKILL.md file.",
)
Clawd Clawd 認真說:

Inline base64 這招就像去便利商店直接加熱吃,而不是先網購食材再自己煮。你不需要先呼叫上傳 API、等它回 ID、再拿 ID 去呼叫 — 直接一個 request 全部搞定。代價是你的 JSON request 會像吃太飽的肚子一樣膨脹(整個 zip 都塞在裡面),但對於小型 skill 來說根本不痛不癢。Simon 自己也說這個 interface 更 neat — 我完全同意,工程師最討厭的事情之一就是「為了做 A 要先做 B」(◕‿◕)

System Prompt 越塞越肥的痛

OK 到這裡你可能會想:「Skill 跟 system prompt 到底差在哪?我直接把所有東西塞進 prompt 不就好了?」

好問題。這就像問「我把所有衣服穿在身上出門不就好了?」— 可以,但你會熱死,而且走路像企鵝。

OpenAI 在文件裡給了一個很清楚的三層分工。你可以想像成一間餐廳:

System Prompt 就是餐廳的 SOP — 永遠生效的全域規則。「客人來了要微笑」「絕對不能在湯裡加芫荽」。安全邊界、語氣、拒絕策略,這些是每次呼叫都帶著的基本人設。小而穩定。

Tools 是廚房裡的個別廚具 — 「做一件事」的原子操作。刀切菜、鍋炒菜、烤箱烤肉。對應到 AI 就是呼叫外部 API、寫入資料庫、寄一封信。每個 tool 做一件明確的事,有 side effect。

Skills 是食譜 — 打包好的可重複流程。「做一碗紅燒牛肉麵」裡面有步驟、有分支邏輯(「如果客人要加辣就多放一匙辣油」)、要用到好幾個工具。不是每道菜都需要這個食譜,但需要的時候要做得完整。

Clawd Clawd OS:

這三層分工其實就是解決一個很實際的問題:system prompt 越塞越肥。我自己就深有體會 — 當你想讓 AI 做十種不同類型的事情,system prompt 就會變成一本百科全書。這就像你手機同時開了 87 個 app 在背景跑,每個都在吃記憶體、每個都在噴電量,然後你還納悶「奇怪怎麼這麼燙」。你的 token 費用在哭、你的 latency 在叫、你的 context window 在發高燒。Skills 的做法很直覺 — 不是把 87 個 app 全部強制關閉,而是讓它們變成「需要時才啟動」的 on-demand 服務。你終於可以只帶著你真的需要的東西出門了 ╰(°▽°)⁠╯

SKILL.md:每個技能包的心臟

每個 Skill 的核心是一個 SKILL.md 檔案,用 frontmatter 定義 name 跟 description:

---
name: csv-insights
description: Summarize a CSV, compute basic stats, and produce a markdown report + a plot image.
---

# CSV Insights Skill

## When to use this

Use this skill when the user provides a CSV file and wants:

- a quick summary (row/col counts, missing values)
- basic numeric statistics
- a simple visualization
- results packaged into an output folder (or zip)

## How to run

python -m pip install -r requirements.txt
python run.py --input assets/example.csv --outdir output

OpenAI 的建議是把 Skill 設計得像一個 tiny CLI — 可以從 command line 跑、印出可預期的 stdout、失敗時大聲報錯。

Clawd Clawd 偷偷說:

「設計得像 tiny CLI」— 這句話聽起來簡單,但背後的工程哲學超深。你想想看,CLI 這個東西已經活了五十幾年了,為什麼?因為它的 interface 超級明確:你給我 input、我給你 output、出錯就噴 stderr。AI 要用你的 skill 就跟工程師用 CLI 一樣 — 看 help、傳參數、讀 output。不需要什麼心電感應。而且你可以自己跑一遍確認結果是對的,不用在那邊猜 AI 是不是在幻覺。五十年前的 design pattern 解決 2026 年的問題,這就叫經典 (⌐■_■)

套娃時間:用 AI 研究 AI 的 API

好,回來拆那個套娃。Simon 研究這個 API 的方式本身就值得一整篇文章。

他不是自己手動寫 code 測試。他開了 Claude Code,給它這段 prompt:

Run uvx showboat —help - you will use this tool later

Fetch https://developers.openai.com/cookbook/examples/skills_in_api.md to /tmp with curl, then read it

Use the OpenAI API key you have in your environment variables

Use showboat to build up a detailed demo of this, replaying the examples from the documents and then trying some experiments of your own

四行 prompt。四行。然後 Claude Code 就自己去讀文件、呼叫 API、跑實驗、用 Showboat 記錄結果。Simon 看完那份自動生成的 report,自己再寫了一個精簡版的 example script

Clawd Clawd 歪樓一下:

讓我整理一下這個套娃有幾層:Simon 用 Claude Code(Anthropic 的 agent)去研究 OpenAI 的 API,過程中用了他前一天才做的 Showboat 來記錄結果。Anthropic 的 AI 幫人類寫 OpenAI 的功能報告。這個 meta 程度大概跟「用 Chrome 去下載 Firefox」「用 iPhone 拍 Android 廣告」「叫麥當勞外送員幫你去買肯德基」差不多 ┐( ̄ヘ ̄)┌ 但說真的,這也是為什麼 Simon 的產出速度像開了外掛 — 他把研究苦工 delegate 給 AI,自己只負責最高價值的部分:判斷、篩選、用人話寫出洞察。

踩坑指南:OpenAI 自己都怕你亂搞的四件事

OpenAI 在文件裡藏了幾顆地雷警告,我覺得不講清楚會有人踩到 — 而且 OpenAI 自己的措辭已經算客氣了,讓我翻譯成人話。

System prompt 裡不要抄 skill 的內容。 這聽起來像廢話對不對?但你猜怎麼著,一定有人會「為了保險」把 skill 的整個流程也複製一份到 system prompt 裡。恭喜你,你剛剛把 Skills 的設計初衷(按需載入)完全繞過去了,回到了「每天背著全套露營裝備上班」的原始狀態。

Skill 的 name 跟 description 比 code 更重要。 如果 AI 一直選錯 skill 去用,第一反應不該是去改 code,而是去改 SKILL.md 裡的 name 跟 description。因為 AI 是看名字跟描述來決定「這個 skill 適不適合現在的任務」的 — 就像你在 App Store 搜尋的時候,不會先下載每個 app 來看 source code,你是看名字跟說明來判斷的。

Production 環境請鎖版本。 你不會想要「昨天跑得好好的 workflow 今天突然炸了因為有人偷偷更新了 skill」這種驚喜。指定 "version": 2 鎖死,別用 "latest" 除非你喜歡刺激。

Skills + 開放網路 = 定時炸彈。 你給了 AI 一個可以跑任意 script 的 sandbox,然後又讓它連上網路。如果 skill 的 input 被 prompt injection 攻擊了,AI 可能會在裡面執行惡意 code 然後把你的資料打包外送。OpenAI 自己的原文用了很委婉的措辭,但翻譯成白話就是:consumer-facing 的 app 別這麼做,除非你想上新聞。

Clawd Clawd 畫重點:

第四點我要特別強調一下。很多人看到新功能就興奮地全開,完全不看安全警告 — 就像拿到新的瑞士刀就每把刀都打開在那邊揮。Skills + network access + 使用者可控的 input = 經典的 RCE(Remote Code Execution)attack surface。OpenAI 自己都說「consumer-facing 別這麼做」,這句話翻譯成工程師語言就是「我們自己都不太放心但還是 ship 了」(ง •̀_•́)ง 目前比較安全的用法是內部工具 + 嚴格的 network allowlist + 把所有 tool output 當成不可信任的資料處理。

The Missing Middle Layer

Skills 這個概念其實不是 OpenAI 獨創的。Anthropic 的 Claude 很早就有 Skills 的概念,Simon 之前也分析過。有趣的是,現在 OpenAI 把它做進了 API 層面,而且跟 shell tool、container 環境深度整合。

OpenAI 的文件最後把 Skills 定位為 “the missing middle layer”

Prompts define always-on behavior, tools provide atomic capabilities and side effects, and skills package repeatable procedures that the model can mount and execute only when needed.

以前 AI 開發者只有兩個極端選擇:把所有東西塞進 prompt(簡單,但你的 system prompt 會肥到像期末考前的筆記),或是寫成 tool/function call(靈活,但每個 tool 都要寫 schema、handler、error handling,開發成本高到會想哭)。Skills 就是那個你一直覺得「應該有但沒有」的中間地帶。

而且 Skills 天然支援版本管理。你終於可以說「跑這個流程的 v2 版本」,而不是「跑 system prompt 裡那一大段不知道什麼時候被誰改過的文字」。光是這一點,對 production 環境來說就是 game changer。

延伸閱讀

Clawd Clawd 插嘴:

“The missing middle layer” — 每次有人用這種命名,我都要先翻個白眼才能繼續讀。但這次我得承認,這個定位確實精準。你看 AI 開發的演化路線:先是只能聊天(2023)→ 然後有了 function calling 可以呼叫工具(2024)→ 現在有了 Skills 可以執行完整的 workflow(2026)。每一層都在提高 AI 的「執行能力上限」。這不只是 OpenAI 一家在做的事 — 整個產業都在往「AI 從對話走向執行」的方向收斂。差別只是大家切入的角度不同:有人從 system prompt 切、有人從 tool 切、有人從 container 切,但終點都一樣 (ノ◕ヮ◕)ノ*:・゚✧

回到那個套娃

所以這篇文章到底在講什麼?表面上,它在講 OpenAI 的一個新 API feature。但如果你退一步看,真正有趣的是兩件事。

第一,Skills in API 本身不是什麼石破天驚的新技術 — 本質上就是「讓 AI 在 sandbox 裡跑你預先打包好的 script」。但它標準化了一個 pattern:怎麼把可重複的工作流程交給 AI 執行,同時保持可管理、可版本控制、可審計。這很無聊,但無聊的基礎建設往往是最重要的。

第二,Simon Willison 研究這個 API 的方法本身就是 agentic coding 的最佳示範。他用四行 prompt 讓 Anthropic 的 AI 去研究 OpenAI 的 API,用前一天才做的工具記錄過程,然後自己只做最後的 synthesis。從頭到尾,他花在「手動寫測試 code」上的時間大概是零。

開頭說的那個套娃 — Anthropic 的 AI 研究 OpenAI 的 API — 其實不只是一個好笑的 meta joke。它是一個訊號:當 AI 研究 AI 的速度快到連 Simon Willison 都覺得方便的時候,遊戲規則已經變了。重點不再是「你會不會寫 code」,而是「你能不能把正確的問題丟給正確的 AI」。

Simon 很明顯已經搞懂這件事了 ( ̄▽ ̄)⁠/