OPSD 讓你把點擊變訓練
我把 OPSD 拆成一個可直接抄的閉環:怎麼把隱性用戶回饋變成校正資料,再持續訓練模型。

OPSD 把隱性用戶回饋變成持續校正的訓練閉環。
我最近一直盯著 post-training 的流程看,越看越火大。很多團隊嘴上說在做回饋學習,實際上收的卻是很假的訊號:按讚、按倒讚、幾個人工標籤,再配一個 reward model,然後就假裝自己掌握了用戶真正要什麼。問題是,真實產品裡的訊號根本沒那麼乾淨。用戶會重試、會改寫、會只接受一半、會繼續追問,因為模型差一點就對了,但就是差那一下。那一下,才是我最想抓的地方。
把我拉進這個主題的,是一篇知乎文章:On-Policy Self-Distillation(OPSD)。文裡把 OPSD 放在 OPD 的延伸脈絡裡,還提到 DeepSeek 的工業實作方向,以及 Cursor 的訓練思路。老實講,我不是把它當成可以逐行驗證的論文來看,我是把它當成一個很實際的提醒:如果模型能從自己在場的輸出,加上用戶留下的隱性回饋去學,那我是不是就不用死等完美標註了。
別再把回饋當實驗室樣本
訂閱 AI 趨勢週報
每週精選模型發布、工具應用與深度分析,直送信箱。不定期,不騷擾。
不會寄垃圾信,隨時可取消。
最近 DeepSeek V4 的多專家整合方案采用了 OPD(On-Policy Distillation),在工业级项目上证明了 OPD 在后训练中占据一席之地。而它的进阶版本 OPSD(On-Policy Self-Distillation)也在 Cursor 的模型训练上大规模…
翻譯一下就是:模型不是只從一包靜態資料學,而是從自己剛剛在真實情境裡做出的行為學。OPD 已經比傳統離線蒸餾更貼近產品;OPSD 再往前一步,直接把 on-policy 行為變成教學訊號。這很重要,因為模型不再是在空房間裡被評分,而是在它未來真的要工作的分佈裡被修正。

我自己做產品時,最常撞到的就是這種落差。benchmark 看起來漂亮,因為 prompt 很乾淨;但用戶根本不會照 benchmark 講話。人會插話、會改需求、會在第一版答案後面補一句「不是,我要的是另一種寫法」。如果我只拿精修過的 gold answer 來訓練,我會錯過那條很髒、但很有價值的修正軌跡。OPSD 的意思很直白:把這條軌跡留下來,拿來學。
實操上怎麼做?我會先把 live output、當下 prompt state、以及用戶下一步行為一起記下來。不要只存最後有沒有按接受。要存修改、重試、放棄、追問。這些都是 breadcrumbs。你如果在做內部助手,最簡單的做法就是記錄每一輪對話,還有用戶在哪一輪停止修正模型;你如果在做 coding agent,就把第一版建議和最後被接受的 diff 存下來。那個 diff 往往比人工寫的 label 更值錢。
- 存 on-policy response,不要只存 prompt。
- 存用戶在上下文中的反應,不要把評分切成孤立事件。
- 能用 correction trace,就少用二元好壞。
隱性回饋不是沉默,是行為
這篇文章真正賭的點,是隱性回饋其實可以比顯性分數更有用,只要你會讀。用戶把你的答案重寫一遍,這就是訊號;用戶只留下一段 code、把說明刪掉,這也是訊號;用戶換個說法又問一次,基本上就是把 failure cluster 直接丟給你。這些都算回饋,只是它們沒被包裝成漂亮的 label。
我喜歡這個角度,因為顯性標籤太貴,也太容易偏。人會在「差不多有用」的時候按 good,也會在答案內容正確但語氣煩的時候按 bad。我看過不少團隊被這種標籤帶歪,最後優化的是客氣話,不是實際效用。隱性回饋雖然醜,但它比較接近產品價值。
但坑也在這裡:不能把所有行為都當成同一種訊號。重試可能代表答案失敗,也可能只是用戶想換語氣;複製 code 片段可能代表成功,也可能只是拿去檢查。真正要做的是先定義一小組可解釋的行為,再把它們映射成訓練訊號。這一步很多人省略,然後又怪模型學到垃圾。
實操上,我會先定四個桶:accepted、edited、retried、abandoned。若你的產品 telemetry 比較完整,再加 copied、ran、executed successfully、user reverted。接著給不同事件不同權重。accepted unchanged 不等於 accepted after edit;edited 也不等於 rejected。模型要看得出差別。
- Accepted unchanged:強正向訊號。
- Accepted after edit:部分正向,但要保留修正目標。
- Retry / reformulation:對前一版是負向訊號。
- Abandonment:弱負向,但量大時很有用。
On-policy 重要,因為 off-policy 常常在騙你
on-policy 這詞聽起來很學術,直到你真的看過模型在 production 裡怎麼死。off-policy 訓練用的是別處來的資料,問題就在這裡:模型一旦變了,舊資料就不再貼合它現在的行為。你得到的是過期 supervision,學到的東西跟用戶眼前看到的東西慢慢脫節。

