把 Skill 文件當成可訓練參數:SkillOpt 的文字空間優化
讀 SkillOpt 這篇論文的時候,我一直覺得哪裡不對勁。
不是論文本身的問題——而是這個想法太簡單了,簡單到讓我懷疑自己沒讀懂。它說的是:把一份 Markdown 文件當成神經網路的 weight 來優化。Forward pass 是 agent 跑任務,backward pass 是 LLM 分析失敗案例然後提出 edit,learning rate 是你每步最多允許幾個修改,validation 是 held-out 的 test split,momentum 是跨 epoch 的 slow update。整個深度學習的優化邏輯,逐一對應到文字空間。
我後來想清楚了:這不是比喻,是工程上的精確對應。每一個設計決策背後,都有消融實驗支撐。
讀完精華版(2 分鐘),你會理解:
- SkillOpt 如何把「skill 文件優化」精確對應到深度學習的優化邏輯
- 五個核心組件各自解決什麼問題(消融結果支撐)
- 52/52 的結果背後,真正有意思的數字在哪裡
這篇文章不是 SkillOpt 的使用教學,而是理解它為什麼設計成這樣。
精華版
深度學習類比對照表
| 深度學習概念 | SkillOpt 對應 | 說明 |
|---|---|---|
| 可訓練參數 | skill 文件(.md) | 優化目標,部署時凍結 |
| Forward pass | Target model rollout | Agent 跑任務,記錄軌跡 |
| 損失函數 | Verifier score(0/1) | 任務是否完成 |
| Gradient | LLM 提出的 add/delete/replace edits | 從失敗軌跡反推應該怎麼改 |
| Learning rate | Edit budget L_t(每步最多幾個 edit) | 控制每次更新幅度 |
| Validation check | Held-out selection split | Gate:candidate 必須比 current 好才接受 |
| Rejected gradient | Rejected-edit buffer | 記錄失敗的 edit,避免重複嘗試 |
| Momentum / slow update | Epoch-wise protected field | 保護跨 epoch 學到的長期 pattern |
五個組件,各解決一個問題
- Rollout Evidence(Forward pass):Target model 對
D_tr跑任務,harness 記錄完整軌跡(tool calls、observations、verifier feedback),讓後續 reflection 看到「agent 實際做了什麼」而非只有最終答案。 - Minibatch Reflection(Backward pass):Optimizer model 讀取 rollout 後,分離成功/失敗軌跡,每組分成 minibatch(B_m=8),各自回傳 structured add/delete/replace edits;minibatch 暴露的是跨多個例子的 recurring error pattern,不是單一案例的 anecdotal fix。
- Bounded Edit Budget:把合併後的 edit pool 截斷到最多
L_t個(預設 4,cosine schedule);沒有這個限制的「無約束重寫」在所有 benchmark 均落後,因為同時改太多會讓 validation gate 難以判斷哪個 edit 有效。 - Validation Gate + Rejected Buffer:只有嚴格大於當前 selection score 的 candidate 才被接受;被 reject 的 edits 進 buffer,讓同 epoch 後續的 reflection 知道「這條路已試過」。
- Epoch-wise Slow Update:比較前後 epoch 的表現差異,寫成 concise longitudinal guidance 進 protected field;SpreadsheetBench 移除這個組件後從 77.5 暴跌到 55.0(-22.5 點),因為 fast local edits 每 epoch 相互覆蓋,無法積累跨 epoch 學到的 workbook-level strategies。
幾個值得先想清楚的設計問題
為什麼 edit budget 不是越大越好? Edit budget 是 SkillOpt 最重要的機制之一。無約束重寫(without lr 那一組)在 SearchQA/SpreadsheetBench/LiveMath 均落後於 lr=4 的預設值,最大差距約 2.5 點。原因是:同時改太多讓 validation gate 無法做有意義的比較,candidate 和 current 差太遠,風險變成「接受一個局部好但整體退步的 skill」。
Rejected buffer 真的有差嗎? 有,且差距比想像大。SpreadsheetBench 移除 rejected buffer 後下降 4.6 點(77.5→72.9),LiveMath 下降 2.4 點。沒有 buffer,optimizer 下一輪可能再次提議相同的失敗 edits,浪費 budget 在已知不走的路上。
Skill 的遷移性如何? Cross-model transfer 對 GPT-5.4-nano 的 LiveMath,transferred skill 反超 in-domain SkillOpt(28.8 vs 27.2)。Cross-harness transfer 在 SpreadsheetBench 達到 +59.7 點。這說明 skill 編碼的是 target-model-agnostic 的 procedural knowledge,不是針對特定模型或 API 的 heuristics。
以下是完整版,按需取用。
深度學習類比在文字空間為什麼成立?
深度學習最核心的設計選擇是:把「知識」壓縮進可微的參數裡,然後用梯度讓這些參數自動往正確方向移動。這個選擇讓人類不需要手寫每一條規則:你給 loss function,模型自己找規則。
SkillOpt 在問的是:同樣的優化邏輯,能不能在文字空間裡成立?
答案是可以,但需要把每一個組件替換成文字世界的等價物。Gradient 沒辦法在文字上算,但 LLM 可以讀取失敗軌跡然後提出「應該加什麼規則、刪什麼規則、改什麼規則」,功能上等價於梯度:都是「從失敗反推應該怎麼改參數」。Learning rate 沒辦法用數字直接 scale,但 edit budget 可以限制每步更新的幅度,效果等價。Validation 的邏輯完全一樣:只接受在 held-out data 上更好的版本。
這個類比的精確性體現在消融實驗上:把任何一個組件拿掉,性能都會下降,而且下降的原因和深度學習裡拿掉對應組件的原因相同。拿掉 edit budget,就像拿掉 learning rate scheduler,update 太大,容易震盪或 overfit 局部失敗。拿掉 rejected buffer,就像拿掉 gradient memory,每次從頭計算,重複做無效的 update。拿掉 slow update,就像拿掉 momentum,短期梯度覆蓋長期趨勢,無法積累跨 epoch 的 pattern。
這讓「skill 文件優化」從一個模糊的想法,變成一個有工程紀律的系統。
SkillOpt 訓練循環:一個 Epoch 裡發生什麼?
預設配置是 4 個 epoch,每個 epoch 裡:
- Target model 對
D_tr的 40 個 tasks 跑 rollout,harness 記錄完整執行軌跡 - 失敗和成功的軌跡各自分成 minibatch(B_m=8),16 個 analyst worker 並行處理
- 每個 minibatch 回傳最多幾個 atomic edits;失敗的提出 missing/corrective rules,成功的確認 already-working behaviors
- Batch-level merge:排序(failure corrections 優先)、去重、clip 到 edit budget(cosine schedule,從大到小,floor L_t=2)
- 用
D_sel(selection split)評估 candidate skill。Strictly better → 接受為新的best_skill.md;否則 → edits 進 rejected buffer - Epoch 結束後,slow update:用上一 epoch 和當前 epoch 的 skill 各跑 20 個 tasks,比較哪些 cases 改善/退步/始終失敗,寫 concise guidance 進 protected field
訓練完成後,輸出 best_skill.md。這個文件是 deploy artifact,直接 prepend 進 system prompt 或注入 SKILL.md,不需要任何 optimizer。
一個重要性質:這個 training cost 是一次性付清的,但 skill 可以無限次 deploy。SpreadsheetBench 的 training cost 約 21.4M tokens,換來 +38.9 點的增益,cost 是 0.6M tokens/pt,六個 benchmark 裡最低。
Skill 如何從 Generic Plan 演化成 Finite-State Policy?
ALFWorld 的 skill 演化最能說明 SkillOpt 學到的是什麼。初始 skill 是一個 4 步的 generic household plan:搜尋目標物體、拿起它、必要時轉換、放到目的地。這是任何人會寫的第一個版本。
經過 4 個 epoch 後,這個 generic plan 變成了一個 finite-state execution policy:
- 精確物體識別:mugs、cups、pans 不能互相替代,必須做 exact name matching
- 已探索位置記憶:維護一個 visited/frontier ledger,優先探索未訪問的 receptacles,避免無限兜圈
- 目的地記憶:記住已知目標位置,避免重複確認
- pick-two progress lock:需要拿兩個物品時,確保兩個都到手才進行放置
- 直接完成規則:能 clean/heat/cool/place 時立即執行,不再做多餘的 examine/close/verify
結果:held-out test 從 49.3 → 74.6(+25.3 點)。這些規則沒有一個 name 到特定的測試案例或特定的物品,它們編碼的是「frontier model 在 zero-shot 時系統性不執行的紀律」。
SpreadsheetBench 更戲劇性:初始 skill 是「使用 Python spreadsheet libraries,保留 workbook 內容」。最終 skill 變成了一份 workbook-forensics policy:先 inspect workbook 結構和 formula、確定 header 和 target ranges、跨 sheets normalize keys,然後有一個關鍵規則:「如果 grader 讀取 cell values,compute 並 write 靜態值,即使 prompt 提到 INDEX/MATCH 或 XLOOKUP」。這個規則是 optimizer 從失敗案例裡反推出來的,它需要理解 grader 的行為才能寫出來,而 zero-shot 的模型不會想到要理解這件事。
增益:40.4 → 78.9(+38.5 點)。
52/52 背後,真正有意思的數字
論文說 SkillOpt 在 52/52 個 model × benchmark × harness 組合上 best-or-tied。這個數字好看,但它掩蓋了兩個更有意思的事實。
第一個:OfficeQA 和 LiveMath 的增益分別是 +39.0 和 +29.3 點,但各自只來自 1 個 accepted edit。 Optimizer 在這兩個 benchmark 上提議了很多 edits,validation gate 只讓其中一個過了。這說明 gate 在做實質性的工作,不是 rubber stamp。大部分提議的改動在 held-out data 上沒有得到確認。
第二個:小模型受益最大。 GPT-5.4-nano 的平均增益是 +26.7 點,是七個模型裡最高的。Qwen3.6-35B-A3B 反而只有 +9.1 點。原因在於 compact skill artifact 補充了小模型 weights 裡不存在的 procedural knowledge。大模型本來就有能力做這些事,只是 zero-shot 時沒做;小模型沒有這個能力,skill 文件直接讓它有了。
為什麼 Skill 可以跨模型和 Harness 遷移?
Cross-model transfer 的結果有一個反直覺的數據點:GPT-5.4 優化的 skill 部署到 GPT-5.4-nano 的 LiveMath 上,transferred skill(28.8)反超了 nano 自己優化出來的 in-domain SkillOpt(27.2)。用更大模型的 optimizer 提煉出的 skill,反而比小模型自己優化的更好。
Cross-harness transfer 在 SpreadsheetBench 上達到了 +59.7 點(Codex 優化的 skill 轉移到 Claude Code)。原因是 SpreadsheetBench 的 skill 編碼的是 workbook-level 的通用策略,這些策略和 harness 的 API 設計無關,不管用哪個 harness 執行,structure-first inspection 和 static-value materialization 都是正確的做法。
Cross-benchmark transfer 在數學 benchmark 之間也是正的:從 OlympiadBench 優化的 skill 轉移到 Omni-MATH 上,GPT-5.4 增益 +3.7 點。因為 skill 編碼的是「如何做數學推理」的 procedure,不是「記住 OlympiadBench 的答案格式」。
這三個維度的遷移性說明了一件事:SkillOpt 學到的不是 dataset-specific 的 heuristics,而是 domain-level 的 procedural knowledge。
SkillOpt 的限制:在哪些情況下不划算?
SkillOpt 有四個明確的限制,值得在使用前想清楚。
最核心的限制是需要自動 verifier。Validation gate 的邏輯是「在 held-out split 上,candidate 必須比 current 嚴格更好」,這需要一個可以自動計算 score 的 verifier。SearchQA 用 exact match,SpreadsheetBench 用 Python 執行確認,ALFWorld 有 simulator。但如果你的任務是主觀評估、多維度成功指標、或需要 human judgment 的 open-ended generation,這個 gate 就沒辦法直接用。
第二個限制是training cost 是真實成本。對 one-off tasks 不划算。划算的前提是這個 skill 會被反覆使用,一份 skill 可以 amortize 多少次 deployment,取決於 domain 的 reusability。
第三個是單一 skill 的設計上限。SkillOpt 優化一個 portable skill,不做 skill library management。如果你的 domain 高度異質(不同子任務需要完全不同的 procedural knowledge),單一 skill 可能不夠。
第四個是 optimizer 強度和 target model 不需要相同,但 optimizer 越強結果越好。論文測試了 target-matched optimizer(用 target model 自己當 optimizer),恢復了 strong optimizer 增益的 56-74%。意思是用更弱的 optimizer 仍然有效,只是天花板低一些。
拉開距離,看整個系列
這是這個系列的最後一篇,值得退一步看整個圖。
Karpathy 的 AutoResearch 觀察從「LLM 可以閉環驅動科學研究流程」開始。Paradigm Shift 那篇講的是 RLVR:任何可驗證的任務現在都是可解的,Lean proof、code test、terminal output 都是現成的 reward signal。Meta-Autodata 把這個觀察往前推:如果 reward signal 可以自動生成,data 的概念也跟著變了。Heuristic Learning 問的是:如果不想 fine-tune weights,用 coding agent 持續維護一份 Heuristic System,能不能替代梯度下降?
SkillOpt 是這條線的終點,也是一個閉環:把 HL 的核心想法(skill 文件作為 policy)用深度學習的優化邏輯系統化。Forward pass、backward pass、learning rate、validation、momentum,不是比喻,是可以實作、可以測量、可以消融的工程選擇。
52/52 的結果說明這個方向是 real 的。但更有意思的問題是後面的:skill library(多個 domain 共享 optimizer infrastructure)、reward-free 的 validation gate(解決 open-ended task 問題)、把 optimized skill 蒸餾進 target model weights。
這些問題的答案,可能就是下一個 AutoResearch 系列的起點。
結語:Skill 文件從來不只是 prompt——它是一個可以優化的參數,而 SkillOpt 給了這個直覺一個精確的工程形狀。