ブログや技術メディアを継続的に運用し、質の高い情報を発信し続けることは、多くのブロガー、エンジニア、コンテンツクリエイターにとって非常に大きな課題です。1つの記事を世に送り出すまでには、企画の案出し、ファクトリサーチ、本文執筆、推敲・校正、アイキャッチや図解画像の作成、画面での入稿と装飾といった、多大で定型的な作業プロセスが存在します。
「生成AIを活用してコンテンツ作成を自動化したい」と考えたとき、単一の長大なプロンプトで記事全体を一括出力させようとすると、途中で文脈が破綻したり、事実誤認(ハルシネーション)が混入したり、画像ブロックのHTML属性が壊れて入稿時にエラーが発生するといった深刻な問題に直面しがちです。
本記事では、Google DeepMindの自律型AIエージェント環境「Gemini Spark」を活用し、ハーネス制御(ライフサイクルフック、送信前自動HTMLバリデータ、独立サブエージェントによるGateレビュー) および WordPress REST API 連携を組み込んだ本格的なブログ投稿自動化パイプラインの構築・実践ノウハウを徹底解説します。
1. ブログ自動化システムのアーキテクチャと3階層ルール

システム全体を堅牢かつ拡張しやすくするために、本システムでは3階層ルール (3-Tier Directives) による責任とルールのカプセル化(分離管理)を採用しています。
/Users/totsu00/spark_work/
├── GEMINI.md # 第2階層: プロジェクト指示書 (動作環境・パス定義)
├── main.py # 統一CLIエントリーポイント
│
├── hooks/ # 宣言的ライフサイクルフック
│ ├── pre_task.md # 実行前フック(過去失敗ログの自動点検)
│ └── post_task.md # 実行後フック(詳細ログ出力+シートサマリー)
│
├── agents/blog_orchestrator/ # オーケストレーターエージェント
│ ├── AGENT.md # 第3階層: エージェント仕様書
│ ├── agent.py # パイプライン制御プログラム
│ └── state.json # 実行状態・進捗管理(レジューム用)
│
├── skills/ # 専門サブスキル群(単一責任原則)
│ ├── blog_researcher/
│ ├── blog_writer/
│ ├── blog_image_generator/
│ ├── blog_wp_publisher/
│ └── sheets_logger/
│
└── output/blog/ # 成果物出力先
└── drafts/{YYYYMMDD}_{slug}/ # 記事別専用フォルダ
├── state.json # 該当記事の進捗メタデータ
├── 01_plan.md # 企画書 (8要素構成案)
├── 02_research.md # リサーチ資料 (技術仕様・FAQ)
├── 03_draft.md # 初稿原稿
├── 04_proofread.md # 校正後原稿
├── 05_wp_data.md # WP投稿用プレーンHTML成形データ
├── image_prompts.json # 画像生成プロンプト
├── 06_image_report.md # 画像生成レポート
└── images/ # 実画像ファイル群 (eyecatch.png, h2_1.png等)
3階層指示ルールの基本原則
- 第1階層(Global Directive): クラウド上の
gemini-spark-instructions。対話トーン、プランモード、全フェーズでのサブエージェントレビュー必須化、ファクトチェック原則などの全域共通規範を規定します。 - 第2階層(Project Directive): 接続フォルダ直下の
GEMINI.md。作業ルート (/Users/totsu00/spark_work/)、ドメイン別成果物出力パス(output/blog/drafts/)、技術スタックを定義します。 - 第3階層(Agent / Skill Spec): 各フォルダ内の
AGENT.mdやSKILL.md。単一責任原則に基づき、個別の入出力フォーマットや具体的スクリプト呼出手順をカプセル化します。
日常の例え:オーケストラの指揮者と専門演奏家
この3階層ルールは、オーケストラの演奏に例えることができます。第1階層の指示書は「音楽の基本ルールや演奏の姿勢」、第2階層のプロジェクト指示書は「コンサートホールの音響特性や楽譜の配置規約」、そして第3階層のスキル仕様書は「バイオリン奏者やフルート奏者といった専門演奏者ごとのパート譜」に相当します。各パートが自分の持ち場に専念し、指揮者(オーケストレーターエージェント)が全体の進行を統括することで、調和の取れた美しく長大な交響曲(本格技術記事)が奏でられるのです。
2. 専門サブスキルによる自律連携パイプライン