on-policy 的做法,就是盡量把這個 gap 拉近。模型先產生答案,用戶再反應,而這一組互動本身就變成下一輪教學樣本。這看起來只是小改,但它其實改變了整個閉環。模型不是從昨天的資料學,而是從它今天剛剛造成的結果學。這比假裝舊資料還代表現在,老實太多了。
我自己碰過的問題很像「神祕退步」。模型在某一類 prompt 上進步了,另一類卻變差,因為訓練集根本沒看過新的互動方式。on-policy 資料可以比較快抓到這種偏移。它不是魔法,只是讓訓練分佈更接近 live 分佈,而痛點本來就發生在 live 裡。
實操上,我會讓 post-training loop 只吃目前 checkpoint 產生的新輸出,不要永遠回收老答案。做 rolling window,優先抽最近的互動。若你在做 preference training,就把 on-policy response 和用戶修正,或同一 session 裡後來生成的更好版本配對起來。
我自己有個很土但很好用的規則:模型版本一變,訓練混合也要跟著變。你如果還拿舊版本的行為去教新版本,那其實是在教昨天的習慣,然後把它叫做 improvement。
Self-distillation 其實就是模型學自己的更好草稿
self-distillation 這件事,讓它看起來比較像寫作流程,而不是一般訓練管線。模型先產出草稿,再根據用戶的反應和同一份上下文,產出更好的版本。這裡的「self」很重要,因為模型不是每次都靠外部 oracle 重置,而是沿著自己的軌跡變好。
我在 code generation 裡看過這種模式很有效。第一版通常結構對,但局部很粗;第二輪如果知道用戶卡在哪裡,就能把弱點補掉,而且不必整個重寫。這就是 self-distillation 的吸引力:保留骨架,修掉關節。
也就是說,你可以訓練模型去模仿「在相同操作條件下、自己更好的版本」。用戶回饋告訴你草稿失敗在哪,distillation 步驟再把它轉成 target。這個 target 可以是另一個模型的輸出、修訂後的 completion,或是修正過的片段。重點不是形式,重點是 correction 要留在原本的 on-policy context 裡。
實操上,我會先生成一個 candidate answer,觀察用戶反應後,再生成 revised answer。訓練時拿 revised answer 當 teacher target,對回原始 prompt state。你如果做 coding assistant,target 可以是被接受的 diff,不一定要整份重寫;你如果做 chat assistant,target 可以是修好用戶抱怨點的那段段落。
這裡我會特別小心。self-distillation 如果修正步驟太弱,很容易把自己的錯誤越學越大。所以我會保留一條人審抽樣線,不是每筆都看,只抽一部分 correction,至少先抓出模型是不是在教自己胡扯。
真正重要的不是 label,是閉環
很多人一看到訓練就只盯 objective,我懂,loss function 很整齊,pipeline 也很整齊。但這裡真正有價值的不是公式,而是閉環:觀察、反應、修正、再訓練、再重來。OPSD 不是一次性的技巧,它是把產品本身變成模型老師的一種方式。
知乎那篇文章把它放進工業實作脈絡,我覺得這才是重點。真實系統沒有那麼多完美標註週期,你面對的是活的用戶、一直變的行為、還有一個不能一直卡住不動的模型。用隱性回饋做閉環,至少能讓你不用每次模型歪掉就停工一週去做標註。
我自己的經驗是,最好的 loop 都很無聊。它不需要神奇基礎設施,只需要紀律:把 log 記完整、feedback schema 定清楚、retraining 的觸發條件不要被雜訊騙。若你說不清楚某個用戶行為代表什麼,就先別拿去訓練;若你說得清楚,就先小規模上,看看修正後的下一輪互動有沒有真的變好。
實操上,我會用 signal volume 來決定 retrain,不看日曆 hype。比如某個 task category 累積到足夠多的 accepted edits 或 repeated retries 才重訓。再留一組最近的 live interactions 當 holdout。若新 checkpoint 讓 correction rate 變好,但 completion quality 變差,那就是你過度擬合回饋了。這種失敗,越早抓越省錢。
- 用 rolling window 看最近互動。
- 只對可解釋的行為訓練。
- 看 post-correction success,不要只看 offline loss。
工業落地只剩髒限制,沒有漂亮理論
我之所以認真看這類方法,不是因為縮寫好聽,而是因為它背後真的有工業壓力。像 DeepSeek、Cursor 這種系統,面對的是 latency、cost、quality 三個一起壓上來的現實。訓練方法如果撐不住這些髒限制,講再漂亮都沒用。OPSD 吸引人的地方,就是它沒有假裝世界是 benchmark,而是直接承認世界本來就很亂。
落地時,你一定會碰到一堆討厭問題:什麼叫 user correction?怎麼避開誤觸發的行為?怎麼把私密資料擋在訓練外?怎麼避免模型只朝著最大聲的用戶過度修正?這些問題很煩,但它們才是工作本體。
實操上,我會先加 guardrails 再談擴大。先過濾敏感內容、去重重複 session、按 task type 分流 feedback。不要把 code completion 的訊號和客服聊天的訊號亂混,除非你真的知道自己在幹嘛。不同任務產生的隱性回饋本來就不同,一個萬用 trainer 常常只會把它們搓成一團爛泥。
如果要我從零做,我會先選一條窄 workflow、一套 feedback taxonomy、一個 retraining trigger。這個 loop 先真的改善一個指標,再往外擴。不是反過來。
可抄的模板
# OPSD feedback loop template(可直接改成你自己的 pipeline)
## 1. Capture on-policy interactions
每次模型回覆都記:
- prompt state
- model output
- model version
- timestamp
- user action after output
- follow-up prompt or edit
- task category
## 2. Normalize implicit feedback
把產品行為映射成訓練訊號:
- accepted unchanged -> positive
- accepted after edit -> positive with correction target
- retry / reformulation -> negative on prior output
- abandonment -> weak negative
- copied / executed / saved -> task-specific positive
## 3. Build correction pairs
每個 session 產出:
- input: prompt state + model draft
- target: user-edited answer, accepted diff, or revised completion
- weight: based on feedback strength
## 4. Train on current behavior
只吃目前 checkpoint 產生的新輸出。
用 rolling window,不要一直回收老資料。
## 5. Distill the better draft
先根據用戶反應生成 revised answer。
把 revised version 當 teacher target,對回原始 draft。
## 6. Filter and audit
訓練前先移除:
- private data
- ambiguous feedback
- duplicate sessions
- low-confidence corrections
抽樣人工看一小部分,別全自動到失控。
## 7. Measure what matters
追這些指標:
- correction rate
- retry rate
- acceptance after edit
- task completion success
- regression on recent live prompts
## 8. Retrain and redeploy
當某個 task slice 累積到足夠新訊號再重訓。
只有在 live correction metrics 真的變好、baseline quality 沒掉時才上線。
## Minimal data schema
{
"model_version": "vX",
"task": "code_assist",
"prompt": "...",
"draft": "...",
"user_action": "edited",
"user_edit": "...",
"follow_up": "...",
"signal_weight": 0.8,
"created_at": "2026-06-24T00:00:00Z"
}
## Minimal training pair
input: prompt + draft + context
target: accepted edit or revised completion
weight: signal_weight我喜歡這個模板,因為它夠無聊,反而能上線。它不靠神秘標註,也不要求你有超人類的資料團隊。它只是逼你正視用戶真的怎麼走過你的系統。以我對這篇知乎文章的理解,OPSD 的核心不是名詞,而是把模型自己的 live 行為,加上用戶留下的隱性修正,變成下一輪訓練的原料。
來源致謝:原始想法主要來自這篇 知乎文章,以及文中提到的 DeepSeek 與 Cursor 脈絡;我這篇的拆解、例子和模板是我自己的整理,方便台灣開發者直接拿去改成自己的 loop。