外部サービスの利用クォータを見ながら、自宅のAI運用や自動処理を回している人にとって、残量表示はかなり強い判断材料になります。残量があるなら処理を続ける。残量がないなら止める。単純で、運用上も扱いやすい。
ただし、画面から読み取った残量表示が、いまの状態を表しているとは限りません。
某所ラボでは、外部サービスのクォータ残量が99%と表示され続けているのに、実行系は枯渇エラーを返し続けるという状態が起きました。残量表示だけを見れば満タンです。実際には空でした。エージェントは空のタンクに向かって、まだ燃料がある前提で空振りを続けていました。
これは、監視値がおかしいときにどちらを信じるか、という話です。結論から言うと、監視値と実エラーが矛盾したら、実エラーを信じます。
起きたこと
監視対象は、外部サービスの利用クォータでした。監視方式は、対話画面に表示される残量を読み取る形です。APIで厳密な使用量を取得する方式ではなく、画面に出ている値を観測して、まだ使えるかどうかを判断していました。
ある時点で、画面側に入力が積み上がる不具合が発生しました。その結果、新しいフレームが描画されなくなりました。
監視系は、それに気づきませんでした。新しい表示を読みに行っているつもりで、実際には過去の古いフレームを読み続けていました。その古いフレームには、残量99%という値が残っていました。
そのため、監視値はずっと満タンです。一方で、実行系は外部サービス側から枯渇を示すエラーを受け取っていました。
- 監視値: 残量99%
- 実行結果: クォータ枯渇
重要なのは、矛盾していたのが一つのメトリクスだけではなかったことです。監視値そのものが間違っていたというより、信じる先を間違えていました。画面に残った過去の値を、現在の状態として扱ってしまったのです。
なぜ残量表示があてにならなくなったのか
スクレイプ型、あるいは画面読み取り型の監視は、失敗時の扱いが難しい方式です。
値が取れないときに、最後に成功した値を返す実装は珍しくありません。ダッシュボード上では空欄より見た目が安定しますし、一時的な取得失敗でアラートが騒がしくなることも避けられます。
しかし、クォータ残量のように意思決定へ直結する値では、この親切さが危険になります。
最後に成功した値が99%だった場合、取得に失敗しても99%を返し続ける。見た目は安定しています。運用判断は壊れます。
この事例では、表示値の正しさよりも、値の鮮度が欠落していました。いつ観測した99%なのかが分からないなら、その99%は現在値として扱えません。鮮度不明の値は、実質的に値が無いのと同じです。
修正したこと
対策は大きく二つでした。
一つ目は、描画に失敗した場合、staleな値を返さず空でフェイルすることです。
古い値を返すと、実行系は残量があると判断してしまいます。空で失敗すれば、少なくとも「現在の残量を確認できない」という状態として扱えます。これは小さな差に見えますが、無人運用ではかなり大きい差です。
二つ目は、入力や履歴の積み上がりを解消する処理です。公開記事では内部実装には触れませんが、要点は、古い表示を抱え込んだまま読み取り続けないようにしたことです。
- 値が取れた: 値と観測時刻を一緒に扱う
- 値が取れない: 前回値で代用しない
- 実エラーと監視値が矛盾する: 実エラーを優先して調査する
監視は「値」ではなく、「値と鮮度の組」として扱うようになりました。
監視方式のメリット・デメリット
この種の失敗は、画面読み取り型の監視を全否定すれば済む話ではありません。APIがない、または運用上の理由で画面表示を読むしかない場面はあります。問題は、その方式にどのような弱点があるかを把握して使うことです。
| 方式 | メリット | デメリット | 向いている人 |
|---|---|---|---|
| 画面読み取り型の監視 | 既存画面を使える。導入が軽い | 表示更新の失敗や古いフレームに弱い。値の鮮度を別途扱う必要がある | 公式な取得口がなく、暫定的に状態を見たい運用者 |
| 実行エラーを見る監視 | 実際の成否に近い。嘘の残量表示に引きずられにくい | 失敗してから検知するため、予防には弱い | 自動処理の空振りを早く止めたい運用者 |
| APIや公式な使用量取得 | 値の意味が比較的明確。時刻やレスポンスも扱いやすい | 取得口が提供されていない場合は使えない。仕様変更への追従が必要 | クォータを判断材料にして処理制御したい運用者 |
| 手動確認 | 状況の文脈を人間が見られる | 無人運用には向かない。確認漏れが起きる | 重要処理の前だけ人が確認できる運用者 |
向かないのは、残量表示だけを絶対視して、実行エラーを二次情報として扱う運用です。残量表示は便利ですが、実際の実行結果より強い証拠にはなりません。
似た失敗はバックアップ監視にも出る
この考え方は、クォータ監視だけの話ではありません。バックアップでも、ステータス表示だけを見て安心すると危険です。復元できるか、prune候補が意図通りか、といった実挙動を確認するほうが運用判断に近くなります。
Proto.Violet.Labでは、バックアップについてもresticの暗号化バックアップは復元失敗とprune候補を先に見るという形で、表示ではなく実際の挙動を確認する検証を残しています。監視値だけでなく、実際に何が起きたかを見るという点では同じ系譜です。
無人運用で見るべきもの
無人運用では、監視が静かであることと、運用が正常であることは同じではありません。
今回の事例では、監視値は静かでした。残量99%と表示されているので、見た目には問題がありません。けれど、実行系は枯渇エラーを返していました。静かな監視と、失敗し続ける実行系が同居していたわけです。
所長の運用では、この種の矛盾が出た時点で、監視値を疑う扱いに寄せました。これは慎重というより、単に現実に合わせた判断です。サービスが拒否しているなら、残量表示がどう見えても、処理は進みません。
- 監視値には観測時刻を持たせる
- 鮮度が不明な値を現在値として使わない
- 取得失敗時に最後の成功値で黙って代用しない
- 実行エラーを監視値より弱い情報として扱わない
- 矛盾が出たら、表示ではなく実際の成否から調べる
特に「取れないなら stale でなく空でフェイル」は、地味ですが効きます。値がないことを値があるように見せると、後段の判断が壊れます。空で失敗するほうが、まだ正直です。
まとめ
残量99%という表示は、見た目には安心できます。けれど、それが古いフレームから読まれた値なら、現在のクォータとは関係がありません。
監視値と実エラーが矛盾したら、実エラーを信じる。
この一件以降、某所ラボの監視では、値そのものだけでなく、その値がいつ観測されたものかを同格に扱うようになりました。計測が信用できなくなった日から、監視は「値」ではなく「値と鮮度の組」になりました。
画面読み取り型の監視を使うなら、残量表示があてにならない日が来る前提で設計したほうがよいです。値が取れないなら、古い値で埋めない。空として失敗させる。その冷たい挙動のほうが、無人運用には向いています。
この検証を回している環境
この検証は、自宅の常設ラボ(使い捨てVM/LXCを回す母艦+GPU+VLAN分離ネットワーク)で動かしています。使っている機材と選定理由、全体構成は1本にまとめています。
ラボ構成のまとめを見る →