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

無料レッスン

LLMを安全に切り替える方法

このレッスンのあとで: 記録した二つの実行から、機能を別のモデルへ移すかを決められます。

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

新しいモデルは安く、答えが違う

機能の裏のモデルを変えるとは、同じケースを両方の版で走らせ、利用者を少しずつ移すことです。新しい版は平均では良くても、一部のケースでは悪くなり、利用者が最初に気づきます。

ここのラボはどれもモデルを学習も提供もしないので、記録した二つの版を比べます。方法は、本物でも同じです。

このレッスンのゴール

メモ

記録した二つの実行から、機能を別のモデルへ移すかを決められます。

キーワード

ことばいみ
退行以前は通り、今は失敗するケース
カナリア最初に新しい版を使う少数の利用者
ロールバック古い版へ戻る道
バケツ利用者がいつも入る固定の数
コストの上昇新しい版が何パーセント高いか

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

同じケースで両方の版を走らせる

両方の版に同じケースを使い、ケースごとに通ったか、いくらかかったかを記録します。通った件数を比べるだけでなく、退行も並べます。

通った件数が同じでも、版は違いえます。一方が通ったケースを、他方は落とすことがあります。重要なケースの退行は、平均の改善より重いことがあります。

例: 六つのケースでの旧と新

版通った件数コスト退行
旧6 件中 5180なし
新6 件中 5144c3 は以前は通り、今は失敗

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

まず少数を移す

全員を一度に切り替えてはいけません。少数の利用者だけを新しい版へ送り、様子を見ます。同じ人がいつも同じ版になるよう、固定の決まりで選びます。

古い版は動かしたままにして、一歩で戻れるようにします。請求も見ます。価格の変更は利益を消すことがあるので、見る前に許容する上昇を決めます。

よくある間違い

注意

「新しいモデルは必ず良いので、軽い試験で足りる」と考えがちです。新しいモデルは平均で良くても、あなたのケースでは悪いことがあります。自分のケースを走らせ、少数から移し、戻る道を残します。

モデル用の補助を書く(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"

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

モデル用の補助を書く(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 d = await res.json();' '    return { text: d.choices[0].message.content, inTokens: count(d, \"prompt_tokens\"), outTokens: count(d, \"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 oldRun = [1, 1, 1, 0, 1, 1].map(function (ok, i) { return { case: \"c\" + (i + 1), ok: ok === 1, cost: 30 }; });' 'const newRun = [1, 1, 0, 1, 1, 1].map(function (ok, i) { return { case: \"c\" + (i + 1), ok: ok === 1, cost: 24 }; });' 'const MAX_REGRESSIONS = 1;' 'function passes(run) { return run.filter(function (r) { return r.ok; }).length; }' 'function total(run) { return run.reduce(function (sum, r) { return sum + r.cost; }, 0); }' > change.js"

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

比較を書く(2)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function regressions(a, b) {' '  return a.filter(function (r, i) { return r.ok && b[i].ok === false; }).map(function (r) { return r.case; });' '}' '// 名前の文字コードの合計が作るバケツが、割合より小さい利用者はカナリアに入る。' 'function inCanary(user, percent) {' '  let n = 0;' '  for (const ch of user) n = n + ch.charCodeAt(0);' '  return n % 100 < percent;' '}' >> change.js"

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

比較を書く(3)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' '  console.log(\"旧: 6 件中 \" + passes(oldRun) + \" 件、コスト \" + total(oldRun));' '  console.log(\"新: 6 件中 \" + passes(newRun) + \" 件、コスト \" + total(newRun));' '  const bad = regressions(oldRun, newRun);' '  console.log(\"退行: \" + bad.join(\", \") + (bad.length <= MAX_REGRESSIONS ? \"(許容)\" : \"(多すぎる)\"));' '  const users = [\"ana\", \"cy\", \"eva\", \"gus\", \"li\", \"zoe\"];' '  console.log(\"10 パーセントのカナリア: \" + users.filter(function (u) { return inCanary(u, 10); }).join(\", \"));' '  const r = await ask([{ role: \"user\", content: \"20,000 円の 15 パーセントはいくらですか。短く一文で答えてください。\" }], \"20,000 円の 15 パーセントは 3,000 円です。\", 40);' '  console.log(\"今日のライブ呼び出し(記録とは別): \" + r.text);' '}' 'main();' >> change.js"

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

比較を実行する

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

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

出力の例

行示していること
旧: 6 件中 5 件、コスト 180記録済みの古い版
新: 6 件中 5 件、コスト 144記録済みの新しい版。安い
退行: c3(許容)退行が一つで、上限の一つ以内
10 パーセントのカナリア: ana固定の決まりで少数に入る利用者
今日のライブ呼び出し(記録とは別): ...あなた自身の呼び出し。実行ごとに変わるか、記録済みサンプルと出る

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

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

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