クリーム色の背景、色付き表示、高コントラスト、大きな文字のほうが読みやすいですか?配色と文字を選ぶと、すべてのページに一度で反映されます。

無料レッスン

A/Bテストと影のテスト

このレッスンのあとで: 偶然にだまされずに、二つのバージョンを比べることができる。

70分のレッスンコマンド6件AI コーディングエージェントのラボ:opencode でコードを説明・修正し、その結果を確かめる

二つのバージョンを公平に比べる

A/Bテストは、ある群の利用者にバージョン A を、別の群にバージョン B を渡し、それぞれがどれだけ動くかを比べます。影のテストは、新しいバージョンを本物のリクエストで動かしますが、その答えは誰にも見せません。

どちらも、人をだますことがあります。9 ポイントの差でも、偶然のことがあります。

このレッスンのゴール

メモ

偶然にだまされずに、二つのバージョンを比べることができる。

キーワード

ことばいみ
A/Bテスト二つの利用者の群に、一つずつバージョンを渡すこと
影のテスト誰にも見えない所で、新しいバージョンを動かすこと
合格率うまく動いたリクエストの割合
差一方の合格率から他方を引いた数、ポイントで表す
ゆれ差が偶然で動く幅

学生が入力するセルは、このプレビューでは空白です。

差は、ゆれより大きくなければならない

バージョン B は 200 件中 138 件、A は 200 件中 120 件で合格しました。差は 9 ポイントです。でも、200 人ずつの二つの群は、偶然でも違いが出ます。

ゆれは、差が偶然で動く幅です。目安の規則: 差がゆれの 2 倍以上のときだけ、その差を信じます。

例: 二つのテスト

テスト各群の人数差ゆれゆれの 2 倍判定
A と B2009.04.89.6証明されていない
A と C1,0005.02.24.3信頼できる

学生が入力するセルは、このプレビューでは空白です。

よくある間違い

注意

点が高いほうが勝ちだと考える人が多いです。小さなテストの高い点は、偶然かもしれません。差がゆれの 2 倍以上のときだけ勝者と言い、そうでなければ証明されていないと言って、データを集めます。

影のテストは、新しい失敗を安全に見つける

同じ本物のリクエストで新しいバージョンを動かし、その答えは隠します。リクエストごとに、古い結果と新しい結果の組ができます。

合計が同じでも、変化は隠れます。二つの事例が悪くなり、別の二つが良くなることもあります。悪くなったものを数え、一つずつ読みます。

例: 十二の組

組(古い、新しい)意味数
合格、合格同じ7
不合格、不合格同じ1
不合格、合格新が良い2
合格、不合格新が悪い、読む2

学生が入力するセルは、このプレビューでは空白です。

助っ人 model.js を書く(1)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const base = process.env.AI_URL || \"http://ai:4000\";' '// 応答のトークン数。なければ null。' 'function count(data, name) {' '  return data.usage && typeof data.usage[name] === \"number\" ? data.usage[name] : null;' '}' > model.js"

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

助っ人 model.js を書く(2)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function ask(messages, sample, max) {' '  try {' '    const res = await fetch(base + \"/v1/chat/completions\", {' '      method: \"POST\",' '      headers: { \"content-type\": \"application/json\", authorization: \"Bearer lab\" },' '      body: JSON.stringify({ model: \"lab\", messages: messages, max_tokens: max || 100 }),' '      signal: AbortSignal.timeout(30000),' '    });' '    if (res.ok === false) throw new Error(\"status \" + res.status);' '    const data = await res.json();' '    const text = data.choices[0].message.content;' '    return { text, inTokens: count(data, \"prompt_tokens\"), outTokens: count(data, \"completion_tokens\"), recorded: false };' '  } catch (error) {' '    console.log(\"記録済みサンプル: モデルが答えませんでした (\" + error.message + \")。\");' '    return { text: sample, inTokens: null, outTokens: null, recorded: true };' '  }' '}' 'module.exports = { ask };' >> model.js"

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

比べるスクリプトを書く(1)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { ask } = require(\"./model\");' 'function wobble(a, an, b, bn) {' '  const p = (a + b) / (an + bn);' '  return Math.sqrt(p * (1 - p) * (1 / an + 1 / bn)) * 100;' '}' 'function gap(a, an, b, bn) { return (b / bn - a / an) * 100; }' 'function verdict(a, an, b, bn) {' '  const ok = Math.abs(gap(a, an, b, bn)) >= 2 * wobble(a, an, b, bn);' '  return ok ? \"信頼できる\" : \"証明されていない\";' '}' > ab.js"

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

比べるスクリプトを書く(2)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const tests = [' '  { name: \"A と B\", a: 120, an: 200, b: 138, bn: 200 },' '  { name: \"A と C\", a: 600, an: 1000, b: 650, bn: 1000 },' '];' 'const pairs = \"pp pp pf pp fp pp ff pp pf pp pp fp\".split(\" \");' 'function count(kind) { return pairs.filter(function (p) { return p === kind; }).length; }' >> ab.js"

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

比べるスクリプトを書く(3)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' '  tests.forEach(function (t) {' '    console.log(t.name + \": 差 \" + gap(t.a, t.an, t.b, t.bn).toFixed(1) + \" ポイント、ゆれ \" + wobble(t.a, t.an, t.b, t.bn).toFixed(1) + \" -> \" + verdict(t.a, t.an, t.b, t.bn));' '  });' '  console.log(\"影: 同じ \" + (count(\"pp\") + count(\"ff\")) + \"、新が良い \" + count(\"fp\") + \"、新が悪い \" + count(\"pf\"));' '  const q = \"短く一文で答えてください。9 ポイントの差が、それでも偶然のことがあるのは、なぜですか。\";' '  const sample = \"各 200 人では、偶然だけでも、それくらい点が動くことがあるからです。\";' '  const reply = await ask([{ role: \"user\", content: q }], sample, 80);' '  console.log(\"モデル: \" + reply.text);' '}' 'main();' >> ab.js"

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

比べるスクリプトを動かす

コマンド
docker exec -w /home/node/project agent node ab.js

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

Run の出力

行意味
A と B: 差 9.0 ポイント、ゆれ 4.8 -> 証明されていない差は大きいが、テストが小さい
A と C: 差 5.0 ポイント、ゆれ 2.2 -> 信頼できる差は小さいが、テストが大きい
影: 同じ 8、新が良い 2、新が悪い 2記録した十二組から数えた
モデル: ...ラボからの一文。モデルが答えなければ記録済みサンプル

学生が入力するセルは、このプレビューでは空白です。

このラボとソースについて: AI コーディングエージェントのラボ:opencode でコードを説明・修正し、その結果を確かめる

授業で使いますか?このモジュールを学生に割り当てると、教員用ガイド、自動採点つきの課題、学生ごとのラボを使えます。