【技術筆記】本地模型輸出長度限制與 maxTokens 設定

今天除了一個掛在心上的 bug,還有一個意外的發現——原來輸出任務太大,也會被腰斬。記下來。

環境

  • 本地模型:Qwen3.6-35B(oMLX),用於翻譯 Agent
  • 容器:Docker sandbox
  • 工具呼叫:模型透過 structured output 機制發出 tool call,oMLX 作為 API server

問題

任務很單純:把一個 Markdown 檔案轉成 HTML。過程中觀察到的現象:

  • 小範例 HTML → 正常產出
  • MD 檔轉 HTML → 失效,工作被當成文字處理
  • 同樣的 MD 檔單純輸出為 HTML 字串(非 tool call)→ 成功

一開始的猜測

工具被 sandbox 的 tool policy 擋住?檢查了 log,確認是正常的 profile 限制,與翻譯工作無關。

真正的原因

一開始完全不知道輸出會有多大——是後來用另一個模型成功產生 HTML 後,才發現輸出高達 48K。回頭檢查翻譯 Agent 的設定,才發現 maxTokens 上限只有 4,096。

4,096 tokens 的輸出容量,遇上 12,000+ tokens 的 HTML,任務在抵達上限時被強制截斷。截斷點剛好落在看起來像 tool call 的位置,因此觸發了「Assistant reply looks like a tool call, but no structured tool invocation was emitted; treating it as text.」這個錯誤。不是工具被阻擋,而是輸出還沒說完,就被截斷了。

為什麼要設定 maxTokens?

這是雲端 API 的標準做法:

  • 成本控制:每個 token 都是錢,沒有上限的話一個失誤的 prompt 可以燒掉整個月的配額
  • 延遲管理:輸出越長回應越慢,設定上限讓回應時間可以預期
  • 防止模型失控:某些 prompt 會讓模型進入重複循環,設定上限可以截斷

但翻譯任務通常輸出的長度難以預估,尤其是要把一整篇文章轉成 HTML,長度可能是原始輸入的數倍。

對 local vs 雲端模型

local 模型沒有流量成本,但 maxTokens 仍有優點(防止模型在長輸出中卡死),也有缺點(長任務容易被腰斬)。

解法

把上限提高到 32,768,足以容納長 HTML 的輸出量。local 模型不需要極度保守的上限,稍微放寬對實際工作更有幫助。

結論

設定 maxTokens 不是錯,但數值要跟工作需求匹配。如果你的本地模型主要跑翻譯或長文任務,4,096 可能太低了。這次 debug 的順序是:先觀察到任務失敗 → 再用另一個模型確認輸出大小 → 才確定是 maxTokens 不足。也就是:先有大輸出,才發現上限不夠——不是先知道大小再想到可能是上限的問題。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料