<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Strands Decider on AI博士 万戈</title>
        <link>https://www.yesmiracle.net/tags/strands-decider/</link>
        <description>AI博士万戈的技术博客，聚焦 Agentic AI、AI Infra 与 Agent Security，分享 AI 基础设施与工程落地实践。</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh-cn</language>
        <managingEditor>admin@yesmiracle.net (万戈)</managingEditor>
        <webMaster>admin@yesmiracle.net (万戈)</webMaster>
        <lastBuildDate>Wed, 11 Nov 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://www.yesmiracle.net/tags/strands-decider/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>Strands Decider 源码级拆解：砍掉输出头换成指针头，亚马逊内部用它替掉 Sonnet 4.6，那笔「省 98%」的账我重算了一遍</title>
        <link>https://www.yesmiracle.net/post/20261111-strands-decider-teardown/</link>
        <pubDate>Wed, 11 Nov 2026 00:00:00 +0000</pubDate>
        <author>admin@yesmiracle.net (万戈)</author>
        <guid>https://www.yesmiracle.net/post/20261111-strands-decider-teardown/</guid>
        <description>&lt;img src="https://www.yesmiracle.net/post/20261111-strands-decider-teardown/cover.svg" alt="Featured image of post Strands Decider 源码级拆解：砍掉输出头换成指针头，亚马逊内部用它替掉 Sonnet 4.6，那笔「省 98%」的账我重算了一遍" /&gt;&lt;p&gt;先说清楚这篇跟站内已有的那几篇的分工。我们从九月底起写过这个品类的不少东西：&lt;a class=&#34;link&#34; href=&#34;https://www.yesmiracle.net/post/20260921-typesafe-jev-system-one-deep-dive/&#34; &gt;《TypeSafe AI Jev 深度解析》&lt;/a&gt;讲的是「System One 模型」这个范式本身，&lt;a class=&#34;link&#34; href=&#34;https://www.yesmiracle.net/post/20260925-decision-model-llm-hybrid-architecture/&#34; &gt;《决策模型 + LLM 混合架构》&lt;/a&gt;把当时四条技术路线横着比了一遍，&lt;a class=&#34;link&#34; href=&#34;https://www.yesmiracle.net/post/20261003-openai-decisions-api-jev-clone-wars/&#34; &gt;《14 天，OpenAI 就抄了个 Jev！》&lt;/a&gt;和&lt;a class=&#34;link&#34; href=&#34;https://www.yesmiracle.net/post/20261010-microsoft-decision-1-jev-decision-model-big-vendor/&#34; &gt;《微软也下场做决策模型了》&lt;/a&gt;讨论的是这个品类的资本与竞争格局。那些讲的是形态、生态和谁在抢谁。&lt;/p&gt;
