メインコンテンツへスキップ
       

複数のAIエージェントでWordPressを安全に更新する方法-単一書込者,編集ロック,REST API及び読戻し検証(AI作成)

第1 結論

複数のAIエージェントを使う場合でも,調査,構成,執筆,画像作成及び査読は分担できる。
これに対し,WordPressの本番サイトへ記事を新規登録し,又は既存記事を更新する経路は,一つの書込担当と直列の待ち行列へ集約するのが安全である。

ここでいう単一書込者は,全ての作業を一つのAIに任せるという意味ではない。
外部状態を変える最終工程について,同じ投稿又は関連する設定を複数の担当が同時に変更せず,一件ずつ,変更前確認,保存,保存値の読戻し及び公開面の確認を終えてから次へ進むという意味である。

WordPressの管理画面には投稿ごとの編集ロックがあるが,サイト全体の更新を直列化する仕組みではない。
また,通常の投稿更新用REST APIと自動保存用REST APIでは,編集ロックの扱いが同一ではない。
したがって,「管理画面に編集ロックがあるから複数の自動化が安全に競合できる」と考えず,運用側で書込経路を一本化する必要がある。

本記事は,WordPress Coreの開発者向け資料並びにWordfence及びCloudflareの公式資料を基礎とする技術運用上の整理である。
法令又は裁判例に基づく法律上の結論は扱っていないため,裁判所ウェブサイト及び判例秘書による裁判例検索は行っていない。

第2 分担してよい工程と一本化すべき工程

1 調査,執筆及び査読は並行できる

調査担当は公式資料を探し,執筆担当は原稿を作り,査読担当は根拠,重複及び読みやすさを確認できる。
これらの工程では,成果物をローカル又は共有された案件フォルダへ出し,WordPressの管理画面又はAPIには接続させない方法が考えられる。

各担当の成果は,記事本文,タイトル,スラッグ,カテゴリー,アイキャッチ画像,SEO説明及び出典台帳のように,項目を分けて受け渡す。
同じ項目について複数案がある場合は,本番担当へ渡す前に採用案を一つへ確定する。

2 本番書込みは単一書込者へ集約する

本番担当は,確定した成果物だけを受け取り,一件ずつ処理する。
投稿ID又は新規投稿の別,タイトル,スラッグ,カテゴリー,本文,SEO項目,画像及び予定する保存回数を,保存前に確定する。

一つの投稿を処理している間は,他の担当が同じ投稿を管理画面又はAPIから更新しない。
本文の更新とSEO項目の更新が別の経路に分かれる場合も,どちらが先に実行し,それぞれを何で読戻すかを一つの作業票に記録する。

「一つのエージェントに一本化」より,「一つの書込経路に一本化」と表現する方が正確である。
担当AIを交代させることはできるが,同時に動かさず,直前の保存値と未完了の操作を読んでから引き継ぐ必要がある。

本番作業の指示は,同じ内容であっても,複数の担当へ同時に出さない。
複数の担当が同じ指示を受けると,後から着手した担当が,先行担当の作業途中の状態を未完了の不具合と受け取り,同じ保存を重ねるおそれがある。
同じ指示を受けたことに気付いた担当は,保存せずに停止し,先行担当の進捗と完了時刻を確かめた上で,読戻しによる確認だけを引き受けるのが安全である。

第3 WordPressの編集ロックで防げることと防げないこと

1 管理画面の編集ロックは投稿単位である

WordPress Coreのwp_set_post_lock()は,現在の利用者が投稿を編集していることを示す_edit_lockを保存する。
wp_check_post_lock()は,その投稿が他の利用者によって編集されているかを確認する。

この仕組みは,同じ投稿を管理画面で編集する利用者同士の衝突を減らすためのものである。
別の記事,同じ記事に関連するメディア,カテゴリーその他の設定を含めてサイト全体を直列化するロックではない。

2 通常のREST更新は管理画面と同じロックを当然には使わない

WordPress CoreのWP_REST_Posts_Controller::update_item()は,投稿データを整えた後にwp_update_post()を実行し,続けてアイキャッチ画像,ターム,メタデータ等を処理する。
公開されている同メソッドのソースには,通常の投稿更新の入口でwp_check_post_lock()を呼び出す処理は見当たらない。

他方,自動保存用のWP_REST_Autosaves_Controllerは,投稿が他の利用者にロックされていないかを確認する処理を明示している。
この違いから,管理画面の編集ロックが,独自のRESTクライアントによる通常更新まで一律に排除すると仮定してはならない。

3 ロックの存在を更新成功の証拠にしない

ロックが表示されなかったことは,他の自動化が動いていないこと又は更新が競合しなかったことの証明ではない。
反対に,ロックが表示された場合も,無理に解除して保存を続けるのではなく,誰がどの経路で作業しているかを確認し,書込担当を一つへ戻す必要がある。

第4 REST APIを使う利点と限界

