你把推理強度調高,等了更久,答案卻和原本差不多。Mistral Large 4 High 到底有沒有用?如果把模型的思考草稿也一起塞進 JSON 解析器,甚至可能連答案都讀錯。想判斷這個開關值不值得開,先要分清「回應讀對了嗎」與「任務真的做對了嗎」。
這篇寫給第一次做模型比較、願意照著範例跑一份小題集的讀者。我們用繁中資料擷取、程式修補和多步計算,教你建立 none/high 配對成績單。你會得到可複製的測試程式、驗收規則,以及保留 none、改用 high 或另找模型的判斷方法。這是一份依官方文件設計的評估教學,本文不提供 AlphaLab 未執行的模型成績。
截至 2026 年 10 月 7 日,官方 changelog將 mistral-large-4 列為 Public Preview。發布背景可先讀 Mistral Large 4 發表解析;本文集中處理測試方法。Simon Willison 的 10 月 6 日原始試用筆記也對 none/high 的差異提出疑問;這是他的有限觀察,並非整款模型失效的證明。
先說結論:Mistral Large 4 High 要用什麼證據判斷?
好設定=能驗收的成果+可接受的完成成本。 把 none 與 high 想成同一位解題者的兩種工作方式:一種較少展示草稿,另一種把草稿分區交出來。草稿長度只是過程訊號,最後交付正確資料、通過測試或算對結果,才是你要買的成果。
- 先驗解析:保留完整 JSON 回應,只把最終文字交給答案檢查。
- 再做配對:同題、同入口、同共同設定,每種模式三次,交錯順序。
- 最後算帳:格式、品質、延遲與費用分開記;三次是探索起點,不能替模型宣布通用勝負。
Mistral Large 4 High 與 none:先讀懂兩種回應
依 官方 reasoning 文件,reasoning_effort="high" 的 message.content 會以區塊列表呈現:type="thinking" 裡放推理文字,type="text" 放最終答案;none 則以字串呈現,省略可見 thinking 區塊。none 不是「完全不思考」的證明,high 也不是答對保證。
像老師收考卷:草稿紙可以保留查問題,答案欄才用來評分。不要把整個列表轉成字串,也不要把 nested thinking 裡的文字串到 final answer。程式應分支處理字串和列表;碰到未知區塊就留下原始回應、標記解析失敗,避免偷偷丟掉資訊後宣告模型答錯。

本文採非串流請求 stream:false,避免先把 streaming 的增量拼接也混進第一次比較。即使 final 看起來完整,也要保存 finish_reason:length 或 model_length 表示截斷訊號,不能和正常 stop 的結果混算。要處理多輪或工具呼叫,再另外建立題集;這次各題都是新的單輪請求。
五個零件:讓配對比較真的能對帳
①「身分收據」:固定入口,留下實際模型名稱
換一次入口,可能同時換掉路由與介接方式。這份題集固定原廠 https://api.mistral.ai/v1/chat/completions,模型選擇從 Models API核對。先執行 curl -sS https://api.mistral.ai/v1/models -H "Authorization: Bearer $MISTRAL_API_KEY" > models.json,確認帳號列出的 ID 或 alias。
模型卡與 changelog 使用 mistral-large-4,推理文件另列 mistral-large-4-0;這裡使用前者並保存 models 清單及每次回應的 model。這是在固定請求名稱,不是在聲稱永久固定後端權重。 Preview 變更後另開一輪,不把不同日期結果合併。若日後要追第三方路由,模型身分查核可以補上收據的判讀界線。
②「公平考場」:共同設定一致,只換 effort
先把相同 prompt、temperature:0.2、max_tokens:8192、response_format:{"type":"json_object"} 寫進 request 檔,再只切換 reasoning_effort。這些數值是教學配置,不是 Large 4 的最佳參數。Chat API有相應欄位;JSON 模式也要在題目明確要求 JSON。
先看第一組兩種模式是否接受相同請求。若有 400,先讀錯誤、修正兩邊共同配置,另開目錄重跑;不要只替其中一邊删參數。若經常截斷,下一輪同時調整預算,保留本輪失敗紀錄。所有預設值或省略欄位都應算配置的一部分,避免看完結果才悄悄改考場。
③「答案尺」:先寫正確答案,再送出題目
模型自己說「已完成」不算驗收。資料擷取要查欄位、型別和數值;程式修補要查功能測試;多步計算要用人工算式。把這些規則先寫好,評分時可隱藏模式名稱,降低你偏愛 high 的心理。格式成功與品質成功分成兩欄:合法 JSON 也能裝著錯的數字。
④「配對跑次」:同題各三次,交錯先後
每個任務先跑 none → high,下一次換 high → none,第三次再換回來。三類任務 × 兩模式 × 三次,共 18 個請求。這個小樣本能揭露解析、格式與明顯失敗,還不能估計廣泛任務的品質。相同題的重複也不是三個獨立題目;挑出差異後,要擴充留出題,避免只為這幾題調參。
⑤「完成帳單」:失敗、重試與人工收尾一起留
一次回應的 API 費用,和一件工作完成的費用不同。記下所有嘗試的 token、耗時、費用與人工分鐘,再算 每件合格成果 API 成本=全部嘗試 API 費用 ÷ 合格成果數。若合格數為零,填「未交付」,不要填零成本;人工費用可再按你自己採用的時薪換算。
三類任務:用同一套方法,不用同一把尺