&lt;p&gt;这篇不重复那些。这里只做两件事：把亚马逊自己的那个 2B 模型拆到源码级，然后把 11 月 9 日那篇「换掉 Sonnet 4.6、成本降 98%」的账重算一遍。&lt;/p&gt;
&lt;p&gt;第二件事是重点，因为那个 98% 里有一部分不是模型的功劳。&lt;/p&gt;
&lt;h2 id=&#34;它到底是什么一次前向没有解码循环&#34;&gt;它到底是什么：一次前向，没有解码循环&lt;/h2&gt;
&lt;p&gt;Strands Decider 是 Strands Agents 团队（也就是 AWS 那边做 Strands Agents SDK 的那批人）在 10 月 1 日放出来的开源模型。仓库是 &lt;code&gt;strands-labs/strands-decider&lt;/code&gt;，Apache-2.0，9 月 29 日建库，到 11 月 9 日有 1,012 颗星、123 个 fork、59 个未关的 issue，整仓 32 MB 左右。&lt;/p&gt;
&lt;p&gt;它的架构改动只有一句话：拿一个预训练的解码器 LLM，把语言建模头扔掉。&lt;/p&gt;
&lt;p&gt;官方架构文档 &lt;code&gt;docs/architecture.md&lt;/code&gt; 给了完整的打分公式。整段推理路径是这样的：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;logit_k = &amp;lt;q(h_answer), k(h_option_k)&amp;gt; / sqrt(dim)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;h_answer&lt;/code&gt; 是 &lt;code&gt;&amp;lt;answer&amp;gt;&lt;/code&gt; 那个位置的隐状态，当 query；&lt;code&gt;h_option_k&lt;/code&gt; 是每个选项那一行的最后一个 token 的隐状态，当 key。之所以取每个选项的最后一个 token，是因为在因果注意力下，那个位置已经读完了整个选项。然后对 K 个 logit 做 softmax，就是答案。&lt;/p&gt;
&lt;p&gt;没有生成，没有解码循环，没有重试，没有 JSON 解析。一次前向出结果。&lt;/p&gt;
&lt;p&gt;读出头（pointer head）大概 100 万参数，&lt;code&gt;dim=256&lt;/code&gt;；除此之外只训了挂在躯干投影上的 rank-16 LoRA。v14 的 checkpoint 只有 88 MB，就是适配器加读出头加 tokenizer，底座权重加载时从 HuggingFace 拉。躯干是 Qwen3.5-2B-Base，1.9B 参数，而且它是个混合体：24 层里 18 层是 Gated DeltaNet（带循环状态的线性注意力），只有 6 层是全注意力。仓库里 &lt;code&gt;mps_kernels.py&lt;/code&gt; 和 &lt;code&gt;cpu_kernels.py&lt;/code&gt; 这两个文件就是在为 Apple 芯片和 CPU 补 Gated DeltaNet 的算子，因为 macOS 上没有 fla。&lt;/p&gt;
&lt;p&gt;架构文档里有一句我认为是这个设计最关键的推论，原文是「An option&amp;rsquo;s score depends on what it says, not where it sits」。因为模型里根本没有任何按选项位置索引的参数，所以它学不到「第一个选项通常是正确答案」这种先验，也就没有选项数量上限，schema 里的 255 是唯一的限制。同一个权重可以回答两选的 yes/no，也可以回答三十选的工单路由，标签集在训练里从没见过也没关系，因为选项的含义完全由 prompt 建立。&lt;/p&gt;
&lt;p&gt;代价也在同一份文档里写着。它承认「Reversing the option list moves the distribution by ~0.016」，也就是把选项顺序倒过来，分布会动大约 0.016。原因是在因果注意力下选项之间仍然互相看得见。要彻底消掉得做逐选项的注意力隔离，没实现。&lt;/p&gt;
&lt;p&gt;这个 0.016 后面还会出现，而且会变成整篇最有意思的一个对比。&lt;/p&gt;
&lt;h2 id=&#34;置信度是算出来的不是预测出来的&#34;&gt;置信度是算出来的，不是预测出来的&lt;/h2&gt;
&lt;p&gt;这是我读这个仓库最大的收获，站内之前几篇都没写到这一层。&lt;/p&gt;
&lt;p&gt;决策模型卖的一个核心点就是「每个决策都带一个可信度分」。但 Strands Decider 的 confidence 并不来自一个专门的输出头，它是从概率分布里现算的。&lt;/p&gt;
&lt;p&gt;选一（choice）用的是归一化最大概率：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;confidence = (N · p_max − 1) / (N − 1)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;均匀分布得 0，one-hot 得 1，而且这个式子的关键是它与选项数 N 无关。所以一个 0.9 的阈值，在三个选项的路由问题上和十个选项的路由问题上，含义是同一个。如果你自己拿 max-prob 当置信度，这两者会不一样：N 越大 max-prob 越低，阈值就废了。&lt;/p&gt;
&lt;p&gt;二选一（noul）干脆没有 confidence 字段，理由写得很直接，只有两个结果的时候，概率本身就是不确定性。&lt;/p&gt;
&lt;p&gt;打分（score）用的是另一套，归一化标准差：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;sigma = sqrt( Σ p_i · (i − mean)² )        confidence = 1 − sigma / sigma_max
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这里修了一个真的排序 bug。如果用最大概率当置信度，一个两端都有质量的双峰分布会排在均匀分布前面，但对有序量表来说，双峰恰恰是最坏情况，因为返回的期望值恰好落在模型认为答案不在的位置上。换成标准差之后这个倒挂没有了。&lt;/p&gt;
&lt;p&gt;还有一个更细的坑，我觉得是整份文档里最工程的一句话。训练时会故意把目标质量的一小部分放到相邻档位（序数平滑），所以一个拟合得完美的模型，它的 sigma 也不会是 0，而是大概 &lt;code&gt;sqrt(eps)&lt;/code&gt;。如果不把这个地板修正掉，一个三档的 score 问题的置信度上限会被卡在 0.68，也就是「0.9 以上直接自动执行」这一档在结构上永远到不了。&lt;/p&gt;
&lt;p&gt;这是那种只有真跑过、真被卡过才会发现的问题。文档把它写出来了。&lt;/p&gt;
&lt;h2 id=&#34;训练里那条最反直觉的细则&#34;&gt;训练里那条最反直觉的细则&lt;/h2&gt;
&lt;p&gt;训练目标有三部分。对金标签的交叉熵（score 目标有 10% 质量挪到相邻档）、对冻结躯干自身读出头的 KL（权重 0.3，让模型留在预训练已知的地方）、以及对一个冻结教师模型的 KL（权重 1.0，只在多步推理的行上）。教师是 Qwen3.5-4B，不做任何训练直接读，而且只在它确实比学生强的行上用。短分类上它并不更强，蒸馏那里「moved nothing」。&lt;/p&gt;
&lt;p&gt;但文档说，有一条细节比任何一个损失项都重要：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;每个样本、每个 epoch，选项顺序都重新打乱，标签跟着重映射。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;不这么做，读出头会悄悄地记住「slot 0 倾向于正类」，通用性就没了。有了这一条，能在梯度下降里活下来的唯一策略就是真去读选项文本。打分题是例外，因为它的槽位是有序的，所以只做整体反转，不做置换。&lt;/p&gt;
&lt;h2 id=&#34;他们自己承认的部分新版本在没见过的短分类上不如老版本&#34;&gt;他们自己承认的部分：新版本在没见过的短分类上不如老版本&lt;/h2&gt;
&lt;p&gt;这部分我建议所有做模型的人看一遍。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;evaluation/results.md&lt;/code&gt; 里有一张泛化表，列的是「在训练混合里」和「四个从未训练过的任务」上的准确率。总体一行是这样：&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;版本&lt;/th&gt;
          &lt;th&gt;训练混合内&lt;/th&gt;
          &lt;th&gt;从未见过&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;v7&lt;/td&gt;
          &lt;td&gt;0.866&lt;/td&gt;
          &lt;td&gt;0.653&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;v14&lt;/td&gt;
          &lt;td&gt;0.888&lt;/td&gt;
          &lt;td&gt;0.637&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;v16&lt;/td&gt;
          &lt;td&gt;–&lt;/td&gt;
          &lt;td&gt;0.629&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;v17&lt;/td&gt;
          &lt;td&gt;–&lt;/td&gt;
          &lt;td&gt;0.640&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;v18&lt;/td&gt;
          &lt;td&gt;–&lt;/td&gt;
          &lt;td&gt;0.641&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;v19&lt;/td&gt;
          &lt;td&gt;–&lt;/td&gt;
          &lt;td&gt;0.647&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;文档自己的结论写得很直白：v14 在训练混合上每一个原语都比 v7 强，但「none of v14 and v16 to v19 generalises to unseen classification tasks better than v7 overall」。连续五个版本，在没见过的短分类任务上，全都没有超过最早的 v7。它们的增益落在长文档和多步推理上，不在短分类上。&lt;/p&gt;
