agentic-process-monitor について
Agentic Process Monitor は、Claude Code のバックグラウンドプロセスを監視するためのパターン集です。センチネルファイルと監視サブエージェントを使って成功、失敗、タイムアウト、ハングを検出し、監視役の障害時にも復旧できます。
主な機能
- 01センチネルファイルによる状態追跡
- 02ハートビートの鮮度によるハング検出
- 03タイムアウトと失敗への対応
- 04サブエージェントへのポーリング委任
- 05監視エージェント障害時の復旧
- 06環境の事前確認とトラブルシューティング
活用シーン
- 01バックグラウンド処理を待ち結果を取得
- 02応答しないプロセスを検出して停止
- 03サブエージェント障害後に監視を復旧
- 04Python 仮想環境のスクリプト問題を調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ terrylica/ cc-skills --skill agentic-process-monitorインストール後、Claude Code で/agentic-process-monitorを入力して読み込まれたか確認します。
詳細
エージェント型プロセスモニター
Claude Code からバックグラウンドプロセスを監視するためのパターンです。成功、失敗、タイムアウト、ハングしたプロセスを検出し、結果をメインコンテキストに返して次のアクションにつなげます。
関連スキル:devops-tools:pueue-job-orchestration(リモート/キューイングされた作業) | devops-tools:distributed-job-safety(並行処理)
自己進化型スキル:このスキルは使用を通じて改善されます。手順に誤りがある場合、パラメーターがずれている場合、または回避策が必要になった場合は、先送りせず、このファイルをすぐに修正してください。実際に再現可能な問題がある場合に限り更新してください。
アーキテクチャ:センチネル + ハートビート + エージェント
Main Context Monitor Agent (subagent)
───────────── ──────────────────────
1. Start work (Bash run_in_background)
└─ work wrapper writes sentinel files
2. Launch Agent (poll every 15s) ────► poll loop:
3. Continue other work .status exists? → return result
.heartbeat stale? → kill, return error
elapsed > max? → kill, return timeout
4. Agent returns ◄──────────────────── detected outcome
5. Act on result (next step / retry / abort)
このアーキテクチャを採用する理由:メインコンテキストを軽量に保てます(ポーリングでトークンを消費しません)。サブエージェントが待機処理をすべて担当します。サブエージェント自体に障害が発生した場合も、メインコンテキストはセンチネルファイルを直接確認して復旧できます。
センチネルプロトコル
作業プロセスは、既知のディレクトリ(例:/tmp/<project>-monitor/)に4つのファイルを書き込みます。
| ファイル | 書き込みタイミング | 目的 |
|---|---|---|
<step>.pid | 起動時 | タイムアウト時に終了するための PID |
<step>.heartbeat | 作業中、N 秒ごと | mtime の新しさで稼働中と確認 |
<step>.status | 終了時(SUCCESS / FAILED) | 完了を示すセンチネル |
<step>.result | 成功時 | 構造化された出力(JSON) |
作業ラッパーのテンプレート
#!/usr/bin/env bash
set -uo pipefail
STEP="${1:?step name required}"
MONITOR_DIR="${2:-/tmp/monitor}"
mkdir -p "$MONITOR_DIR"
echo $$ > "${MONITOR_DIR}/${STEP}.pid"
# Heartbeat: touch file every 10s in background
(while true; do touch "${MONITOR_DIR}/${STEP}.heartbeat"; sleep 10; done) &
HB_PID=$!
trap "kill $HB_PID 2>/dev/null" EXIT
# === YOUR WORK HERE ===
if your_command --args 2>"${MONITOR_DIR}/${STEP}.log"; then
echo "SUCCESS" > "${MONITOR_DIR}/${STEP}.status"
echo '{"key": "value"}' > "${MONITOR_DIR}/${STEP}.result"
else
echo "FAILED" > "${MONITOR_DIR}/${STEP}.status"
fi
モニターの判断ツリー
ポーリングエージェントは POLL_INTERVAL 秒ごと(デフォルト:15 秒)に確認します。
every POLL_INTERVAL:
.status exists?
→ read status + result, return to main context
.heartbeat exists AND mtime stale (> STALE_THRESHOLD)?
→ process hung — kill PID, return "hung" error
elapsed > MAX_TIMEOUT?
→ timeout — kill PID, return "timeout" error
otherwise
→ sleep POLL_INTERVAL, continue
推奨デフォルト値
| パラメーター | デフォルト値 | 理由 |
|---|---|---|
POLL_INTERVAL | 15s | レイテンシーとトークンコストのバランスを取ります |
HEARTBEAT_INTERVAL | 10s | STALE_THRESHOLD / 2 未満にする必要があります |
STALE_THRESHOLD | 60s | ハートビート間隔の6倍で、十分な余裕があります |
MAX_TIMEOUT | 1800s (30min) | インフラストラクチャの障害を検出します |
サーキットブレーカー
失敗の繰り返しによる計算リソースの浪費を防ぎます。クラッシュまたは失敗が3回連続したら停止して報告します。成功したらカウンターをリセットします。
consecutive_failures = 0
MAX_CONSECUTIVE = 3
on failure:
consecutive_failures += 1
if consecutive_failures >= MAX_CONSECUTIVE:
STOP — likely infrastructure, not the work itself
on success:
consecutive_failures = 0
エージェントの自己修復
監視サブエージェントに障害(コンテキストのオーバーフロー、タイムアウト、クラッシュ)が発生した場合、メインコンテキストは次の手順で復旧します。
.statusファイルを直接確認します。エージェントが停止している間に作業が完了している可能性があります.statusが存在する場合は、結果を読み取り、通常どおり続行します.statusがなく、.heartbeatが新しい場合は、代わりの監視エージェントを起動します.statusがなく、.heartbeatが古い場合は、プロセスがハングしています。PID を終了し、エラーを記録します
これにより、メインコンテキストが永久に停止することはありません。
アンチパターン
| アンチパターン | 失敗する理由 | 代わりに使用する方法 |
|---|---|---|
tail -f | grep -m1 | macOS では動作しません。パイプのバッファリングにより、grep の終了で tail が終了せず、永久にハングします。 | ループ内で grep を使い、ログファイルにマーカーが出力されるまでポーリングします |
run_in_background のみ | タスク ID の有効期限が切れたり、取得できなくなったりすることがあります。実行中のまま停止するバグがあり、途中経過も確認できません。 | センチネルファイルとエージェントによるポーリング |
| メインコンテキストからポーリング | ポーリングのたびに出力がコンテキストウィンドウに挿入され、確認のたびに約 50K トークンを消費します。 | ポーリングをサブエージェントに委任します |
ハードコードされた sleep タイムアウト | 処理が速く終わると時間を無駄にし、遅い場合は時間が足りません。 | ポーリング間隔と最大タイムアウトを設定します |
| PID のみで生存確認 | ハングしたプロセス(PID は存在するが進捗がない)と実行中のプロセスを区別できません。 | ハートビートファイルの mtime を確認します。ハングしたプロセスはファイルを更新しなくなります。 |
uv run が古い venv の問題を隠す | uv run は独自の解決処理を行うため、壊れた venv の状態を回避します。コンソールスクリプト(pytest、ruff)の shebang は、リポジトリの名前変更後も古いままです。 | リポジトリの名前変更または移動後は必ず uv sync --python 3.14 --extra dev を実行します |
環境の事前確認
自律的なループに入る前に実行してください。確認に失敗した場合は、先へ進む前に修正してください。
# 1. Python package importable?
uv run --python 3.14 python -c "import your_package" \
|| uv sync --python 3.14 --extra dev
# 2. Console scripts have valid shebangs? (catches post-rename breakage)
uv run --python 3.14 pytest --co -q tests/ 2>/dev/null \
|| uv sync --python 3.14 --extra dev
# 3. External service reachable?
curl -sf "http://localhost:PORT/?query=SELECT+1" \
|| echo "FAIL: start service or SSH tunnel"
よくある uv/venv の問題
| 症状 | 根本原因 | 対処法 |
|---|---|---|
ModuleNotFoundError が発生するが、uv run python -c "import ..." は動作する | 古い venv — コンソールスクリプトの shebang が以前のリポジトリパスを指しています | uv sync --python 3.14 --extra dev |
bad interpreter: ...old-path/.venv/bin/python3 | 同じ問題 — .venv/bin/pytest の shebang に名前変更前のディレクトリがハードコードされています | uv sync --python 3.14 --extra dev |
pip show では見つからないが、uv run ではインストール済みと表示される | uv run の解決処理が venv の pip メタデータを回避しています | uv sync で両方の状態を一致させます |
ルール:リポジトリの名前変更、ディレクトリの移動、または Python のバージョン変更後は、何かを実行する前に必ず uv sync --python 3.14 --extra dev を実行してください。
実行後の振り返り
このスキルの完了後、終了する前に以下を確認してください。
- コマンドは成功しましたか? — 成功しなかった場合は、失敗の原因となった指示またはエラーテーブルを修正してください。
- パラメーターや出力に変更はありましたか? — 基盤となるツールのインターフェースに変更があった場合は、使用例とパラメーターテーブルを更新して実際の仕様に合わせてください。
- 回避策が必要でしたか? — 異なるフラグや追加手順などの工夫が必要だった場合は、次回同じ回避策が不要になるよう、この SKILL.md を更新してください。
問題が実際に発生し、再現可能な場合にのみ更新してください。推測に基づいて更新しないでください。