AI障害の原因を突き止める
障害とは、機能の費用が要件書の許す額を超えたり、答えが悪くなったりする時間のことです。原因は記録から探します。いつ、いくらかは費用ログ、どこかはトレースです。
図書館のアシスタントは、公開から1週間です。正午に、費用アラートが鳴りました。モデルは誰も変えていません。では、何が変わったのでしょうか。
このレッスンのゴール
メモ
私は、トレースとログから、何がまずかったかを突き止められます。
キーワード
| ことば | いみ | れい |
|---|---|---|
| 障害 | 機能が要件書を破っている時間 | |
| 費用ログ | 各時間の費用の記録 | |
| トレース | 一つのリクエストが通った手順 | |
| スパン | トレースの一つの手順と、その時間 | model |
| 試行 | 一つのリクエストのための、モデルへの一回の呼び出し |
学生が入力するセルは、このプレビューでは空白です。
記録ごとに、答えられる問いがある
まず、知りたいことに答えられる記録はどれかを考えます。全部は読みません。
費用ログは、いつ、いくらかを教えます。トレースは、一つのリクエストの中で、時間と呼び出しがどこへ行ったかを教えます。デプロイのようなイベントの一覧は、何が変わったかを教えます。
例: 三つの記録
| 記録 | 答えられること | 答えられないこと |
|---|---|---|
| 費用ログ | どの時間の費用が高いか | なぜ高いのか |
| トレース | 一つのリクエストが何をしたか | それがどれだけ多いか |
| イベント一覧 | 何がいつ変わったか | それが影響したか |
学生が入力するセルは、このプレビューでは空白です。
いつ、どこ、そしてなぜ
最初にいつを探します。上限を破った時間です。次にどこ。その時間のリクエスト一つのトレースです。最後になぜ。両方を説明できる原因です。
原因は、確かめます。本当なら、ログがほかにも何かを示すはずです。何も予測しない原因は、推測にすぎません。
よくある間違い
注意
費用が急に増えたら、利用者が増えたのだと考える人が多いです。リクエストの数も見てください。リクエストが同じで試行が増えたなら、一件あたりの費用が増えたのです。利用は増えていません。
障害を読む道具を書く(1)
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const fs = require(\"fs\");' '// 時間ごとのリクエスト数と、モデルへの試行回数。1回の試行は費用5。アラートは1時間1500。' 'const HOURS = [[\"08\", 120, 126], [\"09\", 150, 158], [\"10\", 140, 149], [\"11\", 160, 520], [\"12\", 155, 310], [\"13\", 150, 160], [\"14\", 145, 152]];' 'const LIMIT = 1500;' 'const log = HOURS.map(function (h) {' ' return { hour: h[0], requests: h[1], attempts: h[2], cost: h[2] * 5 };' '});' 'fs.writeFileSync(\"cost-log.json\", JSON.stringify(log, null, 1));' > incident.js"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
障害を読む道具を書く(2)
docker exec -w /home/node/project agent sh -c "printf '%s\n' '// リクエスト r481、延滞料についての質問を、スパンで見たもの。' 'const TRACE = [' ' { span: \"read_sheet\", attempt: 0, ms: 4, length: 0 },' ' { span: \"model\", attempt: 1, ms: 900, length: 52 },' ' { span: \"model\", attempt: 2, ms: 880, length: 51 },' ' { span: \"model\", attempt: 3, ms: 910, length: 55 },' ' { span: \"model\", attempt: 4, ms: 890, length: 53 },' ' { span: \"model\", attempt: 5, ms: 905, length: 54 },' ' { span: \"send_last\", attempt: 5, ms: 1, length: 54 },' '];' 'fs.writeFileSync(\"trace-r481.json\", JSON.stringify(TRACE, null, 1));' >> incident.js"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
障害を読む道具を書く(3)
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'console.log(\"時間 リクエスト 試行 1件あたり 費用\");' 'for (const h of log) {' ' const ratio = (h.attempts / h.requests).toFixed(2);' ' console.log(h.hour + \":00\", h.requests, h.attempts, ratio, h.cost, h.cost > LIMIT ? \"超過\" : \"ok\");' '}' >> incident.js"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
障害を読む道具を書く(4)
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'for (const t of TRACE) {' ' console.log(t.span, t.attempt, t.ms + \" ms\", \"長さ \" + t.length, t.length > 40 ? \"長すぎ\" : \"\");' '}' 'const tries = TRACE.filter(function (t) { return t.span === \"model\"; }).length;' 'console.log(\"r481 のモデル試行:\", tries);' >> incident.js"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
ログとトレースを読む
docker exec -w /home/node/project agent node incident.jsここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
Run の表示
| 部分 | 示すこと |
|---|---|
| 08:00 から 10:00 | 1リクエスト1.05前後の試行、費用は630から790 |
| 11:00 | 1リクエスト3.25試行、費用2600、超過 |
| 12:00 | 1リクエスト2.00試行、費用1550、超過 |
| 13:00 と 14:00 | 1.05前後に戻り、費用は1500以下 |
| r481 のトレース | モデルのスパンが5つ。長さはすべて40超 |
学生が入力するセルは、このプレビューでは空白です。