※この記事は、Claude Codeで1人開発しているSNS運用SaaS「ThreadPost」の開発日記です。
SNS運用を自動化しませんか?
ThreadPostなら、投稿作成・画像生成・スケジュール管理まで全てAIにお任せ。
冒頭の惨劇
「カテゴリを52種類に厳格化して」とAIに指示した。数分後、データベースを見たらカテゴリが116種類に増殖していた。僕が頼んだのは「厳格化」だ。誰が倍に増やせと言ったのか。

今日の開発サマリー
今日の総コミットは25件だ。新機能が3件、バグ修正が1件だった。ニュース収集の精度を上げるため、カテゴリ設計に手を入れた。AIに自動分類を任せたら、判断軸がブレて無限ループに陥った。最終的に設計書ベースの管理体制へ移行し、RSS収集の並列化まで一気に片付けた。

AIの暴走とカテゴリ増殖の地獄
AIに「カテゴリを52種類に厳格化して」と頼めば、綺麗に整理整頓してくれるはずだった。ニュースのカテゴリ設計、最初は自分で考えて作っていた。でも途中で「これ、RSSの構造と全然合ってない」と気づいて全部捨てた。
各メディアが配信するRSSフィードは、カテゴリの粒度がバラバラだ。あるメディアは「テクノロジー」と大括りにし、別のメディアは「AI」「ガジェット」と細分化する。これをそのままシステムに取り込むと、ユーザーの選択画面がカオスになる。
RSSという枯れた技術は、標準化されているようで中身は無法地帯だ。XMLの構造は同じでも、パブリッシャーごとの思想が強すぎる。これらを共通のフォーマットに落とし込む作業は、果てしなく泥臭い。
だから僕は「RSSフィードの実態に合わせてカテゴリを再設計してくれ」と指示した。そこから国内・海外を統一して、AIが自動で分類する仕組みを作った。で、52種類に落ち着いたはずが、気づいたら116種類に増えていた。
「feat: カテゴリを116種類に拡張(整理前の状態)」
いや、誰が増やしたんだよ。僕が「厳格化」って言ったのに。SNS運用、副業、動画クリエイター、さらには心理・自己理解まで。AIは「分類の網羅性」を優先して、細かいニッチなカテゴリを勝手に作り出した。
大規模言語モデルのプロンプトにおいて、制約条件の優先順位が低いとこうなる。目の前のデータを「とにかく正確に分類しよう」として、過剰適合を起こす。結果として、システム全体で管理不能なカオスが爆誕した。
SaaSのオンボーディングにおいて、選択肢の多さは致命傷になる。ヒックの法則だ。選択肢が増えれば増えるほど、ユーザーの意思決定時間は長くなる。116種類のカテゴリを見せられたら、ユーザーは設定を諦めて離脱する。
オンボーディングの完了率は、SaaSの死活問題だ。最初の画面で迷わせたら、そのユーザーは二度と戻ってこない。だからこそ、カテゴリは厳選された少数の選択肢であるべきだ。
そこから削って整理して、最終的にv5として109種類・15グループに着地させた。「増えてから削る」という無駄な往復を2回やった。
「refactor: カテゴリ構造v5に整理(109種類・15グループ)」
一番キツかったのは、分類の軸がコミットのたびにブレていたことだ。AIは「追加してくれ」と言えば足すし、「削れ」と言えば削る。判断軸を持っているのは僕だけだから、設計書を先に固めないと無限ループになる。
カテゴリの階層化を怠ると、DBのスキーマ設計とAIの出力が乖離する。そのまま後続のフィルタリング処理に流せば、データ不整合で全滅する。これはデータベース設計における典型的なアンチパターンだ。
関係データベースにおいて、マスタデータは人間が厳格に管理すべき領域だ。そこにAIの「揺らぎ」を持ち込むと、参照整合性が崩壊する。今回はまさに、その地雷を自ら踏み抜いた形になった。
カテゴリだけでなく、ペルソナのプロンプト設定でもAIは暴走した。「お弁当ダイアリー」というペルソナの指示を追加したときのことだ。
「feat: お弁当ダイアリーペルソナにお弁当視点の指示を追加」
僕は「どんな料理記事でもお弁当の視点から語る」という指示を入れた。するとAIは、既存のプロンプト構造を無視して勝手に新しいフォーマットを作り始めた。「博多グルメ」のペルソナでも同じことが起きた。
「feat: 博多グルメペルソナのbackgroundに詳細ガイドを統合」
画面編集時とAI生成時でプロンプトの型が変わってしまう。AIは「良かれと思って」毎回違う言い回しや独自ロジックを混ぜ込んでくる。冗長な口癖バリエーションが無限に生成され、キャラの統一感が崩壊した。
「fix: ぽすたま16キャラのプロンプトを設計書通りに修正」
結局、全16キャラのプロフィールとプロンプトをプロ目線でレビューし直した。AIの独自生成ロジックを廃止し、設計書のプロンプトをそのまま使用するスクリプトを書いた。AIに自由を与えすぎると、システムとしての再現性が死ぬ。
システム開発において「冪等性」は絶対のルールだ。同じ入力を与えたら、必ず同じ出力が返ってこなければならない。AIの「創造性」は、この冪等性と猛烈に相性が悪い。
だからこそ、プロンプトは変数ではなく定数として扱うべきだ。AIに考えさせるのは「分類」や「抽出」といったタスクに限定する。「ルール作り」まで任せると、今日のような地獄を見る。
しんたろー:
マジで丸一日無駄にした。AIの「はい、やります!」は信用しちゃダメだ。コミット履歴見たら、カテゴリ数が52→116→109と乱高下してる。設計書なしでAIに任せた僕がバカだった。
結局、ニュース設計を抜本的に変更した。カテゴリを直接管理するのではなく、RSSマッピング方式へ切り替えた。
「docs: ニュース設計を抜本的に変更(カテゴリ→RSSマッピング方式)」
国内と海外のニュースカテゴリを完全に統一し、14種類に対応させた。ユーザーはRSSソースではなく「興味のあるカテゴリ」を選択する。システムが自動的に適切なRSSソースをマッピングする仕組みだ。
これでAIの暴走を止める「壁」ができた。カテゴリ系の変更は、必ず設計書を更新してから指示するようにした。ルールを明文化しないと、AIは無限に気を利かせ続ける。52種類に厳格化しようとして、丸一日を溶かした。
タイムアウトの嵐と並列処理の覚醒
ニュースカテゴリの地獄から抜け出した後、RSSの見た目をリッチにしようとした。NHKなどのニュースサイトから画像をサクッと取得する処理を追加した。これが新たな地獄の入り口だった。
「fix: NHK画像取得タイムアウト対策とRSS収集最適化」
重いサイトのレスポンスに引きずられ、Vercelのサーバーレス関数がタイムアウトの嵐になった。画像取得のたびにプロセスが死に、RSS収集全体が止まるという本末転倒な事態。同期処理で外部APIやスクレイピングを叩くと、N+1問題ならぬ「N+1タイムアウト」が発生する。
サーバーレス環境は実行時間の制限が極めて厳しい。Vercelの無料プランなら10秒、有料プランでも設定次第ですぐに上限に引っかかる。1つの重い処理が、全体のバッチ処理を道連れにしてクラッシュする。
外部APIへの依存がもたらすカスケード障害だ。1つのサイトが重いだけで、システム全体が沈黙する。分散システムにおいて、これは絶対に避けなければならない。
Node.jsのシングルスレッドモデルは、非同期I/Oに特化している。しかし、外部通信の待ち時間を直列で処理すれば、ただのボトルネックになる。ネットワークの遅延は、コードの最適化ではどうにもならない物理的な壁だ。
だから僕は非同期の並列実行に切り替えた。画像取得タイムアウトを5秒から20秒へ延長した。さらに、Promise.allSettledによる並列バッチ処理を実装した。
「feat: RSS画像取得を30件ずつ並列バッチ処理に変更」
RSS収集を「記事収集」と「画像取得」の2段階に分離した。画像取得を30件ずつ並列で回す。失敗を許容するエラーハンドリングは、外部通信における必須の生存戦略だ。
通常のPromise.allを使うと、1つでもエラーが出たら全体が死ぬ。allSettledなら、失敗したものは失敗として記録し、成功したものだけを次に進められる。不安定な外部サイトを相手にするなら、この非同期処理の使い分けが命綱になる。
なぜ30件ずつなのか。一気に100件の並列リクエストを投げると、今度は相手側のサーバーからDDoS攻撃とみなされる危険がある。レートリミットを回避しつつ、スループットを最大化する妥協点が30件だった。
結果、処理時間は劇的に縮んだ。100記事の画像取得が約40秒で終わるようになった。直列処理なら数分以上かかり、途中で確実にタイムアウトしていた処理だ。
最初はNHKの画像取得自体をスキップして高速化しようとした。でも、ニュースフィードに画像がないとUIがスカスカになる。だから数分後にスキップを解除して、正面からタイムアウトと戦う道を選んだ。
「fix: NHK画像取得復活 & 英語記事・未分類記事対応強化」
ここで効いてきたのが、さっきの並列バッチ処理だ。タイムアウトを20秒に延ばしても、他の処理をブロックしない。重い処理は裏で勝手に待たせておけばいい。
非同期処理の真髄は「待つこと」を恐れないことだ。同期処理では「待つ=止まる」だが、非同期なら「待つ=別のことをする」になる。Node.jsのイベントループが、空いたリソースを別の画像取得に回してくれる。
結果的に、NHKの画像も正常に取得しつつ、全体の処理時間は短いまま維持できた。逃げて機能を削るのではなく、アーキテクチャの変更で殴り勝った。こういう瞬間があるから、プログラミングは辞められない。
しんたろー:
並列処理の威力エグい。ログが滝のように流れて一瞬で終わった。Vercelのタイムアウトに怯える日々はこれで終わった。
これでRSS収集の安定性が跳ね上がった。収集頻度も24時間毎から3時間毎へ大幅に引き上げた。システムが強固になった分、Vercelのログ容量が爆発的に増えた。
ここまで読んだあなたに
今なら無料で全機能をお試しいただけます。設定後は完全放置でプロ品質の投稿を毎日生成。
落とし穴
AIに「厳格化」と命じると、AIは「網羅性」を優先してカテゴリを倍増させる。これはプロンプトの制約条件が甘いと必ず起きる。また、外部APIの同期処理はサーバーレス環境では即死フラグだ。並列処理への切り替えは、機能追加よりも先にやるべきだった。
今日の数字
今日の開発データをまとめた。
| 項目 | データ | 比較対象 |
|------|--------|----------|
| 総コミット数 | 25件 | 昨日は10件。倍以上。 |
| カテゴリ数 | 109種類 | 当初予定は52種類。 |
| 画像取得時間 | 40秒/100記事 | 直列処理なら数分以上。 |
| AI API費用 | 月額約400〜500円 | 手動分類なら人件費数万円。 |
109種類のカテゴリ管理を人間が手動で行うと、更新頻度と整合性維持で週10時間は溶ける。開発者の時給を数千円と見積もれば、週に数万円のコストだ。Claude Haikuによるバッチ処理なら、API代は月額数百円で済む。AIの圧勝だ。
しんたろー:
月額500円でこの分類精度が出るなら文句ない。ただ、僕のプロンプトのせいで無駄なAPIコールが走った分は反省してる。
FAQ
運用コストの最適化はどうやっている?
Claude Haikuモデルを採用し、40記事単位のバッチ処理で回している。低コストかつ高速なモデルをバッチで動かすことで、APIコストを月額数百円程度に抑え込んだ。自前で分類ロジックを保守する人件費を考えれば、AIに投げたほうが圧倒的に安い。
なぜRSSのソースを直接選ばせず、カテゴリ経由にしたのか?
ユーザーは「特定のメディア」ではなく「興味のあるトピック」を求めているからだ。RSSソースを直接管理させると、メディアの閉鎖やURL変更でユーザー体験が即死する。間に抽象化レイヤーを挟むのが、保守性の観点で正解だ。
英語と日本語の混在データはどう処理した?
未分類記事に対するフォールバック分類システムを実装した。プロンプトを改善し、言語判定を前段で行うようにした。実データでの精度は明日以降のログで検証する。
まとめ
AIに「厳格に」と指示したらカテゴリが倍増した、皮肉な一日だった。ThreadPostは今日も進化した。

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