繁中擷取:「林小文購買 3 本筆記本,每本 80 元,免運。」要求 name、qty、total,預期為 {"name":"林小文","qty":3,"total":240}。先查唯一欄位集合及整數型別,再查姓名與金額。擴充時加入退款、同名欄位、全形數字與缺失資訊,預先定義缺失值如何表示。
程式修補:把 def clamp(x, lo, hi): return min(lo, max(x, hi)) 修成將 x 限制於閉區間的函式;只考 lo <= hi 的需求。驗收包含 clamp(-1,0,10)==0、clamp(5,0,10)==5、clamp(12,0,10)==10、兩個端點與 lo==hi。要保留簽名,也要檢查模型是否改動測試。
測試程式只保存模型提出的 code,不自動執行。把補丁放進你控制、沒有帳號金鑰且不連外的測試環境,先讀差異再跑既有測試;這裡省略沙箱建置,因為任務是比較模型回應。若要把它接成正式開發流程,可讀 Agent 回歸測試,補上必要證據與禁止動作。
多步推理:18 箱 × 24 件,出貨 137 件,再收到 5 箱 × 24 件,其中 12 件損壞。人工算式為 18×24−137+5×24−12=403,驗收 {"remaining":403}。這裡考的是清楚條件下的算術;將來可加入不同退貨規則,先寫好新答案,別把文字歧義直接算成模型推理能力。
可複製上手:產生一份保留原始回應的成績單
在已有 Python 3 與可用 Mistral API 帳號的環境,先於自己的 shell 設好 MISTRAL_API_KEY。將下面程式存為 evaluate.py,在一個新資料夾執行 python3 evaluate.py。它使用 Python 標準函式庫,依 官方 Chat 協定發送請求,輸出 ml4-runs/scorecard.csv、每次 request、完整 response 與 final answer。
程式採一次請求一次紀錄,不做自動重試;遇到 HTTP 400/401/403 就停止,先修正設定或存取權。429、timeout、未知回應和解析錯誤會留在 error 欄。它不會替你確認帳單、沙箱補丁品質或人工工時,這三項需要另外填。每輪使用新的工作資料夾,避免相同檔名覆蓋前一輪;不要把金鑰寫進程式或公開 artifact。
import csv, json, os, time, pathlib, urllib.request, urllib.error
OUT = pathlib.Path('ml4-runs'); OUT.mkdir(exist_ok=True)
MODEL = os.environ.get('ML4_MODEL', 'mistral-large-4')
KEY = os.environ['MISTRAL_API_KEY']
req = urllib.request.Request('https://api.mistral.ai/v1/models', headers={'Authorization':'Bearer '+KEY})
with urllib.request.urlopen(req,timeout=60) as response:
raw_models=response.read(); (OUT/'models.json').write_bytes(raw_models)
cards=json.loads(raw_models)['data']
assert any(c['id']==MODEL or MODEL in c.get('aliases',[]) for c in cards), 'model unavailable'
TASKS = [
('extract', '從以下虛構訂單擷取資料,只回傳 JSON,欄位必須為 name、qty、total。姓名保持繁體中文,qty 與 total 為整數。訂單:林小文購買 3 本筆記本,每本 80 元,免運。', {'name':'林小文','qty':3,'total':240}),
('repair', '修補 Python 函式 def clamp(x, lo, hi): return min(lo, max(x, hi))。限制 lo <= hi,將 x 限制於閉區間 [lo, hi];只回傳 JSON,唯一欄位 code,其值為完整函式程式碼。不要更改函式簽名。', None),
('reason', '假設倉庫有 18 箱,每箱 24 件。先出貨 137 件,再收到 5 箱,每箱 24 件,其中 12 件損壞不能出售。剩餘可售件數是多少?只回傳 JSON,唯一欄位 remaining,值為整數。', {'remaining':403})
]
def split_content(content):
if isinstance(content, str): return content, False
if not isinstance(content, list): raise ValueError('unexpected content shape')
final, thinking = [], False
for chunk in content:
if chunk.get('type') == 'text': final.append(chunk['text'])
elif chunk.get('type') == 'thinking': thinking = True
else: raise ValueError('unknown chunk type: ' + str(chunk.get('type')))
if not final: raise ValueError('no final text')
return ''.join(final), thinking
rows=[]
for task_id, prompt, expected in TASKS:
for repeat in range(1,4):
# Alternate order to limit systematic time-of-day differences.
for effort in (['none','high'] if repeat%2 else ['high','none']):
rid=f'{task_id}-{repeat}-{effort}'; start=time.perf_counter()
body={'model':MODEL,'messages':[{'role':'user','content':prompt}],
'reasoning_effort':effort,'stream':False,'max_tokens':8192,'temperature':0.2,
'response_format':{'type':'json_object'}}
(OUT/(rid+'-request.json')).write_text(json.dumps(body,ensure_ascii=False))
row={'run':rid,'task':task_id,'repeat':repeat,'effort':effort,
'utc':time.strftime('%Y-%m-%dT%H:%M:%SZ',time.gmtime()),
'model':'','finish_reason':'','thinking':'','format_ok':False,
'quality_ok':'','input_tokens':'','output_tokens':'','seconds':'',
'api_cost_usd':'','human_minutes':'','error':''}
req=urllib.request.Request('https://api.mistral.ai/v1/chat/completions',
data=json.dumps(body).encode(),headers={'Authorization':'Bearer '+KEY,
'Content-Type':'application/json'})
try:
with urllib.request.urlopen(req,timeout=300) as response:
raw=response.read(); (OUT/(rid+'-response.json')).write_bytes(raw)
data=json.loads(raw); choice=data['choices'][0]
row['model']=data.get('model',''); row['finish_reason']=choice['finish_reason']
usage=data.get('usage',{})
row['input_tokens']=usage.get('prompt_tokens','')
row['output_tokens']=usage.get('completion_tokens','')
answer, thinking=split_content(choice['message']['content'])
row['thinking']=thinking
(OUT/(rid+'-answer.txt')).write_text(answer)
value=json.loads(answer)
if task_id=='extract':
row['format_ok']=isinstance(value,dict) and set(value)=={'name','qty','total'} and isinstance(value['name'],str) and type(value['qty']) is int and type(value['total']) is int
elif task_id=='reason':
row['format_ok']=isinstance(value,dict) and set(value)=={'remaining'} and type(value['remaining']) is int
else:
row['format_ok']=isinstance(value,dict) and set(value)=={'code'} and isinstance(value['code'],str)
if expected is not None: row['quality_ok']=row['format_ok'] and value==expected
# repair quality is filled after isolated tests; never execute generated code here.
except urllib.error.HTTPError as exc:
(OUT/(rid+'-http-error.txt')).write_bytes(exc.read()); row['error']='HTTP '+str(exc.code)
except Exception as exc: row['error']=type(exc).__name__+': '+str(exc)
row['seconds']=round(time.perf_counter()-start,3); rows.append(row)
with (OUT/'scorecard.csv').open('w',newline='') as f:
writer=csv.DictWriter(f,fieldnames=list(row));writer.writeheader();writer.writerows(rows)
print(rid,row['finish_reason'],row['format_ok'],row['error'])
if row['error'] in ('HTTP 400','HTTP 401','HTTP 403'):
raise SystemExit('Fix access or the common request configuration before rerunning both modes.')
跑完先用文字編輯器開原始 response,抽查至少一組 high/none:final 是否來自頂層 text、thinking 是否另存於 raw、回應 model 是否一致。接著開 CSV:擷取與計算題會填 quality_ok;修補題留白,等隔離測試後填入。format_ok=true 只表示這個題目的格式檢查通過,尚未等於成果合格。
正式統計時,合格要同時符合:finish_reason=stop、沒有 error、format_ok 成立、quality_ok 成立,以及人工定義的其他驗收條件。正常完成的條件可以與完整原始回應對照;tool_calls 在本輪沒有工具的任務中應另外追查,而非自動視為正確。
成本怎麼填:先對帳,再比較合格成果
截至 2026 年 10 月 7 日,官方模型卡同列原價與上市折扣價;changelog寫明上市優惠為兩週五折。圖中金額是當日每百萬 token 的美元單價,不能當成長期固定費率。

