背景
私は個人でいくつかのセール情報サイトを回していて、更新は1日2回、自動で走らせています。
その自動更新が、あるとき3日連続で「今日は更新なし」を返したことがありました。
原因はあとから分かって、Amazonが取得元としてbot対策で弾いていた、という話でした。
でも当時いちばん困ったのは、原因ではなくて どこにも記録が残っていなかった ことです。
ログには「実在するセールを確認できませんでした」の一行だけ。
何を試したのか、なぜ駄目だったのか、次に何をすればいいのかが、まったく残っていませんでした。
翌日も同じ理由で落ちて、その翌日も落ちました。
当たり前で、直す材料がどこにもないので…
決めたこと
「一次情報が取れなかったので今日は更新なし」を、仕様として認めないことにしました。
ここで大事なのは、捏造しないことと、更新を止めることは別の話 だという点です。
価格が確認できないなら価格を書かなければいい。
書かない理由が、サイトを更新しない理由になってはいけない。
そこで、取れなかった回には必ず次の3つを踏むルールにしました。
- 診断を残す(試したURL・クエリ・HTTPステータスまで)
- 打開案を出す(次回そのサイトを更新可能にする具体案を1つ以上)
- 代替の記事を1本出す(価格に依存しない題材のストックから消化する)
手順書に書くだけでは実行されなかった
最初はこれを手順書に書きました。
結果、実行されませんでした。
読む側(このケースだとLLMのエージェント)にとって、3つ別々の作業に見えるからです。
1つ目をやって満足して、2つ目を忘れる。
そもそも面倒なときは、まるごと飛ばして「更新なし」と書く。
なので、1コマンドで3つとも残るようにしました。
node automation/run.js no-update-report \
--site coffee \
--reason "日本のEC価格を検証できず(検索APIがUS-onlyで現在価格を返さない)" \
--tried '["WebSearch:コーヒー豆 セール 2026-07 -> 日本の現在価格は出ない","WebFetch:https://example.jp/... -> 403"]' \
--proposal "価格比較サイトの検索結果を直接読めるか実測し、可否を調査手順書に記録する" \
--fallback "evergreen: guide-xxx を1本追加した"
これを叩くと、その日のログに「更新不可→代替出力」の節が追記され、残課題リストに打開案が起票されます。
同じ理由の再発は二重起票せず、優先度を上げて発生日を積む作りにしました。
肝は --reason と --proposal が無い呼び出しを exit 2 で落とす ようにしたことです。
「診断を書いたことにして通す」ができない。
面倒を回避する経路を塞ぐのが、この手のルールでは一番効きました。
代替の記事はどこから出すのか
3つ目の「必ず1本出す」を成立させるには、書ける題材のストックが要ります。
サイトごとにキュー(JSON)を持たせて、価格に依存しない題材を並べてあります。
node automation/run.js evergreen:next --site coffee
# -> { "picked": [{ "id": "scale-yuon", "title": "スケールと湯温を使うと何が安定するか" }],
# "remaining": 13 }
今日も実際、5サイトすべてでAmazonのセール期間外(次の大型セールは8月末)でした。
なので5サイトとも、このキューから1本ずつ書いて出しています。
たとえばコーヒーのサイトなら「スケールと温度計は何を固定する道具なのか」という記事です。
https://coffee.autoarticles.net
キューが空なら exit 3 で落ちます。
黙って「題材なし」を返して0件終了に戻らないため、これも意図的にそうしました。
残り5本を切ったら補充のissueが立ちます。
結論
自動化が失敗したとき、人間の反省に任せると同じ理由で毎日落ちます。
落ちた事実を「次回の入力」に変換する経路を、コマンド1つで強制するところまで作って、ようやく止まりました。
仕組みに落ちていない運用ルールは、実行されないものとして設計したほうがいいです。
本記事はAI補助で執筆した、個人開発の紹介記事です。