&lt;p&gt;同一份文件里，校准那一节也自己划了边界：「These bands are measured on short classification, and that is the only place they hold.」在长文档和多步判断上，v19 是过度不自信的，说 0.64 的时候实际对 0.83，说 0.40 到 0.51 的时候实际对 0.72 到 0.86。而且重拟合温度会把短分类搞坏，「no single temperature per primitive serves both」。&lt;/p&gt;
&lt;p&gt;我先说一句我的看法：一个模型发布方主动把「新版本在某一类任务上不如三代前」写进结果文件，这件事本身比它的准确率数字更值得注意。我不知道有几个团队会这么写。&lt;/p&gt;
&lt;h2 id=&#34;那笔-98-的账我拆了一遍&#34;&gt;那笔 98% 的账，我拆了一遍&lt;/h2&gt;
&lt;p&gt;现在进正题。&lt;/p&gt;
&lt;p&gt;11 月 9 日 Strands 官方博客登了一篇两位亚马逊工程师（Carr 和 Mehul）的案例。他们在一个内部工单系统里，把 Claude Sonnet 4.6 换成了 Strands Decider 的 E4B（Gemma 4 底座那一版）。标题里的数字是「98% less cost」，正文说「performed just as well」，并称一年能省下数百万美元的 token 成本。工单有 20 个分类，量极大。&lt;/p&gt;
&lt;p&gt;官方给的原始数字我照抄在这里：&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;&lt;/th&gt;
          &lt;th&gt;Claude Sonnet 4.6&lt;/th&gt;
          &lt;th&gt;Strands Decider E4B&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;每次调用平均耗时&lt;/td&gt;
          &lt;td&gt;4,215 ms&lt;/td&gt;
          &lt;td&gt;897 ms&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;每单输入 token&lt;/td&gt;
          &lt;td&gt;6,554&lt;/td&gt;
          &lt;td&gt;2,009&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;每单输出 token&lt;/td&gt;
          &lt;td&gt;170&lt;/td&gt;
          &lt;td&gt;1&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;单价&lt;/td&gt;
          &lt;td&gt;$3.00/M 输入，$15.00/M 输出&lt;/td&gt;
          &lt;td&gt;$1.408/实例小时（&lt;code&gt;ml.g5.xlarge&lt;/code&gt;）&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;每单成本&lt;/td&gt;
          &lt;td&gt;$0.0222&lt;/td&gt;
          &lt;td&gt;约 $0.0005&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;每百万单&lt;/td&gt;
          &lt;td&gt;约 $22,200&lt;/td&gt;
          &lt;td&gt;约 $500&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;22,200 除以 500 是 44.4，所以是「about 44 times cheaper」；再换成降幅就是 97.7%，写成了 98%。这些数字我复算过，都能对上。&lt;/p&gt;
