
大型語言模型要替客服工單分類,得先讀完提示,再逐字生成答案,例如一段 JSON 加上理由。決策模型(decision model)不生成文字:給它一段情境(state)和幾個問題,它直接回傳每個選項的機率。Strands Decider 支援三種問題型別:choice 從 N 個選項挑一個,回傳每個選項的機率和信心分數;noul 是是非題,回傳答案為真的機率 P(true);score 是 2 到 10 級的有序量表,等級從 0 開始編號,回傳各級機率加權後的期望值 ,所以 3 級量表的期望值落在 0 到 2 之間。README 用同一段抱怨示範三種問題:「Help! My payouts have been failing for 3 days!」,choice 問這張單該交給 billing、sales 還是 retail,noul 問它有沒有急迫感,score 問寫信的人有多沮喪。
Strands Decider 是 AWS 的 strands-labs 在 2026 年 10 月 1 日開源的模型,程式碼和權重都採 Apache-2.0 授權。strands-labs 是 AWS 讓開發者試用 agent 開發實驗性做法的地方。發表文章由 Marc Brooker、Mike Chambers 與 Fabio Nonato de Paula 署名,文中說這類模型自 TypeSafe AI 推出 Jev 之後受到很多關注(Jev 的社群用法見〈Jev 應用研究:從 Agent Context 到即時控制的社群案例〉)。第一個模型以 Qwen3.5-2B-Base 為骨幹,當時以 strands-decider-2B-hobson-v19 的名字發布。10 月 15 日又加上以 Gemma 4 為骨幹的 E2B、E4B、12B、26B-A4B 四個尺寸,尺寸沿用 Gemma 4 的命名:E 表示有效參數量(effective parameters),26B-A4B 是混合專家模型,260 億參數中推論時約啟用 40 億。
版本編號要分開看。v7、v19、v21 這類編號是開發期的內部輪次,其中 v19 和 v21 曾以 hobson 的名字發布;之後的發布版改用新的命名規則,v1 表示在某個骨幹家族上的第一個發布版。所以 strands-decider-2B-qwen3.5-v1-2610 晚於 hobson-v21,兩者是不同的配方,v1 也不是 v21 改名。Hugging Face 的 StrandsAgents 目前有七個模型:五個 v1 版(2B 的 Qwen3.5 版和四個 Gemma 4 版),加上較早的 strands-decider-2B-hobson-v19 與 -v21。
11 月 9 日,Strands Agents 官網刊出 Amazon 兩位工程師的文章,說他們把內部工單分類從 Claude Sonnet 4.6 換成 Strands Decider 的 Gemma 4 E4B 版之後,每次呼叫的平均時間降 78%,token 降 70%,照牌價推算每百萬張工單的成本從約 22,200 美元降到約 500 美元;這些數字都是 Amazon 自報,沒有附任何準確率,兩邊模型讀到的輸入也不同。
以下我先說明它怎麼替選項打分、信心分數怎麼算、怎麼訓練,再整理 Strands 團隊自己測到的成績、Amazon 的案例,以及使用前要知道的限制。
指標頭怎麼替選項打分?
每個請求會組成一段提示:情境放在 <state> 裡,每個問題列出它的選項,最後以 <answer> 結尾。docs/architecture.md 的例子如下,它的選項和 README 的例子不同:
<state>
Help! My payouts have been failing for 3 days.
</state>
<question type="choice">
Select exactly one option.
Which team should handle this?
<options>
1. billing — payments, invoices, payouts
2. technical — bugs, outages, API errors
3. sales — pricing and upgrades
</options>
</question>
<answer>
骨幹(torso)是拿掉語言模型輸出層(language-modelling head)的預訓練解碼器,所以它不能再生成文字。骨幹之後負責打分的小模組統稱讀出頭(readout head),Strands Decider 用其中一種,叫指標頭(pointer head)。骨幹只跑一次前向計算(forward pass),指標頭讀兩種位置的隱藏狀態(hidden state):<answer> 位置的隱藏狀態當查詢(query),每個選項那一行最後一個 token 的隱藏狀態當鍵(key)。在因果注意力(causal attention)下,每個 token 只看得到它前面的內容,所以 <answer> 已經讀過整段提示,選項那行的最後一個 token 剛讀完自己的選項。兩種隱藏狀態先做 LayerNorm,各經一層線性投影到 256 維,再取點積除以 ,得到選項 的 logit:
對這題的 K 個 logit 做 softmax,就是各選項的機率。同一批次裡各題的選項數不同,會補齊到同樣的寬度,超過這題選項數的位置在 softmax 前遮掉。三種問題型別都走同樣的遮罩 softmax(masked softmax),noul 固定兩個選項(false、true),差別只在選項數和怎麼讀回結果。
模型裡沒有任何屬於「第幾個選項」的參數,選項的分數只取決於它寫了什麼。架構文件列出三個後果:
- 類別在請求時定義。選項從請求讀進來,新增類別不必重訓;同一組權重可以回答兩個選項的是非題,也可以回答三十個選項的分流題。
- 結構上沒有選項數上限,只有 API schema 規定一題最多 255 個選項;
score限 2 到 10 級。 - 選項順序仍有一點影響。架構文件寫道,把選項倒過來排,分布移動約 0.016,因為在因果注意力下,後面的選項看得到前面的選項。文件沒有說明 0.016 是哪一種差值;
research/history.md補充,這是在未訓練的指標頭上量的。要完全消除,得讓每個選項的注意力互相隔離,目前沒有實作。
Strands Decider 到 v7(2026 年 9 月 22 日)才改用指標頭。之前的讀出頭是槽位頭(slot head):把最後的隱藏狀態對應到固定數量的槽位,每個槽位有自己的參數。改用的依據記在 src/strands_decider/modeling.py 裡 PointerHead 的 docstring。Strands 團隊在 v6 凍結的隱藏狀態上,用同一批資料重新擬合幾種讀出頭來比較:256 維的指標頭準確率比線性槽位頭高 0.063;16 維的指標頭只有 7 萬個參數(線性槽位頭有 5.3 萬個),也高 0.058;210 萬參數的 MLP 槽位頭卻只高 0.032。他們據此認為,增益來自逐一替每個選項評分的方式,而非參數量。research/history.md 記錄的同一組比較還試了折衷的做法:先把所有選項的隱藏狀態取平均,再交給槽位頭,保留集準確率 0.706,介於線性槽位頭的 0.662 和指標頭的 0.725 之間。他們的解讀是,增益約一半來自讓讀出頭看到選項本身的表示,另一半來自逐一評分、不把選項平均在一起。
Cloudflare 10 月公開的 Clef 也是決策模型,同樣回答 noul、choice、score 三種問題,讀出頭卻是小型 transformer(joint schema head):讀骨幹最後一層的隱藏狀態,每個選項先從提示抽出相關脈絡,同一請求裡的各個問題再彼此交叉注意、回頭讀原始輸入,最後一次評完所有問題的所有選項(見〈新聞|Clef 凍結 Qwen 骨幹,用 schema head 平行評分決策選項〉)。Strands Decider 的讀出只有一次點積,選項之間的互動全靠骨幹本身的因果注意力。
信心分數怎麼算?
模型沒有另外預測信心,信心分數都從機率推導。choice 的信心是正規化後的最大機率:
機率平均分布時是 0,全部集中在一個選項時是 1。架構文件寫道,這個值與選項數 N 無關,所以同樣的門檻用在 3 個選項和 10 個選項的問題上,意思相同。README 的例子裡,billing 在三個選項中拿到 0.773,代入得 ,和輸出的信心 0.659 一致。noul 沒有信心欄位,因為只有兩個結果時,機率本身就表達了不確定程度。
score 改用標準差。Strands 團隊的理由是:最大機率把機率分散一律當成不確定,但在有序量表上,機率落在相鄰等級表示精確,例如機率在第 2 級和第 3 級之間各半,等於很有把握地說「大約 2.5」。最大機率還會把集中在兩端的雙峰分布排在均勻分布之前,對序數量表來說,雙峰卻是最糟的情況,因為回傳的期望值正好落在模型認為不是答案的地方。所以 score 的信心是:
其中 是期望值, 是機率平分在兩端時的標準差。訓練時 score 題的目標會把 10% 的機率分給相鄰等級(序數平滑,ordinal smoothing),即使模型完全擬合,σ 也還有約 。
架構文件沿用 Jev API 文件的路由慣例:信心 0.9 以上直接採用,0.5 到 0.9 先確認,0.5 以下交給人。不校正的話,3 級量表的信心最高只到 0.68,0.9 的門檻永遠達不到。程式碼(schema.py)因此把 σ 的下限 扣掉,用 計算。README 的 score 例子是三級機率 0.196、0.574、0.230(編號 0 到 2):期望值 1.03,σ 約 0.652,不校正的信心約 0.348,校正後約 0.509,和輸出的 0.509 一致。
怎麼訓練?
每次訓練只更新兩部分:約 100 萬參數的讀出頭(256 維),以及加在骨幹投影層上的 LoRA。LoRA(low-rank adaptation)凍結骨幹原本的權重,只在旁邊學一組低秩的小矩陣,把它的輸出加到原本的投影上;rank 是這組小矩陣的寬度,Strands Decider 每次訓練用 rank 16。骨幹用 bf16,讀出頭用 fp32,Strands 團隊的理由是讀出頭很小,用低精度只會徒增校準誤差。v13 到 v19 的骨幹是 Qwen3.5-2B-Base(19 億參數),24 層裡 18 層是 Gated DeltaNet(帶遞迴狀態的線性注意力),6 層是全注意力,LoRA 涵蓋兩種層的投影;v7 以前用 Qwen3-1.7B-Base。
架構文件描述的損失函數有三項:正確答案的交叉熵(score 題把 10% 的機率分給相鄰等級);KL 項,把答案拉近同一個骨幹關掉 LoRA 時自己的讀法,保住預訓練已有的知識;只用在多步驟題目上的另一個 KL 項,把答案拉近教師模型的分布。教師模型是另一個凍結、不再訓練的模型,它對選項的機率分布當學習目標;文件描述的配方用 Qwen3.5-4B。Strands 團隊寫道,有個細節比任何損失項都重要:每個例子、每個 epoch 都重新打亂選項順序,標籤跟著重新對應;score 題的選項有順序,只會整個反轉。
目前的 2B 發布版是 v1。evaluation/results.md 的〈v1, the released model〉一節列出它的訓練資料:共 246,678 列,約是 v21 的兩倍,包括 v21 的資料(拿掉 2 萬列限制商業使用的資料集)、24,533 列程式碼任務、96,638 列其他公開資料集,以及 22,168 列規則應用題(把書面政策套用到案例上)。規則應用題的政策文字和案例由 gemma-4-31B-it 生成,標準答案由程式計算;Claude 只用來獨立檢查、過濾資料,只有 gemma 和 Claude 的答案都與程式一致的列才保留,資料裡沒有 Claude 寫的文字。v1 的教師模型換成 gemma-4-31B-it,它的輸出分布只在答案與標準答案一致時當訓練目標;另有 KL 項把答案拉近前一個發布版 v19。同一節也寫明,這份資料的建置程式還沒合進 main,目前無法從 main 重建訓練資料。
發布的檢查點是三次訓練(seed 0、1、2)的模型湯(model soup):每層的 LoRA 更新取三次的精確平均,存成 rank 48 的轉接器;三個讀出頭堆在一起,選項分數是三者的平均;混合後再校準。所以 Hugging Face 上的設定檔寫著 lora_r: 48、pointer_dim: 768,單次訓練仍是 rank 16、256 維。
四個 Gemma 4 版用同樣的指標頭和模型湯做法,訓練資料卻不同:v21 的 123,339 列加上 12,263 列程式碼任務,共 135,602 列,教師模型是 Qwen3.5-4B。它們只讀文字,基礎模型的視覺和音訊編碼器在載入時就丟掉。Amazon 用的 E4B 屬於這一組,沒有用上述 v1 的資料。
Strands 團隊自己測到什麼?
主要的基準是 JevBench,README 稱它是第三方為這類模型設計的基準,公開集有 231 題。Brier 分數是預測機率與實際結果之差的平方平均,ECE(expected calibration error)是各信心區間裡宣稱的信心與實際準確率的落差,兩者都是越低越好。v1 模型湯答對 180 題(0.779),Brier 0.280、ECE 0.072;三個 seed 各答對 178、177、184 題,平均 179.7 ± 3.8。README 提醒,231 題不多,兩次單獨訓練的結果相差不到約 10 題時,應視為還沒分出高下。
evaluation/results.md 另外列了四個保留資料集。其中只有 HotpotQA 從來沒訓練過,v1 答對率 0.832;訓練資料裡有性質類似的多跳問答資料集 2WikiMultihopQA。另外三個是 MuSiQue(0.882)、ContractNLI(0.878)和 BoardgameQA(0.810)的開發集,它們的訓練集都在訓練資料裡。
四個 Gemma 4 版和 2B 版的 JevBench 成績如下,延遲是單張 H100 上每題的中位數,記憶體是 README 列的 bf16 權重所需 GPU 記憶體:
| 模型 | JevBench(231 題) | Brier | H100 延遲中位數 | 權重記憶體 |
|---|---|---|---|---|
| 2B(Qwen3.5,v1) | 180 | 0.280 | — | — |
| E2B(Gemma 4) | 180 | 0.313 | 102 ms | 約 9 GB |
| E4B(Gemma 4) | 187 | 0.243 | 139 ms | 約 15 GB |
| 12B(Gemma 4) | 200 | 0.173 | 136 ms | 約 23 GB |
| 26B-A4B(Gemma 4) | 207 | 0.162 | 245 ms | 約 51 GB |
README 沒有在同樣條件下列出 2B 的 H100 延遲,只說 v19 在 RTX 3090 上每題中位數 115 毫秒,v1 與 v19 架構和大小相同。
README 開頭說,在沒見過的短分類任務上,信心 0.9 以上的答案約有 95% 正確。這句話的出處是 evaluation/results.md 的〈Summary〉:在 emotion、hate_severity、massive_intent、sarcasm 四個沒訓練過的任務上各抽 6,000 列,v7 到 v19 信心 0.9 以上的答案準確率在 0.950 到 0.961 之間,但只有 21% 到 24% 的答案達到這個信心;表裡沒有 v1 的數字。同一節也寫明,這些信心區間只在短分類任務上成立:在長篇多步驟文件上,v19 反而信心不足,實際答對 0.83,宣稱的信心只有 0.64。
這裡的信心經過溫度校準:softmax 之前把 logit 除以溫度,溫度小於 1 讓分布變尖、大於 1 讓分布變平。Strands 團隊對每種問題型別各擬合一個溫度,擬合在保留分類任務的一半資料上做,另一半用來評分。Gemma 4 版的發表文章也說,校準溫度是在短的保留分類任務上擬合的,信心門檻要在自己的流量上測試。
Amazon 怎麼把 Sonnet 換掉?
撰文的 Carr Onstott 與 Mehul Jaiswal 負責 Amazon 的內部工單系統,工單可能是客戶升級處理、容量申請、自動警報、資安發現等,全部要歸到 20 個類別之一。原本的做法是每張工單都讓 Sonnet 4.6 讀很長的系統提示,針對固定的類別清單推理,生成 JSON。換成決策模型後,情境是工單,選項是類別清單。他們先試原本的 2B 版,在一組測試工單上,E4B 的結果明顯較好,就改用 E4B,之後再調整套用類別所需的信心門檻。文章說,在另一組工單上,E4B 勝過正式環境的 Sonnet。
E4B 部署在 SageMaker 的 ml.g5.xlarge 執行個體上,每台一張 24 GB 的 A10G。文章說模型約用 19 GiB,和上表 README 列的權重記憶體(約 15 GB)量的不是同一件事。一台執行個體處理單一請求約 640 毫秒。端點隨流量自動擴展,網路隔離、容器無法連外,權重在啟動前由 SageMaker 從 S3 複製進來。工單事件進入 SQS 佇列,觸發 Lambda 函式,讀取工單資料後呼叫 SageMaker 端點;AppConfig 放切換設定,CloudWatch 負責日誌、指標和警報,整個堆疊用 CDK 定義,分 Beta、Gamma、Prod 三個部署階段。
切換設定有三段,Lambda 每處理一則訊息都會讀一次:
BEDROCK:Sonnet 標註每張工單,不呼叫 Strands Decider。DUAL:兩個模型平行呼叫,工單套用 Sonnet 的結果,再和 Strands Decider 的結果比對。DECIDER:Strands Decider 標註每張工單,不呼叫 Bedrock。
兩人說,不論用什麼模型,他們都會沿用這個三段開關:在真實流量上兩邊都跑、逐一判讀分歧,比任何離線評測告訴他們更多;要切回去,也只需要 45 秒的設定變更。他們量到的數字如下:
| 項目 | Claude Sonnet 4.6 | Strands Decider E4B | 降幅 |
|---|---|---|---|
| 每次呼叫平均時間 | 4,215 ms | 897 ms | 78% |
| 每張工單輸入 token | 6,554 | 2,009 | |
| 每張工單輸出 token | 170 | 1 | |
| 每張工單 token 總計 | 6,724 | 2,010 | 70% |
表格的 897 毫秒是每次呼叫的平均時間,前面的約 640 毫秒是一台執行個體處理單一請求的時間,文章沒有說明兩者的差別從哪裡來。關掉 Sonnet 那天,Lambda 的平均執行時間降了 74%。
token 減少有兩個來源。第一,Strands Decider 只輸出它的選擇,不生成 JSON。第二,它的提示短得多:正式環境的類別說明本身就超過 Strands Decider 4,096 token 的視窗,所以他們把 20 個類別各改寫成一兩句準則,當成同一個 choice 問題的選項,再加上「none」選項。工單資料和 Sonnet 讀到的相同,但長工單會丟掉最舊的留言,讓內容放得進視窗。
成本照 us-east-1 的隨需牌價計算。Sonnet 4.6(Bedrock 全域端點)每百萬輸入 token 3 美元、輸出 token 15 美元,以上表的 token 數算,每張工單 0.0222 美元,每百萬張約 22,200 美元。E4B 的 ml.g5.xlarge 每小時 1.408 美元,成本取決於每台執行個體有多忙:每個請求約 640 毫秒,一台一小時約可處理 5,600 張,滿載時每百萬張 250 美元;他們保留應付尖峰的餘裕,實際約每百萬張 500 美元。文章把這寫成「便宜約 44 倍」和「降 98%」,兩者是同一組數字的兩種說法(500 ÷ 22,200 約為 2.3%)。這些都是公開牌價,沒有算進 Lambda 的費用。
他們意外發現,JSON 鍵的順序會改變答案:同樣的內容換一種鍵順序送出,輸出機率最多移動 0.19,所以他們現在一律把鍵排序後再送。程式碼裡,情境若是 JSON 物件,prompting.py 的 render_content 以 json.dumps(..., sort_keys=False) 轉成文字,請求裡的鍵順序會原樣進入提示。函式庫不會替使用者排序鍵,要穩定的答案,得自己先排好。
用之前要知道哪些限制?
- 案例刊在 AWS 自家的 Strands Agents 官網,由 Amazon 員工撰寫,數字沒有第三方查核。
- 「E4B 勝過正式環境的 Sonnet」沒有數字支撐:文章沒有公布準確率、測試集大小、
DUAL階段的分歧率,也沒有說信心不到門檻的工單怎麼處理。 - 兩邊讀到的輸入不同,表中的延遲與 token 差距反映整個流程的改變,其中一部分來自提示改寫,不全歸於模型本身。
- 成本是牌價推算,隨使用率變動。「一年省下數百萬美元」沒有明細:以每百萬張省約 21,700 美元算,一年省 100 萬美元需要約 4,600 萬張工單,文章沒有公布工單量。
- Onstott 與 Jaiswal 自己列出不適用的情境:需要模型說明分類理由、類別清單每週都在變,或有用的脈絡放不進幾千個 token。Strands 團隊 10 月 1 日的發表文章也說,這類模型在複雜問題上明顯不如推理模型;Gemma 4 版的發表文章說,只改問題、情境和選項不變時,模型可能給出同樣的答案,處理需要多步推理的長文件也有困難。
- v1 的訓練資料目前無法從 main 重建。
- 輸入的排列會影響答案,選項順序和 JSON 鍵順序都是。
- 「信心 0.9 以上約 95% 正確」沒有 v1 或 Gemma 4 版的數字,長文件上也不成立,門檻要用自己的流量測。
參考資料
- Carr Onstott、Mehul Jaiswal、Strands Agents Team,〈Amazon saves millions by replacing Sonnet 4.6 with Strands Decider〉,Strands Agents 官網,2026 年 11 月 9 日。
- Marc Brooker、Mike Chambers、Fabio Nonato de Paula,〈Introducing Strands Decider 2B: a small, open source, decision model〉,Strands Agents 官網,2026 年 10 月 1 日。
- Tim Moreton、Strands Agents Team,〈Strands Decider adds four Gemma 4 models〉,Strands Agents 官網,2026 年 10 月 15 日。
- 程式碼:strands-labs/strands-decider(Apache-2.0),本文依據 commit
846b69e的README.md、docs/architecture.md、docs/naming.md、docs/inference.md、src/strands_decider/modeling.py、src/strands_decider/schema.py、src/strands_decider/prompting.py、evaluation/results.md與research/history.md。 - 權重:Hugging Face StrandsAgents,設定檔取自 strands-decider-2B-qwen3.5-v1-2610 與 strands-decider-E4B-gemma4-v1-2610 的
strands_decider_config.json。