実測

「黙って間違えない」経路を作った
— 182問で3回とも0件。ただし検算できたのは76%

LLM の一番困る壊れ方は、間違えることではなく、間違えたのに自信満々で返すことです。 返ってきた数字が正しいのか怪しいのか、受け取る側には見分けがつきません。

そこで「100%正しく答える」を諦めて、「答えるときは正しく、怪しいときは怪しいと言う」を目標にした経路を作りました。 teai.io で shitate/orchestrator:sure として使えます。 この記事は、その実測記録です。効かなかった施策と、自分たちのベンチマークにあった欠陥5件も全部書きます。

先に結論

実走(182問)正答要確認黙って間違えコスト
1回目99.5%1.10%0件$0.173
2回目100.0%1.10%0件$0.176
3回目100.0%1.65%0件$0.168

ただし、これを「間違えない LLM ができた」とは書けません。理由は3つあります。

設計 — 4段の関門

  1. 安い2モデルを並列に投げる(ベンダーの違うもの)
  2. 答えが一致し、かつ 根拠が設問文にあり、かつ コードの検算で否定されない → 採用
  3. どれか欠ければ裁定役へ上げる。裁定役の答えが候補と一致すれば採用
  4. それでも合わなければ ⚠️要確認 を付けて返す

なぜ一致だけでは足りなかったか

最初は「ベンダーの違う2モデルが一致したら正しい」で作りました。実測で 89% → 99.7% まで上がります。 ところが残った誤答を全部見たら、4件すべてが「2モデルが同じ間違いをして一致した」ものでした。

設問正解両モデルの答え誤りの型
税込33,333円(8%)の税抜、1円未満切り捨て3086330864切り捨てを切り上げた
45.9㎡は何坪(小数第3位四捨五入)13.8813.89切り上げた
2026年2月26日の翌日から4営業日目03-0403-022日早い
2026年5月29日の翌日から4営業日目06-0406-022日早い

誤りは2種類だけ。端数処理の方向営業日の数え方です。 どちらも「よくある慣習」なので、ベンダーを分けても同じ癖を共有して揃って外します。 一致を信号に使う設計の、構造的な穴でした。

コードは「答えを作る側」ではなく「検算する側」に置く

最初はコードで計算させて、その結果を採用しました。黙って間違える率が 0.27% → 4.12% に悪化しました。 抽出条件が外れると、コードが自信満々に間違った答えを出すからです。

そこで役割を逆にしました。コードは答えを作らず、モデルの答えを検算するだけにします。

Confirmed  検算して合っていた
Rejected   検算して合わなかった  → 採用しない
Unknown    検算できなかった      → 何も言わない

肝は Unknown を「正しい」と混同しないことです。 そして「動かない」が既定なので、抽出が外れても答えは壊れません。壊れ方は「不要な⚠️が出る」だけで、 「間違った答えを返す」にはなりません。この非対称性のおかげで、検算の範囲を安心して広げられます。

根拠の検出 — 一致していても「暗記」なら上げる

検算を広げた後も、まだ黙って間違えが出ました。

継続勤務1.5年の年次有給休暇は何日か → 正解11日 / 安い2モデルが揃って「10」

設問文に表が無い、つまり暗記の問題です。ここで法令の数値をコードに焼き込むのは簡単ですが、 やりませんでした。法改正のたびに、正しい答えを弾く側に回るからです。

代わりに「答えの数値が設問文の数から四則演算で導けるか」をコードで判定し、 導けなければ記憶依存=危険側として裁定役へ上げます。 これを入れて、黙って間違えは6回連続で0件になりました。

この判定にもバグがありました。許容誤差1.01を大小問わず許していたため、小さい数ではほぼ何でも「導ける」ことに なっていました。実例が上の年休で、1.5年 + 8割 = 9.5 と答え 10 の差 0.5 が許容内に入っていた。 誤差を緩める理由は端数処理の指定があるときしか無いので、そのときだけ緩めるようにしました。

裁定役を替えたらコストが半分になった

14モデルを同じエンドポイントで測り、束ね方を 1,820構成 総当たりしました。 各モデルの回答テキストを1回集めておけば、束ね方の評価に追加のAPI呼び出しは要りません。

裁定役正答(2回)黙って間違え要確認コスト
gemini-3.1-pro(変更前)100.0 / 99.5%0.00 / 0.00%1.1%$0.340
inkling(変更後)100.0 / 100.0%0.00 / 0.00%1.1%$0.179

正答・黙って間違え・要確認は同じで、コストだけ半分になりました。

