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

無料レッスン

エージェントの変更を危険の順に見直す

このレッスンのあとで: 読む前に、エージェントの変更のまとまりを危険の順に並べることができる。

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

エージェントの変更の見直し方

変更のまとまりは、エージェントが一つのタスクのために足し、変え、消したファイルのすべてです。エージェントは一分で二十のファイルを変えられます。全部を同じ注意で読むやり方は、追いつきません。

危険から先に見る見直しでは、危ないファイルを見つけて、それを先に読みます。前に学んだのは、小さな差分を一つ読むことでした。このレッスンでは、まとまり全体を並べます。

このレッスンのゴール

メモ

読む前に、エージェントの変更のまとまりを危険の順に並べることができる。

キーワード

ことばいみ
変更のまとまり一つのタスクで変わったファイルのすべて
範囲の広がりタスクが頼んだ以上の変更
依存パッケージコードが動くのに要るパッケージ
危険の印変更に注意が要るというしるし
重み印が何点になるか

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

注意が要る変更のしるし

タスクが指定していないファイルは、範囲の広がりです。消えたテストや、行が減ったテストは、壊れた機能を隠すことがあります。設定ファイルが変わると、ビルドのしかた全体が変わることがあります。

とても大きな新しいファイルは、読むのが大変です。ここまでが、点をつける危険の印です。

新しい依存パッケージは、チームの誰も書いていないコードを持ち込みます。これは点にせず、別の行で知らせて見ます。

例: 印とその重み

印つくとき重み
テスト削除テストファイルが消された5
テスト縮小テストファイルで、足した行より消した行が多い3
範囲外タスクがそのファイルを指定していない3
設定package.json、package-lock.json、ci.yml2
大きい足した行と消した行が合わせて 200 より多い1

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

点をつけ、並べ、それから読む

ファイルごとに、印の重みを足して点にします。点の高い順に並べ、同じ点なら来た順を保ちます。

それから、上のファイルを一行ずつ全部読みます。点の低いファイルも読みますが、もう危ないファイルを隠しません。テストが消えていれば、まとまり全体を差し戻します。

よくある間違い

注意

見直しとは、どの行も同じ注意で読むことだと考える人が多いです。400 行あると、危ない十行が安全な行の間に隠れます。先に危険の順に並べ、危ないファイルはすべて全部読みましょう。

助っ人 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 allowed = [\"shop.js\", \"shop.test.js\"];' 'const CONFIG = [\"package.json\", \"package-lock.json\", \"ci.yml\"];' 'const WEIGHT = { \"テスト削除\": 5, \"テスト縮小\": 3, \"範囲外\": 3, \"設定\": 2, \"大きい\": 1 };' > risk.js"

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

危険の見直しを書く(2)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const changes = [' '  { path: \"shop.js\", added: 12, removed: 2, kind: \"modified\" },' '  { path: \"shop.test.js\", added: 1, removed: 9, kind: \"modified\" },' '  { path: \"prices.json\", added: 1, removed: 1, kind: \"modified\" },' '  { path: \"old.test.js\", added: 0, removed: 40, kind: \"deleted\" },' '  { path: \"package.json\", added: 1, removed: 0, kind: \"modified\" },' '  { path: \"README.md\", added: 3, removed: 0, kind: \"modified\" },' '  { path: \"utils/format.js\", added: 230, removed: 0, kind: \"added\" },' '];' 'const before = [\"date-tools\"];' 'const after = [\"date-tools\", \"money-format\"];' >> risk.js"

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

危険の見直しを書く(3)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function flags(c) {' '  const out = [];' '  const isTest = c.path.indexOf(\".test.\") >= 0;' '  if (isTest && c.kind === \"deleted\") out.push(\"テスト削除\");' '  if (isTest && c.kind === \"modified\" && c.removed > c.added) out.push(\"テスト縮小\");' '  if (allowed.indexOf(c.path) < 0) out.push(\"範囲外\");' '  if (CONFIG.indexOf(c.path) >= 0) out.push(\"設定\");' '  if (c.added + c.removed > 200) out.push(\"大きい\");' '  return out;' '}' 'function score(c) {' '  return flags(c).reduce(function (sum, f) { return sum + WEIGHT[f]; }, 0);' '}' >> risk.js"

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

危険の見直しを書く(4)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' '  const order = changes.slice().sort(function (a, b) { return score(b) - score(a); });' '  order.forEach(function (c) {' '    console.log(score(c) + \" \" + c.path + (flags(c).length ? \": \" + flags(c).join(\"、\") : \"\"));' '  });' '  after.filter(function (d) { return before.indexOf(d) < 0; })' '    .forEach(function (d) { console.log(\"新しい依存: \" + d); });' '  const gone = changes.some(function (c) { return flags(c).indexOf(\"テスト削除\") >= 0; });' '  console.log(gone ? \"差し戻す: テストが消された\" : \"この順で見直す\");' '  const q = \"短く一文で答えてください。見直す人が、消えたテストファイルを最初に見るのは、なぜですか。\";' '  const sample = \"テストが消えると、もう何も確かめないので、壊れた機能が隠れるからです。\";' '  const reply = await ask([{ role: \"user\", content: q }], sample, 80);' '  console.log(\"モデル: \" + reply.text);' '}' 'main();' >> risk.js"

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

危険の見直しを動かす

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

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

Run の出力

行意味
8 old.test.js: テスト削除、範囲外一番危ないファイルで、最初に読む
5 package.json: 範囲外、設定タスクが指定していない設定ファイル
4 utils/format.js: 範囲外、大きい誰も頼んでいない大きな新しいファイル
3 shop.test.js: テスト縮小指定したテストの行が減った
3 prices.json: 範囲外タスクが指定していない値段のファイル
3 README.md: 範囲外タスクが指定していない説明の文書
0 shop.jsタスクが本来扱うファイル
新しい依存: money-formatチームの外から来た新しいコード
差し戻す: テストが消されたまとまり全体についての判断

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

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

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