&lt;p&gt;下面是我的拆分。这几步来源里没有，是我自己算的，读者可以自己核。&lt;/p&gt;
&lt;h3 id=&#34;第一刀sonnet-的钱几乎全花在输入上&#34;&gt;第一刀：Sonnet 的钱几乎全花在输入上&lt;/h3&gt;
&lt;p&gt;$0.0222 拆开看：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;输入：6,554 × $3.00/M = $0.019662&lt;/li&gt;
&lt;li&gt;输出：170 × $15.00/M = $0.00255&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;输入占 88.5%，输出占 11.5%。&lt;/p&gt;
&lt;p&gt;这个比例很重要。那篇文章把「输出从 170 token 掉到 1 token」放在了很显眼的位置（表格里唯一没填百分比改进的就是输出行），可这一项在 Sonnet 的账单里只值 11.5%。真要动 Sonnet 的成本，动的是输入，不是输出。&lt;/p&gt;
&lt;h3 id=&#34;第二刀输入砍下来这件事sonnet-自己也能吃到&#34;&gt;第二刀：输入砍下来这件事，Sonnet 自己也能吃到&lt;/h3&gt;
&lt;p&gt;输入从 6,554 掉到 2,009，少了 69%。为什么掉的？文章自己交代了原因：生产的标签描述本身超过了 Decider 的 4,096 token 窗口，所以他们把 20 个标签每个重写成一句到两句的判据，再加一个「none」选项，作为一个单选的选项发过去。长工单还会丢掉最旧的评论来塞进窗口。&lt;/p&gt;
&lt;p&gt;省下来的这些 token 跟模型无关，是他们把题面重写短了。&lt;/p&gt;
&lt;p&gt;那如果同样的短题面喂给 Sonnet 呢？&lt;/p&gt;
&lt;p&gt;2,009 × $3.00/M = $0.006027&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;170 × $15.00/M = $0.00255
= $0.008577 每单，也就是 $8,577 每百万单&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;比原来的 $22,200 便宜了 2.59 倍。这 2.59 倍跟决策模型一点关系都没有，任何人只要把标签描述写短一点就能拿到。&lt;/p&gt;
&lt;h3 id=&#34;第三刀乘起来看这个-98-是怎么分配的&#34;&gt;第三刀：乘起来看，这个 98% 是怎么分配的&lt;/h3&gt;
&lt;p&gt;总倍数 44.4 = 2.59（题面重写）× 17.15（换成决策模型及其计费口径）。&lt;/p&gt;
&lt;p&gt;换成对数来分摊：log(44.4) = 3.793，其中 log(2.59) = 0.952 占 25.1%，log(17.15) = 2.842 占 74.9%。&lt;/p&gt;
&lt;p&gt;所以那 98% 里大约四分之一来自把提示词改短，这一份 Sonnet 也能拿；剩下约四分之三来自换模型和换计费口径。&lt;/p&gt;
&lt;p&gt;这不影响「该换」的结论，但它影响你抄的时候抄什么。如果你照着这个案例去立项，你真正拿到的是那份标签重写，而那个不需要决策模型。&lt;/p&gt;
&lt;h3 id=&#34;第四刀44-倍是吞吐曲线上的一个点不是常数&#34;&gt;第四刀：44 倍是吞吐曲线上的一个点，不是常数&lt;/h3&gt;
&lt;p&gt;这一点文章一个字没提，但它决定了那个 44 倍能不能搬走。&lt;/p&gt;
&lt;p&gt;决策模型的每单成本算的是除法：&lt;code&gt;$1.408 × 实例小时 ÷ 处理单数&lt;/code&gt;，它不是一个模型的固有属性。&lt;/p&gt;
&lt;p&gt;在 Sonnet 的 $0.0222/单 面前，盈亏平衡点是每实例每小时 63 单（1.408 ÷ 0.0222 = 63.4）。按他们自己测到的 897 ms 一次调用，一台实例的容量是每小时 4,013 单，也就是只要跑到单机容量的 1.6%，自托管就比 Sonnet 便宜。&lt;/p&gt;
&lt;p&gt;所以对这个用例，结论是稳的。量足够大，怎么算都赢。&lt;/p&gt;
&lt;p&gt;反过来说：同一个模型、同一套代码，把量降到每小时 63 单，那个 44 倍就变成 1 倍。那篇文章给的是一个吞吐极高的工单系统的快照，也就是曲线上的一个点。你要是把「省 98%」当成决策模型的固有属性搬到自己的低流量场景里，会翻车。&lt;/p&gt;
&lt;h3 id=&#34;第五刀他们自己的两个时间数字对不上&#34;&gt;第五刀：他们自己的两个时间数字对不上&lt;/h3&gt;
&lt;p&gt;回头看那张表，E4B 每次调用平均 897 ms。&lt;/p&gt;
&lt;p&gt;再看成本那一节：「At about 640 ms per request, one instance can handle about 5,600 tickets an hour, which would be $250 per million tickets at full use.」&lt;/p&gt;
&lt;p&gt;5,625 单/小时 × 640 ms 确实对得上。但他们量到的平均值是 897 ms，不是 640 ms。&lt;/p&gt;
&lt;p&gt;按 897 ms 重算：3600 ÷ 0.897 = 4,013 单/小时，$1.408 ÷ 4,013 × 100 万 = $351 每百万单。&lt;/p&gt;
&lt;p&gt;所以那个「满负荷下的 $250 每百万」的理论地板，按他们自己测到的延迟应该是 $351。而他们实际用的口径是 $500，比这个地板高了 42%。&lt;/p&gt;
&lt;p&gt;我不是说他们在粉饰，留给突发流量余量是正常做法，文章也写明了「We keep headroom for bursts」。但这两个数字（897 和 640）出现在同一篇文章的成本推导里，没有一句话解释为什么算钱的时候用快的那个。&lt;/p&gt;
&lt;h3 id=&#34;第六刀98-之外还有哪些没算进去&#34;&gt;第六刀：98% 之外还有哪些没算进去&lt;/h3&gt;
&lt;p&gt;文章自己交代了一句：「These are published list prices. They leave out the Lambda, which also runs for less time per ticket now.」这是个诚实的补充，方向也是对省钱有利。&lt;/p&gt;
&lt;p&gt;除此之外还有几块不在这个数里：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Lambda 之外的那一圈，SQS、SageMaker endpoint 的常驻、AppConfig、CloudWatch、S3、CDK 栈，单看都不大，但方向和多寡文章没说。&lt;/li&gt;
&lt;li&gt;把它跑起来的人力成本，一整套 SageMaker endpoint 加自动扩缩、一套带 Beta/Gamma/Prod 三阶段的 CDK、把 20 个标签重写、还有那套三路开关（下面讲）。这些不便宜，而且不换算成百分比就看不见。&lt;/li&gt;
&lt;li&gt;Bedrock 的企业价格。对照用的是「Bedrock, global endpoint」的公开目录价。真实企业拿到的可能是预留吞吐或承诺折扣，那样 Sonnet 那一侧会便宜下来，差距会缩小多少不知道。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我算完这一圈，对那篇文章的整体判断是：数字没有造假，但标题里的 98% 是一堆不同性质的收益被加总后的口径，其中只有一部分是决策模型带来的。&lt;/p&gt;
&lt;p&gt;倒是文章里有一套做法我觉得比 98% 更值得抄，下面单独说。&lt;/p&gt;
&lt;h2 id=&#34;被埋在括号里的那个数&#34;&gt;被埋在括号里的那个数&lt;/h2&gt;
&lt;p&gt;文章中间有这么一句，夹在一段话的末尾：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;One thing that surprised us was that JSON key order changed the answer. Sending the same content with keys in a different order moved the output probabilities by up to 0.19. We now send every request with sorted keys.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;键的顺序换一下，输出概率最多动 0.19。&lt;/p&gt;
&lt;p&gt;这句话被放在了一个不显眼的位置，但它是整篇文章里最重的一句话。因为 0.19 不是个小数字，它是驱动那个 0.9 阈值的东西。概率动 0.19，意味着同一个请求，换个 key 顺序，可能就从「直接执行」跳到「送人工复核」。&lt;/p&gt;
&lt;p&gt;现在把它和仓库里另外两个数并排看：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;发布检查里有一条设备一致性。同一个 checkpoint，CPU 和 CUDA 上「probabilities within 0.006」，而且在 231 个任务上答案完全相同；和训练时的 A100 硬件比，231 个任务里 230 个答案一致，剩下那一个还是接近平局（0.346 对 0.345）。&lt;/li&gt;
&lt;li&gt;架构文档里量了选项顺序的敏感性，约 0.016。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;于是就有了这个对比：&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;扰动来源&lt;/th&gt;
          &lt;th&gt;概率偏移&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;换硬件（CPU ↔ CUDA）&lt;/td&gt;
          &lt;td&gt;0.006&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;反转选项列表&lt;/td&gt;
          &lt;td&gt;~0.016&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;换 JSON 键序&lt;/td&gt;
          &lt;td&gt;0.19&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;按倍数看，键序的影响是硬件差异的约 32 倍，是选项顺序的约 12 倍。&lt;/p&gt;
