今回は、どのモデルに渡すかを決める時点の話です。前回は「いつ止めるか」でしたが、今回は「誰に渡すか」になります。⚠️ 先に、題を否定しておきます。安いモデルは、使うべきです。私も使っています。⭐⭐ やめたのは、一番安いのを「既定」にすることのほうです。

⚠️ もう 1 つ断っておきます。この回にもモデルの名前も、価格も、性能の数字も出てきません。半年で古くなるものは、この連載では書かないと決めています。比べるものは「高い側」と「安い側」とだけ呼びます。⭐ そのかわり、倍率は全部出します。あなたの手元の単価を掛ければ、そのまま判断に使えるはずです。

⭐⭐ そして白状します。私はこの検証で 2 度、「差が無い」と読み間違えました。どちらも数字は正しく、読み方が間違っていました。⚠️⚠️ 2 度とも、指摘を受けて初めて気づきました。そのままなら「杞憂でした」と書いていたはずです。今回はその 2 回も含めて書きます。

一つ思い出してみてください。あなたが安いモデルに任せた仕事は、本当に安く終わりましたか。 ⚠️ やり直しの回数まで、数えたうえで言えますか。

CC BY 4.0

予測から始めました —— 「安いほうは、見逃しが増えるはず」

最初に立てた予測はこうです。

安いモデルにテストを書かせると、テストは書けるが、見逃しが増える。

⭐ 題材にテストを選んだのには理由があります。テストは、失敗が緑で隠れる唯一の成果物だからです。実装のバグはいつかどこかで落ちますが、テストの見逃しは何も言いません。「テストを書かせた」は緑で完了に見え、請求は後から来ます。

物差しは、過去に実物へ入れて、実物の検査が実際に落とした変異 8 種を当て直したものにしました。⚠️⚠️ この実験のために変異を書いてはいけません。書いた瞬間、見逃し率は書き方ひとつで 0% にも 100% にもなります。

⭐ 比べる相手も置きました。同じ対象に、人(私)が書いた既存のテストです。⚠️ そちらは 8 種のうち 6 種しか落としません。天井は満点ではありません。

条件は 2 つだけです。モデル(高い側 / 安い側)と、範囲call 1 メソッドに絞る / 「必要だと思うテストを書いて」だけ)。⚠️ 観点は 1 つも渡していません。

1 回目 —— 安い側は、半分が走りませんでした

会話を引き継がない作業者を 12 体そろえて書かせ、変異を入れる前に、まず素のまま走らせました。

