これまでの記事で、Mac上のローカルLLM、画像生成環境、VPSとの通信、複数ワーカーのジョブ管理を検討しました。
最後に、これらをつなげて、記事本文とアイキャッチ画像をPayload CMSへ登録する仕組みを構築します。
初期段階では自動公開しません。
ローカル生成AIが作成した内容は、Payload CMSへ下書きとして保存し、人間が確認してから公開します。
全体の処理フロー
記事生成からPayload登録までの流れは次のとおりです。
- VPSへ記事生成ジョブを登録する
- Macのワーカーがジョブを取得する
- ローカルLLMで記事構成を作る
- ローカルLLMで本文を生成する
- 画像生成用プロンプトを作る
- ComfyUIでアイキャッチ画像を生成する
- 記事と画像をVPSへ返す
- VPS側で内容を検証する
- 画像をPayloadのメディアへ登録する
- 記事を下書きとして登録する
- 人間が内容を確認する
- 問題がなければ公開する
Mac側は生成処理を担当し、Payloadへの登録や公開判断はVPS側へ集約します。
なぜMacからPayloadへ直接登録しないのか
MacからPayloadのAPIへ直接記事を送ることもできます。
しかし、その場合は各MacへPayloadの認証情報を保存する必要があります。
生成結果を一度VPSへ返す構成にすると、次の利点があります。
- Payloadの認証情報をVPSだけで管理できる
- Macの役割を生成処理に限定できる
- 登録前の検証を一か所へ集約できる
- 失敗時の再実行を管理しやすい
- 将来ワーカーを追加しやすい
- 公開フローを変更しやすい
Mac側には、ジョブ取得と結果返却に必要なワーカー用APIキーだけを持たせます。
記事生成を一度で終わらせない
LLMへ「記事を書いて」と一度だけ指示すると、構成が不安定になったり、必要な要素が抜けたりする可能性があります。
そこで、記事生成を複数の段階に分けます。
1. 記事要件の整理
入力されたテーマから、次の内容を整理します。
- 想定読者
- 読者の疑問
- 記事の目的
- 含めるべき内容
- 含めない内容
- 文体
- 文字数の目安
- 注意事項
2. 見出し構成の作成
記事本文を生成する前に、見出し構成を作ります。
この段階で、内容の重複や不足を確認できます。
3. 本文生成
確定した見出し構成に沿って本文を生成します。
長い記事では、全体を一度に生成するより、見出し単位で処理する方法もあります。
4. 校正と整形
生成後に次の内容を確認します。
- 同じ説明を繰り返していないか
- 見出しと本文が一致しているか
- 不自然な表現がないか
- 指示した文体になっているか
- 結論が曖昧になっていないか
- 必要な注意事項が含まれているか
ただし、ローカルLLMだけで事実確認を完了させることはできません。
公開前には人間が確認します。
画像生成用プロンプトを作る
記事本文をそのまま画像生成モデルへ送るのではなく、画像向けの要件へ変換します。
画像プロンプトには次の内容を含めます。
- 主題
- 表現する場面
- 構図
- 視点
- 色調
- 光の雰囲気
- 背景
- 画像の用途
- アスペクト比
- 避けたい要素
例えば、ローカルLLMの記事であれば、単に「MacとAI」と指示するのではなく、記事の内容に合った構図を作ります。
例としては次のような方向性です。
デスク上にMacBook ProとMac miniがあり、両方がネットワーク上のサーバーと接続されている。ローカルAI処理を視覚化した抽象的な光の流れ。現実的で清潔感のあるテクノロジー系の構図。ブログの横長アイキャッチ向け。画像内に文字は入れない。
画像内の文字は崩れやすいため、基本的には生成させません。
タイトル文字が必要な場合は、生成後に別処理で合成します。
複数候補を生成する
画像は1枚だけ生成せず、複数の候補を作ります。
例えば3枚から4枚を生成し、その中から採用する画像を選びます。
初期段階では人間が選択します。
将来的には、画像の技術的な品質を判定する仕組みを追加できますが、記事内容との適合性や好みまで完全に自動判定するのは難しいため、無理に全自動化しません。
VPS側で検証する
Macから結果を受け取ったら、VPS側で形式を確認します。
記事については次の内容を検証します。
- タイトルが存在するか
- 本文が空でないか
- 文字数が極端に短くないか
- 必要な見出しがあるか
- 不正なHTMLが含まれていないか
- 許可していない外部スクリプトがないか
- ジョブIDが一致しているか
画像については次の内容を検証します。
- 許可されたファイル形式か
- ファイルサイズが上限以内か
- 画像が破損していないか
- 解像度が指定範囲内か
- アスペクト比が想定どおりか
- ファイル名が安全か
検証に失敗した場合は、Payloadへ登録せず、ジョブをエラー状態にします。
Payloadのメディアへ画像を登録する
画像検証が完了したら、Payload CMSのメディアコレクションへ登録します。
登録時には、画像ファイルだけでなく次の情報も保存します。
- 代替テキスト
- キャプション
- 生成モデル
- 生成日時
- 元となった記事ジョブID
- 使用したプロンプト
- 画像の用途
- 人間による確認状態
すべての生成情報を公開画面へ表示する必要はありません。
しかし、後から問題を調査できるよう、内部情報として残しておくと便利です。
記事を下書き登録する
画像の登録後、記事をPayloadへ保存します。
記事データには次の情報を含めます。
- タイトル
- スラッグ
- 概要
- 本文
- アイキャッチ画像
- カテゴリ
- タグ
- SEOタイトル
- メタディスクリプション
- 生成元ジョブID
- 使用したモデル
- 生成日時
- 確認状態
- 公開状態
公開状態は下書きにします。
ローカルAIが作成した記事を、自動的に公開状態へ変更しないことが重要です。
人間が確認する項目
Payloadの管理画面では、少なくとも次の内容を確認します。
- 事実関係
- 製品名や機能名
- 数値や日付
- 引用や参考情報
- 不自然な言い回し
- 重複表現
- 読者に誤解を与える内容
- 画像と記事の整合性
- 画像の不自然な部分
- モデルや素材の利用条件
- SEOタイトルと本文の一致
必要に応じて修正した後、人間が公開します。
エラー時の扱い
記事生成は成功しても、画像生成だけ失敗する場合があります。
その逆もあり得ます。
すべてを最初からやり直すのではなく、処理工程ごとに状態を保存します。
例として次のように分けます。
- requirements_completed
- outline_completed
- article_completed
- image_prompt_completed
- image_completed
- uploaded
- payload_draft_created
途中まで成功していれば、失敗した工程から再開できます。
これにより、長い記事を何度も生成し直す無駄を減らせます。
全自動公開は必要か
技術的には、記事と画像を生成し、そのまま自動公開することも可能です。
しかし、初期運用では採用しません。
理由は次のとおりです。
- 誤情報が含まれる可能性がある
- 古い情報を断定する可能性がある
- 存在しない機能や仕様を作る可能性がある
- 画像が不自然な可能性がある
- ライセンスや権利関係の確認が必要
- サイト全体の品質を下げる可能性がある
自動化の目的は、人間の確認を完全になくすことではありません。
記事作成に必要な下準備を減らし、人間が確認と編集へ集中できる状態を作ることです。
今回の完成形
最終的な構成は次のようになります。
```text
管理画面・自動処理
↓
ConoHa VPS
・ジョブ管理
・PostgreSQL
・認証
・結果検証
・Payload連携
↑
│ HTTPSロングポーリング
│
MacBook Pro / Mac mini
・Pythonワーカー
・OllamaまたはMLX
・ComfyUI
↓
記事と画像をVPSへ返却
↓
Payload CMSへ下書き登録
↓
人間が確認して公開
```
まとめ
M1 Max MacBook ProとM4 Pro Mac miniを使えば、記事本文とアイキャッチ画像をローカルで生成できます。
Mac側は生成を担当し、ConoHa VPSはジョブ管理、認証、検証、Payload連携を担当します。
自宅側のポートを公開せず、MacからVPSへ仕事を取りに行くことで、安全性と運用の分かりやすさを両立します。
初期段階では、次の方針を採用します。
- 記事は複数工程に分けて生成する
- 画像は複数候補を作る
- 結果は一度VPSへ返す
- VPS側で形式を検証する
- Payloadへ下書き登録する
- 公開前に人間が確認する
- 失敗時は途中工程から再開する
この構成が安定した後は、実際の生成速度、消費電力、メモリ使用量、失敗率、外部APIとの費用差などを継続的に記録します。
それらの結果は、長期利用レビューとして改めてまとめる予定です。