しんたろーのITアカデミー
開発日記

1人開発でSNS自動投稿を極めたら、AIが生成したサムネから手が3本生えてきた。(Claude Code開発日記)

1人開発でSNS自動投稿を極めたら、AIが生成したサムネから手が3本生えてきた。(Claude Code開発日記)
しんたろーしんたろー
17分で読めます
この記事の内容(目次)
※この記事は、Claude Codeで1人開発しているSNS運用SaaS「ThreadPost」の開発日記です。

SNS運用を自動化しませんか?

ThreadPostなら、投稿作成・画像生成・スケジュール管理までAIがサポート。

無料で始める

核心回答:なぜAIは手を3本生やすのか

AIに「あごに手を当てる知的なポーズ」と指示したら、生成された人物の腕が3本になった。

画像生成AIの仕組み上、プロンプト内の特定の単語に過剰に反応する現象が起きる。

「手」というトークンに強い重み付けがされると、AIは全体の構図を無視して画面のどこかに手をねじ込もうとする。

業界ではプロンプト・オーバーフィッティングと呼ばれる現象だ。

解決策はシンプルだった。

プロンプトから「手」や「腕」の指示を完全に削除した。

AIに渡す情報を増やすのではなく、渡さない情報を選ぶ。

顔のサイズ指定も緩和し、自然な上半身バランスをAI自身に決めさせた。

結果として、腕が増殖するバグは完全に消滅した。

今週の総コミットは20件だった。

新機能は2件だけで、残りの18件は全部バグ修正に消えた。

終わらない泥沼。4回直して4回壊れた自動化の記録
終わらない泥沼。4回直して4回壊れた自動化の記録

自動化の修正履歴は、解決の記録ではなく「また壊れた」という事実の羅列だ。

SNS自動投稿システムを作ろうとしたら、多重配信やAI特有の奇妙な挙動に殴られ続けた。

今週のハイライトは以下の通りだ。

* TikTokのコメント送信ボタンが押せない問題

* Cookie取得時の原因不明のタイムアウト

* AIが生成した人物の腕が増殖するホラー現象

* 同じニュースレターがユーザーに3回届く大事故

自動化とは、システムを放置することではない。

壊れ続ける仕組みと共生し、ひたすら絆創膏を貼り続ける作業だ。

画像生成AIの根幹をなすDiffusionモデルは、ノイズから徐々に画像を復元していく過程で、テキストプロンプトの各単語に対してアテンションを割り当てる。

CLIPと呼ばれるテキストと画像の関連性を学習したモデルが、この過程をガイドする。

「手」という単語が含まれていると、CLIPモデルはその単語の表現を画像内に強く反映させようとする。

人間の体は手が2本という物理的な制約よりも、テキストの指示を満たすことが優先される。

その結果、すでに両手が描かれているにもかかわらず、あごの近くに3本目の手を生成してしまう。

AIアートの界隈でも、指の数がおかしくなる問題や、手足が増殖するバグは長年の課題とされている。

Stable DiffusionMidjourneyの最新モデルでも、この根本的な構造的欠陥は完全には解決されていない。

プロンプトに特定の部位を明記することは、AIに対する過剰な制約となり、結果として全体の構図を破壊する。

TikTok自動投稿の泥沼

TikTokに動画とコメントを自動で投げる仕組みを作っていた。

ブラウザを自動操作して、特定の入力欄にテキストを流し込む。

今週の開発スタッツ:新機能2件、バグ修正18件
今週の開発スタッツ:新機能2件、バグ修正18件

ただそれだけの単純作業だと思っていた。

しかし、現実はブラウザとTikTokの強固な防御壁に阻まれることになった。

最初はコメントの送信ボタンが押せなかった。

画面上ではボタンが見えているのに、システムからは無効化されていると判定される。

「fix: TikTokコメント投稿のテキスト入力をevaluate方式に変更」

evaluate方式を試した。

ブラウザの内部に直接JavaScriptを流し込んで、強制的にテキストを書き換える手法だ。

これで入力はできた。

と思ったら、今度はログイン状態を維持するためのCookie取得で処理が完全に止まった。

「fix: TikTok Cookie取得のETIMEDOUTエラーにリトライとキャッシュフォールバックを追加」

ETIMEDOUTという無機質なエラーがログに並んだ。

ブラウザのCookieは、裏側ではSQLiteというデータベースに保存されている。

OSレベルでファイルにロックがかかると、外部プロセスからの読み取りが完全にブロックされる。

一般的に、データベースのロック競合はシステム開発で最も厄介な問題の一つと言われている。

僕は以下の対策をコードに組み込んだ。

* タイムアウト時間を延長

* エラー発生時に最大3回のリトライを実行

* すべて失敗した場合はキャッシュからフォールバック

なんとかCookieは取れるようになった。

しかし、肝心のテキスト入力がまたしても弾かれた。

TikTokのエディタは、Draft.jsというフレームワークで動いている。

Facebookが開発したこのリッチテキストエディタは、独自の内部状態を持っている。

