技術・研究 · · Team LATENT
Strands Decider 2Bはローカルで選択を担う小型AI
大型LLMが計画を立て、小型AIが繰り返しの選択を引き受ける。Strands Decider 2Bの仕組み、ローカルの専門モデルへの振り分け方、confidenceの読み方、実行環境と測定値の条件を解説します。
大型LLMを使うアプリでは、文章を考える仕事の間に小さな選択が何度も入ります。問い合わせをどの担当へ回すか、次にどのツールを使うか、実行前に利用者へ確認するか。Strands Decider 2Bは、そうした選択をローカルで処理するための小型AIです。
Strandsチームは2026年10月1日にv19を公開しました。モデルに状況、質問、選択肢を渡すと、候補ごとの数値が返ります。文章やコード、要約、ツールに渡す引数は生成しません。大型LLMに計画と最終回答を任せ、その途中で繰り返す分類を小型モデルに分担させる構成に向いています。公式発表
この記事は2026年10月4日日本時間に確認した公開資料とコードをもとにしています。性能の数値は開発者の測定結果です。LATENTでは依存関係の導入、重みのダウンロード、モデルの実行、ベンチマークを行っていません。後述する振り分け図は、使い方を説明するために作った未実行の構成例です。
この記事の要点
- Strands Decider 2Bは、渡された候補を採点して選ぶローカル向けの小型AIです。文章やコード、ツールの引数は生成しません。
- 大型LLMが計画と最終回答を担い、Deciderが繰り返す振り分けを補助する構成に向いています。実際のツール実行や人への確認はアプリが制御します。
- choiceのconfidenceは最大確率と候補数から求める値で、正解率や安全性を保証しません。長文や異なる用途にも校正が通用するとは限らず、用途ごとの評価が必要です。
文章を生成する部分を候補の採点に置き換える
Deciderは、Qwen3.5-2B-Baseの言語処理部分を使います。開発者は次のトークンを予測するLM headを取り除き、候補を採点するpointer headを付けました。
生成と選択では出力の作り方が違う
一般的な生成LLM
状況や指示
言語処理部分
LM headで次のトークンを予測
トークンを順に生成
文章・コード・構造化データなど
Deciderのchoice
state + 質問 + 指定した候補
Qwen3.5-2B-Baseの言語処理部分
pointer headで候補を採点
指定した候補から選択
選んだ候補の識別子
各候補の確率とconfidence
pointer headは、各候補の末尾に対応する内部表現と、回答位置の内部表現を比べてスコアを求めます。生成を1トークンずつ繰り返す処理はありません。
pointer headは約100万パラメータで、言語処理部分の調整にはrank 16のLoRAを使います。LoRAは、元の重み全体を書き換える代わりに小さな追加パラメータを学習する方法です。開発者の文書では、もとにしたモデルを約19億パラメータとしています。
候補の意味は、要求ごとに文章で渡せます。そのため、担当部署を追加するたびに分類用の出力層を作り直す必要はありません。モデルの構造
入力のstateには文章や構造化データを入れ、questionsに質問と候補を指定します。同じ計算結果を、質問の種類に応じて次のように読み出します。
| 種類 | 返すもの |
|---|---|
choice | 選んだ候補と全候補の確率とconfidence。APIでは2〜255候補を指定できます。 |
noul | はい/いいえに相当する質問のP(true)。独立したconfidence欄はありません。 |
score | 順序のある2〜10段階の尺度について、期待値と確率分布とconfidenceを返します。 |
たとえば0、1、2の3段階なら、scoreは1.10のような平均的な位置を返せます。自由な文章による説明が返るわけではありません。また、候補に正解が含まれなければ、候補の中から選ぶ仕組みだけでは正解を作れません。入出力の定義
大型LLMが計画し小型AIが定型の振り分けを担う
普段のチャットで一度質問するだけなら、大型LLMに判断と回答をまとめて頼めます。Deciderを組み込む利点が出やすいのは、アプリが同じ種類の判断を何度も行う場面です。毎回の振り分けに大型LLMを呼ばずに済めば、APIの呼び出し回数や待ち時間を減らせます。ただし、ローカル推論にも計算と保守の費用がかかります。
たとえば大型LLMが、複数の社内文書から回答を作る計画を立てるとします。各作業について「項目を抽出する専門モデル」「翻訳する専門モデル」「大型LLMへ戻す」「利用者に確認する」を候補にします。アプリは作業対象、必要な出力、ここまでの結果をDeciderへ渡し、選ばれた候補を実際の処理へ対応づけます。
選ぶのはDecider 実行を決めるのはアプリ
依頼を読み取り作業を計画
↓ 作業の状況と許可した候補を渡す
ここはローカルで処理
抽出・翻訳・大型LLM・利用者確認から選ぶ
候補の識別子と数値を返す
入力の不足・用途別の閾値・実行ルールを確認
モデルの選択だけで実行しない
分岐A 条件を満たす
アプリが処理を実行
ローカルの専門モデルやツールで
項目の抽出・翻訳など
↓ 処理の結果を戻す
分岐B 不確か・情報不足・要確認
実行を保留して戻す
大型LLMで再検討
または利用者に確認
↓ 再検討や確認の結果を戻す
結果を照合し計画を見直すか最終回答を作る
この構成でDeciderが返すのは、用意した候補の識別子と数値です。抽出項目の定義、翻訳の指示、ツールの引数を組み立てるのはアプリや大型LLMの仕事になります。専門モデルも別途用意する必要があり、Deciderを導入すると自動的に一式がそろうわけではありません。
複雑な計画の変更や複数の結果の統合は、大型LLMに任せます。実行ルールを決めるときは、確認先へ戻す条件もアプリ側で用意します。
処理全体がローカルに収まるかは、各モデルをどこで動かし、アプリがどのデータを渡すかで決まります。
confidenceは正解率を直接表す数値ではない
choiceのconfidenceは、最大確率と候補数から計算する値です。公式CLI例のbillingの確率0.845とconfidence 0.768は、次の式で結びつきます。confidenceを別の予測器が出しているわけではありません。
候補の確率からconfidenceを計算する
公式CLIの部署振り分け例 選択はbilling
confidence 0.768
候補数 N = 3
最大確率 p_max = 0.845
(N × p_max − 1) / (N − 1)
(3 × 0.845 − 1) / 2
= 0.7675 ≈ 0.768
正解率を示す値ではありません。
confidenceは、候補に均等な確率を付けた場合を0、1候補に全確率を付けた場合を1にそろえた値です。0.768を「76.8%の確率で正しい」と読み替えることはできません。0.845も、与えた状況と候補に対するモデルの確率であって、そのまま現実の正答率や安全性を保証する値ではありません。
scoreのconfidenceは別の式です。尺度上の確率分布の標準偏差を使い、学習時に隣の段階へ確率を分ける処理も補正します。noulはtrue側の確率だけを返します。名前が似ていても、これらの数値を同じ意味で比較することはできません。confidenceの実装
公開モデルは、学習から分けた短い分類課題で、質問の種類ごとにtemperatureを調整しています。これは確率の過大評価や過小評価を調整する処理です。開発者自身も、長い文書や異なる尺度ではその調整が通用しにくいと報告しています。0.9以上なら自動実行といった文書中の例は、用途を問わず使える閾値ではありません。自分の入力で、通してよい選択と止めるべき選択をどの程度間違えるかを確かめる必要があります。校正と適用範囲の限界
公開231課題の結果は実務全体の成功率ではない
開発者はJevBenchの公開セット231課題を使っています。18分野の選択式課題について、所定の正解ラベルと予測を比べる評価です。第三者が作ったベンチマークですが、ここで紹介するのはStrands側が実行した結果であり、LATENTによる追試ではありません。
| 測定対象 | 正解数とBrier |
|---|---|
| Hugging Face公開重み 4,096トークン窓 | 167 / 231 Brier 0.348 |
| 同モデルカードの3,072トークン窓 | 167 / 231 Brier 0.349 |
| GitHubの元のv19評価 3,072トークン窓 | 167 / 231 Brier 0.342 |
167 / 231は約72.3%です。公開モデルカードとGitHubの元の実験記録では、同じv19でも確率の評価値が違います。GitHubには再学習の比較もあり、元の実験を4,096トークン窓で評価した結果は168 / 231と記されています。その168を、配布中の重みの成績として置き換えてはいけません。モデルカードの3,072トークン条件には、重みをシンボリックリンクしたコピーで、重みのハッシュは確認していないという注記もあります。公開重みのモデルカード / 実験と再学習の比較
この評価のaccuracyは、最も確率の高いラベルが正解だった割合です。尺度の質問でも最上位ラベルで判定し、期待値の誤差は別に扱います。正解の判定
Brier scoreでは、正解候補を1、ほかの候補を0として、それぞれの予測確率との差を二乗します。その誤差を候補全体で足し、課題間で平均した値がBrierです。低いほどよく、二択でも両候補の誤差を足します。単なる誤答率でも、校正だけを切り離した指標でもありません。Brierなどの定義
元のv19実験を開発者が難度別に分けた結果は、easyが48 / 48、standardが63 / 72、hardが56 / 111です。「簡単な課題で100%」にはこの48問という範囲があります。長い条件文や複数段階の推論まで解けるという意味にはなりません。公開セットの正答率は、非公開問題や速度・費用も組み込むJevBenchの総合得点とも別です。公開セットの条件
公式発表の「2Bクラスで3位」という表現も、当時の公開課題の成績とモデル規模の区分に基づきます。GitHubの記録は、v19自体がランキングに掲載されたという意味ではないと補足しています。学習のやり直しでも成績は動くため、数問の差で実務上の優劣まで決めるのは難しい評価です。
115msは測定した版と機材をセットで読む
発表記事はRTX 3090で中央値約115msと説明しています。ただし、その記事の速度グラフの注記は測定対象をv18としています。この図を、公開版v19がどの環境でも115msで動く証拠にはできません。発表記事の図3
確認時点のGitHubには、別の結果としてv19をWSL2上のRTX 3090で測った中央値115ms、95パーセンタイル299msもあります。JevBenchでは課題ごとに1質問を送り、この数値に複数質問の共有キャッシュの効果は含まれません。発表のv18グラフと、v19の実験記録は分けて読む必要があります。
Macの153msにも条件があります。開発者の詳細記録では、M3 Proのメモリ36 GB、macOS 26.6、MPSのbf16で動かしたv19について、300トークン未満の課題を再実行した際の中央値です。同じ長さの初回要求は中央値310msで、JevBench全体の再実行時は中央値234ms、95パーセンタイル2,628msでした。短い課題の値を長文にも当てはめることはできません。機材と初回・再実行の条件
同じstateに複数の質問を付けると、stateの計算結果を共有できます。ただし、質問どうしは互いの回答を参照しません。「前の回答を見て次の問いを考える」という逐次的な計画は、アプリや大型LLMが担当します。処理全体の短縮量は、モデルの読み込み、入力の長さ、専門モデルの実行、大型LLMへ戻す回数も含めて変わります。状態の共有方法
CLIとHTTP経由のPythonから同じ形式で呼び出せる
公式の入口はPythonパッケージstrands-deciderです。次は公式発表にあるCLIの使い方で、掲載用に1行にまとめています。初回利用時にはDeciderの配布物に加え、もとにしたQwenのモデルも取得します。ここでは実行していません。
pip install strands-decider
strands-decider ask StrandsAgents/strands-decider-2B-hobson-v19 --state "Help! My payouts have been failing for 3 days! " --choice "Which team should handle this?=billing,sales,retail"
この要求に対する公式の出力は、先ほどの確率バーに示したとおりです。候補の説明や入力を変えれば、同じ話題でも選択は変わり得ます。
繰り返し呼ぶアプリでは、strands-decider serveでモデルを常駐させ、POST /v1/systemoneへ要求します。公式サンプルのPythonクライアントは、標準ライブラリのurllibでこのHTTP APIを呼ぶ実装です。Deciderはサンプル内の_client.pyにあるクラスで、パッケージのトップレベルから同名をimportする案内ではありません。
from _client import Deciderdecider = Decider("http://127.0.0.1:8099")
answers = decider.ask(
state="Help! My payouts have been failing for 3 days!",
questions={"route": Decider.choice(
"Which team should handle this?",
{"billing": "payments and invoices", "sales": "pricing and upgrades"},
)},
)
print(answers["route"])
このPython例は公式クライアントのAPIに合わせてLATENTが組んだ未実行の例です。クローンしたexamples/strands/の_client.pyを参照できる場所と、指定先で稼働するDeciderサーバーが前提です。プロセス内から使う入口として、モデルカードにはStrandsDeciderModel.load(...)も記載されています。Pythonクライアント / モデルの読み込み
サーバーは既定で127.0.0.1に待ち受け、認証はありません。公式文書はローカル実験向けとし、同時要求の動作は未検証としています。GET /healthでチェックポイントや機材を確認できますが、OpenAI互換のチャットサーバーを提供する仕様ではありません。モデルを常駐させる手段はあっても、複数利用者に公開する運用基盤まではそろっていません。HTTPサーバーの範囲
実行前の確認はモデルの数値をアプリのルールへ渡す
公式には、天気ツールの実行前にDeciderを挟むサンプルがあります。利用者が場所を言わずに天気を尋ねると、大型LLMがSeattleを仮定してツールを呼ぼうとする設定です。Deciderは会話と予定された呼び出しを読み、「引数は利用者が伝えた事実に基づくか」「確認せずに実行するのは早すぎるか」を判定します。
Python側は2つの数値を見て、処理を進めるProceedか、モデルへ修正の指示を返すGuideを選びます。Strandsの介入APIには、処理を拒否するDenyや、人の承認を待つConfirmなどもあります。これらの動作を決めるのはハンドラーです。Deciderが確認文や修正した引数を生成するわけではありません。公式サンプルの実装 / 介入API
サンプルの閾値0.45は、説明のために人が選んだ値です。天気ツールも固定の返答をするデモで、実際の気象情報を取得しません。また、このサンプルの大型LLMはAmazon Bedrockを呼ぶため、AWSの認証情報とアクセス権が必要です。ローカルなのはDecider側の判定であり、構成全体が端末内だけで動く例ではありません。サンプルの前提と位置づけ
公式の配布物はアダプターと採点用の重みが中心
PyPIの公開版は確認時点で0.1.0、Pythonの要件は3.10以降です。推論にはCPU、NVIDIAのCUDA、Apple siliconのMPSを指定できます。CUDAの手順はLinuxまたはWindowsのWSL2を前提とします。パッケージ
CPUでは一部の計算に参照実装を使い、公式文書はGPUより大幅に遅いと説明しています。2Bという規模だけで、自分のCPUでも100ms台と見積もることはできません。実行環境
GitHubの確認した版にはMLXバックエンドもあります。Apple siliconで--device mlxを明示する方式です。ただし文書では、mlxやcudaなどの追加インストール指定は次のパッケージ公開からとされています。PyPI 0.1.0の追加指定はtrainとdevだけで、MLXを試す手順はクローンしたソースからのインストールです。公開パッケージとGitHubの最新コードを混ぜて手順を読むと、前提がずれます。
Hugging Faceの公式配布物はPEFT形式のLoRAアダプターとhead.safetensors、設定、トークナイザーなどです。Qwen本体の重みは含まれず、初回に別途約4.5 GBを取得すると文書にあります。これは保存するファイルのおおよその容量で、必要なRAMやVRAMの合計ではありません。入力と質問数によって作業用メモリも増えます。公式ファイル一覧 / 読み込みの仕様
公開設定は言語処理部分をbf16で計算し、採点用のheadをfp32で扱います。LoRAは量子化ではなく、safetensorsもビット数を減らす方式の名前ではありません。公式ファイルにGGUFや4-bit版の配布は確認できませんでした。MLX実装も、量子化済みのベースモデルへのアダプター統合を拒否します。公開設定 / MLX実装
第三者のfabricant451はQ8_0の実験的なGGUFを公開しています。ただし、その作者はStrandsに対応した専用のllama.cpp/wllamaランタイムが必要で、通常のGGUFクライアントとの互換性は想定しないと明記しています。作者による8件の確認例は変換の小規模な検査で、品質ベンチマークではありません。GGUFが存在することだけから、通常のOllamaでそのまま使えるとは言えません。LATENTではこの変換版も取得・実行していません。変換版の作者による説明
コードと重みのライセンスを学習データへ広げない
学習には、話題や意図を分類する公開データ、ContractNLIやMuSiQueなどの複数段階の判断を含むデータ、生成モデルで作成・検証した問題を使います。v19ではHelpSteer2などをもとに、回答が依頼に十分応えているかを判定する学習例を追加しています。HotpotQAは評価専用です。学習元と用途の一覧
合成した学習例やモデルが付けた教師分布はリポジトリに保存されています。一方、元の公開データセットは別途ダウンロードして変換する方式です。「データを公開した」という説明は、すべての元データが同じ場所に同じ条件で再配布されているという意味ではありません。再現用レシピは保存済みの合成データを利用するため、その再現に有料の生成API呼び出しは不要とされています。保存済みデータと再取得するデータ
コードと公開されたアダプター・headはApache-2.0です。もとにしたQwen3.5-2B-BaseもApache-2.0と表示されています。ただし、学習元のデータにはCC BY、CC BY-SAなどが混在し、公式の一覧で条件が未記録のものや、モデルのライセンスだけが記された合成データもあります。記事では全データを一括してApache-2.0とは扱いません。コードのライセンス / 公開重みとデータの注記 / ベースモデル
確認した公式発表、モデルカード、研究記録には、Strands Decider 2B自体の独立した論文へのリンクは見当たりませんでした。研究の根拠として公開されているのは、構造の説明、学習レシピ、事前に記した実験条件と結果です。参照されるHelpSteer2などの論文は元データの論文であり、Deciderの論文として紹介するものではありません。研究記録
任せる判断を狭く定めるほど分担を確かめやすい
試す対象を選ぶなら、候補が明確で、間違いを評価できる繰り返しの判断が出発点になります。たとえば抽出と翻訳の振り分けなら、正しい担当を選んだ割合だけでなく、大型LLMへ戻した割合、処理全体の待ち時間、誤って自動実行した件数を比べられます。これはLATENTの構成上の提案で、実測した効果ではありません。
候補に正解がない場合、stateに必要な事実がない場合、質問の意味を取り違えた場合には、高い数値でも誤った候補を選びます。文書は質問の言い換えや否定に弱い点も挙げています。長いstateは既定で窓に収まるよう切り詰められるため、必要な条件が失われる場合があります。--strict-windowでは、入り切らない要求をエラーにする選択肢があります。質問への追従の限界 / 入力長の扱い
確認先へ戻す候補を設けるだけで、必ずそこへ戻る保証が得られるわけではありません。実行を許可する範囲や人の承認は、アプリのルールとして残す必要があります。Deciderはそのルールの中で選択を補助します。複雑な依頼を解きほぐし、足りない情報を聞き、最終的な説明を作る役割は、大型LLMや利用者が引き続き担います。
出典と確認した版
公式発表は2026年10月1日。GitHubはコミット6d5dec6、公式配布重みの資料はbb282d7を確認しました。リンク先のモデルやコードは実行せず、文書・設定・ソースを読み取って調べています。第三者GGUFの説明は変換版の作者の資料で、公式の対応保証とは分けています。
関連する技術解説として、ローカルモデルの実行環境を扱うTensorFoldの記事もあります。