走った体走った体だけの検出(8 種のうち何種を落としたか。⚠️ 多いほうが良い
高い側6 / 63.33 / 8
⚠️ 安い側2 / 63.00 / 8

⚠️ 走らなかった 4 体の中身は、存在しないアサーションを呼ぶ・辞書の行を重複させるといった壊れ方でした。⭐ どれも、走らせた瞬間に分かります。

⭐ そこで私は、走らなかった 4 体を「見逃しとは別枠」として、検出の集計から外しました。理屈も一応ありました —— 走らないテストは、その場で気づけて、高いほうへ切り替えられます。

⚠️⚠️ これが 1 つ目の間違いです。

間違い 1 —— 走らなかったテストを、母数から落としていました

外した結果、残った安い側は 2 体だけです。その 2 体の平均を「安い側の実力」として、高い側 6 体と並べていました。

⚠️⚠️⚠️ 走らなかったものを母数から落とすと、いちばん危ない側が消えます。

⭐ 直し方は簡単でした。現実と同じように差し戻したのです。エラーの出力だけを返して「直してください」と送る。⚠️ 何が悪いかは言いません(言えば、それは物差しを渡すことになります)。

⭐⭐ 差し戻しを重ねて、12 体とも緑にしました。そのうえで数え直すと、こうなりました。

範囲を絞る絞らない
高い側3.33 / 83.33 / 8
安い側3.33 / 82.33 / 8

⭐⭐ 範囲を絞れば、安い側は高い側と同点です。私はここで、こう書こうとしました ——「安いモデルで増えるのは、その場で気づける失敗のほうです。見逃しは増えません。

⚠️⚠️ これも間違いでした。

間違い 2 —— 物差しに、天井がありました

8 項目のうち 3 項目は、12 体とも 0 でした。⚠️ 人が書いた既存のテストは、その 3 つを落とします。

⭐ 3 つを並べてみると、共通点がありました。どれも「材料か測り方を、先に自分で用意しないと書けない」項目です。

  • 表の中でいちばん長い見出し語を、自分で辞書に入れる
  • 同じ表記に読みを 2 通り持たせる
  • 戻り値ではなく、問い合わせの本数を数える

⚠️⚠️ 課題は、そんなことを一言も言っていませんでした。「単体テストを書いてください」としか書いていない。⭐ つまり 12 体とも 0 だったのは、書けなかったからではなく、課題がそこを指していなかったからかもしれない。

そこで、課題に 1 段落だけ足しました。

setup で作る辞書に現象が入っていなければ、そのテストは何も見ていません。 見たい振る舞いが出せるように、辞書のほうを組み立ててください。 戻り値を見るだけでは分からない振る舞いもあります。そういうものは、測り方のほうを用意してください。

⚠️ 8 項目はどれも名指ししていません。言っているのはやり方だけです。⚠️⚠️ そして両方の条件に、1 バイトも同じだけ渡しました(条件の差を増やしてしまうと、測っているものが変わります)。

天井が外れたら、結論がひっくり返りました

もう一度 12 体に書かせました。3 項目とも動きました。

1 回目(天井あり)⭐ 2 回目(天井なし)
高い側3.33 / 85.00 / 8
安い側2.83 / 82.83 / 8
高い側・範囲を絞る3.33 / 85.00 / 8
⚠️⚠️ 安い側・範囲を絞る3.33 / 8(同点)3.00 / 8(同点ではない)

⭐⭐⭐ 天井を外すと、高い側だけが伸びました。安い側は 2.83 のまま動きません。

⚠️⚠️ 「絞れば同点」は、両方が簡単な項目しか取れず、そこで並んでいただけでした。

⚠️ ついでに、範囲の絞り方は見逃しには効きませんでした(高い側は 5.00 と 5.00 で差 0、安い側は 3.00 と 2.67)。⭐ 1 回目で範囲が効いていたのは「そもそも走るか」のほうで、見逃しの側ではありません。

⚠️⚠️ 最初の予測は当たっていました。ただし、当たっていると分かるまでに、母数の落とし方と物差しの天井を 2 つとも直す必要がありました。

差し戻しは、テストを消させます

差し戻しの回数は、高い側が 2 回の実験とも 0 回、安い側は 1 回目が 6 回・2 回目が 10 回でした。⭐ ここまでは想像どおりです。

⚠️⚠️⚠️ 想像していなかったのは、直し方のほうです。「実装は正しい。テストを直してください」と送ると、返ってきた直しのうち 3 件は、赤いテストを消したものでした。

  • 「上限ちょうどは通す」という 1 件を、削除
  • 全角の正規化を見る 1 件を、削除
  • 重複した辞書の行を消さず、例外だけを飲む書き方に変更

⭐ どれも緑になります。⚠️⚠️ そして、消えた 1 件はそのまま見逃しになります。

⚠️⚠️⚠️ 「実装は正しい」と言って差し戻すと、直すより消すほうへ倒れます。

⚠️ これはモデルの話ではなく、差し戻し方の話です。⭐ ただし、差し戻しが要ったのは安い側だけでした。だから結果としては、モデルの側に効いています。

原理: 安いかどうかは「単価の比 × 量の比」で決まります

⭐ ここまでの数を、判断に使える形へ畳みます。1 回の応答の値段ではなく、1 つの仕事が終わるまでの総額で見ます。

同じ課題で、安い側が高い側の何倍を使ったかです。

数えたもの範囲を絞る絞らない全体
初めて読ませた量1.64 倍1.24 倍1.48 倍
⭐ 使い回せた量9.71 倍2.62 倍5.29 倍
書いた量0.26 倍0.38 倍0.31 倍
手番(差し戻し込み)3.33 倍2.00 倍2.67 倍

⚠️⚠️ 安い側は、単価が安いだけではありません。量そのものが多いのです。やり直すたびに会話が伸び、伸びたぶんが次の手番でもう一度流れます。

⭐⭐ 使い回した部分は安く課金されますが、ゼロではありません。ここを 0 と見なすと、リトライは「ほぼタダ」に見えます。⚠️ 5.29 倍のものを 0 と数えれば、どんな結論でも作れます。

書いた量だけは安い側のほうが少ない(0.31 倍)ので、出力の重い仕事なら向きが変わります。

⭐⭐⭐ 値段は「単価の比 × 量の比」。単価の比はカタログに書いてありますが、量の比は測らないと分かりません。

⚠️⚠️ だから「一番安いから既定」は、片方だけを見た判断です。⭐ 同じ理由で「一番高いから既定」も片方だけです。既定を置かず、用途ごとに 2 つとも数えます。

⚠️ 前作で、私は翻訳の用途では安い側を使うと書きました。その判断はいまも変えていません。あの用途では、安い側のほうが手数まで少なかったからです。⭐ 今回の結果は、それを打ち消しません。打ち消さないことこそが要点で、用途が変われば向きも変わるというだけです。

検証手順: 単価の比と、量の比を、別々に数える

前提

  • 同じ課題を、2 つのモデルへ同じ材料で渡せること。⚠️ 材料が 1 バイトでも違うと、モデルの差ではなく材料の差を測ります
  • 合否が機械で出る物差しがあること。⚠️⚠️ 人が読んで採点すると、測る回数が費用になって続きません
  • 使ったトークンが、新しく読ませた量・使い回した量・書いた量に分けて残ること。⚠️ 分かれていないなら、この手順の後半は使えません

所要時間: 半日(物差しが既にある場合)

手順

  1. 物差しにする変異を、過去に実物へ入れて実物の検査が落としたものから採ります。⚠️⚠️ この実験のために書いてはいけません
  2. 人が書いた既存のテストを、同じ物差しに掛けます。⭐ これが天井です。⚠️ 満点なら物差しが緩いので、変異を足してください
  3. 同じ課題を 2 つのモデル × 2 つの範囲 × 3 回渡し、書かせます。⚠️ 走らせるのはこちらで、書き手には走らせません
  4. 変異を入れない状態で全部を走らせます。⚠️⚠️ 赤い体を「集計から外す」のは禁止です。エラーの出力だけを返して差し戻し、全部が緑になるまで繰り返します
  5. 緑になったものへ、変異を 1 種ずつ当てて走らせます。⭐ 変異 1 種につき全員ぶんを 1 回で回せます
  6. 差し戻しの回数と、新しく読ませた量・使い回した量・書いた量を、モデルごとに合計します
  7. 手元の単価表を掛けて、完了までの総額を出します

合格条件(すべて満たすこと)

  • 手順 2 で、人の書いたテストが落とせない変異が 1 つ以上ある(満点なら天井です)
  • 手順 4 のあと、全部の体が緑である(1 体でも赤いまま数えると、いちばん危ない側が母数から消えます)
  • 手順 5 で、全員が 0 の項目が、全体の半分未満である。⚠️⚠️ 半分以上あるなら、課題がそこを指していません(材料と測り方を自分で用意する、と課題に書き足してください)
  • 手順 6 で、使い回した量が 0 でない(0 なら分けて取れていません)

合格しなかったとき

  • 人のテストが満点 —— ⚠️ 物差しが緩いか、実物の検査が落とした変異を採っていません
  • 赤い体が緑にならない —— ⭐ そこが「高いほうへ切り替える」判断点です。⚠️ 回数を費用として記録してから切り替えます
  • 全員が 0 の項目が半分以上 —— ⚠️⚠️ 天井です。課題の骨に 1 段落足して、両方の条件へ同じだけ渡し、測り直します
  • 使い回した量が 0 —— ⚠️ 記録が分かれていません。分けて取れないなら、量の比は出さずに手番だけで判断します

後始末

  • 一時的に置いたテストを消します。⚠️ 記録(トークンの内訳)は残します
  • ⚠️ 結果は日付つきで残します。記録は増え続けるので、同じ道具を明日走らせると数が動きます

注意: この数字が言えないこと

⚠️⚠️ 1 つの枡が 3 体しかありません。向きだけを読んでください。5.00 と 2.83 の差は、順位としては読めますが、倍率として持ち出せる精度ではありません。

⚠️ 比べたのは 2 点だけです。高い側と安い側を 1 つずつ選んだので、「安いほど落ちる」という直線は、ここからは引けません。

⚠️⚠️ 8 項目のうち 1 つは、天井を外したあとに 12 体とも 0 になりました(⭐ 天井があったときは、12 体のうち 1 体が落としていた項目です)。人が書いたテストも、それは落とせません。⭐ つまりまだ天井が残っています。「どこまで差があるか」は、今回の物差しでは測り切れていません。

⚠️ 差し戻しは「実装が正しい」という前提で送っています。⭐⭐ その前提そのものが、テストを消させました。実務では実装が間違っていることもあるので、この差し戻し方をそのまま真似しないでください。

⚠️ 書き手にテストを走らせていません。⭐ 走らせられれば、安い側の赤は自分で気づけたはずです。「走らせない丸投げ」の数字だと思ってください。

⚠️⚠️ 最後に、題材のコードは、コメントがかなり厚いものでした。壊したときに何が起きるかまで、実装自身が書いています。⭐ コメントの薄いコードでは、両方とももっと落ちるはずです。そのまま持ち出せる数ではありません。

CC BY 4.0 はここまで

既定にしなくなったもの

  • ⭐⭐ 「安いほうで足りるだろう」で渡すのをやめました。 ⚠️ それは予測です。単価の比はカタログにありますが、量の比は測らないと出ません
  • 走らなかった結果を、集計から外すのをやめました。 ⚠️⚠️ 外した瞬間、いちばん危ない側が母数から消えます。差し戻して、全部を緑にしてから数えます
  • ⚠️ 「差が無い」と書く前に、物差しが動くかを見るようにしました。全員が 0 の項目が半分あるなら、それは差が無いのではなく、測れていないだけです
  • ⚠️⚠️ 「実装は正しい。テストを直せ」とだけ言って差し戻すのをやめました。 ⭐ 消して緑にする道が、そこに開いています
  • やめていないこともあります —— 用途ごとに安い側を選ぶことです。⚠️ 前作で選んだ用途は、いまも安い側のままです

安いモデルは安い、という感じは、たいてい正しく見えます。⚠️ 請求のうち、1 回ぶんの単価しか見ていないからです。 ⭐⭐ 見えないのは、やり直した回数と、そのたびに読み直された会話のほうでした。


次回は「最新モデルを使わない技術」。私は、新しいモデルが出た日に乗り換えるのをやめました。強いモデルでないと通らなかった仕事が、モデルを変えずに通るようになったからです。