&lt;p&gt;一个把「同一个输入在不同芯片上答案一致到 0.006」写进发布检查的团队，没有把「同一个输入换一种序列化方式」写进同一个检查。而部署方在真实系统里撞上的，恰好是后者。&lt;/p&gt;
&lt;p&gt;我没有资格替他们判断这是不是疏漏，键序影响的是 prompt 渲染，属于调用方那一侧的输入构造。但作为一个读者，我认为这里藏着一条比「省 98%」更有用的经验：你在给一个概率驱动的阈值系统做确定性工程时，要先把输入的所有变换都编目。硬件、选项顺序、键序、空白、换行，全都算变换。只对其中一类做了测试，剩下那些就是没有护栏的。&lt;/p&gt;
&lt;h2 id=&#34;4096-是一道硬墙而且没有旋钮&#34;&gt;4,096 是一道硬墙，而且没有旋钮&lt;/h2&gt;
&lt;p&gt;前面说到亚马逊那个团队必须把标签描述重写成一两句话，因为生产的描述本身就超过窗口了。这个窗口有多硬，仓库里写得很清楚。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;training/AGENTS.md&lt;/code&gt; 里那句话是：「The recipe saves a 4096-token window and &lt;code&gt;strands-decider serve&lt;/code&gt; has no flag to change it.」&lt;/p&gt;
&lt;p&gt;没有 flag 可以改。4,096 就是服务端的天花板，想用更长的上下文得去改代码。&lt;/p&gt;
&lt;p&gt;这解释了那个团队的处境。重写标签并不是他们的主动选择，窗口摆在那里，不改就跑不起来。而这件事对用户的影响比看起来大。如果你的标签体系本身就依赖长描述（比如每个类目要写清楚边界和排除条件），那这个模型现在装不下。文章自己的结论部分也把这条列为不适用的场景之一：「if your labels need explanation text&amp;hellip; a decision model probably can&amp;rsquo;t replace the LLM&amp;rsquo;s job」。&lt;/p&gt;
&lt;p&gt;仓库在窗口处理上有个讲究，值得单独提。超窗的行是丢弃，不是截断。文档的理由是，如果 prompt 从选项列表中间被切断，某个选项就会从邻居的表示里被打分。所以训练和评估直接丢掉超窗的行；服务时先保留问题的 token，再从前部切掉状态（&lt;code&gt;infer.py&lt;/code&gt; 里的 &lt;code&gt;_fit&lt;/code&gt;）。这跟亚马逊那篇里的「drops the oldest comments to fit」是一致的。&lt;/p&gt;
&lt;h2 id=&#34;那套三路开关我认为才是这篇的真正干货&#34;&gt;那套三路开关，我认为才是这篇的真正干货&lt;/h2&gt;
&lt;p&gt;98% 会被记住，三路开关会被忽略，但从工程上讲后者更有用。&lt;/p&gt;
&lt;p&gt;他们没有直接切换。标签的 Lambda 每收到一条消息，都从 AWS AppConfig 读一个三值开关：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;BEDROCK&lt;/code&gt;：Sonnet 给每张单打标，Decider 不被调用&lt;/li&gt;
&lt;li&gt;&lt;code&gt;DUAL&lt;/code&gt;：两个模型并行调用，Sonnet 的结果照常生效，同时和 Decider 的结果对比&lt;/li&gt;
&lt;li&gt;&lt;code&gt;DECIDER&lt;/code&gt;：Decider 给每张单打标，Bedrock 不被调用&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;先在真实流量上并行跑，然后逐条判分歧，最后才切。文章里两句话我觉得该抄下来。一句是「Running both on real traffic, then judging every disagreement, told us more than any offline eval would have」，在真实流量上并行跑再逐条判分歧，比任何离线评测告诉他们的都多。另一句是回滚是一个 45 秒的配置修改。&lt;/p&gt;
&lt;p&gt;这也顺手解释了为什么那套栈里东西那么多：SQS 队列、Lambda、SageMaker endpoint、AppConfig、CloudWatch、CDK 三阶段。复杂度花在了能回滚上，而不是花在省钱上。我认为这笔投入是值的，而且它不依赖你用什么模型。&lt;/p&gt;
&lt;h2 id=&#34;想自己跑一遍的话门槛在哪&#34;&gt;想自己跑一遍的话，门槛在哪&lt;/h2&gt;
&lt;p&gt;我把仓库量了一遍，顺手记几个数，方便判断要不要动手。&lt;/p&gt;
&lt;p&gt;推理包 &lt;code&gt;src/&lt;/code&gt; 一共 3,532 行 Python，测试 5,063 行，示例 363 行；整仓 334 个文件，其中 121 个 &lt;code&gt;.py&lt;/code&gt;。Apache-2.0，权重在 HuggingFace 上（&lt;code&gt;StrandsAgents/&lt;/code&gt; 和 &lt;code&gt;amazon/&lt;/code&gt; 两边都放了同一份），训练数据、生成脚本、preregistration 全在仓库里。&lt;/p&gt;
&lt;p&gt;训练侧的实际开销文档写得很具体：v19 是 1.9B 躯干，12.4 GiB 峰值，单张 RTX 3090 在 WSL2 下跑 123k 行一个 epoch 约 6 小时，加上它父代的约 5 小时。底座权重下载约 4.5 GB。这个门槛对个人研究者是够得着的。&lt;/p&gt;
&lt;p&gt;有两个地方让我有点意外。一是 &lt;code&gt;skills/&lt;/code&gt; 目录里直接放了两个 Agent Skills（&lt;code&gt;benchmark-decider&lt;/code&gt; 和 &lt;code&gt;customize-decider&lt;/code&gt;），带脚本和 references，等于把「怎么评测」和「怎么定制」都封装成技能交出去了。二是 &lt;code&gt;research/preregistrations/&lt;/code&gt; 里从 v9 到 v20 每个版本都有一份预注册文件，预测在跑之前就固定下来，结果事后追加。这在模型发布里不常见。&lt;/p&gt;
&lt;p&gt;至于要不要用，结合它自己写的适用条件和那份泛化表，我的判断是这样。&lt;/p&gt;
&lt;p&gt;适合的场景是选项封闭（标签集稳定、不需要解释文本）、量大、老路径的延迟真的影响体验。不适合的场景是标签需要长长地解释边界、类目每周都变、或者有用的上下文塞不进几千个 token。&lt;/p&gt;
&lt;p&gt;另外那个 &lt;code&gt;score&lt;/code&gt; 原语要留个心眼。它的从未见过任务的准确率在 0.43 到 0.50 之间（v14 是 0.432，v19 是 0.499），比 &lt;code&gt;choice&lt;/code&gt; 的 0.73 低一大截。让一个 2B 模型给主观的东西打有序分，现在还不是它的强项。&lt;/p&gt;
&lt;h2 id=&#34;我的结论&#34;&gt;我的结论&lt;/h2&gt;
&lt;p&gt;那篇 98% 的文章，我认为它写得比大部分厂商案例更诚实。它给了完整的分项表，主动说了「标题数字依赖利用率」，主动说了标签描述超过窗口所以要重写，主动把 JSON 键序那个坑写了出来，还在最后清楚地列了不适用场景。&lt;/p&gt;
&lt;p&gt;但它把一堆不同性质的收益合成了一个 98%。拆开之后，这个数里约四分之一来自把题面写短（Sonnet 也能拿），剩下的主要来自把按 token 计费换成按实例小时计费，然后靠极大的吞吐把固定成本摊薄。决策模型在这个案例里是省钱的必要条件，不是充分条件。少了那个量，44 倍会掉到 1 倍。&lt;/p&gt;
&lt;p&gt;而真正能搬走的东西是另外两样：那套能 45 秒回滚的三路开关，和那个被埋在括号里的 0.19。前者是方法，后者是教训。&lt;/p&gt;
&lt;p&gt;相关阅读：&lt;a class=&#34;link&#34; href=&#34;https://www.yesmiracle.net/post/20260921-typesafe-jev-system-one-deep-dive/&#34; &gt;《TypeSafe AI Jev 深度解析》&lt;/a&gt;那篇讲的是这个范式的起点，&lt;a class=&#34;link&#34; href=&#34;https://www.yesmiracle.net/post/20261010-microsoft-decision-1-jev-decision-model-big-vendor/&#34; &gt;《微软也下场做决策模型了》&lt;/a&gt;那篇讲的是这个品类怎么被大厂接手。&lt;/p&gt;
</description>
        </item>
        
    </channel>
</rss>
