標註引擎
用模型為資料集打標籤,用一份盲態隨機抽取的人工標籤樣本檢驗這些機器標籤,併為釋出的資料集附上一份證書,記錄檢驗了什麼。
標註引擎用模型為資料集打標籤,再用人來衡量模型出錯的頻率。你在一份契約裡宣告最終標籤必須滿足的條件,例如“被接受的機器標籤中至多 5% 是錯的,置信度為 90%”。引擎向人索取檢驗這一說法所需的標籤,接受檢驗所支援的機器標籤,把其餘條目交給人來標註。產出是資料集,外加一份證書,記錄檢驗了什麼、用了多少條人工標籤。
標註引擎從 Potato 2.11 起提供。標註伺服器、potato label 命令列、REST API、MCP 伺服器和 Python SDK 都通過任務目錄裡同一個 engine.sqlite 檔案來驅動它。
什麼樣的研究適合用引擎
當人沒法標完所有條目、而模型能標好大部分時,引擎才划算。如果人無論如何都會標完每個條目,引擎就沒有任何增益,這時普通的分配策略是更好的選擇。以下三種情況適合使用:
- 條目多到人標不完,而你有一個大多數時候都對的模型。
- 你需要報告標籤有多好,而不只是說明它們出自模型,無論是為了論文、資料集釋出,還是一份別人要用的訓練集。
- 你在用 LLM 評審來評測一個模型或智慧體,需要知道這個評審能否代替人。
從模型預測到最終標籤
引擎把機器預測、人工請求和契約結果存放在同一個儲存裡,每個條目都經過同樣的六個步驟:
- 來源就是模型。來源可以是 LLM、視覺語言模型、決策模型(Laya、Jev 或 OpenJev)、目標檢測器、LLM 評審、用本研究自身標籤訓練的模型、由其他來源組成的評審團,或者你已有的標籤。每個來源在給出每條預測時都會記錄一個置信度。
- 級聯給來源排定順序。條目先交給第一個來源;如果契約不接受這個答案,就由下一個來源來試。最後一個來源之後,條目交給人。
- 請求是引擎要人去做的事。每個請求都記錄它為何發出(例如校準、認證、核驗、抽查)、它的條目被抽中的機率,以及這個人能否看到機器的答案。校準請求隨機抽取,並且始終是盲態的。
- 契約在隨機樣本上拿機器標籤與人工標籤對照檢驗。這份樣本的一半(dev 劃分)用來選定接受規則,另一半(cert 劃分)用來檢驗它。契約的狀態為
met、insufficient(還需要更多標籤,並給出所需數量的估計)、infeasible、violated或stale。 - 定案為每個條目給出最終標籤。這個標籤要麼是在已滿足的契約下被接受的機器標籤,要麼是某個人的標籤,要麼待定。
- 證書記錄每份契約的結果、帶有模型和提示詞版本的級聯、每種用途各用了多少條人工標籤、模型花費,以及呼叫日誌的摘要。
保證背後的規則
已滿足的契約是關於人工標註的那份隨機樣本的統計陳述,它之所以成立,靠的是這份樣本的抽取方式和使用方式。引擎執行五條規則:
- 盲態請求不顯示任何機器答案。 當某人持有一個校準、認證或抽查請求時,伺服器會扣下該條目的所有機器答案。預標註、內聯評審、AI 助手(返回
403)和 AI 幫助按鈕全部關閉。看過機器答案之後給出的標籤,不能獨立地檢驗那個答案。 - 選定和檢驗使用不同的標籤。 閾值在 dev 標籤上選定,在 cert 標籤上檢驗。在 cert 標籤上的每一次新檢驗都使用更嚴格的水平,所以反覆認證直到檢驗通過並不會抬高置信度。
- 只有人能認證。 機器標註者可以參與推斷最終標籤,但永遠不會進入契約用來檢驗的那些標籤。
- 任何改動都會讓證書過時。 更改來源、提示詞、閾值或方案,會把所有受影響的契約標為
stale,並把它們已接受的標籤移到pending_recert,直到契約再次被檢驗。人工標籤會保留。 - 機器預測不佔標註者名額。 引擎的預測不計入每個條目的標註者上限。
引擎不會檢查人工標籤是否正確。每份契約衡量的都是機器與標註樣本的那些人之間的一致程度,所以用不可靠的人檢驗的契約,證明的是與不可靠的人的一致。請同時用品質控制、重疊標註(humans.overlap)和 no_worse_than_human 契約來檢查標註的人。
第一項研究
Potato 在 examples/labeling-engine/ 下附帶三個示例研究,分別針對文本、影像和智慧體軌跡。下表列出每個示例使用的來源和契約:
| 示例 | 來源 | 契約 |
|---|---|---|
text-certified-sentiment/ | Laya(決策模型)、一個 Ollama LLM | 10% 的選擇性風險,PPI 流行率 |
image-objects-and-people/ | YOLOv8n 檢測器、一個 Ollama 視覺模型 | 邊界框(IoU)上和“有人”標籤上的選擇性風險 |
agent-trace-judge/ | 一個帶標籤順序互換的 LLM 評審 | 選擇性風險、不差於人類、PPI 任務成功率 |
文本示例用四條命令就能跑起來。第一條用級聯為每個條目打標籤並抽取第一份盲態樣本,第二條把這份樣本提供給人來標註,等人標完樣本後,最後兩條檢驗契約並列印證書:
potato label run examples/labeling-engine/text-certified-sentiment/config.yaml
potato start examples/labeling-engine/text-certified-sentiment/config.yaml -p 8000
potato label certify examples/labeling-engine/text-certified-sentiment/config.yaml
potato label certificate examples/labeling-engine/text-certified-sentiment/config.yaml --format md要在你自己的研究里加入引擎,就在一份已有 data_files 和一個名為 sentiment 的標註方案的配置里加上下面這些鍵。這份契約要求被接受的機器標籤中至多 10% 是錯的,置信度為 90%,budgets.human_labels 則限定引擎最多能發出多少個人工請求:
assignment_strategy: engine
labeling_engine:
enabled: true
sources:
- id: gemma
kind: llm
endpoint_type: vllm
model: google/gemma-4-12B-it-qat-w4a16-ct
base_url: http://localhost:8001/v1
confidence: {method: logprob}
contracts:
- id: accuracy
kind: selective_risk
schema: sentiment
error: 0.1
confidence: 0.9
budgets:
human_labels: 400這個來源根據 token 的對數機率給出置信度(method: logprob),每個條目只需一次呼叫,而且通常是各種置信度方法中校準得最好的。配置列出了每一個鍵,契約說明了每種契約檢驗什麼。
標註頁面上的請求
設定 assignment_strategy: engine 後,標註者拿到的是引擎的請求,優先順序最高的先發。順序是:仲裁、認證、校準、為分佈型契約追加的評分者、沒有任何機器能標註的條目、核驗,最後是抽查。校準請求按固定的隨機順序發放,dev 和 cert 請求交錯出現。一個人會一次拿到某個條目上所有未關閉的請求,每個方案一個,同一條目的同一方案永遠不會給他兩個請求。
條目上方有一條簡短說明,指出這是哪類請求;在有多個問題的頁面上,它還會點明是哪個問題:
- 盲態。 說明寫著 "Label this one yourself. Suggestions are off for this item." 這個人儲存之後,條目對他仍保持盲態,重新載入和後退時都一樣。
- 核驗。 機器的答案已經填好,說明會提示:對就保留,不對就修改。頁面會記錄預填的答案,所以你可以衡量人們接受它的頻率。在這個人動手之前什麼都不會儲存,所以開著不管的頁面不會替他作答。頁面無法預填答案的方案(時間片段、3D 物體、智慧體軌跡)改為以盲態提供。
- 定案。 沒有任何機器標籤能被接受,所以這個人的答案就是標籤。
某人持有卻在 runtime.hold_minutes(預設 60)內沒有作答的請求,會回到請求池並從他的頁面上移除。在引擎沒有派給某人的條目上儲存的標籤,永遠不會關閉別人的請求,引擎會把它保留為自發標籤(organic label)。當一次新的認證接受了機器標籤時,引擎會取消它現在覆蓋的那些條目上未關閉的核驗和定案請求。某人已經持有的請求仍歸他,他的答案會取代機器標籤。
進度計數器統計的是一個人還能接的請求數,而不是整個語料。暫時沒有事可做時,標註者會看到一個簡短的等待頁面,規劃器發出新請求後就會派給他。當不會再有更多請求時,也就是每個條目都有了標籤、人工標籤預算已經用完,或這個人自己的上限已經達到時,他的部分會照常結束,進入研究後的頁面,在眾包平臺上則給出完成碼。在規劃器第一次執行之前,沒有人會被判定為已完成。
Pocket Mode 也會提供引擎請求,每次一整批,並且在顯示 "All caught up" 之前會先請求更多。Pocket Mode 從不顯示機器答案,所以在那裡提供的核驗請求會被記錄為盲態,除非桌面頁面已經向這個人顯示過答案。在定案和仲裁卡片上,它顯示的說明與桌面頁面相同。
管理頁面
開啟引擎後,管理面板會連結到位於 /admin/labeling-engine 的 Labeling engine 頁面。頁面上的每張圖表都有對應的表格檢視。頁面顯示:
- 每份契約的狀態、覆蓋率、檢視次數,以及還需要多少標籤,並附上它所作的完整陳述(未滿足的契約陳述的是它的目標,而不是保證);
- 每份
ppi契約的區間,旁邊是僅憑人工標籤得到的區間; - 對上次執行失敗、或每個答案都出錯的來源給出的警告;
- 最後一層級聯的錯誤率隨覆蓋率變化的曲線,帶有保證的上界和目標;
- 每一層的可靠性圖,把宣告的置信度與在人工標籤上的正確比例對照畫出,附 ECE 和 Brier 分數,標籤較少的分箱畫得較淺;
- 對已接受標籤的抽查,以錯誤數對照目標顯示,並標明抽查數量是否少到無法判斷;
- 按用途和狀態分列的人工請求;
- 模型呼叫日誌,最新的在前,附 token 數、延遲和成本;以及
- 執行一次規劃器、立即認證和開啟證書的按鈕。
沒有管理員會話時開啟這個頁面,會轉到管理面板的金鑰表單。引擎關閉時,頁面會說明這一點,並指出開啟它的那個鍵。
延伸閱讀
- 標註引擎契約:六種契約以及各自檢驗什麼
- 標註引擎配置:每一個
labeling_engine鍵 - 命令列、REST API、MCP 工具和 SDK
- 從
icl_labeling、judge_calibration和pre_annotation遷移到標註引擎 - Solo Mode,適合一位專家與一個 LLM 協作
- LLM 預標註和 LLM 評審一致性
實現細節見源文件。