Content Operatorを作ったら、記事制作からGhost下書きまでが一つの承認フローになった
記事制作とGhost下書き保存を一つの承認フローにまとめたContent Operatorの実装記録。競合検知や古い承認の拒否を備えつつ、最終公開は人間が担う設計です。
「記事を書けるAI」は、もう珍しくありません。ただ、一人会社や小規模事業者の実務で本当に時間がかかるのは、文章を生成する部分だけではありません。
テーマを決め、根拠を確認し、本文とタイトル、概要、タグをそろえ、CMSへ移し、内容を見直して公開する。途中で修正が入れば、どれが最新なのかも確認する必要があります。記事一本のために、いくつもの画面と手順を行き来していました。
今回作ったContent Operator/Ghost Draft Operatorは、この流れのうち、記事制作からGhostの下書き保存までを一つの承認フローとして扱うための仕組みです。
目指したのは、AIに勝手に公開させることではありません。Agentが記事と公開用メタデータをまとめ、人間が内容を確認し、承認されたものだけをGhostの下書きに反映する。そのうえで、最終公開は人間がGhost管理画面から行う。この境界を明確にすることが、今回の実装で最も大切な点でした。
記事ではなく「Publish Package」を作る
Content Operatorがまとめるのは、本文だけではありません。タイトル、slug、excerpt、meta title、meta description、tagsなど、Ghostへ下書きを作るために必要な情報を一つのPublish Packageとして扱います。
本文だけを生成しても、その後に人間が各項目をコピーし、表記を整え、CMSへ入力するなら、作業はまだ分断されたままです。そこで、記事制作の時点から「Ghostへ渡せる単位」で成果物をまとめるようにしました。
この形にすると、人間が承認する対象も分かりやすくなります。文章だけを読むのではなく、検索結果や一覧画面でどう見えるかまで含めて確認できます。承認後に保存される内容とのずれも小さくできます。
Ghostとの接続とDraftだけを扱う仕組み
Ghost側とはCustom Integrationで接続しました。今回のOperatorが扱えるのは下書きです。公開機能は実装していません。
既存記事を探す処理でも、公開済みの記事は検索結果から除外し、Draftだけを対象にします。同じslugの記事が公開済みだったとしても、それを更新対象として扱わない設計です。既存コンテンツへの意図しない変更を避けるための境界でもあります。
新しい記事については、承認されたPublish PackageからGhost下書きを作成します。画像は必須にせず、今回のように画像なしでも下書きを準備できます。
ここまでを自動化すると、承認後にGhostへ移し替える手作業がなくなります。一方、下書きから公開へ進める操作は残しています。公開日時、サイト全体との整合、最終的な表現などをGhost管理画面で確認し、人間が公開ボタンを押します。
更新はHuman Approvalの後だけ
既存Draftを更新する場合も、Agentが判断しただけでは反映しません。変更案を作り、Human Approvalを経た後に更新します。
承認を単なる確認画面にしないため、更新時にはGhostのupdated_atを利用した競合検知も入れました。変更案を作った後、誰かがGhost管理画面で下書きを編集していれば、最初に読んだ時点のupdated_atと一致しなくなります。その状態では更新せず、最新のDraftを読み直して変更内容を見直す必要があります。
これがないと、人間がGhost上で直した文章を、少し前の状態をもとにしたAgentの更新で上書きする可能性があります。小さな運用では複雑な排他制御は不要に見えますが、人間とAgentが同じ下書きを触る以上、最低限の競合検知は必要でした。
古い承認を実行させない
もう一つ実装したのが、古いrevisionに対する承認の即時拒否です。
たとえば、最初の変更案をrevision 1として提示した後、内容を修正してrevision 2を作ったとします。このとき、以前の承認画面や通知からrevision 1を承認できてしまうと、最新ではない内容がGhostへ反映される恐れがあります。
そこで、承認処理に入る前にrevisionを確認し、古いものなら即時に拒否します。Ghostへ更新を試みてから失敗させるのではなく、承認の入口で止めます。
updated_atの競合検知がGhost側で生じた変更を守る仕組みなら、revisionの検証はOperator内部で生じた変更を守る仕組みです。この二つを分けて考えたことで、どの段階の「古さ」を検知しているのかが明確になりました。
Blueprint v1まで作って見えたこと
今回の実装は、動作する一回限りの仕組みで終わらせず、Blueprint v1としてまとめました。記事制作、Publish Packageの作成、承認、Ghost下書きへの反映という一連の形を、今後改善できる土台にするためです。
実際に作ってみて感じたのは、Agent製品の価値は生成能力だけでは決まらないということです。どこで人間に確認を求めるか、何を更新対象にするか、古い情報や競合をどう扱うか。こうした地味な境界の設計が、日常的に使えるかどうかを左右します。
現時点では、記事の自動公開はできません。これは未実装のCapabilityであり、最終公開は人間がGhost管理画面で行います。完全自動化をうたう段階ではありません。
それでも、記事制作からCMS下書きまでが一つの承認フローになったことで、コピー&ペーストや入力漏れを減らし、人間は内容と公開判断に集中しやすくなりました。一人会社や小規模事業者にとっては、この「任せる範囲と止める場所が分かる」ことが、派手な自動化より大切かもしれません。
次は日々の実運用で改善し、Agent製品として磨く。