外部から無理やりテキストをねじ込んでも、エディタは「何も入力されていない」と認識する。

そして、送信ボタンを冷酷に凍結させる。

モダンなフロントエンド開発において、仮想DOMと実際のDOMの乖離は常識だ。

ReactVueで作られたページを外部から自動操作しようとすると、世界中のエンジニアがこの「フレームワークの壁」にぶち当たる。

Draft.jsは内部にContentStateSelectionStateという状態を持ち、ユーザーのキーボード入力イベントを監視して状態を更新する。

JavaScriptで直接DOMの値を書き換えても、内部状態は空のままだ。

Reactの仮想DOMは、実際のDOMの変更を検知しない。

イベントリスナーが発火せず、コンポーネントの再レンダリングが行われない。

その結果、画面上には文字が表示されているのに、システム内部では「文字数ゼロ」として扱われる。

「fix: TikTokコメント投稿をkeyboard.type方式に修正(Draft.js対応)」

結局、人間がキーボードを叩く動作を完全にエミュレートする「keyboard.type」方式に切り替えた。

PuppeteerがOSレベルのキーボードイベントを発生させ、一文字ずつ確実に入力していく。

これでようやく、エディタが文字を認識した。

送信ボタンが有効化され、コメントが投稿された。

しんたろーしんたろー:
まじかよ…4回連続修正コミット。全部「直した」じゃなくて「また壊れてた」の記録だ。ブラウザ制御、一生信用しない。

僕とTikTokとブラウザの三つ巴の戦いは、泥沼の様相を呈していた。

システムに完全に振り回されている。

自動化ツールを作っているはずが、自動化のメンテナンスに時間を奪われている。

ブラウザのアップデートやUIの変更があるたびに、このコードは再び壊れる。

ブラウザ自動化の歴史は、プラットフォーム側とのいたちごっこの歴史だ。

Seleniumから始まり、PuppeteerPlaywrightとツールは進化してきた。

しかし、プラットフォーム側もBot検知の仕組みを高度化させている。

マウスの軌跡、タイピングの速度、さらにはCanvasフィンガープリントまで監視されている。

TikTokのような巨大プラットフォームは、自動化ツールからのアクセスを極度に嫌う。

少しでも機械的な挙動を見せれば、即座にシャドウバンやIPブロックの対象になる。

人間らしさをエミュレートするためのコードが、システムの複雑さを指数関数的に跳ね上げていく。

サムネイル生成の「手3本問題」

動画のサムネイル画像をAIに自動生成させていた。

知的な雰囲気を出すために、「あごに手を当てる」ポーズを指定した。

すると、生成された人物の腕が3本生えてきた。

お前どういう体の構造してんだよ。

「fix: サムネバリデーションのプロンプト強化(手3本検出漏れ対策)」

最初は、生成された画像を別のAIにチェックさせる仕組みを入れた。

VLM(Vision-Language Model)を使って、生成された画像に異常がないか判定させる。

以下のルールで厳格なバリデーションを実施した。

* 「腕」だけでなく「手」も個別にカウントする

* 不自然な位置から生えている手足を検出する

* 少しでも怪しければ即座にNG判定とする

「fix: サムネバリデーション偽陽性を削減(シルエット/後ろ姿を許容)」

そしたら、正常な後ろ姿のシルエットまで弾かれるようになった。

偽陽性が多発し、半分以上の正常な画像がゴミ箱行きになった。

GPT-4VClaude 3 OpusなどのマルチモーダルAIに画像を投げ、プロンプトで厳格なチェックを指示した。

VLMは画像の全体的な文脈を理解するのは得意だが、「指が何本あるか」「腕がどこから生えているか」といった幾何学的な正確さを判定するのは苦手だ。

服のシワや影を「余分な腕」と誤認してしまう。

背景の観葉植物の葉っぱを「緑色の指」としてカウントしたこともあった。

僕はAIを力技でコントロールするのをやめた。

プロンプトから手の指定を全部消した。

「fix: サムネ表情プロンプトから手・腕の指示を削除(腕3本バグ対策)」

プロンプトの変更点は以下の通りだ。

* 極端なクローズアップ指定を削除

* スーツ固定をやめ、職業に合わせた多様な服装を許可

* 金額偏重のテキストをやめ、多様な表現に変更

しんたろーしんたろー:
プロンプトから手の指示消したら、一発OK連発。今まで必死に書いてた長文プロンプト何だったんだよ。

AIの特性を理解し、システムの挙動を予測できるようになった。

AIが失敗しにくい環境、つまり制約の少ないキャンバスを用意する。

システムを飼い慣らす視点を持つことで、開発の主導権を取り戻した。

プロンプトエンジニアリングのトレンドは大きく変化している。

初期は「ネガティブプロンプト」に「bad anatomy, extra limbs, missing fingers」といった呪文を大量に詰め込むのが主流だった。

しかし、最新のモデルでは過剰なネガティブプロンプトは逆効果になることが多い。

モデルが「extra limbs」という概念に引っ張られ、かえって不自然な画像を生成してしまう。