1 ブラウザ操作を減らし,処理結果を構造化できる

REST APIを使えば,管理画面を開き,画面要素を探してクリックする工程を減らせる。
更新対象,送信値,HTTP状態及び応答を機械的に記録しやすいため,多数の記事を扱う場合の再現性も高めやすい。

もっとも,API経由の更新にも,認証,ネットワーク,WordPress本体,プラグイン,データベース及びキャッシュの処理が必要である。
パソコン又はサーバーの負荷がゼロになるわけではなく,更新失敗がほぼなくなると保証することもできない。

2 一つのAPI要求でも部分的に反映される可能性がある

WordPress Coreの通常の投稿更新では,主要な投稿データをwp_update_post()で更新した後,アイキャッチ画像,ターム及びメタデータ等を順に処理する。
後段でエラーが返る経路があるため,エラー応答だけから「何も変更されなかった」と推測して同じ要求を直ちに再送してはならない。

成否が不明な場合は,本文,更新日時,カテゴリー,画像,メタデータその他の対象項目を現在値として読み戻し,どこまで反映されたかを確かめる。
その上で,未反映の項目だけを安全に補えるか,又は人の判断へ戻すかを決める。

3 カスタム項目はAPIから当然に扱えるとは限らない

WordPress REST APIでカスタムメタデータを扱うには,登録方法及びshow_in_rest等の条件を確認する必要がある。
SEOプラグインその他の独自項目は,標準の投稿APIへ自動的に含まれるとは限らない。

APIに本文だけを送り,別の担当が管理画面からSEO項目を更新すると,書込経路が再び分かれる。
必要項目をAPIで扱えない場合は,APIと管理画面の順序,担当,保存回数及び読戻し方法を同じ作業票で管理する。

4 認証情報は限定し,保管と失効を管理する

WordPressのApplication Passwordsは,REST API等のプログラム利用向けに,利用者ごと及び用途ごとの認証情報を発行する仕組みである。
通常のログインパスワードを自動化へ埋め込まず,専用利用者又は必要最小限の権限,HTTPS,保管場所,利用記録及び失効手順を決める必要がある。

第5 安全なリレー方式

1 正本となる成果物を確定する

本番担当へ渡す前に,原稿の正本を一つ決める。
本文はMarkdownを正本とし,WordPress用HTMLを機械的に生成する方法,又は既存記事について一意に一致する変更前文字列と変更後文字列を記録する方法が考えられる。

新規記事では,タイトル,スラッグ,カテゴリー,公開状態,本文,SEO説明及び画像の有無を確定する。
既存記事では,投稿ID,公開URL,現在の更新日時,本文ハッシュ,変更箇所及び変更しない項目を記録する。

2 保存前に現在値を再取得する

本番作業の直前に,保存済み本文,更新日時,タイトル,スラッグ,カテゴリー及び対象メタデータを読み戻す。
作業依頼書を作った時点から値が変わっていれば,古い本文へ差分を機械的に当てず,変更内容と競合の有無を確認する。

差分を適用する場合は,変更前文字列が一件だけ存在し,変更後文字列がまだ存在しないことを保存前の条件にする。
ゼロ件又は複数件なら停止し,目視で似た箇所へ当てない。

3 一回の保存ごとに読戻す

保存後は,成功通知だけでなく,WordPressに保存された本文又はメタデータを新たに読み,予定値と照合する。
本文では,改行を統一したSHA-256,タイトル,目次リンク,見出しID,内部リンク及びカテゴリー等を確認する。

公開又は既存の公開記事の更新を行った場合は,ログアウト状態又は認証情報を含まない別経路で公開面を取得し,タイトル,本文,リンク,目次及びSEO説明を確認する。
管理画面の保存値と公開面の表示は,別々の確認層として扱う。

4 成否不明では再試行しない

タイムアウト,画面停止又は通信切断が起きた場合は,自動的に同じ保存操作を繰り返さない。
まず現在値,更新日時及び公開面を読み,既に保存されていないかを確認する。

二重公開,重複画像,重複カテゴリー又は意図しない上書きを防ぐため,最大保存回数及び停止条件を作業開始前に決める。
追加保存が必要になった場合は,最初の作業結果を証拠として残した上で,新しい保存として承認と検証を行う。

5 公開面はキャッシュの層ごとに確かめる

公開面の確認は,問合せ文字列を付けない通常のURLでも行う。
Cloudflareの説明によれば,同社のキャッシュキーは,既定では問合せ文字列を含むURLを要素として作られる。
そのため,キャッシュを避ける目的で問合せ文字列を付けたURLで新しい表示が返っても,通常のURLには古い写しが残っていることがある。

サーバー側のページキャッシュとCDNのキャッシュは別の層であり,一方を消しても,他方の写しは残り得る。
キャッシュを消すときは,オリジンに近い層から順に消し,その後に通常のURLを取得して新しい内容が返ることを確かめる。
先にCDNだけを消すと,残っていたサーバー側の古い写しによって,CDNが再び古い内容で埋まり得る。

