What Is Reasoning

Armin Ronacher

什麼是推理

原文由 Armin Ronacher 發布,訂閱此部落格

幾週前一篇論文被分享,展示了如何從封閉權重模型中提取推理軌跡。加上網路上關於誘騙模型洩漏這些軌跡的討論,出於好奇,我也進一步研究了一下。Twitter 上似乎充斥著關於這套機制如何運作的半真半假說法與混淆,所以或許這篇文章能幫助一些人理解實際上發生了什麼。

隱藏軌跡

推理軌跡通常對我們隱藏。我們曾對此表示遺憾,但大多也只能接受。幸好,開放權重模型會揭露這些軌跡,從它們的行為可以看出,這些軌跡可能又長又令人困惑。這或許正是將它們與一般呈現給使用者的內容分開的好理由。

至少,UI 需要能夠偵測它們。業界很擅長把推理軌跡形塑得好像很特別、很神祕,但它們其實就只是文字:模型被訓練成在給出最終答案之前,先把思考過程輸出到暫存區,作為回應的一部分。

GPT-OSS 的 Harmony 回應格式讓這點一目了然:

<|channel|>analysis<|message|>
I need to work this out ...
<|end|><|start|>assistant<|channel|>final<|message|>
The answer is ...
<|return|>

這些標記是特殊 token,但夾在中間的推理過程使用的「同樣的文字」跟最終答案是一樣的(只是 GPT 的 chain-of-thought 文字聽起來真的很好笑)。當模型取樣到 analysis 頻道 token 時,解析器會將接下來的文字導向另一個獨立的串流,透過 Responses API 對外提供。對於封閉模型,想必是用一個簡單的模型來對其進行遮蔽與摘要。

推理強度

有多少預算分配給推理?早期的 API 會暴露推理 token 的預算,讓人以為這是取樣過程的某種屬性。實際上,推理強度是直接寫在 system prompt 裡的。GPT-OSS 就是這樣在 system prompt 中設定:

Reasoning: low

就這樣而已。訓練會產生相應的行為,例如輸出一串能切換到 analysis 頻道的 token 序列。這也解釋了為什麼改變強度會讓 KV cache 失效。我想封閉的 GPT 模型把推理強度稱為「juice」,因為你可以問大多數模型它們還有多少 juice。

DwarfStar 中,針對 DeepSeek 開啟最大推理時,會在 system prompt 裡加入這段:

Reasoning Effort: Absolute maximum with no shortcuts permitted.
You MUST be very thorough in your thinking and comprehensively decompose the
problem to resolve the root cause, rigorously stress-testing your logic against
all potential paths, edge cases, and adversarial scenarios.

別思考

因此,推理 token 的去向其實是一種學來的慣例:模型被訓練成把草稿計算留在 final 頻道之外。騙它以為自己已經在那個頻道裡,它就可能會洩漏 token。我們甚至看過較舊的模型在思考被關閉時,會把推理過程寫進 bash 工具裡,並把想法 echo 到 /dev/null

所以在某種意義上,對某些模型而言,唯一的「特殊」行為就是不去思考。那有時是透過「機械式地」移除模型慣用的思考方式來達成。在DwarfStar 中,關閉思考時會使用 prefill 的 </think>,開啟思考時則使用 <think>,這兩個分別是結束與開始思考的 token。GPT-OSS 則不會做 prefill,而是讓模型自行決定要不要思考。

不過可以推測,有些推論 API 在啟用推理時會預先填入起始 token,因此模型本身永遠不會去取樣它;而在停用時則可能會阻止對推理 token 的取樣,因為這很容易被偵測到。這或許能解釋為什麼一個自訂的 think 工具能夠誘使模型把部分推理放到不該放的地方——但只有在原生推理被停用時才有效。

趣聞:這篇部落格文章觸發了安全檢查

好笑的是,我本來想用 GPT 5.6 terra 幫這篇部落格文章做拼字與文法檢查,卻因為安全過濾機制而無法使用。只好改用 Kimi。

GPT-5.6-terra 拒絕為這篇部落格文章進行拼字檢查

本文章由 muse-spark-1.2-contributor 進行翻譯

留言