美容室のブログ投稿アシストをAIで作る — 管理画面解析から文体学習・ホールドアウトE2E検証まで
美容室のブログ投稿アシストをAIで作る — 管理画面解析から文体学習・ホールドアウトE2E検証まで
顧問先の美容室のブログ投稿を、写真を渡すだけで下書きまで進められないか。対象は美容室の予約管理サービスの管理画面にあるブログ投稿機能で、ログインが必須、そのうえ下書き保存ボタンが存在しない。だから到達点を「フォームを全部埋めて、送信の手前で止める」ことに決めた。午前に調査と計画、昼にPhase 0の分析、午後にホールドアウトE2E検証。1日でドラフト生成からフォーム入力まで通った。
ログイン済みブラウザで管理画面を解剖する
まず Claude in Chrome で、ログイン済みのまま投稿画面を開かせてフォーム構造と内部処理を調べさせた。すんなりとはいかない。生のJavaScriptを出力させようとするたびDLPフィルタに弾かれる。出力を諦めて、「この関数は何を受け取り、送信先をどう組み立てるか」という質問形式で構造だけ聞き出させた。
わかった中核はこれだった。
WYSIWYGエディタ(1枚)に本文と画像を入れる
└─ 送信時に分解 → blogContents1〜5(本文5分割)+ imagePath1〜4(画像パス4枠)
画像は先に専用エンドポイントへmultipartでアップロードし、サーバー側のパスをもらわないと確認画面で弾かれる。プレースホルダー画像や外部URLでは通らない。
調査のあいだフォームは無入力のまま保ち、最後にタブを閉じて副作用ゼロを確かめた。相手は本番の管理画面なので、この規律は計画書にもそのまま書いた。
Codexレビュー、1回目は空回り
内部仕様をもとに実装計画書を書き、Codexにレビューさせた。外部サイトへの自動投稿を扱う計画なので、レビュー必須ルールに該当する。これで穴は塞がるだろう、と思っていたら、1回目のCodexはリポジトリのファイルを読んだだけでターンを終えていた。指摘ゼロ。リトライで空回りする代わりに、自分で挙げていた技術リスク3点(トークン、画像パスの整合、副作用ゼロ性)を先に精査して計画を固めた。
2回目の実行で本物のレビューが返ってきた。致命点は4つ。最大の欠陥は「ローカルの画像ファイルをページのファイル入力へ渡す橋」が計画から抜けていたことだった。4つとも計画に反映した。
構想が「投稿代行」から「自己改善ループ」へ
会話しているうちに構想が広がった。スマホで撮った写真が同期されるディレクトリを起点に、過去投稿の分析→文体学習→ドラフト生成→人間の修正→投稿→投稿結果を履歴へ取り込んで再学習、というループ。スラッシュコマンド1発でこれが回る形を目標に据えた。なおスマホ単体からの実行は無理で、ログイン済みChromeのあるマシンで動かす前提になる。
一番こだわったのは画像と文章の整合だ。これからは画像だけ渡してAIに本文を書かせる。ならば「AIが画像から読み取れること」と「オーナー本人が実際に書いた文章」のあいだのズレこそが学習対象で、言い回しだけ学んでも本人の書き方には近づかない。Phase 0の分析を「文体」と「画像→文章の変換」の2軸に分けて計画へ明記した。
もう1つ、画像解析はOpenAIのCodexの方が表現が良い気がしていた。ただの印象で決めたくない。同じ画像を両モデルにブラインドで読ませ、実際の文章に近いほうを突き合わせで決めるベンチマークをPhase 0の必須工程にした。
置き場所は独立リポジトリに
スキルの置き場所も迷った。モノレポのプロジェクトレベルに置くか、専用リポジトリを新設するか。決め手は配布で、いずれ第三者の環境で動かすことまで考えると、モノレポの中では個人ルールや他プロジェクトへの依存が混ざって切り出せなくなる。専用の新リポジトリを切り、以後の作業セッションはそちらで開く運用にして、計画書だけ先にコミットした。
Phase 0 — 過去投稿の取り込みと2モデル比較
昼から新リポジトリでPhase 0を回した。過去投稿を11バッチに分けてスクレイプさせ、投稿履歴のJSONLを構築。画像は91枚中90枚で止まり、欠けた1枚を特定して取り直した。本文の全文ダンプを通読させ、文体ルールを style-guide.md にまとめさせた。
Codexへのブラインド読み取りは、バッチ実行が14件まとめて失敗した。原因はWindowsパスのバックスラッシュのエスケープで、フォワードスラッシュに書き換えたら全部通った。読み取り結果は相互レビューにかけた。Codexの読み取り15件をClaude側でレビューさせると、指摘ありが8件。材料をベンチマークレポートに落とした結論は、どちらか一方ではなく併用だった。読み取り役を1人に絞る根拠は出なかった。
ホールドアウトE2E — 声で答えるだけでドラフトが完成した
検証はホールドアウト方式にした。学習から除外しておいた実際の過去投稿1件について、正解の実投稿文を開かないブラインド規律のまま、画像からドラフト生成→フォーム入力まで通す。
画像から読み取れない事実はヒアリングで埋めた。カテゴリはおすすめメニュー。施術メニューはカットカラー。オーダーはショートにしたい。ビフォーは黒髪で長め。クーポンはあり。声でそう答えていくだけで、価格や手順といった任意項目は「書かない」で確定し、ドラフトが完成形まで出てきた。承認すると、ログイン済みブラウザがフォームを埋めていく。画像アップロードのモーダルも、ファイル入力への受け渡しも通り、「確認する」ボタンの手前で停止。スクリーンショットで入力内容を目視確認した。
評価フェーズで初めて正解を開き、実投稿文と突き合わせた評価レポートまで作らせた。1点だけ、確認ボタンを押した先の画面遷移チェックはタブを閉じてしまったので、未実施のまま記録に残した。初回の実投稿で自然に検証される。
選択肢はマスターとして持つ運用へ
E2Eの途中で気づいたことがある。クーポンもカテゴリも投稿者も、選択肢は有限だ。毎回ページを開いて確認するのは無駄で、スキルの中にマスターとして持てばいい。ただし持ちっぱなしのマスターは古くなる。落とし所は「マスターはドラフト会話の高速化用、フォーム入力時は必ずライブの画面から解決、実行のたびに再取得して上書き」というハイブリッドで、data/masters.json に投稿者4・カテゴリ11・クーポン20件を保存した。ドラフトの会話中にブラウザを開かずに選択肢を出せるのが効き目になる。
成果物を共有ドライブへ同期する
最後に、成果物ディレクトリを顧問先と共有する共有ドライブへ同期したくなった。Google Drive for desktop のフォルダ同期はマイドライブ専用で、共有ドライブには使えない。代わりに robocopy のミラーリングで「実行時に完全一致」を作った。
robocopy <ローカル成果物> <共有ドライブ宛先> /MIR /XD .git
.git を除外し、ファイル数の突き合わせで完全一致を検証した。/MIR には「宛先にしかないファイルを削除する」という地雷がある。除外設定と検証手順ごと固定するため、この同期方法自体を /sync-gdrive スキルにした。宛先パスを毎回思い出す必要もなくなる。
スキルへの切り出しと残り
投稿アシスト本体も、この日のうちにドラフト版のスキルへ切り出した。ヒアリング→ドラフト→承認→フォーム入力→評価という今日の手順を、次は1コマンドで呼び出せる。
残りは3つ。
- 初回の実投稿で、確認ボタンから先の画面遷移を検証する(今日の未実施分)
- マスターの自動更新(実行のたびにページから再取得して上書き)をスキル本体に実装する
- 投稿済みの内容を履歴へ取り込み、文体ルールを再分析する再学習ループを回す
学び
- APIドキュメントのない管理画面でも、ログイン済みブラウザと内部処理の解析で自動化計画は立つ。ただし「無入力を保つ・送信手前で止める・タブを閉じて確認する」の副作用ゼロ規律をセットで守る
- AIレビューは1回の結果を信用しない。ファイルを読んだだけで終わるターンもある。再実行したら致命点が4つ出た
- 文体だけ学んでも本人の文章には近づかない。「画像から読み取れること」と「本人が書いたこと」のズレを学習対象に据える
- モデル選定は印象で決めず、同条件のブラインド読み取りで突き合わせる。結論が「併用」になることもある
- 有限の選択肢はマスター保持+入力時ライブ解決のハイブリッドが安全。マスターは会話を速くするためのもので、入力の正はライブ画面に置く