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

無料レッスン

悪いプロンプトでビルドを止める

このレッスンのあとで: 悪くなったプロンプトで、ビルドを失敗させられる。

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

悪いプロンプトでビルドを失敗させる

あるチームが、金曜日にプロンプトを変えました。月曜日、お客さんの目に入る答えが悪くなっていました。点数を見る仕組みがなく、誰も見なかったのです。

回帰テストをビルドに入れれば、これを止められます。評価とテストのモジュールでは、二つの実行を手で比べました。ここでは、その比較が変更を自動で止めます。

このレッスンのゴール

メモ

悪くなったプロンプトで、ビルドを失敗させられる。

キーワード

ことばいみれい
ビルド変更のたびに自動で動く、一連の確認
固定した集まり実行のあいだで変わらない、評価用の集まり
合格の基準変更が下回ってはいけない、最低の合格率80
大事な事例合格から不合格に変わってはいけない事例
終了コードプログラムが終わるときに返す数。0 は問題なし

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

固定した集まりと合格の基準

ビルドは、毎回同じ固定した集まりで機能を動かします。プロンプトと一緒に集まりも変わると、二つの実行を比べられません。

次に、合格の基準を決めます。たとえば 80 パーセントです。基準を下回った変更は、ビルドを失敗させます。

変わった事例が一番大事

合格率は、動きを隠します。一つの事例が壊れ、別の一つが直っても、率は同じままです。

そこでビルドは、変わった事例も並べます。壊れた事例は、前は合格で今は不合格です。直った事例は、その反対です。

例: 12 件、二つの実行

項目前の実行今の実行
合格した件数12 件中 10 件12 件中 9 件
合格率(整数のパーセント)8375
壊れた事例-4 と 7
直った事例-6
大事な事例が壊れたか-はい、事例 4

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

よくある間違い

注意

合格率が基準を上回っていれば、その変更は安全だと考える人が多いです。率が高いまま、大事な事例が壊れることがあります。大事な事例を先に調べ、率はその次に見ましょう。

終了コードがビルドを動かす

プログラムは、終わるときに数を一つ返します。0 は問題なし、それ以外は問題ありです。ビルドは、0 でない数を見ると止まります。

ここでは、大事な事例が壊れたら 2、率が基準を下回ったら 1、通れば 0 とします。大事な事例の確認が先です。

助っ人 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 mark = 80;' 'const rows = [' '  \"1 c 1 1\", \"2 n 1 1\", \"3 n 1 1\", \"4 c 1 0\",' '  \"5 n 1 1\", \"6 n 0 1\", \"7 n 1 0\", \"8 n 1 1\",' '  \"9 c 1 1\", \"10 n 0 0\", \"11 n 1 1\", \"12 n 1 1\",' '].map(function (r) {' '  const p = r.split(\" \");' '  return { id: Number(p[0]), critical: p[1] === \"c\", old: p[2] === \"1\", now: p[3] === \"1\" };' '});' > gate.js"

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

ビルドの関所を書く(2)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function rate(key) {' '  const n = rows.filter(function (r) { return r[key]; }).length;' '  return Math.floor(n * 100 / rows.length);' '}' 'const broken = rows.filter(function (r) { return r.old && r.now === false; });' 'const fixed = rows.filter(function (r) { return r.old === false && r.now; });' 'function ids(list) {' '  return list.length === 0 ? \"なし\" : list.map(function (r) { return r.id; }).join(\", \");' '}' >> gate.js"

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

ビルドの関所を書く(3)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function exitCode() {' '  if (broken.some(function (r) { return r.critical; })) return 2;' '  if (rate(\"now\") < mark) return 1;' '  return 0;' '}' 'async function main() {' '  console.log(\"合格率: \" + rate(\"old\") + \" -> \" + rate(\"now\") + \" (基準 \" + mark + \")\");' '  console.log(\"壊れた: \" + ids(broken) + \"   直った: \" + ids(fixed));' '  console.log(\"終了コード: \" + exitCode());' '  const q = \"落ち着いた一文で、プルリクエストへのコメントを書いてください。事例 4 は前は合格で、今は不合格です。\";' '  const sample = \"事例 4 は、前のプロンプトでは合格でしたが、今回は不合格なので、ビルドを止めます。\";' '  const reply = await ask([{ role: \"user\", content: q }], sample, 80);' '  console.log(\"コメント: \" + reply.text);' '}' 'main();' >> gate.js"

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

関所を動かす

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

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

関所の出力

行意味
合格率: 83 -> 75 (基準 80)前と今の率、そして基準
壊れた: 4, 7 直った: 6変わった事例
終了コード: 2事例 4 が大事なので、ビルドは止まる
コメント: ...ラボからの一文。答えがなければ記録済みサンプル

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

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

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