創刊準備号 · 2026年秋English · RSS
AgentKoji

PR一部の記事にはアフィリエイトリンクを含みます。経由して申し込まれると、当サイトに報酬が入ることがあります。評価は変えません。 アフィリエイト開示

常駐Bot監視の落とし穴

AIエージェントの監視で、毎回失敗しているのにハートビートは緑だった。beatを打つ位置ひとつで監視は嘘をつく。その穴を再現コードで示す。

常駐の Bot を監視するときの4つの不変条件は、「AIエージェントをVPSで24時間動かす」で紹介しました。おさらいすると、次の4つです。

PR:以下の段落にアフィリエイトリンクを含みます。

監視用の別ホストは、小さなプランで足ります。国内なら ConoHa VPS や XServer VPS の最小構成を、本体とは別の契約で用意すると「一緒に落ちる」を避けられます。

この記事では、4つを守っていても残っていた穴を書きます。再現コードは、編集部の検証環境(Python 3.13.5、2026-10-16)で動かしたものです。

AIエージェントの監視とbeatの位置

ハートビート(「生きている」の合図)を、処理の開始時に打つか、完了後に打つか。どちらにも穴があり、向きが逆です。

def job(i): raise RuntimeError("always fails")   # 毎回失敗する処理
beats_start, beats_end = [], []
for i in range(3):
    beats_start.append(i)               # A: 開始時に beat
    try: job(i); beats_end.append(i)    # B: 完了後に beat
    except Exception: pass
A(開始時beat) 回数: 3 → healthy に見える
B(完了後beat) 回数: 0 → 失敗と停止の区別がつかない

片方を塞ぐと、もう片方の穴が開きます。だから、ok でも error でもない3つ目のラベルが必要になります。

def label(last_ok_age, paused):
    if paused: return "inert"
    return "ok" if last_ok_age < 600 else "error"
# label(30,False)→ok / label(9999,False)→error / label(9999,True)→inert

初期値が ok のヘルスキーは、恒久的な嘘になる

状態を表すキーを、最初から "ok" で作っていました。その後、キーを更新していた処理を消しました。キーは "ok" のまま残り、誰も更新しないのに緑を表示し続けました。再現コードでも、更新元を消したあとに読むと health key: ok が返ります。

ヘルスキーの初期値は "unknown" にします。値と一緒に「最後に更新した時刻」を持たせて、古くなったら error として扱います。

初回の観測値を、黙って基準値にしない

新しく監視のレーンを足したとき、最初に取った値を、そのまま基準値(baseline)にしました。ところが、その時点ですでに、検知したかった異常が起きていました。異常な値が基準になってしまい、通知は一度も出ませんでした。初回の値は、人が見て「正常」と確かめてから基準にします。

「正常な沈黙」と「故障」を分ける

出力が無いことには、2つの意味があります。処理する対象が無かっただけなのか、出力を作る処理が止まったのか、です。両方を「0件」で表すと区別できません。対象が無かったときも、「0件を確認した」という記録を残します。

失敗が人に届くまでを設計に含める

ログインのセッションが切れて、その日の処理が失敗していたのに、誰も気づかなかったことがあります。失敗は、ログには残っていました。自動化の設計は、失敗が人の目に届くところまでを範囲に含めます。

成功に見える静かな失敗の型は「AIの「完了しました」を信じない仕組み」にまとめました。

外部への副作用は3値で扱う

Bot が外部の API に書き込むなら、結果は「成功」と「失敗」の2値では足りません。

型は正しいのに中身が違う、という同じ形の問題は、LLM の出力でも起きます。その確かめ方は「LLMは「選ぶ・抜く」だけにする」にまとめました。

まとめ

一部の記事にはアフィリエイトリンクを含みます。経由して申し込まれると、当サイトに報酬が入ることがあります。評価は変えません。 アフィリエイト開示