目次
- はじめに:16記事公開するまでに、10回壊れた話
- 失敗 #1:カテゴリ未作成で投稿が「未分類」に入った
- 症状
- 原因
- 解決
- 次にどう変えたか
- 失敗 #2:.env のキー名が違うだけで認証が通らない
- 症状
- 原因
- 解決
- 次にどう変えたか
- 失敗 #3:公開記事に制作メモが混入した(2026-04-21 品質事故)
- 症状
- 原因
- 解決
- 次にどう変えたか
- 失敗 #4:SEO Simple Pack が REST API 経由のメタ設定を受け付けない
- 症状
- 原因
- 解決
- 次にどう変えたか
- 失敗 #5:status: future でタイムゾーンが噛み合わず、記事が公開されない
- 症状
- 原因
- 解決
- 次にどう変えたか
- 失敗 #6:frontmatter の YAML リスト形式ミスで parse が壊れる
- 症状
- 原因
- 解決
- 次にどう変えたか
- 失敗 #7:アイキャッチ生成で gpt-image-2 が拒否応答を返す
- 症状
- 原因
- 解決
- 次にどう変えたか
- 失敗 #8:自動化の暴走 — Claude Code が同じスクリプトを何度も書き直す
- 症状
- 原因
- 解決
- 次にどう変えたか
- 失敗 #9:API レート制限に引っかかって月末に作業が止まる
- 症状
- 原因
- 解決
- 次にどう変えたか
- 失敗 #10:「自動化できた」と思ったら、手動の方が速かった作業があった
- 症状
- 原因
- 解決
- 次にどう変えたか
- 10回壊れてわかったこと:失敗前提の仕組みを作る
- この記事を読んで自動化を始めたい人へ
はじめに:16記事公開するまでに、10回壊れた話
AIでブログ運営を自動化する5ステップでは、Claude Codeでブログ自動化を仕組み化した全体像をまとめました。
でも正直に言うと、あの記事には書けていないことがあります。16記事を公開するまでの間に、少なくとも10回は壊れたということです。
スクリプトがエラーを吐いて止まる。記事が意図しないカテゴリに入る。公開済み記事に制作メモが混入する。APIの制限に引っかかって月末に作業が止まる。
うまくいった話だけ書いても半分しか伝わらないと思ったので、失敗を全部まとめることにしました。
この記事では、10の失敗事例をそれぞれ「症状 → 原因 → 解決 → 次にどう変えたか」の流れで書いています。実際のエラーメッセージや解決コマンドも載せているので、同じ壁にぶつかったときにそのまま使ってもらえるはずです。
壊れたけど全部直せました。これを読んでいる人も、同じように直せると思います。
失敗 #1:カテゴリ未作成で投稿が「未分類」に入った
日付:2026-05-07
症状
publish_post.py を実行して記事を投稿したら、frontmatter で指定していた「ブログ自動化」ではなく「未分類」カテゴリに入っていた。
4/7 カテゴリ・タグを解決します...
❌ カテゴリ 'WordPress効率化' が WordPress に存在しません。
既存のカテゴリ/タグ名と一致していることを確認するか、
--allow-new-categories を付けて明示的に新規作成してください。
2回目に試したときは上のエラーで止まったが、1回目は別のカテゴリで --allow-new-categories なしで実行していたため、エラーなしで「未分類」に格納された。
原因
WordPress の REST API は、frontmatter に指定したカテゴリ名が存在しない場合、エラーを返さずデフォルトカテゴリ(未分類)にフォールバックします。publish_post.py の初期バージョンはこの挙動をそのまま通過させていました。
もう一つの原因は「ドメイン変更後にカテゴリを作り直していなかった」こと。halolab.com から halolab.jp に切り替えたタイミングで WordPress を再インストールしたため、以前作成していたカテゴリが消えていました。
解決
手順 1:WordPress 管理画面でカテゴリを先に作成する
管理画面 → 投稿 → カテゴリー → 新規カテゴリーを追加
または WP-CLI で一括作成する場合:
/usr/bin/php8.3 /usr/bin/wp term create category "ブログ自動化" \
--slug=blog-automation \
--path=/home/USER/halolab.jp/public_html
手順 2:publish_post.py にカテゴリ存在チェックを追加
現バージョンでは allow_create=False がデフォルトになっており、存在しないカテゴリ名はエラーで止まります。新規カテゴリを作りたいときのみ --allow-new-categories を明示します。
# 既存カテゴリへの投稿(デフォルト)
python blog-automation/scripts/publish_post.py articles/drafts/{slug}/
# 新規カテゴリを作成して投稿(明示的に許可)
python blog-automation/scripts/publish_post.py articles/drafts/{slug}/ --allow-new-categories
次にどう変えたか
記事フォルダを作る前に「WordPress 側にカテゴリが存在するか」を確認するステップを作業手順に追加しました。また、CLAUDE.md の「カテゴリ作成責任」セクションに「新カテゴリが必要な場合は WP-CLI または管理画面で先に作成してから publish_post.py を実行する」と明記しました。
失敗 #2:.env のキー名が違うだけで認証が通らない
日付:2026-05-06
症状
publish_post.py を初めて実行したとき、401 エラーが返ってきて投稿できなかった。パスワードは正しいはずなのに。
7/7 WordPress に公開投稿します...
公開に失敗しました。
{'code': 'rest_cannot_create', 'message': 'Sorry, you are not allowed to create posts as this user.', 'data': {'status': 401}}
原因
.env ファイルのキー名が、スクリプトが参照するキー名と一致していなかった。
実際に起きた不一致のパターン:
# .env に書いていた(古いテンプレートベース)
HALOLAB_WP_URL=https://halolab.jp
HALOLAB_WP_USER=admin
HALOLAB_WP_PASS=xxxx xxxx xxxx
# publish_post.py が参照するキー名
WP_BASE_URL=https://halolab.jp
WP_USERNAME=admin
WP_APP_PASSWORD=xxxx xxxx xxxx
os.getenv("WP_BASE_URL") が None を返しても、エラーメッセージが「キーが見つからない」ではなく「認証失敗」で出てくるため、原因の特定に時間がかかりました。
解決
手順 1:.env のキー名を publish_post.py の参照名と突合する
# publish_post.py が参照する3つのキー
base_url = os.getenv("WP_BASE_URL") # ← これと一致しているか
username = os.getenv("WP_USERNAME") # ← これと一致しているか
app_password = os.getenv("WP_APP_PASSWORD") # ← これと一致しているか
手順 2:.env.example を作って正しいキー名を明示する
# .env.example(値は空・キー名のみ記載)
WP_BASE_URL=https://your-site.com
WP_USERNAME=your-wp-username
WP_APP_PASSWORD=xxxx xxxx xxxx xxxx xxxx xxxx
WP_SEO_PLUGIN=seopress
OPENAI_API_KEY=sk-...
手順 3:デバッグ用の確認コマンド
# .env のキーと値(値は伏せ字)を確認する
python -c "
from dotenv import load_dotenv
import os
load_dotenv('.env')
for k in ['WP_BASE_URL','WP_USERNAME','WP_APP_PASSWORD']:
v = os.getenv(k)
print(k, '=', v[:4]+'...' if v else '未設定')
"
次にどう変えたか
publish_post.py の .env 読み込み部分を「キーが存在しない場合は具体的なキー名を含めてエラーを出す」仕様にしました。「不足があります: WP_BASE_URL, WP_USERNAME」のようにキー名が明示されるため、設定ミスをすぐに特定できます。
失敗 #3:公開記事に制作メモが混入した(2026-04-21 品質事故)
日付:2026-04-21
症状
公開済み記事のHTML内に、品質審査のコメントや内部メモが残っていた。
## 自己チェック結果
### 読者が「自分も同じ」と思えるか → ◯(看護師あるある多め)
### 読者が「少し楽になる」か → △(まとめが教訓寄り・要修正)
...
上のような内容がそのまま記事本文に表示されていた。公開後2時間で気づいて修正しましたが、Googleにクロールされる前に対処できたのは運が良かっただけです。
原因
当時の 04_draft_v{N}.md には、記事本文とメタ情報案・自己チェック結果が同じファイルに混在していました。publish_post.py は frontmatter 以降のテキストをすべて本文として読み込むため、セパレータなしに記事本文と審査コメントが連続していると区別できません。
自動完走モードで「品質審査 → 公開」が連鎖したとき、審査コメントの除去が必要なことを誰も(どのエージェントも)確認していませんでした。
解決
手順 1:記事本文と制作メモを物理的に別ファイルに分離する
04_draft_v{N}.md ← 記事本文のみ(frontmatter + 本文)
04_meta_v{N}.md ← メタ情報案・タイトル候補・自己チェック(公開対象外)
手順 2:parse_post.py に制作メモ検知バリデーションを追加する
現バージョンでは、本文に制作メモキーワードが含まれている場合、エラーで投稿を止めます。
❌ 本文に制作メモが混入しています:
- [自己チェック] ## 自己チェック結果...
公開を中止しました。制作メモを本文から削除してください。
意図的に含める場合(記事の主題が品質審査の話など)は --allow-meta-keywords で通過できます。
python blog-automation/scripts/publish_post.py articles/drafts/{slug}/ --allow-meta-keywords
手順 3:Claude Code への指示文に「本文ファイルにメタ情報を書かない」を明記する
# CLAUDE.md の記事ライターへの指示(抜粋)
記事ライターは以下のファイルを作成する:
- 04_draft_v{N}.md : frontmatter(7項目)+ 記事本文のみ
- 04_meta_v{N}.md : タイトル案・自己チェック・品質審査前確認(公開対象外)
04_draft_v{N}.md の末尾に「自己チェック」「タイトル案」「メタ情報案」等の
見出しやセクションを書くことを禁止する。
次にどう変えたか
この事故を起点に、ファイル分離とバリデーションの仕組みが整備されました。現在は publish_post.py が実行時に本文を走査し、制作メモが混入していれば公開前に止まります。2026-04-21 以降、同じ事故は一度も起きていません。
失敗 #4:SEO Simple Pack が REST API 経由のメタ設定を受け付けない
日付:2026-05-06〜07
症状
frontmatter に seo_title と seo_description を書いて投稿したのに、公開後に Google 検索プレビューで反映されていない。publish_post.py の実行ログには「SEOタイトル反映済み」と表示されているのに。
6/7 SEOメタ情報を準備します...
SEOタイトル: Claude Codeブログ自動化の始め方|非エンジニアの実例
SEO説明文 : 現役看護師がClaude Codeで16記事...
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✅ 公開が完了しました
SEO : ⚠️ 手動設定が必要
「SEO : 手動設定が必要」と出ているのに、「反映済み」と同じように読んでしまっていた。
原因
halolab.jp で使っている SEO Simple Pack は、WordPress REST API 経由でのカスタムフィールド書き込みに標準対応していません。wp-json/wp/v2/posts に meta フィールドで _seopress_titles_title を送っても、SEO Simple Pack 側のメタ登録(register_post_meta)がなければ保存されない仕様です。
ryman-nurse.com では別のSEOプラグイン(SEOPress)を使っており、Code Snippets による register_post_meta 設定が入っていたため自動反映できていました。halolab.jp で SEO Simple Pack を採用した際に、この設定が必要だと気づいていませんでした。
詳しい REST API 周りのつまずきは WordPress REST API 自動投稿でつまずいた10件 にまとめています。
解決
手順 1:SEO Simple Pack が REST API 対応プラグインかを事前確認する
SEO Simple Pack は公式 REST API エンドポイントを提供していません。回避策として WP-CLI 経由でポストメタを直接書き込みます。
# WP-CLI でSEOタイトル・メタディスクリプションを設定する
/usr/bin/php8.3 /usr/bin/wp post meta update {POST_ID} \
"_ssp_meta_title" "SEOタイトルをここに" \
--path=/home/USER/halolab.jp/public_html
/usr/bin/php8.3 /usr/bin/wp post meta update {POST_ID} \
"_ssp_meta_description" "メタディスクリプションをここに" \
--path=/home/USER/halolab.jp/public_html
手順 2:publish_post.py の .env で SEO プラグイン種別を指定する
# .env
WP_SEO_PLUGIN=seo-simple-pack # または seopress / yoast / rankmath / none
手順 3:自動反映が難しい場合は手動設定ガイドを出力する
publish_post.py は SEO 反映確認で失敗した場合、管理画面 URL と設定値を出力します。
┌─────────────────────────────────────────┐
│ 📋 SEO Simple Pack 手動入力ガイド
└─────────────────────────────────────────┘
編集画面を開く: https://halolab.jp/wp-admin/post.php?post=43&action=edit
SEO Simple Pack の「SEOタイトル」に以下をコピー:
▶ Claude Codeブログ自動化の始め方|非エンジニアの実例
SEO Simple Pack の「メタディスクリプション」に以下をコピー:
▶ 現役看護師がClaude Codeで16記事を...
─────────────────────────────────────────────
次にどう変えたか
「SEO プラグインの REST API 対応状況を新サイト立ち上げ時に確認する」を設計チェックリストに追加しました。新サイトでは SEOPress を使うか、WP-CLI 経由の設定スクリプトを最初から組み込む方針にしています。
失敗 #5:status: future でタイムゾーンが噛み合わず、記事が公開されない
日付:2026-05-07
症状
frontmatter に status: future と翌日の date を書いて投稿したが、指定した時刻を過ぎても記事が公開されなかった。管理画面を確認すると「予約投稿」のままで止まっていた。
逆のパターンも起きました。status: publish で投稿したのに、記事が「予約投稿」ステータスになっていた。
7/7 WordPress に公開投稿します...
✅ 公開が完了しました
投稿ID : 45
投稿URL : https://halolab.jp/?p=45
投稿は成功しているのに、管理画面では「予約投稿」。
原因
publish_post.py が date フィールドを処理するとき、タイムゾーン変換に問題がありました。
# 問題があった変換(publish_post.py 内)
if len(post_date) == 10:
post_date = post_date + "T10:00:00"
payload["date"] = post_date # JST(UTC+9)の時刻を送信
payload["date_gmt"] = post_date.replace("T10:00:00", "T01:00:00") # UTC に変換
WordPress はサーバー側のタイムゾーン設定(UTC+9)と REST API で受け取る date フィールドの整合性で日付を判断します。frontmatter の日付を「今日」の日付で書いても、UTC 変換後に「昨日の夜9時」になってしまうと、WordPress が「過去の日付 = 既に公開予定時刻を過ぎた = 予約失敗」と判断して下書きに戻すことがありました。
詳細は WordPress REST API 自動投稿でつまずいた10件 の「タイムゾーン問題」セクションに解説があります。
解決
手順 1:日付にタイムゾーン情報を明示する
# frontmatter
date: "2026-05-07T10:00:00+09:00"
ISO 8601 形式でタイムゾーン(+09:00)を付けると、WordPress が正確に処理します。
手順 2:publish_post.py の date 処理を修正する
# 修正後の変換
from datetime import datetime, timezone, timedelta
JST = timezone(timedelta(hours=9))
if "T" not in post_date:
# 日付のみの場合、JST の午前10時として扱う
dt = datetime.strptime(post_date, "%Y-%m-%d").replace(tzinfo=JST)
post_date = dt.strftime("%Y-%m-%dT%H:%M:%S")
payload["date"] = post_date
# date_gmt は送らない(WordPress が date から自動計算する)
手順 3:投稿直後にステータスを確認する
/usr/bin/php8.3 /usr/bin/wp post get {POST_ID} \
--fields=ID,post_status,post_date,post_date_gmt \
--path=/home/USER/halolab.jp/public_html
次にどう変えたか
frontmatter の date フィールドは常にタイムゾーン付きの ISO 8601 形式で書くルールにしました。日付だけ書く場合は publish_post.py 側でタイムゾーン処理を行うよう修正しています。
失敗 #6:frontmatter の YAML リスト形式ミスで parse が壊れる
日付:2026-05-06〜07
症状
publish_post.py がカテゴリを解決できず、意図しないカテゴリに入ったり None を返したりした。
4/7 カテゴリ・タグを解決します...
カテゴリID: [] ← 空のリストが返ってきた
タグID: []
frontmatter には正しくカテゴリ名を書いていたのに。
原因
YAML のリスト記法が混在していた。
# NG パターン 1:文字列として書いてしまった
categories: ブログ自動化
# NG パターン 2:インラインリスト([] 形式)
categories: [ブログ自動化]
# NG パターン 3:スペースの有無が混在
categories:
- ブログ自動化 ← インデントなし
# OK パターン(publish_post.py が期待する形式)
categories:
- ブログ自動化
tags:
- Claude Code
- ブログ自動化
parse_post.py の frontmatter パーサは PyYAML を使っており、パターン 2 のインライン形式は Python のリストとして正しく読まれます。ただし、パターン 1(文字列)は ensure_list() で ["ブログ自動化"] に変換されるため、一見動いているように見えても WordPress 側でカテゴリ名の完全一致検索に失敗するケースがありました。
Claude CodeでWordPress自動投稿を完全解説 の「frontmatter バリデーション」セクションにも詳しく書いています。
解決
手順 1:frontmatter のリスト形式を統一する
---
title: "記事タイトル"
slug: article-slug
categories:
- ブログ自動化
tags:
- Claude Code
- WordPress REST API
---
categories と tags は必ずインデント付きの - item 形式。インライン形式([item1, item2])は使わない。
手順 2:バリデーションスクリプトで確認する
python -c "
import yaml
with open('articles/drafts/{slug}/04_draft_v1.md') as f:
content = f.read()
fm = content.split('---')[1]
data = yaml.safe_load(fm)
print('categories:', type(data.get('categories')), data.get('categories'))
print('tags:', type(data.get('tags')), data.get('tags'))
"
list 型が返ればOK。str 型や None が返ったら修正が必要です。
手順 3:Claude Code への指示文に形式を明示する
# CLAUDE.md の記事ライターへの指示(frontmatter サンプル)
categories と tags は必ず以下の YAML リスト形式で書く。
インライン形式([item1, item2])や文字列(categories: ブログ自動化)は使わない。
categories:
- ブログ自動化
tags:
- Claude Code
- ブログ自動化
次にどう変えたか
parse_post.py に frontmatter のバリデーションを追加し、categories と tags がリスト型以外だった場合に具体的なフィールド名とサンプルを出力して止まるようにしました。
失敗 #7:アイキャッチ生成で gpt-image-2 が拒否応答を返す
日付:複数回・2026年4〜5月
症状
generate_eyecatch.py を実行したら、コンテンツポリシー違反でエラー終了した。
画像生成を実行します...
エラー: openai.BadRequestError: 400 Bad Request
{
"error": {
"code": "content_policy_violation",
"message": "Your request was rejected as a result of our safety system.",
"type": "invalid_request_error"
}
}
ryman-nurse.com のアイキャッチを生成しようとしたとき、2回連続で拒否されました。
原因
プロンプトに医療・患者・病棟に関連する具体的な表現が含まれていたことで、gpt-image-2 のコンテンツフィルタに引っかかりました。
# 拒否されたプロンプト(抜粋)
...ナースステーションで患者対応をする看護師...病棟の廊下...
ベッドサイドで患者と話している場面...
「患者」「病棟」「ベッドサイド」の組み合わせが医療行為・患者情報に関わるコンテンツとみなされた可能性があります。
解決
手順 1:医療固有の表現を抽象化する
# 変更前(拒否された)
→ 病棟の廊下で患者対応をする看護師
# 変更後(通過した)
→ 明るい建物の廊下で書類を確認している女性
→ オフィスの一角でノートパソコンに向かっている人物
「患者」→「人物」、「病棟」→「建物・施設」、「看護師の制服」→「業務着」のように医療コンテキストを薄めると通過率が上がりました。
手順 2:リトライ上限を設ける
# generate_eyecatch.py の拒否対応(擬似コード)
MAX_RETRY = 3
for attempt in range(1, MAX_RETRY + 1):
try:
response = client.images.generate(
model="gpt-image-2",
prompt=prompt,
size="1536x1024",
quality="high",
)
return response # 成功
except openai.BadRequestError as e:
if "content_policy_violation" in str(e) and attempt < MAX_RETRY:
prompt = soften_medical_terms(prompt) # 表現を抽象化
print(f" 拒否 → プロンプトを修正して再試行 ({attempt}/{MAX_RETRY})")
else:
raise # 3回とも失敗したらエラーを上げる
手順 3:アイキャッチ仕様書にプロンプト禁止ワードを列挙する
# 06_eyecatch_spec.md の禁止事項
以下の表現は gpt-image-2 で拒否されやすい。抽象化した表現に置き換えること。
- 患者 → 人物・来訪者
- 病棟 → 建物・施設・廊下
- ベッドサイド → 部屋・場所
- 手術 → 作業・処置(極力避ける)
- 血液・傷 → 描写しない
次にどう変えたか
アイキャッチ仕様書のテンプレートに「拒否されやすい表現の置き換えリスト」を追加しました。生成前のプロンプトチェックも自動化の候補として検討しています。
失敗 #8:自動化の暴走 — Claude Code が同じスクリプトを何度も書き直す
日付:2026年4〜5月(複数回)
症状
「publish_post.py に新機能を追加して」と Claude Code に頼んだとき、既存の機能が消えて退行する現象が繰り返し起きた。
具体的には:
- アイキャッチアップロード機能を追加したら、カテゴリ解決のロジックが削除されていた
- SEO メタ送信機能を追加したら、
done/フォルダへのファイル移動処理が消えていた - 修正を戻そうとしたら、さらに別の箇所が消えた
会話が長くなるほど、以前の修正内容を Claude Code が「覚えていない」状態になっていました。
原因
2つの原因が重なっていました。
原因 1:CLAUDE.md に「既存コードを壊さない」ルールがなかった
Claude Code はコンテキストが長くなると、前のターンで追加した機能の意図を引き継げなくなります。「改善してほしい」という指示を受けると、コンテキスト内にある最新の状態を「完全なファイル」として書き直すことがあります。
原因 2:Git でバージョン管理していなかった
退行が起きても「1つ前の状態に戻す」手段がなかったため、どこで壊れたかの特定に時間がかかりました。
解決
手順 1:CLAUDE.md に差分修正ルールを追加する
# CLAUDE.md(ai-blog-automation-lab)に追加したルール
## スクリプト修正のルール
既存スクリプト(publish_post.py / parse_post.py / generate_eyecatch.py 等)を
修正する場合は必ず差分修正にすること。
禁止:ファイル全体の書き直し
必須:変更する関数・ブロックのみ修正
修正前に対象ファイルを必ず Read ツールで読み込み、
既存の機能リストを確認してから差分を追加する。
手順 2:Claude Code への指示文に「保持する機能リスト」を含める
# Claude Code への指示文サンプル
publish_post.py に「投稿後の自動検査」機能を追加してください。
以下の既存機能は絶対に削除・変更しないこと:
- upload_media()(アイキャッチアップロード)
- resolve_term_ids()(カテゴリ・タグ解決)
- check_production_meta_contamination()(制作メモ検知)
- done/ フォルダへのファイル移動処理
追加する機能の仕様:
...
手順 3:Git で修正ごとにコミットする
git add blog-automation/scripts/publish_post.py
git commit -m "feat: publish_post.py に投稿後自動検査を追加"
退行が起きたら git diff HEAD~1 で変更内容を確認し、git checkout HEAD~1 -- path/to/file で1つ前に戻せます。
次にどう変えたか
スクリプトへの新機能追加は「必ず差分修正、全書き直し禁止」をCLAUDE.md に明記しました。また、主要スクリプトを Git で管理するようになり、退行が起きても5分以内で元の状態に戻せるようになりました。
失敗 #9:API レート制限に引っかかって月末に作業が止まる
日付:2026年4月末〜5月初
症状
Claude Code の Max プランを使っていたが、月末にレート制限がかかって作業が中断した。「使用量が上限に達しました」のメッセージが出て、しばらく応答が返ってこなくなる状態が断続的に続いた。
原因
自動完走モードで記事の生成パイプラインを連鎖させると、トークン消費が想定以上に膨れます。
1本の記事を自動完走で処理する場合の概算トークン消費:
| 工程 | 入力 | 出力 | 概算トークン |
|---|---|---|---|
| 競合分析 | WebSearch結果(10サイト) | 分析レポート | 30,000〜50,000 |
| 構成設計 | 競合分析 + キーワード | 構成案 | 15,000〜25,000 |
| 記事執筆 | 構成案 + 体験素材 | 8,000字記事 | 30,000〜50,000 |
| 品質審査 | 記事本文 | 審査レポート | 20,000〜30,000 |
| 修正・再審査 | 記事本文v2 + 審査指摘 | v2記事 + 再審査 | 30,000〜50,000 |
| 合計(1本) | 125,000〜205,000 |
Max 20x プランの月間上限は非公開ですが、月25本ペースで記事を量産しようとすると月末に制限に当たりやすくなります。
解決
手順 1:1日あたりの自動完走記事数に上限を設ける
# CLAUDE.md(運用ルール)
自動完走モードは1セッションあたり最大2本まで。
月末5日間(26〜31日)は自動完走モードを使わず、
構成設計・記事執筆・審査を1工程ずつ手動確認で進める。
手順 2:品質審査の繰り返しを効率化する
差し戻しが1回で済むように、初稿の品質を上げることが最もトークン消費を抑えます。
# 構成案の充実度を上げることで差し戻しを減らす
# 体験素材が少ない状態で執筆を始めない
# 指示文に「ハウツー具体性6項目」の遵守を明示する
手順 3:Pro → Max の乗り換え基準を持つ
Pro プランは1日あたりの上限が比較的低く、ブログ自動化のパイプラインでは月10日前後で制限に当たります。記事量産フェーズに入るならMax プランへの移行が実質的に必要です。費用の目安と乗り換えタイミングについては Claude Code の料金とプラン選び方 で詳しく書いています。
次にどう変えたか
月初に「今月の記事本数目標 × 1本あたりのトークン概算 = 月間消費見込み」を計算して、月末にバッファを残す本数配分を決めるようにしました。月末は自動完走を止めて、手動確認モードに切り替えています。
失敗 #10:「自動化できた」と思ったら、手動の方が速かった作業があった
日付:2026年4〜5月
症状
X 投稿の自動生成を仕組み化したが、生成 → 確認 → 修正のサイクルが、手動で書くより時間がかかっていた。
generate_x_posts.py で3〜5パターンの投稿案を生成し、そのうちの1つを選んで微調整して投稿する、という流れでした。スクリプト実行時間は1分以内でも、「どれを使うか選ぶ」「微調整する」「口調を合わせる」の手間がじわじわと積み重なっていました。
原因
「自動化できる ≠ 自動化すべき」を検証していなかった。
X 投稿は文字数が少なく(140字)、書き手の口調や旬のネタを反映させたい度合いが高い作業です。記事公開の直後に書けば、記事の内容が頭に入った状態で5〜10分で書けます。
一方、自動生成案の確認・修正には「生成された文章を読んで評価する」認知コストがかかります。短い文章を評価する方が、ゼロから書くより時間がかかることがあります。
解決
手順 1:各作業の「手動時間 vs 自動化後の時間(初期構築含む)」を比較する
| 作業 | 手動時間 | 自動化構築時間 | 自動化後の時間 | ROI |
|---|---|---|---|---|
| 記事投稿(WP公開) | 15〜20分 | 8時間 | 2〜3分 | 高 |
| アイキャッチ生成 | 30分 | 3時間 | 5分 | 高 |
| X 投稿 | 5〜10分 | 3時間 | 5〜8分(確認・修正含む) | 低 |
| カテゴリ・タグ設定 | 2分 | 1時間 | 0分(自動) | 高 |
手順 2:ROI が低い作業は手動に戻す
X 投稿の自動生成は「ひな形の生成補助」として使い、最終的な文面は手動で書くことにしました。スクリプトは参考案を出すだけで、投稿自体は手動確認後に実行します。
手順 3:自動化の判断基準を明文化する
# CLAUDE.md(自動化の判断基準)
## 自動化すべき作業の条件
1. 繰り返し頻度が高い(月5回以上)
2. 手順が定型で、判断の余地が少ない
3. 初期構築コスト < 1年分の節約時間
## 自動化しない方が良い作業の条件
1. 書き手の個性・旬の情報が必要
2. 作業時間が短い(10分以内)で確認コストが生成時間を超える
3. 自動生成結果のレビューが毎回必要
次にどう変えたか
「自動化できるか」ではなく「自動化した方が速くなるか」で判断するようになりました。今は記事投稿・アイキャッチ生成・インデックス申請は自動化し、X 投稿・記事タイトルの最終判断・カテゴリの新規追加は手動で行っています。
10回壊れてわかったこと:失敗前提の仕組みを作る
10回の失敗をまとめてみると、共通するパターンがあります。「壊れたとき、止まれなかった」ということです。
エラーが出ても投稿が続いて「未分類」に入る。審査コメントが本文に混入したまま公開される。スクリプトが書き直されて機能が消える。どれも「壊れたら止まる」仕組みがなかったから、問題が表に出るまでに時間がかかりました。
今の仕組みで変えたのは4点です。
ファイル分離(失敗 #3 より):本文ファイルと審査・メタ情報ファイルを物理的に別にする。publish_post.py は本文ファイルしか読まないので、混入しようがない構造にする。
バリデーションで止める(失敗 #1, #3, #6 より):カテゴリが存在しない、制作メモが混入している、YAML 形式が壊れている、どれも「止まって教えてくれる」仕組みにする。問題を黙って通過させない。
CLAUDE.md のルール追記(失敗 #8 より):同じ失敗が繰り返されるとき、人(またはエージェント)に覚えさせるのではなく、ルールとして書き込む。「全書き直し禁止」のように具体的に書かないと、次のセッションで忘れられます。
リトライ上限と人手へのエスカレーション(失敗 #7, #9 より):失敗したとき、無限に続けない。3回失敗したら止まって報告する。自動化が「暴走」しないための蓋です。
完璧に壊れない仕組みを作ろうとすると、最初から始められません。壊れても直せる仕組みを育てていく方が、実際には速く前に進めます。
この記事で紹介した解決策は、すべて「一度壊れてから直した」結果です。自動化は最初から完成していなくていい、という一例として読んでもらえると幸いです。
この記事を読んで自動化を始めたい人へ
ブログ自動化の全体像は AIでブログ運営を自動化する5ステップ にまとめています。
WordPress 自動投稿の詳しい実装手順は Claude CodeでWordPress自動投稿を完全解説 で扱っています。失敗 #1・#2・#4 で紹介したエラーの対処も含まれています。
REST API 周りのつまずき集は WordPress REST API 自動投稿でつまずいた10件 でまとめています。
AI で書いた記事が薄くなりがちな問題については、AIブログで差別化するための考え方 が参考になります。失敗 #3 の品質事故との関連が深い記事です。
実際のコードと失敗対応の詳細記録は note の有料記事で公開しています(500円)。
自動化を始めようとしている方も、すでに何かで詰まっている方も、同じような壁にぶつかっている人はきっと他にもいます。一緒に試行錯誤していきましょう。