先把 usage.prompt_tokens 與 usage.completion_tokens 原樣保留,再查看原始 usage 是否有 prompt_tokens_details.cached_tokens。若有快取命中,要拆開未快取與快取輸入單價;不能把快取 token 再重複加進總輸入。範例 CSV 不自動估價,因為你的實際優惠、快取與帳單需要分開核對。
把各次費用填進 api_cost_usd,人工檢查/修補分鐘填進 human_minutes。比較三個 task 各自的合格數與成本,再保留整體彙總。延遲欄量的是 整次 client 嘗試的牆鐘時間,包含網路、服務等待及本機存檔與解析;不要把它改稱模型純推理速度。
延遲可列中位數與全部三次原始值。這麼少的樣本不適合宣稱可靠 p95;如果服務偶發 timeout,連失敗耗時一起記。讀取帳單若與 token 推估不同,先保存差額與計費來源,不用漂亮的估價蓋掉實際支出。
決策層:何時保留 none、開 high 或換模型?

保留 none:它已達到預先訂好的驗收條件,high 在新增留出題沒有帶來你需要的品質改善,而耗時或成本超過預算。這個結論限定該類任務,不能外推成所有推理都不值得。
使用 high:多步或邊界題反覆顯示品質改善,格式與截斷問題已排除,而且每件合格成果的完整成本可接受。先在最受益的任務開,不需要把簡單擷取也一併切換。
比較其他模型或人工處理:兩模式都過不了必要檢查,或錯誤後果要求逐項簽核。把你日常用的模型列為第三組,使用同題、同驗收、各自可核對的計費與配置;不同廠的 effort 名稱不是同一把尺。先驗新路徑,再替換舊路徑。
如果差異不明,下一步不是猜「開關沒生效」,而是按序檢查請求是否送出參數、兩種回應是否讀對、預算是否截斷、題目是否太容易,再增加題目。可見 thinking 只能支持回應格式的觀察,無法單獨證明內部算力投入或答對機率。
Mistral Large 4 High 常見問題:先給直接答案
1. High 一定比 none 準嗎?
不一定。這份方法讓你以任務驗收比較;較長草稿不能取代正確答案與測試。
2. none 就是完全不推理嗎?
不是這樣解讀。官方描述的是較少思考並省略可見 thinking;你不能從缺少草稿推得內部完全沒有推理。
3. high 回傳列表就算格式錯誤嗎?
不算。列表本身是文件描述的回應形狀。先提取 final text,再查題目要求的 JSON;不要用字串解析器直接處理整個列表。
4. 三次就能選出最好的模型嗎?
不足以做通用排名。三次可以抓介接和明顯失敗;選模型之前還要增加代表實際工作的留出題。
5. temperature 設成 0.2 就能保證重跑一樣嗎?
不能把這個設定當成後端版本鎖。它是共同採樣配置;保存日期、模型回應與原始答案,再比較分布。
6. JSON mode 成功就表示資料正確嗎?
不表示。格式與答案是兩格:qty 為整數、total 為整數之後,還要驗數值與來源文字相符。
7. API 回應便宜,完成工作就便宜嗎?
不一定。失敗、重試和人工修補也要計入;零個成果合格時填未交付,別用最低單次費用替整件工作報價。
8. 初次測試該投入什麼資料?
先用本文虛構題。確認解析與紀錄可靠後,再把能合法使用、去識別化且已有答案的工作樣本加入;預寫驗收再送出。
給新手的三個重點
- 先拆回應:原始 JSON 保存,thinking 與 final 分流,解析失敗獨立記。
- 先定答案:資料對帳、程式測試與人工算式各負責自己的任務。
- 再下決定:none/high 是工作配置,合格成果與完成成本才是選擇依據。
接著閱讀
左右滑動查看更多推薦
結語:今天先完成一組配對收據
Mistral Large 4 High 的價值,要落在能驗收的成果+可接受的完成成本。今天先跑一組虛構擷取題,確認兩種回應都讀對,再跑三類題集並填完修補驗收和帳單。將這份成績單留給下一輪 Preview 更新,比記住一次好看的答案有用。想把模型評估接成完整工作流,可以從 最小 Harness 實作接到 AlphaLab 課程,或回 AI 教學文章庫繼續學習。





