Stable Diffusion(SDXL)のタグをカテゴリ別に見本画像つきで選び、「同じキャラで表情や場所だけを変えた prompt」を連番でまとめて作るツール。
本番環境: sd-tag-builder.chibiham.app

コンセプト
差分画像を作るとき、prompt の大半は同じで、変えたいのは表情・場所・小物などの一部だけ。これを手で何十本も書き分けるのはつらく、タグ名だけを見て選んでも、実際にどう描かれるかは生成してみるまで分からない。
- 見て選ぶ: 全タグに、同じキャラ・同じ構図・同じ seed で描いた見本画像を付け、タグだけの違いを見比べられるようにした
- 固定部分と変わる部分を分ける: テンプレートを「固定タグ」「ネガティブ」「スロット(入れ替える候補の束)」で組み立てる
- 番号で再現できる: seed と番号が同じなら常に同じ prompt になる。「#004 だけ作り直す」ができる
- どの生成環境でも使える: 出力はクリップボードへのコピーとテキストだけ。ComfyUI・WebUI など環境を選ばない
アーキテクチャ
- Next.js 16 の静的書き出し(
output: "export"): サーバー処理はなく、out/を Cloudflare Workers の静的アセットとしてそのまま配信する。カスタムドメインで公開 - ローカル完結: テンプレートや独自タグはブラウザの IndexedDB に保存する。アカウント・DB・API が要らない
- 見本画像はビルドに同梱: 画像は 512×512 の JPEG でアプリと一緒に配信する。
_headersで 7 日間キャッシュし、画像の一覧(tag-samples.json)だけは毎回確認させて、作り直した画像は?v=<生成日時>で取り直す
技術選定のポイント
- サーバーを持たない
- 書き込みは自分のブラウザの中だけなので、保存は IndexedDB で足りる。バックアップと移行は JSON の書き出し・読み込みで対応
- 静的アセットへのリクエストは課金されず、Cloudflare は転送量も課金しない。1,000 枚を超える画像を配っても、運用費はドメイン代だけ
- 状態管理は Zustand、保存は
idb- 画面の状態と永続化をストアにまとめ、変更を自動保存する。テストでは
fake-indexeddbで保存と読み込みまで確かめる
- 画面の状態と永続化をストアにまとめ、変更を自動保存する。テストでは
- 生成ロジックは React から切り離した純粋関数
generate(template, run, index)は入力だけで結果が決まる。UI と独立してテストでき、一覧・コピー・書き出しがすべて同じ関数を通る
- UI ライブラリを使わない
- ボタンやダイアログ、初回のツアーまで Tailwind CSS と素の React で作った。機能に対して依存を小さく保つため
特徴的な実装
seed で再現できる連番生成
スロットごとに、(seed, slotId, index) の組を FNV-1a でハッシュして PRNG(mulberry32)の種にする。番号ごとに独立した乱数になるので、途中の番号だけを計算でき、順番に生成し直す必要がない。
スロットには 3 つの進み方がある。
- sequence: 候補を順番に進める。
stride(何枚ごとに進むか)とoffsetを持ち、複数の sequence を「毎枚同時に進める(zip)」か「全組み合わせ(grid)」に揃えるボタンも付けた - shuffle: 周回ごとに順列を作り、一巡するまで同じ候補を出さない。周回番号も種に含めるので、どの番号からでも計算できる
- random: 候補ごとの重みで抽選する
どのモードにも「一度に何個取るか(pick)」と「付与する確率」を設定できる。

送りながらコピーする出力
← → キー(または出力欄のボタン)で番号を送ると、その番号のポジティブ prompt がそのままクリップボードに入る。生成環境に貼っては戻って次を送る、という往復を最小にするための操作。全件を 1 行 1 prompt でまとめてコピー・テキスト保存もでき、一覧では各番号でどの候補が選ばれたかを確かめられる。

自宅 ComfyUI で作った見本画像
見本画像は自宅の ComfyUI(RTX 3090、SDXL)で生成した。カテゴリごとに構図のテンプレートを決め、キャラ・服装・seed を揃えることで、画像の違いがタグだけになるようにしている。
- タグの追加はローカル専用の管理画面から行う。カテゴリを選んでタグを入れると ComfyUI の API で見本を生成し、目で確かめてから
tags.json・画像・一覧をまとめて更新する - ワークフローは ComfyUI に登録したものを API 形式で呼び、差し替えるノードはノード ID ではなく title で探す。ComfyUI 側でノードを組み替えても壊れない
- 人物は服を着せ、性的な構図にしないネガティブを基本にする。露出が増えやすいタグは大人のキャラにし、一括生成から外して採用前に必ず目で確認する
テンプレート集と共有
用意済みのテンプレート(表情差分・キャラシート・衣装ローテーションなど 21 種)をすぐ試せる。テンプレートは 1 ファイルに書き出して人に渡すことができ、使っている独自タグと画像も同梱する。独自タグだけを zip(fflate)で書き出し・読み込みすることもできる。
初回のツアー
初めて開いたときに、画面の各部分を順に光らせて説明するツアーを出す。ライブラリは使わず、対象の要素に付けた data-tour 属性の位置を測り、box-shadow で周りを暗くして切り抜いている。スロットの説明では右のパネルを自動で切り替え、終わると元のタブに戻す。

開発・運用
- テスト(Vitest): 生成ロジック(モードごとの進み方・再現性・重み)、ストアの保存と読み込み、zip の往復、テンプレート集が組み込みタグだけを使っていること、見本画像のプロンプト組み立て
- デプロイ:
next build→wrangler deploy。Worker のコードはなく、静的アセットだけを配信する - コスト: Cloudflare Workers の無料枠とドメイン代のみ