CDNの応答ヘッダーは,キャッシュの状態を確かめる手掛かりになる。
Cloudflareの説明によれば,cf-cache-statusのMISSは,キャッシュの対象であるが要求の時点で写しがなかったことを示し,DYNAMICは,要求の時点でキャッシュの対象外と判断されたことを示す。
したがって,MISSが出たことは,その応答が保存されない設定であることを意味しない。
ログイン中の表示のようにキャッシュしてはならない応答については,応答ヘッダーの観察に加え,CDNの設定そのものを読み戻して確かめる必要がある。

第6 フリーズ及びアクセス遮断の原因を決め付けない

1 パソコン負荷は測定して切り分ける

複数のブラウザ又は自動化環境を同時に動かせば,メモリ,CPU,ディスク及びネットワーク接続を追加で使用する。
もっとも,更新画面が固まった原因がメモリ不足であるとは,タスクマネージャー等の測定なしに断定できない。

切分けでは,メモリ使用量,コミット済みメモリ,CPU,ディスク待ち,ブラウザのプロセス数,通信エラー,WordPressのログ及びサーバー側の応答を時刻とともに記録する。
メモリを増設しても,同じ投稿への上書き,重複実行又は保存順序の競合は解消しない。

2 WAF又はレート制限は設定に依存する

Wordfenceには,要求数に応じてアクセスを制限し,又はブロックする設定がある。
したがって,多数のログイン又は画面遷移が遮断の一因となる場合はあるが,複数のAIを使えば必ず総当たり攻撃と判定されるわけではない。

遮断が疑われる場合は,HTTP状態,WAF又はセキュリティプラグインのログ,対象URL,要求頻度及び送信元を確認する。
同じ操作を繰り返してログを増やす前に停止し,設定値と実際の記録を照合する。

第7 本番作業前のチェックリスト

本番作業前には,少なくとも次を確認する。
①本番書込者と利用する経路が一つに決まっていること
②投稿ID又は新規投稿の別,タイトル,スラッグ及びカテゴリーが確定していること
③本文,SEO項目及び画像の正本とハッシュが確定していること
④保存前に現在の保存値と更新日時を取得していること
⑤変更前文字列が一件,変更後文字列がゼロ件であること
⑥予定する保存回数,停止条件及び失敗時の戻り先が決まっていること
⑦保存後の保存値読戻しと,公開面確認を別々に行うこと
⑧成否不明の場合に自動再試行しないこと
⑨公開面を,問合せ文字列を付けない通常のURLでも確認し,キャッシュを消す層と順序が決まっていること

第8 法律事務所のAI業務設計及びパソコン選びとの関係

調査,起案及び査読の役割分担,共通規律,案件文脈,権限,人の承認及び完了条件は,法律事務所のAIエージェント業務設計-目的・コンテキスト・権限・完了条件をどう分けるか(AI作成)で整理している。
本記事は,そのうちWordPressの本番書込みを単一書込者へ集約する具体的な運用を扱う。

クラウド型AIを中心に使う場合のメモリ,WindowsとMacの選び方及びローカルAIのハードウェアは,AIエージェントを使うならWindowsとMacのどちらがよいか-用途別のパソコン選び(AI作成)を参照されたい。
パソコンの性能を上げることと,WordPressへの書込経路を直列化することは,別の対策である。

第9 出典・参考資料

①WordPress Developer Resources「wp_set_post_lock()」
https://developer.wordpress.org/reference/functions/wp_set_post_lock/
②WordPress Developer Resources「wp_check_post_lock()」
https://developer.wordpress.org/reference/functions/wp_check_post_lock/
③WordPress Developer Resources「WP_REST_Posts_Controller」
https://developer.wordpress.org/reference/classes/wp_rest_posts_controller/
④WordPress Developer Resources「WP_REST_Autosaves_Controller」
https://developer.wordpress.org/reference/classes/wp_rest_autosaves_controller/
⑤WordPress REST API Handbook「Authentication」
https://developer.wordpress.org/rest-api/using-the-rest-api/authentication/
⑥WordPress Developer Resources「Application Passwords: Integration Guide」
https://developer.wordpress.org/advanced-administration/security/application-passwords/
⑦WordPress REST API Handbook「Modifying Responses」
https://developer.wordpress.org/rest-api/extending-the-rest-api/modifying-responses/
⑧WordPress REST API Handbook「Posts」
https://developer.wordpress.org/rest-api/reference/posts/
⑨Wordfence「Rate Limiting」
https://www.wordfence.com/help/firewall/rate-limiting/
⑩Cloudflare Docs「Cloudflare cache responses」
https://developers.cloudflare.com/cache/concepts/cache-responses/
⑪Cloudflare Docs「Cache keys」
https://developers.cloudflare.com/cache/how-to/cache-keys/