現在のベストプラクティスは「書かない」ことだ。

モデルが学習データから獲得した自然な人体のプロポーションを信じ、余計な制約を与えない。

AIをコントロールしようとする人間のエゴが、バグを生み出していた。

ここまで読んだあなたに

今なら無料で全機能をお試しいただけます。設定後はAIが投稿案を毎日生成。確認して選ぶだけ。

無料で始める

落とし穴:ニュースレター多重配信の恐怖

一番肝を冷やしたのは、ニュースレターの多重配信バグだ。

同じメールがユーザーに3通も届いた。

分散システムにおいて、処理の重複を防ぐ冪等性の担保は最も重要だと言われている。

Amazonのカート決済などでも、並列処理のバグは致命的な事故を引き起こす。

「fix: ニュースレター多重配信バグを3層防御で修正」

僕は以下の3層の防御を実装した。

* キューの並列実行数を1に制限する

* 処理開始直後に本日の配信済みフラグをチェックする

* データベースのCAS条件付きで記事を即座にロックする

しんたろーしんたろー:
同じメール3通送信とか冷や汗止まらん。最初から3層防御にしとけばよかった。クレーム対応で週末潰れるところだった。

非同期処理のワーカーが同時に複数立ち上がった際、データベースの更新がミリ秒単位で競合した。

ワーカーAが「未送信」と判定してメール送信処理に入った直後、ワーカーBも「未送信」と判定して同じ処理を始めてしまう。

典型的なレースコンディションだ。

Node.jsのイベントループはシングルスレッドだが、外部APIの呼び出しやデータベースへのクエリは非同期で実行される。

I/O待ちの間に別のリクエストが処理され、状態の不整合が発生する。

これを防ぐには、アプリケーション層のロジックだけでは不十分だ。

データベース層での物理的なロック機構が必要になる。

CAS(Compare-and-Swap)は、更新時の条件として「現在の状態が期待通りであること」を要求する手法だ。

「ステータスが未送信の場合のみ、送信中に更新する」というクエリを投げる。

PostgreSQLMySQLなどのリレーショナルデータベースは、トランザクションのACID特性により、この更新を直列化して処理する。

ワーカーAの更新が成功した場合、ワーカーBの更新は条件不一致で失敗する。

これにより、物理的に同じ処理が走らない状態を作れる。

Stripeなどの決済システムが二重請求を防ぐために使っているのと同じ、オプティミスティックロックの考え方だ。

分散システムにおいて、一度だけ処理が実行されることを保証する「Exactly-Once」の実現は、コンピュータサイエンスにおける最難問の一つとされている。

今日の数字

今週の開発データをまとめた。

数字の裏には、冷や汗をかくようなトラブルが隠れている。

| 項目 | データ |

|---|---|

| 総コミット数 | 20件 |

| バグ修正 | 18件 |

| 新機能追加 | 2件 |

企業なら数人がかりで数週間かかるブラウザ自動化の泥沼と多重配信のバグ修正を、Claude Codeと2人で数日で駆け抜けた。

圧倒的なスピードだ。

ただし、僕の精神力はゴリゴリ削られた。

FAQ

Q: ブラウザ自動化でDraft.jsなどのリッチテキストエディタを操作する際の最大の障壁は何か?

A: 仮想DOMと実際のDOMの乖離だ。外部からJavaScriptで値を直接書き換えても、Reactなどの内部状態は更新されない。人間と同じようにOSレベルでキーボードイベントを発火させる「keyboard.type」方式が確実な回避策になる。

Q: 画像生成AIで特定の部位(手や足)が破綻するプロンプト・オーバーフィッティングを防ぐには?

A: 問題の部位に対する直接的な指示をプロンプトから完全に削除する。AIに細かく指定するほど、そのトークンへの重み付けが過剰になり構図が崩壊する。全体の雰囲気や服装の指定に留め、細部の描画はAIの潜在空間の自然なバランスに任せるのが一番だ。

Q: 1人開発で並列処理による多重配信バグ(同じメールが3通届く等)を完全に防ぐアーキテクチャは?

A: アプリケーション層だけでなく、データベース層での物理的なロック機構を組み合わせる。処理開始前のフラグチェックに加え、更新時にCAS(Compare-and-Swap)条件を付ける。これにより、ミリ秒単位で同時に走った別プロセスをデータベース側で確実に弾き落とせる。

泥沼の先の景色

自動化ツールを作っているはずが、自動化のメンテナンスに追われている。

次からはTikTok側の仕様変更を先に見る。たぶん。

👉 ThreadPostでSNS運用を自動化する

ThreadPost — SNS投稿をAIが自動化

この記事が参考になったら、ThreadPostを試してみませんか?投稿作成・画像生成・スケジュール管理まで、AIがサポートします。

無料で始める

この記事をシェア

XはてブLINE
しんたろー

ThreadPost開発者・個人開発エンジニア

AI × SaaS個人開発者。Cursor / Claude Code を使った効率的開発、SNS自動化について実体験から発信。

人気の記事