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

無料レッスン

評価用の事例は十分か

このレッスンのあとで: 評価用の集まりが、信じてよいほど良いかを言える。

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

評価用の集まりを見分ける

評価用の集まりとは、AI機能の点数を付けるために使う、事例の一覧のことです。点数は、その一覧と同じ程度にしか信用できません。

このモジュールは、評価とテストのモジュールを深めます。そちらでは、最初の集まりを作りました。ここでは、その点数を信じてよいかを問います。

このレッスンのゴール

メモ

評価用の集まりが、信じてよいほど良いかを言える。

キーワード

ことばいみれい
カバー範囲事例が、入力の種類にどれだけ行き渡っているか
ラベルある事例の正しい答えとして、人が付けたものyes
食い違い一つの事例に、二人が別のラベルを付けること
誤差の幅偶然で点数が動く大きさ
差二つの版の点数の違い

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

カバー範囲は、種類ごとに見る

ある店の問い合わせボットを考えます。返金の依頼を受けてよいかを、yes か no で答えます。事例を、ふつうの依頼、条件が混ざった依頼、ぎりぎりの依頼、断るべき依頼に分けて、種類ごとに数えます。

一つか二つしかない種類は、薄い種類です。断る事例が 20 件のうち 2 件では、全部失敗しても点数はほとんど動きません。

例: 20 件を種類ごとに数える

種類(符号)件数割合判断
plain(ふつう)1050 パーセント足りている
mixed(混ざった)525 パーセント足りている
edge(ぎりぎり)315 パーセント足りている
refusal(断る)210 パーセント薄い、足す

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

二人でラベルを見比べる

ラベルは、人の意見です。二人目に、一人目のラベルを見せずに、同じ事例へラベルを付けてもらい、比べます。

一致した事例は、はっきりしています。食い違った事例は、事例か決まりがあいまいです。点数を付ける前に、そこを見直します。

よくある間違い

注意

専門家一人のラベルが、正解そのものだと考える人が多いです。それは一人の意見です。二人目も同じ答えか、そのラベルの理由を書き残してあるときに限って、使いましょう。

小さな集まりでは差が見えない

点数は、偶然でも動きます。誤差の幅の目安は、100 を事例の数の平方根で割った、点数の幅です。100 件なら 10 点です。

誤差の幅より小さい差は、偶然かもしれません。5 点の差を見分けるには、約 400 件が要ります。

例: 件数と誤差の幅

件数誤差の幅(点)信じてよい最小の差
2520約 20 点
10010約 10 点
4005約 5 点
25002約 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\");' 'const rows = [' '  \"1 plain yes yes\", \"2 plain yes yes\", \"3 plain no no\", \"4 plain yes yes\", \"5 plain no no\",' '  \"6 plain yes yes\", \"7 mixed yes no\", \"8 mixed no no\", \"9 mixed yes yes\", \"10 plain no no\",' '  \"11 mixed no no\", \"12 edge yes yes\", \"13 mixed yes no\", \"14 edge no no\", \"15 plain yes yes\",' '  \"16 plain no no\", \"17 edge yes yes\", \"18 plain yes no\", \"19 refusal no no\", \"20 refusal no no\",' '].map(function (r) {' '  const p = r.split(\" \");' '  return { id: Number(p[0]), kind: p[1], a: p[2], b: p[3] };' '});' > audit.js"

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

集まりの監査を書く(2)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const counts = {};' 'rows.forEach(function (r) { counts[r.kind] = (counts[r.kind] || 0) + 1; });' 'const thin = Object.keys(counts).filter(function (k) { return counts[k] < 3; });' 'const apart = rows.filter(function (r) { return r.a < r.b || r.a > r.b; });' 'const same = rows.length - apart.length;' 'const gap = 5;' 'const needed = (100 / gap) * (100 / gap);' >> audit.js"

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

集まりの監査を書く(3)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' '  console.log(\"件数: \" + rows.length + \"  種類別: \" + JSON.stringify(counts));' '  console.log(\"薄い種類 (3 件未満): \" + thin.join(\", \"));' '  console.log(\"一致: \" + (same * 100 / rows.length) + \" パーセント\");' '  console.log(\"見直す id: \" + apart.map(function (r) { return r.id; }).join(\", \"));' '  console.log(\"差が \" + gap + \" 点なら、約 \" + needed + \" 件が要ります\");' '  const q = \"一文で短く答えてください。同じ事例を二人にラベル付けさせるのは、なぜですか。\";' '  const sample = \"二人の答えが分かれる事例は、事例か決まりがあいまいで、その点数はあてになりにくいからです。\";' '  const reply = await ask([{ role: \"user\", content: q }], sample, 80);' '  console.log(\"モデル: \" + reply.text);' '}' 'main();' >> audit.js"

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

監査を動かす

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

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

監査の出力

行意味
件数: 20 種類別: {...}種類ごとの件数
薄い種類 (3 件未満): refusal事例を足したい種類
一致: 85 パーセント二人のラベルが合った割合
見直す id: 7, 13, 18二人のラベルが違った事例
差が 5 点なら、約 400 件が要ります差を見分けるのに要る件数の目安
モデル: ...ラボからの一文。答えがなければ記録済みサンプル

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

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

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