AIにWordPressを操作させる準備|REST APIの最小構成と事故を防ぐ3つの型
AIにサイトを直接直させるには、AIからWordPressを読み書きできる経路が要ります。この記事では、REST APIで繋ぐ最小構成と、公開のときに起きる事故を防ぐ3つの型を書きます。
結論から書きます。AIにWordPressを操作させる準備は、認証の設定・最小の関数モジュール・事故を防ぐ3つの型(書いて読み返す検証/副作用の前に状態を書く/下書きと公開の関数を分ける)の順で用意します。 この3つが揃っていないと、公開は通ったのにSEO欄が空のまま検索結果に出る、同じ記事が二重に投稿される、といった事故が起きます。
この記事は、散らかったサイトをAIで作り変えるマニュアルの「AIに渡す前提」の作業です。AIにSEOを任せる前に渡す4つの前提で用意したファイルを、実際にサイトに書き込めるようにする工程です。
この作業で決まること
この作業が終わると、AIが毎回ライブのサイトを読み書きできるようになります。具体的には次ができます。
- 全記事・全固定ページ・全カテゴリをAIがその場で取得する
- 新しい記事を下書きとして作る
- 既存記事の本文・抜粋・カテゴリを更新する
- テーマのSEOタイトル・メタディスクリプションを、書けたことを確かめたうえで更新する
- 公開前にリンクのステータスを確認する
ここまでできれば、以降の診断・リライト・公開の作業はAIから自動で動かせます。
前提:この記事の前に必要なもの
- 自分または勤務先サイトの管理者権限がある WordPress
- ユーザー画面からアプリケーションパスワードを発行できること(発行方法は公式の手順に従う)
- Claude Code などのファイルを読み書きできるAI
- AIに渡す4つの前提(戦略・今のデータ・判断基準・禁止事項)が用意されていること
AIに渡すもの
AIに渡すのは次の3点です。
- 接続情報:サイトのURL、管理者ユーザー名、アプリケーションパスワード
- 使うSEOメタのキー名:テーマごとに違う。使っているテーマのメタキー名を調べて書き留めておく
- 関数のモジュール1枚:参照・更新・下書き作成・公開・SEO書き込み・URL確認の関数を1枚にまとめた Python ファイル
接続情報は環境変数か、Git管理の外に置いた設定ファイルに書きます。記事やコードに直書きしないでください。
モジュールの構成は、自分で動かしているものだと次の関数を1枚に入れています。
- 参照:
get_all_postsget_all_pagesget_postget_categories - 更新:
update_postupsert_categorydelete_category - 新規:
create_draft(status をdraftに関数内で固定)/publish_post(別名で分離) - SEOメタ:
set_seo_meta(4段ラウンドトリップ検証つき) - 補助:
check_url_status
各関数は生のdict/listを返す作りにしておきます。整形は呼び出し側の責任にすると、同じモジュールをどのスクリプトからも使い回せます。
手順
- WordPress のユーザー画面でアプリケーションパスワードを発行する(手順は公式ドキュメントに従う)
- 接続情報を環境変数ファイルに書き、Git の無視リストに入れる
- REST の関数モジュールを1枚作る(下の「3つの型」をすべて組み込む)
- 書き込みを含まない参照系の関数だけで、公開記事数・下書き数・カテゴリ数が取れることを確かめる(モジュール末尾に配線確認の
__main__を置いておくと楽) - 空のカテゴリを1つ作って削除するなど、小さな書き込みで経路を確認する
- ドラフトでテスト記事を作り、本文・抜粋・SEOメタをそれぞれ書き込んで読み返す
- SEOメタが書けない場合に、公開を止めずに代替の経路(WordPress標準の「抜粋」欄など)を使う判断を、作業の前に決めておく
7は後述の失敗の対策です。経路が1つでも駄目なら全部止める作りにすると、公開が1本も進まなくなります。
事故を防ぐ3つの型
型1:書いて、読み返して、確かめる
テーマのSEOタイトルやメタディスクリプションは、RESTの書き込みが成功して返っても、保存されていないことがあります。テーマやプラグインの設定で、そのメタキーがREST経由の書き込みを受け付けていないと、API はエラーを出さずに素通りします。
対策は、本番の値を書く前に目印の値(sentinel)を書き、読み返して反映を確認し、そのあとで本番の値を書き、もう一度読み返して一致を確認するという4段の手順です。これを set_seo_meta のような関数の中に閉じ込めておくと、呼び出す側は失敗を例外として受け取れます。「書けたつもりで実は空」が消えます。
型2:外部に副作用を出す前に、状態を永続化する
公開や更新のような取り返しのつかない操作では、処理の前に「これからやる」という状態をディスクに書く作りにします。処理が終わってからまとめて状態を書くと、処理中に別の実行が割り込んだとき、同じ行をもう一度処理して二重の操作になります。
さらに、常駐の自動処理には、同じスクリプトが同時に2本動かないように単一インスタンスのロック(flock など)を付けます。状態の永続化と排他ロックの二重で守ります。
型3:下書きを作る関数と、公開する関数を分ける
同じ関数で status を切り替えるのではなく、下書き専用の関数と公開専用の関数を別名で作ります。下書きの関数は status='draft' を関数の中で固定し、呼び出し側から公開に昇格できないようにします。公開の関数は、公開の判断(会社特定チェックや接地監査など)を通したスクリプトからだけ呼び出すルールにします。
関数の名前と中身で公開経路を物理的に分けておくと、AIが途中で判断を誤っても、間違って公開することがありません。
完了条件
- ☐ 接続情報が Git の外にあり、環境変数で読める
- ☐ 参照系(投稿・固定ページ・カテゴリの取得)が動く
- ☐ 下書きの作成・既存記事の更新・SEOメタの書き込みが、それぞれ読み返しで検証されている
- ☐ 下書きの関数と公開の関数が別名で分かれている
- ☐ 公開を含む自動処理に、単一インスタンスのロックと「処理の前に状態を書く」設計が入っている
- ☐ SEOメタが書けなかったときの代替経路が、ファイルに書かれている
実際に起きた失敗
別サイトで動いていた公開モジュールが、SEO欄だけ書けなかった
このサイトの最初の記事を公開したとき、記事本文の公開は通ったのに、テーマのSEOタイトルとメタディスクリプションの欄だけ書き込みが失敗しました。別の自分のサイトで同じテーマを使っていて、そこでは動いていた公開モジュールを移植したものでした。
同じテーマでも、SEO欄のメタキーがREST API経由で読み書きできるかは、サイトごとの設定で決まります。「別サイトで動いていた」ことは、このサイトで動く証拠になりませんでした。
幸い、関数の中に書き込み前の sentinel 検証を入れていたので、「書けたつもりで実は空だった」ではなく、その場でエラーとして気づけました。対応は、公開を止めずに WordPress 標準の「抜粋」欄に説明文を入れることにしました。使っているテーマは抜粋を meta description として出力してくれるので、検索結果用の説明文は出せました。SEO欄が未設定であることは公開の台帳に記録し、後で直す対象として残しました。
教訓は2つです。移植したモジュールは、必ずそのサイトで書いて読み返して確かめる。公開を止める条件と、止めずに代替して記録する条件を、作業の前に分けておく。
90秒かかる投稿処理で、同じ行が二重に処理された
これは別の自分の自動投稿の仕組みで起きた話ですが、WordPress の公開でも同じ構造で事故が起きます。
常駐で動かしていた自動投稿のスクリプトが、「キューを読む → 全部投稿する → 最後にまとめて状態を書き戻す」設計になっていました。1本の投稿に90秒かかるので、その間、キューの行はずっと「未処理」のままです。30秒差で別のタイミングで同じスクリプトが起動して、同じ行を読んで、同じコンテンツをもう一度投稿してしまいました。
原因は、取り返しのつかない操作(投稿)が、状態の永続化より先に起きていたことです。修正は3段で、副作用の前に「処理中」の状態を書いて即保存する、単一インスタンスのロックを付ける、同じコンテンツの重複をキーで弾く、を同時に入れました。安全側の判断は「不明なら止めて人に回す」で、取りこぼし(1回欠ける)より二重(1回多い)のほうを重く扱います。
WordPress の公開も不可逆です。この3つの型は、関数モジュールの最初から入れておきます。
よくある質問
Q. アプリケーションパスワードは、どこから発行しますか?
A. WordPress 管理画面のユーザープロフィール画面から発行します。具体的な手順は公式ドキュメントに従ってください。発行した文字列は環境変数ファイルに書き、Git の管理外に置きます。普通のログインパスワードは使いません。
Q. テーマのSEOメタが書けません。公開を止めるべきですか?
A. 止めなくて大丈夫です。本文は公開し、WordPress 標準の「抜粋」欄に説明文を入れて代替します。使っているテーマが抜粋を meta description として出力するかは、公開後にページのソースで確認します。SEO欄が未設定であることだけ、台帳に記録しておき、後で直します。
Q. 公開の関数と下書きの関数を1本にまとめて、status 引数で切り替えてはいけませんか?
A. 技術的にはできますが、AIに触らせる前提では分けたほうが安全です。下書き関数の中で status='draft' を固定しておくと、呼び出し側が何を渡しても公開になりません。公開はもう1本の関数からだけ呼ばれる、というルールが関数名で読めるようになります。間違えて公開する事故を、コードの形で防げます。
関連記事
- まとめ: AIに渡す前提
- AIにSEOを任せる前に渡す4つの前提
- AIに既存記事をリライトさせると劣化する理由と、外科手術に分解する手順
- サイトに必要なのは大規模・中規模・小規模どの修正か
- AIで書く役と検査する役を分ける
次の作業
- 全記事の台帳を作り、「今のサイト」をAIの判断の基準にする
- AIに任せる範囲・人が決める範囲を決める
- 公開の前に通す接地監査(根拠のない主張を1件も通さない仕組み)を作る