一連の投稿プロセスは、料理の厨房のように役割分担された「専門サブスキル」が順序立ててバトンリレー方式で処理を行います。各サブスキルは前のステップが作成した成果物ファイルをインプットとして受け取り、自身の役割に特化したアウトプットを出力します。
[Phase 1: 編集会議] ──> [Phase 2: リサーチ] ──> [Phase 3: 執筆] ──> [Phase 4: 校正・Gate2]
01_plan.md 02_research.md 03_draft.md 04_proofread.md
│
[Phase 7: WP投稿] <── [Phase 6: WP成形] <── [Phase 5: 画像生成] <──────────────┘
WordPress (ID: 1717) 05_wp_data.md image_prompts.json & images/
パイプラインの各フェーズと詳細役割
- 企画・編集会議 (
blog-editor-meeting):ターゲットペルソナ、狙い目キーワード、ゴール設定、および長文執筆に耐えうる必須8要素構成案(導入、基礎背景、詳細設計、ハンズオン実装、トラブルシューティング、FAQ 5選、独自考察、まとめ)を策定し、
01_plan.mdを作成します。 - ファクトリサーチ (
blog-researcher):Web検索ツールを活用し、信頼性の高い技術ドキュメントや最新事例を調査。8要素の構成案に対応する一次情報、公式パラメータ、コード例、FAQ、トラブル事例を収集し、
02_research.mdへまとめを出力します。 - 本文執筆 (
blog-writer):01plan.mdと02research.mdをインプットとし、ターゲットに寄り添った丁寧な語り口で執筆します。大見出し(H2)1章あたり1,200文字以上を執筆し、専門用語には日常のアナロジー例えを挿入。コピペで動く設定・コード例を省略せずに記述し、03_draft.mdを作成します。 - 校正・SEO最適化 (
blog-proofreader):誤字脱字の修正、ファクト関係の照合、SEOキーワード配置、リーガルリスク(景表法や著作権引用ルール)の点検を行い、
04_proofread.mdを完成させます。 - 画像企画・一括自動生成 (
blog-image-generator):校正済み原稿から視覚的概念を抽出し、プロンプト設定ファイル (
imageprompts.json) を作成。一括生成スクリプト (generateblog_images.py) を実行し、Gemini Interactions API (gemini-3.1-flash-image) を経由してアイキャッチや本文図解画像をimages/ディレクトリへ全自動生成・保存します。 - WordPress投稿データ生成 (
blog-wp-publisher):標準HTML(
<p>,<h2>,<pre><code>)へ変換し、WordPress投稿用データ05wpdata.mdを生成します。 - WordPress API自動投稿 (
blog-wp-api-publisher):wp_poster.pyを実行。認証情報をロードし、ローカル画像をWordPressメディアライブラリへ自動アップロード。取得したWeb公開URLおよびメディアIDで本文中のローカルパスを動的置換し、下書き保存を完遂します。
3. ハーネス制御による品質保証と安全対策
AIエージェントに長文記事の生成や入稿作業を完全自動で任せる際、最も重要となるのが「失敗の未然防止(安全対策)」と「成果物の客観検証(品質保証)」です。本システムでは、以下の重層的なハーネス制御(制御構造)を組み込んでいます。
① 実行前後のライフサイクルフック (Pre / Post Task Hooks)
- Pre-Task Hook (
hooks/pre_task.md):タスク起動直前に
hooks/pre_task.mdプロトコルが自動実行され、output/blog/logs/内の最新ログファイルを自動点検します。過去に発生したエラー分類(APIタイムアウト、フォーマット崩れ、置換ミス等)を特定し、本タスク実行時の「最優先予防制約」としてエージェントのコンテキストに注入することで、同じ失敗の再発を防ぎます。 - Post-Task Hook (
hooks/post_task.md):タスク完了直後に
hooks/posttask.mdプロトコルが自動実行され、ローカル詳細ログをoutput/blog/logs/{YYYY-MM-DD}.logに保存。さらに Google スプレッドシート「sparkwork_実行サマリー」へ非ブロッキング処理で実行サマリー(日時、タスク名、ステータス、処理時間、成果物パス、文字数等)を自動追記します。通信エラー等でスプレッドシート追記が失敗した場合でも、メインの記事作成処理は正常完了させる障害耐性(Non-Blocking Fallback)を備えています。
② 独立サブエージェントによる 3段階Gateレビュー
処理コストと品質保証のバランスをとるため、パイプラインの重要局面で独立したサブエージェント(invoke_subagent)を呼び出し、以下の3段階Gateレビュー(客観検証)を実行します。
- Gate 1 (企画レビュー):
01_plan.md作成後、ペルソナ設定の具体性、SEOキーワードの網羅性、および6,000〜8,000字規模を成立させる8要素構成案の妥当性を検証。 - Gate 2 (校正・ファクト・ボリュームレビュー):
04_proofread.md作成後、事実関係の整合性、可読性、景表法・著作権リスク、および純文字数(6,000字以上)とエンゲージメント(5軸評価)を点検。 - Gate 3 (投稿前構造レビュー):
05wpdata.mdおよび画像生成結果に対し、標準HTML構造、画像参照、URL置換準備の正確性を点検。
③ レジューム機能と二重投稿防止(冪等性の確保)
各記事フォルダ内に設置された state.json に進捗ステータス(completedphases)、作成済みWordPress投稿ID (wppostid)、およびアップロード済み画像マップ (uploadedmedia) を管理・保持します。
万が一処理が途中で中断した場合でも、オーケストレーター(agent.py)が state.json を読み込み、既に完了したフェーズやアップロード済みの画像を自動スキップ([SKIP])します。また、既存投稿IDが存在する場合は新規作成ではなく更新 (POST /wp-json/wp/v2/posts/{wppostid}) リクエストへ安全にリダイレクトされるため、二重投稿や二重画像アップロードが発生しない冪等性(Idempotency)が保証されます。
4. 実践ハンズオン!オーケストレーションコードとWordPress自動連携
本パイプラインの核心となる制御ロジックと、送信前自動バリデータの実装コードを解説します。
オーケストレーター (agent.py) の文字数カウント&自動加筆判定ロジック
agent.py は、Markdownファイルから空白や装飾記号を除外した純文字数を計測し、目標基準(6,000文字)に満たない場合は補強指示を作成して自動リトライを行います。
def count_markdown_chars(file_path: Path) -> int:
"""Markdownファイルの純文字数(スペース、改行、記号を除いた実文字列長)を計測"""
if not file_path.exists():
return 0
try:
with open(file_path, "r", encoding="utf-8") as f:
content = f.read()
# HTMLタグ、コードブロック記号、空白の除外
text_only = re.sub(r"\[comment\][\s\S]*?\[/comment\]", "", content)
text_only = re.sub(r"```[\s\S]*?```", "", text_only)
text_only = re.sub(r"[#*`\-+>|\_]", "", text_only)
text_only = re.sub(r"\s+", "", text_only)
return len(text_only)
except Exception as e:
log_message(f"Failed to count chars for {file_path}: {e}", level="WARNING")
return 0
送信直前自動HTMLバリデータ (validategutenbergcontent)
wp_poster.py は、WordPress REST API へデータを送信する直前に以下の厳格な構造検証を自動実行し、不具合のあるデータが送られるのを物理的に阻止します。
def validate_gutenberg_content(content):
"""送信直前の最終HTML構造の自動バリデータ (Post-Replace Validation)"""
errors = []
# Check 1: 重複クラス名チェック (1つのimgに wp-image-ID が複数存在しないか)
img_tags = re.findall(r'<img\s+[^>]+>', content)
for img_tag in img_tags:
matches = re.findall(r'wp-image-(\d+)', img_tag)
if len(matches) > 1:
errors.append(f"[Check 1 FAIL] 1つの<img>タグ内に複数の wp-image-ID が重複しています: {matches}")
# Check 2: 未置換ローカルパスの残留チェック
local_src_matches = re.findall(r'<img\s+[^>]*src=[\"\'](?!(http://|https://))([^\"Constraints\']+)[\"\']', content)
if local_src_matches:
errors.append(f"[Check 2 FAIL] 本文中に未置換のローカル画像パスが残っています: {local_src_matches}")
if errors:
for err in errors:
print(f"[ERROR] {err}")
raise ValueError("HTML Validation Failed. Post aborted to prevent editor corruption.")
print("[SUCCESS] [Post-Replace Validation] HTML構造バリデーションチェック全項目クリア (PASS)")
WordPress REST API への画像アップロードおよびピンポイント置換
wp_poster.py は、ローカル画像をメディアライブラリへ送信し、取得したURLとメディアIDを用いてピンポイントで属性を置換します。
# クラス名のクリーン化とピンポイント置換
def set_single_wp_image_class(img_tag, media_id):
# 重複する wp-image-ID クラスを一度すべて除去
cleaned_tag = re.sub(r'\bwp-image-\d+\s*', '', img_tag)
# 正しい media_id を唯一付与
if 'class="' in cleaned_tag:
return cleaned_tag.replace('class="', f'class="wp-image-{media_id} ')
else:
return cleaned_tag.replace('/>', f' class="wp-image-{media_id}"/>').replace('>', f' class="wp-image-{media_id}">')
5. 泥臭い試行錯誤とトラブルシューティング事例
システム構築・運用の中で実際に直面した泥臭い開発エラーと、その具体的な解決アプローチをご紹介します。
事例1:画像ブロック重複クラス付与による表示破壊
- 発生現象: エディタ上で「想定されていないコンテンツ」が表示され、画像ブロックが破損する。
- 原因追究: 画像アップロード後の本文置換処理において、複数画像をループ処理する際に全文字に対する置換(
re.sub(r'<img...>'))を重複実行していたため、1つの<img>タグにclass="wp-image-1716 wp-image-1715 wp-image-1714"とクラス名が重なって属性が破壊されていた。 - 解決策: 置換処理前に既存の
wp-image-\d+クラスをクリーン化する関数を新設し、1対1のピンポイント置換へロジックを刷新。さらに送信直前自動バリデータ (Check 1) を実装して重複を物理的に防止。
事例2:LLMの要約癖と文字数不足の克服
- 発生現象: 初期の自動執筆では2,000〜3,000文字程度の要約的な記事しか出力されなかった。
- 解決策: H2章ごとに最低1,200文字以上、ソースコードや設定例の非省略記述、日常のアナロジー挿入、泥臭いエラー試行錯誤の記述をルール化。さらに
agent.pyに純文字数カウントと 6,000字未満時の自動補強リトライ(retry_count)を実装して機械的に長文高クオリティ化を担保。
6. よくある質問 (FAQ) 5選
Q1. APIコストや処理時間の目安はどのくらいですか?
回答: gemini-3.1-flash-image や最新の高速モデルを活用しているため、1記事(8,000字規模・画像3枚生成含む)あたりの総処理時間は数秒〜十数秒程度です。API利用コストも1記事数円〜数十円程度と極めて低コストで運用可能です。
Q2. WordPressのアプリケーションパスワードのセキュリティ管理は?
回答: 認証情報(WPURL, WPUSER, WPAPPLICATIONPASSWORD)はすべてローカル環境の .env ファイルで管理し、コードやGitリポジトリ、Markdown内には一切直書きしません。スクリプト実行時に環境変数から安全にロードされます。
Q3. ネットワーク接続エラーや処理中断が発生した場合の復旧手順は?
回答: 各記事フォルダ内の state.json に進捗状態(completed_phases)と作成済みWP投稿IDが記録されています。コマンドを再実行するだけで、完了済みのステップや画像アップロードを自動スキップし、未完了のフェーズから安全に処理が再開(レジューム)されます。
Q4. 既存のWordPressテーマ(SWELL, Cocoon, SANGO等)との互換性は?
回答: 出力される投稿データは標準のHTML構造(<p>, <h2>, <figure>, <pre><code>)に準拠しているため、どのようなエディタ対応テーマでもレイアウトが崩れず綺麗に表示されます。
Q5. 完全自動化と人間による目視確認のベストバランスは?
回答: 本パイプラインでは投稿ステータスを常に status: "draft"(下書き)として投稿します。AIエージェントが入稿・画像配置までを100%自動で完遂した状態を作り、人間は管理画面で最終的なプレビューを目視確認して「公開」ボタンを押すだけ、という役割分担が最も安全で高効率な運用スタイルです。
7. 独自考察:AIエージェントと人間が創るコンテンツ制作の未来
Gemini Sparkを活用したブログ投稿自動化パイプラインの構築を通じて実感したのは、「定型作業の自動化がもたらす人間側の自由度の飛躍的な向上」 です。
企画の骨組み作り、リサーチ、初稿執筆、誤字チェック、画像作成、WordPressへの画像アップロードとHTML属性調整といった作業は、どれも時間と集中力を激しく消費します。これらを信頼できるハーネス構造を持ったAIエージェント群に任せることで、人間は「どんな独自の体験を読者に届けるか」「どんな新しいアイデアを検証するか」という、最も創造的で本質的な活動に集中できるようになります。
AIエージェントを単なる「文章生成ツール」として使うのではなく、明確な指示階層、ライフサイクルフック、サブエージェントによる客観検証、そして自動バリデータというハーネス(手綱・制御構造) を提供することで、AIは真に頼れるパートナーへと進化します。
まとめ
本記事では、Gemini Sparkを活用したブログ投稿自動化パイプラインのアーキテクチャ、3階層ルール、ハーネス制御、およびWordPress REST APIとの安全な自動同期メカニズムを解説しました。
要点を振り返りましょう:
- 3階層ルールによるカプセル化: グローバル指示、プロジェクト指示、個別スキルを明確に分離。
- ハーネス制御の徹底: Pre/Post Taskフック、3段階のサブエージェントGateレビュー、レジューム機能。
- 送信直前自動バリデータ: 二重クラス付与などをAPI送信直前に自動検知し、エディタのブロック破損を物理的に阻止。
- 定量的・定性的品質担保: 6,000〜8,000字規模の8要素構成、純文字数自動計測、アナロジーやトラブル解決体験を含む5軸評価。
定型作業をAIエージェントに任せ、人間が本来の創造性を発揮する新しいWebコンテンツ制作スタイルを、皆さんもぜひ試してみてください。

コメント