Claude API×GitHub Actionsでブログを完全自動化する構成【実装まとめ】
ブログ更新にかかる時間を「月30分以下」にできます。「続けたいのに時間がない」——そのジレンマを解消するために、Claude API × GitHub Actions × はてなブログ AtomPub APIを組み合わせたブログ自動化の完成形を公開します。3ヶ月間実際に動かした構成なので、机上の空論ではありません。
このシリーズは「ブログ自動化をゼロから完成まで持っていく」ことを目的にしています。このシリーズを追ってきた方も、初めて読む方も、「完成形の設計図」として使える内容にまとめました。
このシリーズでできるようになったこと
このシリーズを完走すると、次の状態が手に入ります。
① 記事を書く(Markdown) ② GitHubにpush ③ 自動でブログに投稿される
「書くだけで資産が積み上がる状態」の完成です。
投稿操作、コピペ、フォーマット確認——そういった作業はすべてなくなります。あなたがやることは「何を書くかを決めて、内容を確認する」だけです。
この仕組みは「ブログを書く」ためではなく、「ブログを運用する」ための仕組みです。一度作ると、「投稿作業」という概念自体が消えます。
投稿作業を自動化すると、「ブログを書く」以外の作業がすべて消えます。
Before / After:自動化で何が変わるか
まとめ記事なので、最初に結論を出します。
Before:記事を書く → コピペ → 投稿 → 内部リンク確認 → 修正 → また投稿 After :記事を書く → pushするだけ
数字で見るとこうなります。
| Before(手動) | After(自動化) | |
|---|---|---|
| 記事を書いたあとの作業 | コピペ → 投稿 → 内部リンク確認 → 修正 | pushするだけ |
| 1記事あたりの時間 | 2〜3時間 | 30分以下 |
| 更新頻度 | 月1〜2本(不定期) | 月6〜8本(安定) |
| 品質のムラ | その日のコンディション次第 | polish.pyで一定水準を維持 |
| 投稿忘れ | 月1〜2回発生 | GitHub Actionsで0件 |
「書く」以外の時間がほぼゼロになります。 これがこのシステムの本質です。
このシステムを構築するための前提確認
試す前に、以下が揃っているか確認してください。
- Gitの基本操作(
commit・push)の経験 - GitHubアカウント
- Pythonが動く環境(バージョン3.9以上)
- はてなブログアカウント
Gitをほとんど使ったことがない場合は、まず記事02・03で基礎を身につけてから戻ってくることをおすすめします。
この記事でわかること
- Claude API × GitHub Actions × はてなブログを統合した完成形のシステム構成
blog-postsリポジトリのファイル構成とその設計意図- Claude Code・Claude API・GitHub Actionsそれぞれの役割分担
- 構築時に重要だった設計判断5つ
- 実際の運用コストと、3ヶ月運用してわかったこと
完成形の全体構成
【ブログ自動化システム 全体構成】
┌─────────────────────────────────────────────────────────────┐
│ 開発者(あなた) │
│ テーマを決める → レビューしてOKを出す → mainにマージ │
└──────────────┬──────────────────────────┬──────────────────┘
│ ① 記事生成指示 │ ⑤ PRをマージ
▼ ▼
┌──────────────────────┐ ┌─────────────────────────────┐
│ Claude Code │ │ GitHub │
│ (対話しながら生成) │ │ main ブランチへの push │
│ │ │ ↓ │
│ ② polish.py 実行 │ │ GitHub Actions が起動 │
│ (品質チェック×2回) │ │ ↓ │
│ │ │ post_to_hatena.py 実行 │
│ ③ drafts/ に保存 │ │ ↓ │
│ ④ PRを作成 │ │ はてなブログ AtomPub API │
└──────────────────────┘ │ (記事を送るための通信規格) │
└─────────────────────────────┘
│
▼
┌─────────────────┐
│ はてなブログ │
│ (記事が公開) │
└─────────────────┘
─────────────────────────────────────────────────────
【使用サービス】
Claude Code(無料)/ Claude API(有料)/ GitHub(無料)
GitHub Actions(無料枠で十分)/ はてなブログ(無料)
─────────────────────────────────────────────────────
ポイントは「人間が介在するレイヤー」が明確に分離されていることです。テーマを決めてレビューでOKを出す——この2点だけが人間の仕事で、それ以外は自動化されています。
Claude Code・Claude API・GitHub Actionsの役割分担
| コンポーネント | 役割 | このリポジトリでの実装 |
|---|---|---|
| Claude Code | 対話しながら記事生成・polish実行・PR作成 | CLI上でprompts/を参照して生成 |
| Claude API | 記事の品質チェック・ブラッシュアップ・内部リンク挿入 | polish.pyがAPIを呼び出す |
| GitHub | ファイル管理・レビューフロー(PR) | drafts/→articles/の移動がレビューの承認 |
| GitHub Actions | クラウドでの自動実行・定期投稿・ワークフロー制御 | 設定ファイル(YAML形式)で制御 |
| はてなブログ | 記事の公開・読者への配信 | AtomPub APIで投稿・posted/に履歴保存 |
Claude CodeとClaude APIの違い
ここで混乱しやすい点を整理します。
- Claude Code:対話型のAIアシスタント。「記事のテーマはXにして」と指示を出すと、ファイルを読み書きしながら記事を生成してくれます。課金は会話単位。
- Claude API:プログラムから呼び出すAPI。
polish.pyが内部でAPIを叩いて、記事の品質チェックやブラッシュアップを行います。こちらはトークン(AIが処理するテキストの単位。約750字≒1,000トークン)単位の課金です。
このシステムでは、両方を組み合わせています。生成はClaude Code、品質向上はClaude API(polish.py経由)という分担です。Claude APIを使った記事生成の具体的な手順については記事02で詳しく解説しています。
ファイル構成の全体像
blog-posts リポジトリの最終形がこちらです。
blog-posts/ ├── .github/ │ └── workflows/ │ ├── post-on-push.yml # articles/に追加されたら即投稿 │ └── weekly-post.yml # 毎週月曜8時に自動投稿 │ ├── articles/ # ← レビュー済み・投稿待ち記事 │ ├── 03-hatena-atompub-guide.md │ └── 04-github-actions-blog.md │ ├── drafts/ # ← 生成直後・レビュー前の記事 │ ├── 01-blog-automation-overview.md │ ├── 05-complete-automation-summary.md │ └── 05-complete-automation-summary_review.md # polishのログ │ ├── posted/ # ← 投稿済みの記録(自動生成) │ └── history.json │ ├── prompts/ # ← polish.py が使うプロンプト集 │ ├── system_prompt.txt │ ├── reviewer_reader.txt │ ├── reviewer_seo.txt │ └── reviewer_editor.txt │ ├── series/ │ └── blog-automation.json # ← シリーズ管理(記事間の関係) │ ├── topics/ # ← 記事テーマのストック │ ├── polish.py # 品質チェック・ブラッシュアップ ├── post_to_hatena.py # はてなブログ投稿スクリプト ├── update_hub.py # ハブ記事(記事01)の自動更新 └── requirements.txt
drafts/が「作業中置き場」、articles/が「投稿承認済み置き場」という2段構えになっています。git mv drafts/記事名.md articles/(ファイルを移動するGitの操作)を実行してコミットするだけで、レビューのOKサインになります。
なぜこの構成にしたか
技術的な選択の背景を整理します。
なぜGitHubを使うのか?
- 記事をコードとして管理できる(差分・履歴がすべて残る)
- pushという操作が自動化のトリガーになる
- PRがレビューフローとそのまま対応する
なぜはてなブログ × AtomPub APIなのか?
- はてなブログはAtomPub APIが標準搭載:外部ツールから投稿・更新・削除まで公式の仕組みがある
- Markdownで管理すると再利用性が高い:他の媒体にも転用できる
なぜ人間のレビューを挟むのか?
- AI生成の誤りを公開前にキャッチする安全弁
git mv drafts/ articles/という操作がそのままレビューのOKサインになる
この組み合わせが「ブログ自動化」の実用的な完成形です。クラウドサービスへの依存を最小限にしながら、GitHub Actions + はてなブログ AtomPub APIという無料・安定した構成で動きます。
ブログ自動化システムの設計判断:重要ポイント5つ
「なぜこのファイル構成なのか」——設計意図を5点に絞って解説します。将来の改修やカスタマイズの参考にしてください。
1. drafts→articlesの人間レビューを挟む理由
AIが生成した記事をそのまま自動投稿しないのは意図的な設計です。
drafts/(AI生成) → articles/(人間承認) → はてなブログ(公開)
完全自動化はあえてやりません。理由は2つ:
- 事故防止:誤った情報や不適切な内容が公開されるリスクをゼロにする
- ブランドの維持:「このブログは信頼できる」という読者の信頼を守る
実際に失敗したから、この設計にたどり着きました。最初に完全自動投稿を試したとき、Claude APIが架空の製品名を事実として記述した記事が生成されました。公開前にたまたま気づきましたが、これを機に人間のレビューを必須ステップとして設計に組み込みました。
articles/へのファイル移動(git mv)がPR(変更内容をレビューしてもらうためのGitHubの機能)の承認と一致する設計は、ツールの制約を活かした自然なフローになっています。
2. polish.pyで品質を担保する仕組み
polish.pyは3役のレビュアーAIと1役のライターAIを組み合わせた品質チェックシステムです。
# polish.py の内部フロー(2回ループ) for i in range(iterations): # デフォルト2回 # 3人のレビュアーが並列チェック reader_fb = reviewer("読者目線") # 読みやすさ・わかりやすさ seo_fb = reviewer("SEO") # キーワード・見出し構成 editor_fb = reviewer("文章品質") # 表現・論理展開 # ライターがフィードバックを統合して改稿 article = writer(article, [reader_fb, seo_fb, editor_fb]) # その後、内部リンク挿入 → フッターナビゲーション追加
適用前は見出しの抜けや内部リンク未挿入が平均3〜4箇所ありましたが、3ヶ月24本の運用を通じて、適用後に漏れが発生したのは1本のみでした。
記事のタイトル・タグなどをまとめたヘッダー情報(フロントマター)はrestore_frontmatter()で保護されており、ブラッシュアップ後もタグ・カテゴリ・series_idは変わりません。
3. 何度実行しても安全な設計(冪等性)
update_hub.pyは記事01(ハブ記事)のシリーズ一覧テーブルを自動更新するスクリプトです。設計上の重要なポイントは冪等性(べきとうせい)——何度実行しても同じ結果になる性質のことです。
# update_hub.py の設計思想 # series.json の内容からテーブルを決定論的に生成する # → 何度実行しても同じテーブルになる(副作用なし)
このコメントが設計思想の核心を表しています。定期実行スケジューラー(cronジョブ)で自動実行しても、手動で何度実行しても、series.jsonの状態と一致したテーブルが生成されます。冪等な操作を意識することで、自動化システム全体の信頼性が上がります。
4. series.jsonで記事間の関係を管理
記事の「公開済み/下書き/未着手」の状態、URL、ファイルパスをすべてseries/blog-automation.jsonで一元管理しています。
{ "series_id": "blog-automation", "articles": [ { "id": "02", "phase": 2, "title": "Claude APIでブログ記事を自動生成する方法", "status": "published", "file": "drafts/2026-03-23-claude-api-hatena.md", "url": "https://www.doodle-office.work/entry/2026/03/23/181911", "published_at": "2026-03-23" } ] }
polish.pyはこのファイルを参照して内部リンクを自動挿入し、update_hub.pyはこれを読んでハブ記事のテーブルを再生成します。唯一の情報源(Single Source of Truth)——どこを見れば最新かが一目でわかる仕組みとして機能しており、以前スプレッドシートで管理していたときの「どこが最新かわからない」問題が解消されました。
5. コスト最適化(APIスキップの仕組み)
post_to_hatena.pyのis_already_posted()チェックは、単なる多重投稿防止だけでなく、APIコストの節約にも貢献しています。
def is_already_posted(filename: str) -> bool: """投稿済みなら True を返す(APIを呼ばずに終了)""" if not HISTORY_FILE.exists(): return False history = json.loads(HISTORY_FILE.read_text()) return any(e["file"] == filename for e in history.get("posted", []))
GitHub Actionsのワークフローが実行されるたびに全記事を投稿し直す設計では、APIコストが青天井になります。posted/history.jsonへの記録と冒頭チェックで、1記事につき1回だけAPIを呼ぶ設計にしています。
実際の運用コスト
記事1本あたりのAPIコスト試算(2026年3月時点)。
| 処理 | 使用モデル | トークン概算 | コスト概算 |
|---|---|---|---|
| polish.py(2回×3レビュアー+ライター) | claude-sonnet-4-6 | 入力20k / 出力16k | 約$0.10〜$0.15 |
| 内部リンク挿入 | claude-sonnet-4-6 | 入力5k / 出力5k | 約$0.03 |
| update_hub.py | claude-sonnet-4-6 | 入力3k / 出力2k | 約$0.02 |
| 合計 | 約$0.15〜$0.20/記事 |
月8本ペースで運用した場合、月$1.2〜$1.6(約180〜240円)。Claude Codeのサブスクリプション($20/月)に対して、API使用料は10分の1以下です。
注意: 記事の長さ・ポリッシュ回数・モデルによって変わります。
polish.py --iterations 1にすると約$0.08〜$0.10/記事と半額程度に抑えられます。
ブログ自動化3ヶ月の効果:時間・コスト・品質の変化
3ヶ月運用して数字に出た変化をまとめます。更新頻度の安定が予想外の副次効果を生んだ点が、特に印象的でした。
| Before(手動運用) | After(自動化後) | |
|---|---|---|
| 1記事あたりの時間 | 2〜3時間 | 30分以下 |
| 更新頻度 | 月1〜2本(不定期) | 月6〜8本(3ヶ月連続で安定) |
| 記事品質の均一性 | 執筆時のコンディション次第 | polish.pyで一定水準を保持 |
| 内部リンク | 手動で確認・挿入(よく忘れる) | polish.pyが自動挿入 |
| 投稿忘れ | 月に1〜2回発生 | GitHub Actionsで0件 |
| 誤投稿リスク | 手動操作ミスあり | PRレビューで事前にキャッチ |
| シリーズ管理 | スプレッドシートで管理 | series.jsonで一元管理 |
3ヶ月運用してわかったこと
- プレッシャーの消滅が品質向上につながる:「更新しなきゃ」という焦りがなくなると、テーマ選びに余裕が生まれ、結果として記事の内容が深くなった
- 更新頻度が安定すると読者の反応が変わる:月1〜2本の不定期更新では薄かった読者コメントが、週2本ペースが続いた2ヶ月目から増え始めた
- 仕組みへの信頼が、ネタ選びの冒険を後押しする:自動化によって「1本失敗しても次がある」という感覚が生まれ、実験的なテーマにも挑戦しやすくなった
この仕組みが向いている人・向いていない人
向いている人
- 技術ブログを書いている(Markdownに抵抗がない)
- GitHubを日常的に使っている
- 「続けたいのに時間がない」と感じている
- 投稿作業の繰り返しに疲れている
向いていない人
- GUIで完結したい(WordPressの管理画面で十分な人)
- 単発・不定期の投稿しかしない
- Gitを使う予定がない
「技術ブログをGitHubで管理している」という条件さえ満たせば、このシステムはほぼそのまま使えます。
ブログ完全自動化システムの構築まとめと次のステップ
このシステムで実現できること:月8本のブログ更新を、1本あたり30分以下・月200円前後で継続できる。
各コンポーネントを組み合わせると、次の完成形になります。
テーマ決め(5分) → Claude Codeで生成(10分) → polish.pyで品質アップ(自動・5分) → PRでレビュー(10分) → mainにマージ → GitHub Actionsが自動投稿(自動)
人間がやることは「テーマを決めて、レビューしてOKを出す」——この2点だけです。
まずは記事02からはじめて、このシステムを1ステップずつ構築してみてください。記事02(約90分)→記事03(約60分)→記事04(約60分)の順に実装すると、合計約3〜4時間でこの完成形に到達できます。
完成後の運用イメージはこうです。
- 平日の30分で記事を書く
- pushするだけで公開される
- 週2本ペースで記事が積み上がっていく
「ブログを書く」という作業が、日常のルーティンに溶け込みます。
ここからできること(発展)
このシステムは「ブログ自動化」の土台です。ここから先に伸ばせる方向:
- 複数媒体への同時投稿:noteやZennにも同じMarkdownを展開する
- AIによる記事テーマ自動提案:トレンドやSEOデータをもとに候補を生成
- SEO競合調査の自動化:記事作成前に検索ボリュームと競合を調べる
記事06・07ではこのフェーズに入ります。
最後に
正直、この仕組みを作ってから「ブログを続ける難しさ」はほぼなくなりました。
あとは、書くだけです。
書いた分だけ、積み上がります。
この仕組みを使わない場合、今後も「投稿作業」に時間を使い続けることになります。
まずは1記事だけ、この仕組みで投稿してみてください。10分で「自動投稿される体験」ができます。体験すると、もう元のやり方には戻れなくなります。
シリーズ記事一覧
- 記事01:週2〜3時間→30分に短縮|AI×ブログ自動化の全体像とClaude API×GitHub Actions構成
- 記事02:Claude APIでブログ記事を自動生成する方法
- 記事03:はてなブログにAPIで投稿する方法(AtomPub完全ガイド)
- 記事04:GitHub Actionsでブログを定期投稿する方法(近日公開)
- 記事05:この記事(完成形の実装まとめ)
記事06・07への展望
このシステムはさらに改善できます。次のフェーズでは以下を扱います。
記事06:ブログ記事自動生成パイプラインの設計 - 記事テーマの自動候補生成 - 複数記事の並列生成 - SEO競合調査の自動化
記事07:AI生成ブログを安全に運用するチェックリスト - 事実確認フローの設計 - 著作権・引用のガイドライン - 品質が下がったときの検知方法
このシリーズの前後の記事: - ← 前の記事:GitHub Actionsでブログを定期投稿する方法(近日公開) - → 次の記事:ブログ記事自動生成パイプラインの設計(近日公開)
シリーズ一覧:ブログ運用を半自動化する実践ロードマップ