AI機能の決定ログ
決定ログとは、機能の裏にある選択の短い一覧です。それぞれに、選択肢、選んだもの、証拠が付きます。半年後には、なぜ小さなモデルのままにしたのか誰も覚えていないので、大切です。
図書館のチームは、4週間で5つの決定をしました。いまはスクリプトが、どれも実在する記録を指しているかを確かめます。
このレッスンのゴール
メモ
私は、機能の裏にある決定を、他の人がたどれるように記録できます。
キーワード
| ことば | いみ | れい |
|---|---|---|
| 決定ログ | 日付のある、選択とその理由の一覧 | |
| 選択肢 | 進めたかもしれない道の一つ | |
| 選択 | 実際に選んだ選択肢 | |
| 証拠 | なぜ選んだかを示す記録 | eval:v4 |
| 見直し | 証拠が変わったときに、もう一度見ること |
学生が入力するセルは、このプレビューでは空白です。
決定には選択肢、選択、証拠がある
一つの項目は、何を決めたか、どんな選択肢があったか、どれを選んだか、それが正しいと何が示したかを書きます。日付と ID も付きます。
最も大切なのは、選択肢です。選択肢が一つなら、それは決定ではありません。読む人は、何を捨てたかを知る必要があります。
例: 決定 D4
| 項目 | 内容 |
|---|---|
| 決定 | 試行を2回までにする |
| 選択肢 | 2回まで、または5回のまま |
| 選択 | 2回まで |
| 証拠 | event:cause_found と log:11 |
学生が入力するセルは、このプレビューでは空白です。
証拠は、スクリプトで確かめられる参照
証拠は ID で書きます。実行なら eval:v4、時間なら log:11、イベントなら event:cause_found です。スクリプトが、どれも実在するかを確かめられます。
証拠のない項目、選択肢にない選択、二度使われた ID も、見つけられます。
書き直さず、項目を足す
証拠が変わると、決定も変わります。古い項目は直しません。新しい項目を足し、何を置き換えるかを書きます。
こうすると、ログには、何をいつ信じていたかが残ります。読む人に必要なのは、それです。
よくある間違い
注意
決定ログは、あとで書く書類だと考える人が多いです。あとで書くと、結果に合わせた物語になります。項目は、決めた日に、その日の証拠で書きます。
決定ログを書く(1)
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const fs = require(\"fs\");' 'const DECISIONS = [' ' { id: \"D1\", date: \"2026-03-02\", decision: \"ファクトシートをプロンプトに入れる\", options: [\"プロンプトに入れる\", \"先に検索する\"], choice: \"プロンプトに入れる\", evidence: [\"eval:v1\"] },' ' { id: \"D2\", date: \"2026-03-09\", decision: \"シートにない数字を禁じる\", options: [\"規則を足す\", \"何もしない\"], choice: \"規則を加える\", evidence: [\"eval:v2\"] },' ' { id: \"D3\", date: \"2026-03-16\", decision: \"小さなモデルのままにする\", options: [\"小さなモデル\", \"大きなモデル\"], choice: \"小さなモデル\", evidence: [\"eval:v5\", \"cost:v5\"] },' > decisions.js"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
決定ログを書く(2)
docker exec -w /home/node/project agent sh -c "printf '%s\n' ' { id: \"D4\", date: \"2026-03-24\", decision: \"試行を2回までにする\", options: [\"2回まで\", \"5回のまま\"], choice: \"2回まで\", evidence: [\"event:cause_found\", \"log:11\"] },' ' { id: \"D5\", date: \"2026-03-25\", decision: \"印刷の長い答えを受け入れる\", options: [\"受け入れる\", \"短くする\"], choice: \"受け入れる\", evidence: [] },' '];' 'fs.writeFileSync(\"decisions.json\", JSON.stringify(DECISIONS, null, 1));' >> decisions.js"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
decisions.json を作る
docker exec -w /home/node/project agent node decisions.jsここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
ログの検査を書く(1)
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const fs = require(\"fs\");' 'function known() {' ' const ids = [];' ' [\"v1\", \"v2\", \"v3\", \"v4\", \"v5\"].forEach(function (v) { ids.push(\"eval:\" + v); });' ' [\"08\", \"09\", \"10\", \"11\", \"12\", \"13\", \"14\"].forEach(function (h) { ids.push(\"log:\" + h); });' ' [\"sheet_published\", \"alert_fired\", \"cause_found\", \"attempts_capped\", \"cost_normal\"].forEach(function (c) { ids.push(\"event:\" + c); });' ' return ids;' '}' > check-log.js"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
ログの検査を書く(2)
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function run() {' ' const entries = JSON.parse(fs.readFileSync(\"decisions.json\", \"utf8\"));' ' const ids = known();' ' const seen = [];' ' let bad = 0;' ' for (const e of entries) {' ' const problems = [];' ' if (e.evidence.length === 0) problems.push(\"no_evidence\");' ' else if (e.evidence.some(function (id) { return ids.includes(id) === false; })) problems.push(\"unknown_evidence\");' ' if (e.options.includes(e.choice) === false) problems.push(\"bad_choice\");' ' if (seen.includes(e.id)) problems.push(\"duplicate_id\");' ' seen.push(e.id);' ' if (problems.length > 0) { bad = bad + 1; console.log(e.id, problems.join(\" \")); }' ' }' ' console.log(\"決定 \" + entries.length + \" 件、問題あり \" + bad + \" 件\");' '}' 'module.exports = { run };' 'if (require.main === module) run();' >> check-log.js"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
ログを検査する
docker exec -w /home/node/project agent node check-log.jsここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
検査の表示
| 行 | 意味 |
|---|---|
| D2 | bad_choice |
| D3 | unknown_evidence |
| D5 | no_evidence |
| 最後の行 | 決定 5 件、問題あり 3 件 |
学生が入力するセルは、このプレビューでは空白です。
修正を書く
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const fs = require(\"fs\");' 'const entries = JSON.parse(fs.readFileSync(\"decisions.json\", \"utf8\"));' 'entries[1].choice = \"規則を足す\"; // 選択は、選択肢の一つ' 'entries[2].evidence = [\"eval:v5\"]; // cost:v5 は記録ではない' 'entries[4].evidence = [\"eval:v4\"]; // v4 には、まだ長い答え c9 がある' 'fs.writeFileSync(\"decisions.json\", JSON.stringify(entries, null, 1));' 'require(\"./check-log\").run();' > fix-log.js"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
ログを直して、もう一度検査する
docker exec -w /home/node/project agent node fix-log.jsここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。