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

無料レッスン

AIのインシデントを進める

このレッスンのあとで: AIのインシデントを進め、そこから学ぶことができる。

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

AIの機能が失敗したときにすること

インシデントとは、機能が利用者や事業に害を与える時間のことです。たとえば、誤った返金や、漏れたアドレスです。インシデントを進めるとは、見つけ、害を抑え、直し、そこから学ぶことです。

害が広がるのは、気づくのが遅いときと、誰が何をするか決まっていないときです。このレッスンは、トレースなどの記録を使って、インシデントを順に進めます。

このレッスンのゴール

メモ

AIのインシデントを進め、そこから学ぶことができる。

キーワード

ことばいみれい
インシデント機能が利用者に害を与えている時間
時系列出来事を、時刻とともに順に並べたもの
重大度どれほど深刻かを表す 1 から 3 の数2
緩和原因を直す前に、害を抑えること
振り返り何が起こさせたかを学ぶための会議

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

記録から、時系列を作る

記録が違う順番で届いても、すべての出来事を時刻の順に並べます。一行ごとに、いつ、誰が、何を、を書きます。

そして、二つの数を出します。気づくまでの時間は、開始から最初の兆しまでです。回復するまでの時間は、開始から直るまでです。

例: 誤った返金のプロンプト

分誰が出来事そこから分かること
0release新しいプロンプトを公開した開始
25supportお客様から最初の連絡気づくまでは 25
31on-callインシデントを宣言した作業が始まる
40on-call古いプロンプトに戻した害が止まる
52monitor返金がゼロに戻った回復するまでは 52

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

重大度が、誰が何をするかを決める

重大度の規則は、インシデントの前に書きます。個人データが見えた、または利用者の半分以上なら、重大度 1 です。10 パーセント以上なら 2、それより少なければ 3 です。

重大度ごとに、短い対応の一覧があり、対応には役割があります。lead、fixer、comms のどれかです。lead は担当者を呼んで全体を進める人、fixer は変更を元に戻す人、comms は利用者やチームに伝える人です。役割があると、みんなが同じ仕事をせずにすみます。

例: 重大度と対応

重大度条件対応
1個人データ、または 50 パーセント以上担当者を呼ぶ、元に戻す、利用者に伝える、振り返りを開く
210 から 49 パーセント元に戻す、チームに伝える、振り返りを開く
310 パーセント未満記録に書く

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

よくある間違い

注意

振り返りは、誰が間違えたかを見つけるものだと考える人が多いです。それでは、次から人が隠すようになります。仕組みの何が通したかを問いましょう。カナリアがない、警報がない、誰も確かめない規則、などです。振り返りには役割を書き、人を責めません。

助っ人 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 events = [' '  { at: 31, who: \"on-call\", kind: \"declared\", what: \"インシデントを宣言した\" },' '  { at: 0, who: \"release\", kind: \"start\", what: \"新しいプロンプトを公開した\" },' '  { at: 52, who: \"monitor\", kind: \"resolved\", what: \"誤った返金がゼロに戻った\" },' '  { at: 25, who: \"support\", kind: \"detected\", what: \"お客様から最初の連絡があった\" },' '  { at: 40, who: \"on-call\", kind: \"mitigated\", what: \"古いプロンプトに戻した\" },' '];' > incident.js"

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

インシデントのスクリプトを書く(2)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function first(kind) { return events.filter(function (e) { return e.kind === kind; })[0].at; }' 'function severity(percent, privateData) {' '  if (privateData || percent >= 50) return 1;' '  return percent >= 10 ? 2 : 3;' '}' 'const sorted = events.slice().sort(function (a, b) { return a.at - b.at; });' >> incident.js"

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

インシデントのスクリプトを書く(3)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' '  sorted.forEach(function (e) { console.log(e.at + \" 分 \" + e.who + \": \" + e.what); });' '  console.log(\"気づくまで: \" + (first(\"detected\") - first(\"start\")) + \" 分\");' '  console.log(\"回復するまで: \" + (first(\"resolved\") - first(\"start\")) + \" 分\");' '  console.log(\"重大度: \" + severity(18, false));' '  const q = \"短く一文で答えてください。インシデントの振り返りで、人ではなく役割を書くのは、なぜですか。\";' '  const sample = \"責められると人は失敗を隠すので、振り返りは、仕組みが何を許したかを探すべきだからです。\";' '  const reply = await ask([{ role: \"user\", content: q }], sample, 80);' '  console.log(\"モデル: \" + reply.text);' '}' 'main();' >> incident.js"

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

インシデントの報告を動かす

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

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

Run の出力

行意味
0 分 release: 新しいプロンプトを公開した五つの出来事を、分の順に並べた
気づくまで: 25 分最初の連絡から開始を引いた
回復するまで: 52 分解決から開始を引いた
重大度: 218 パーセントが影響、個人データなし
モデル: ...ラボからの一文。モデルが答えなければ記録済みサンプル

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

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

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