
ここまで来ると、記事1本を作る"部品"はほぼ揃いました。第5章では画像の自動取得を書きました。あとはこれを"自分がいなくても動き続ける状態"にする番です。今回は個々の仕組みの締めくくりとして、決まった時間にスクリプトを自動で起動する定期実行と、無人で動くからこそ必要になる安全装置の設計を、実運用ベースで書きます。「1コマンドで動く」の先にある「1コマンドを勝手に叩き続ける」の話です。
放っておいても記事が増える——定期実行の仕組み
bash run.sh を、自分の代わりに叩き続けてくれる仕組みが必要になります。MacやLinuxで昔から使われてきた定期実行の仕組みが「cron(クローン)」で、これを使えば「毎日9時と14時と18時に、このコマンドを実行して」といった指定ができます。
でも、私が採用したのは cron ではなく LaunchAgent というmacOS純正の仕組みでした。理由は単純で、macOSの新しめのバージョンでは cron からアクセスできる範囲が制限されていて、Keychain(macOSのパスワード管理機能)に保存された認証情報が読めないケースがあるからです。実際、cronで動かそうとしたところ、WordPress REST APIの認証が通らず 401 エラーで詰まる事象に何度も遭遇しました。
LaunchAgentは、Macの起動時に自動で読み込まれる「常駐プログラムの予定表」のようなもの。「このスクリプトを、毎日この時間に走らせて」という予定を1つの設定ファイル(plist)で宣言しておけば、macOSが責任を持ってその時間にコマンドを起動してくれます。cronより現代的で、macOSの権限モデルとも整合しているので詰まりが起きにくい。同じMacでブログ自動化を組む方には、今から始めるなら LaunchAgent 一択、というのが率直な感想です。
今の運用は、9時から19時まで2時間おきに run.sh を起動する設定です。ただし、run.sh の側でその日の実行本数を数えていて、上限(1日10本)に達したらそれ以降の起動はスキップします。スケジュールでは"呼びかける"が、実際に走らせるかどうかはスクリプト側で判断する、という二段構えにしてあります。
もう一つ大事なのは、Macがスリープしているあいだの起動は飛ぶようにしている点。夜間ずっとMacがスリープしていれば、その間の起動はまとめてキャンセルされ、朝の起動から再開します。「起きて動いているときだけ動く」というシンプルな運用にすることで、深夜にPCがうなり続けることも、電源を切って帰った日に大量に溜まった実行が朝いっぺんに走ることもありません。
自動化でいちばん怖いのは"暴走"——安全装置の設計
無人で動く仕組みには、必ず"歯止め"が要ります。人が見張っていない前提で動くので、ひとたび何かが暴走したら、朝起きたときにとんでもないことになっている可能性がある。「無人=制御を手放す」ではなく、「無人だからこそ歯止めを厚くする」——これが安全装置の設計思想です。
トリヴィペディアの run.sh には、いくつかの歯止めが仕込んであります。
- 1日の実行上限:その日に走った本数をファイルに記録しておき、決めた本数に達したらそれ以降の起動をスキップする。カレンダーが変わるとカウンタがリセットされる仕組み
- 二重起動を防ぐロック:起動時にロックファイルを作って自分のプロセスID(PID)を書き込み、別の実行が並行して立ち上がったら「先客がいるからスキップ」で終わらせる。処理が終わったらロックを消す。万一、前回の実行が異常終了してロックだけ残ってしまった場合は、PIDが生きているかを確認して古いロックなら自動で片付ける
- APIキーの暴走防止:第1章で書いた課金トラブルの安全装置——特定のAPIキーを
unsetしてからclaudeコマンドを叩く仕組みや、Anthropicコンソール側での月間支出上限。これも歯止めの一種として、ここに含まれます
並べると、どれも大したことのない工夫に見えます。実際、1つ1つは単純です。でも、ないと痛い。無人運用は、これらの歯止めが1枚ずつ効くことで、はじめて「放っておいても大丈夫」の状態になります。裏を返せば、"歯止めが1枚も無い自動化"は、無人運用に耐えません。動いているうちは幸せに見えても、いつか壊れます。
安全装置は"性善説で作らない"
安全装置を設計するときに、私がいちばん意識しているのは 「性善説で作らない」 ということです。
自分の書いたコードは、当然、正しく動くつもりで書いています。エージェントも、その時点でのルールに従って正しく動くつもりです。でも、実運用で分かったのは、「起きないと思っていたことが起きる」 ということでした。
思い返すと、この連載で書いてきた失敗は、どれも「そんなことが起きるとは思っていなかった」ものばかりです。Claude Codeなのに環境変数を1か所間違えただけで有料APIモードで課金が走った件。エージェントが「反映完了」と報告してきたのに実データを見に行ったら何もされていなかった件。修正版を再投稿したら同じ内容の下書きが2件できあがった件——どれも、動かす前は誰一人「そんな壊れ方するんだ」と分かっていませんでした。動かしてはじめて、それぞれの壊れ方に頭を殴られた形です。
だから安全装置は、"起きたら困ることが起きる前提で" かけるようにしています。1日の実行上限は「暴走で無限に走ってしまう」前提で、ロックは「異常終了でロックファイルが残る」前提で、APIキーの unset は「うっかり.envを全部読み込む」前提で、それぞれ組んであります。先に想定するのは"正常系"ではなく"最悪の壊れ方"。安全装置の設計は、ここが逆になっていると効きません。
これは、AIブログ自動化に限らず、無人で走る仕組みを組むすべての人に持ち帰ってほしい感覚です。「うちのシステムは大丈夫」という性善説で組むと、いつか必ず、想定していなかった壊れ方に頭を殴られます。自動化を組むということは、正常系ではなく、異常系を設計するということ。無人運用の背骨は、実はここにあります。
まとめ
「1コマンドで動く」の先にある「1コマンドを勝手に叩き続ける」を実現するには、定期実行の仕組みと、暴走を防ぐ安全装置の両方が要ります。片方だけでは、放置運用にはなりません。連載を通していちばん学んだのは、うまく動くことを願うのではなく、壊れ方を先に想定して全てに歯止めを用意しておく——自動化は、正常系ではなく異常系を設計する仕事だ、ということでした。
次章(第7章)では、視点を切り替えます。放置で動くようになった記事が、実際に読まれているかを見て、育てていく話。Google Search ConsoleとGA4のデータから、伸びる記事とそうでない記事を見分けて、リライトで改善していく仕組みを扱います。「作った後」の話です。
なお、この章で触れた run.sh の実ファイル・LaunchAgentの設定内容・ロック実装や1日の上限管理の実コード・具体的な設定値については、シリーズがひととおり出そろったところで、まとめて別途公開する予定です。動く形で手元に置きたい方は、その段になったらまた見に来てください。