この手順が、危うい構成を実際に落とした

1,820構成から「一番良いもの」を選べば、測定のばらつきに合っただけの勝者が必ず出ます。 なので選定は片方の実行回だけで行い、もう片方(選定に使っていない回)で検証しました。

「安い1本 → 必要なときだけ上げる」構成正答要確認黙って間違え
選定に使った回100.0%0.0%0.00%
検証した回98.9%0.0%1.10%

選定回では全1,820構成で最良に見えました。正答100%、要確認0%、黙って間違え0%。 検証回で1.10%黙って間違えました。裁定役の答えを他と突き合わせずに受け入れる構造なので、 裁定役が外れるとそのまま出ます。選定と検証を分けていなければ、これを本番に入れていました。

効かなかったこと

プロンプト調整は汎用的には効かない

安いモデルの正答率を system プロンプトで上げられるか、8変種 × 3モデル × 182問 × 2回 = 8,736回まわしました。

指示flashinklingglm-5.2
端数処理の桁と方向を書き写してから適用+3.3+0.8−2.2
日付や個数は1つずつ書き出してから数える+3.0+1.4−1.9
設問文に表があれば使う行を引用する−6.6+0.8−0.8
手順は指示せず「急がず見直せ」だけ−7.1+1.4+1.9

同じ指示がモデルによって逆に働きます。 「急がず見直せ」は glm-5.2 を +1.9 にし、flash の日付設問を 58% → 0% に壊しました。

効くのは「そのモデルが実際に持っている手順の穴」に当てたときだけです。 flash の「祝日表つき営業日」は列挙させると 58% → 95%(+37pt)、日付以外への影響は ±0 でした。 一方 inkling と glm-5.2 は元から96〜100%で伸びしろが無く、手順を足すとむしろ下がりました。

部品を良くしたら、全体が悪くなった

では flash に列挙を指示すれば全体も良くなるはず — と思って実走しました。

構成正答要確認コストp90
現行(全部baseline)98.4〜100%0.55〜3.30%$0.171〜0.1836.4〜11.7s
flash だけ列挙98.4〜99.5%3.30〜5.49%$0.206〜0.22714.4〜14.7s
3本とも列挙98.9〜99.5%5.49〜8.79%$0.189〜0.2045.0〜13.2s

列挙させると出力が長く・形が揺れるため、もう1本との一致が減り、裁定役への持ち上げが増えます。 黙って間違えは3構成とも0件でしたが、要確認とコストと遅さが増えるだけでした。本番は現行のまま据え置きました。

自分たちのベンチマークが間違っていた(5件)

モデルが揃って間違えたように見えたときは、まず自分の正解を疑うほうが当たります。実際5件出ました。

設問何を間違えたか
源泉徴収 1,234,567円100万円超の税率が変わることを無視した正解を置いていた
割増賃金 時給1450円×9時間端数処理を指定せず、単純な切り捨てを正解にしていた。
実務の慣習(昭和63.3.14 基発150号)を知っているモデルほど不正解になった
容積率 45㎡×150%67.5 を 67 に切り捨てていた。指定容積率に切り捨ての定めはない
コード「空白の畳み込み」テスト入力を二重にエスケープし、タブではなくバックスラッシュ文字を渡していた。全28回とも不正解になった
コード「中央値」浮動小数の丸めを避けることを仕様文に書いていなかった。素直な実装が全部落ちた

5件とも正しく答えたモデルを不正解にする形をしています。 「高いモデルが最安モデルに負けた」と色めき立って中身を見たら、負けていたのはこちらでした。 コードの2件を直したら、コード実装の正答率は 62% → 94〜100% に変わりました。

使い方

curl https://teai.io/v1/chat/completions \
  -H "Authorization: Bearer $TEAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "shitate/orchestrator:sure",
    "messages": [{"role":"user","content":"税込33,333円(消費税8%)の税抜金額を1円未満切り捨てで"}]
  }'

怪しいときは答えの頭に ⚠️ 要確認 が付きます。付かなければ、4段の関門を通っています。 既定は shitate/orchestrator(安く速い)で、:sure は正しさを最優先にしたいときに使ってください。

生データ

認証不要・CORS 開放です。設問と正解ごと出します。正解を隠したまま「うちのベンチではこうでした」は検証できません。

curl https://teai.io/api/v1/bench                    # 全結果 + 1,820構成の評価
curl https://teai.io/api/v1/bench/eval/jp-business   # 評価セット(設問と正解)

表で見るなら teai.io/bench。全モデルが満点で何も測れなかった評価も、そのまま載せています。