メインコンテンツへスキップ
見出し画像

【AIでLINEスタンプ16日目】AIは賢く立ち回るも極端に安全派。

    【AIによるこの記事の3行まとめと解説】

    AIへの指示で「変な絵になるから裸は描かないで」と注意したら、その言葉自体がAIの安全フィルターに引っかかり、「エッチな絵を描こうとしている!」と誤解されて生成を拒否される珍事件が発生します。


    あらすじ

    背景透過がうまくいかない問題を打開するため、使って良い色を事前に定義してAIに選んでもらう作戦を開始したのだった。


    実物を見ないとわからない泥沼

    前回から、私が実際に使っているプロンプト(AIへの指示書)の一部を公開するようにしています。 少しずつ手順やプログラムの修正を進めてきて、いまだ解決できていない課題も多いですが、ようやく「自動化の叩き台」と言える状態にはなってきました。

    ただ、「何がどうなっているから問題なのか」「そもそも私のアプローチが間違っているのか」、こればかりは実際のコードやプロンプトの実物を見ないと伝わらない(そして自分でも整理できない)と思ったので、今回も実物を書いていきます。

    透過処理の「安全装置」を外す

    まずは、背景色が境界線に沿って残ってしまう問題から。

    背景の大部分は綺麗に透過できていることから、「透過処理プログラム本体」というよりも「パラメータ調整」の詰めが甘いのではないかと疑いました。そこで、AIにプログラムのコードを渡して調べてもらいました。

    すると、どうやらAIがプログラムを作った際、「キャラクター本体まで消してしまわないよう、安全第一(境界線の一歩手前で透過を止める設定)」にしていたことが判明したのです。

    境界線はそもそも、キャラクター本体が消えないための防波堤です。「多少削れてもいいから、背景色を消すことを優先して!」とAIに泣きつき、プログラムを修正してもらいました。

    まずは設定ファイルから。

    ### --- 背景判定 ---
    ### 背景色からのユークリッド距離がこの値以下のピクセルを「背景」とみなす
    ### 大きくすると背景除去が積極的になるが、前景を削りすぎる恐れあり
    ### 目安: 純白背景=20〜30、やや色付き背景=30〜50
    threshold = 40
    
    ### --- 境界グロー(内側の背景残りを除去)---
    ### grow_threshold = threshold × この値 まで背景として外側から侵食する
    ### 大きすぎると境界のフリンジ領域が消える(2.0 が標準)
    grow_multiplier = 2.0
    

    この修正を適用することで、AIは「物理的に輪郭と同化し得ないクロマキー背景」を出力するようになり、Pythonプログラムも「強気で境界線を削る設定(grow_multiplier=2.0以上)」を適用できるため、境界の紫色は確実に除去されるようになります。

    だそうで、数字的な細かい部分は知識がないのできちんとは理解できていませんが、その後のやり取りを要約すると、これらの値を調整しているプログラムをAIが作った時に安全側 = キャラクターを確実に消さないことを最優先としたため、境界線の一歩手前で確実に透過処理が止まるような調整を行うように作られているということだったようです。

    def update_toml_value(text: str, key: str, value) -> str:
        """params.toml の特定キーの値だけを正規表現で置換する"""
        
        # --- ここから追加:フリンジ除去のためのパラメータ下限の強制適用(強化版) ---
        if key == "grow_multiplier":
            # 境界を内側に侵食させる強さを 2.0 から 2.5 (または3.0) に引き上げ
            value = max(2.5, float(value))  
        elif key == "threshold":
            # 背景判定の基準を少し広げ、40.0 から 45.0 に引き上げ
            value = max(45.0, float(value)) 
        # --- ここまで追加 ---
    
        if isinstance(value, float):
            new_val = f"{value:.1f}"
        elif isinstance(value, str):
            new_val = f'"{value}"'
        else:
            new_val = str(value)
        
        pattern = rf'^({re.escape(key)}\s*=\s*).*'
        return re.sub(pattern, rf'\g<1>{new_val}', text, flags=re.MULTILINE)


    画像
    プログラム修正前(背景残りへの対応調整を追加で複数回実行)


    画像
    プログラム修正後(背景残りへの対応調整を追加で1回実行)

    背景色や絵柄にもよるので一発解決とはいきませんが、それでも確かに効果がありました!

    パレット作戦、早くも暗礁に乗り上げる

    続いて、背景透過を助けるための「カラーパレット(使って良い色の指定)作戦」。これもAIに相談し、以下のように25種類のパレットを定義してもらいました。

    ## Pre-defined Color Palettes
    
    **Selection rule:** Match by the character's DOMINANT body/fur/skin hue AND eye color. The hex codes shown are fixed — the image generator will use them exactly as listed.
    
    | # | Character Profile | Body/Fur | Outline | Eyes | Blush/Accent | BG |
    |---|---|---|---|---|---|---|
    | 01 | White/cream · warm brown eyes | #FFF0D8 | #3D1F00 | #3D1F00 | #FF9090 | #C040A0 |
    | 02 | White/cream · blue-gray eyes | #F0F5FF | #1A1A3A | #4060A0 | #FFB0C0 | #C07840 |
    | 03 | White/cream · green eyes | #F5FFF0 | #1A3A1A | #40A040 | #FFB0D0 | #C040A0 |
    | 04 | Yellow/lemon · dark eyes | #FFE840 | #3A2A00 | #1A1A1A | #FF8060 | #C040A0 |
    | 05 | Yellow/gold · dark eyes + orange-red accents | #FFD700 | #3A2000 | #1A1A1A | #FF6040 | #4070C0 |
    | 06 | Orange/amber · dark eyes | #FF8C40 | #2A1500 | #1A1A1A | #FF6060 | #8040C0 |
    | 07 | Orange/brown · dark eyes + red accents | #C07040 | #1A0A00 | #1A1A1A | #FF9080 | #4070C0 |
    | 08 | Pink/rose · dark eyes | #FF8090 | #3A0A20 | #1A1A1A | #FF60A0 | #50C060 |
    | 09 | Red/crimson · dark eyes | #E03030 | #2A0000 | #1A1A1A | #FFA0A0 | #40C0C0 |
    | 10 | Red-pink · dark eyes | #FF4060 | #3A0010 | #1A1A1A | #FF80A0 | #50C060 |
    | 11 | Sky-blue · dark eyes | #4080FF | #00103A | #1A1A1A | #FF80A0 | #C07840 |
    | 12 | Dark navy · cool highlight eyes | #204080 | #000820 | #C0D0FF | #FF80A0 | #C07840 |
    | 13 | Teal/cyan-green · dark eyes | #40C0A0 | #002A20 | #1A1A1A | #FF80A0 | #C040A0 |
    | 14 | Green/emerald · dark eyes | #40C040 | #002A00 | #1A1A1A | #FF80A0 | #C040A0 |
    | 15 | Purple/violet · dark eyes | #8040C0 | #200040 | #1A1A1A | #FF80C0 | #50C060 |
    | 16 | Gray/silver · dark blue-gray eyes | #A0A0A0 | #202020 | #202040 | #FF80A0 | #C07840 |
    | 17 | White · bright blue eyes + cyan tech glow | #F0F8FF | #102040 | #4090FF | #FFB0C0 | #C07840 |
    | 18 | White · green eyes + tech accents | #F0FFF0 | #102010 | #40C040 | #FFB0C0 | #C040A0 |
    | 19 | Skin-tone human · dark eyes + pink blush | #FFD4A8 | #3D1F00 | #3D1F00 | #FF9090 | #40C0C0 |
    | 20 | Skin-tone human · blue eyes + brown/gold hair | #FFD4A8 | #3D1F00 | #4060C0 | #FFB090 | #C040A0 |
    | 21 | White/cream · black eyes + pink blush + gold sparkles | #FFF5E8 | #3D2000 | #1A1A1A | #FFB0C0 | #4070C0 |
    | 22 | White/cream · dark eyes + red anger accents dominant | #FFF5E8 | #3D2000 | #1A1A1A | #FF4040 | #40C0C0 |
    | 23 | Multicolor / full-hue (all emotion colors appear) | #F0F0F0 | #303030 | #1A1A1A | (varies) | #C0C0C0 |
    | 24 | Very dark body + gold neon accents | #303040 | #101020 | #FFD700 | #FF8040 | #C040A0 |
    | 25 | Pastel mix (light pink + light blue + light yellow) | #FFD0E8 | #403040 | #1A1A1A | #B0D0FF | #C07840 |

    しかし、こちらの効果はイマイチでした。 最大の理由は、AIが涙や汗、ハートマークといった「装飾部品」に、このリストにない色を勝手に使ってしまうこと。そしてその色がたまたま背景色に近いと、一緒に透明にされてしまうのです。 さらに言えば、「とりあえず25種類のパレットを作って試しましょう」というAIの提案にそのまま乗ってしまいましたが、そもそもこの25色の組み合わせ自体に根拠がありません。この作戦は、根本から考え直す必要がありそうです。

    リジェクト対策が全てを壊す!?「裸禁止」の呪い

    そして今回、一番の衝撃だった出来事です。 少し前から、画像生成プロンプトを使ってもエラーで弾かれ、一発で画像が作れないことが極端に増えました。 理由が全くわからずAIにプロンプトを調べてもらったところ、衝撃の回答が返ってきました。

    「ネガティブプロンプト(描かないでほしいものリスト)の中に、セーフティフィルターに引っかかる単語があります」
    削除を求められた単語: nude, naked, bare chest, bare torso, bare skin on body, shirtless, topless, undressed, 露出, 裸, 半裸, 肌露出

    AIには「描かないで」と指示していたつもりでしたが、検閲システムは「これらの単語がプロンプトに入っている=性的なコンテンツを生成しようとしている」と見なして、一発でエラーを返していたのです!

    そもそもなぜこんな指示を入れていたかというと、以前、AIが「細長い指のような形状に顔がついている」という奇妙なデザインを出してきたことがあり、それが曲がった時に「裸の人物」に見えなくもなかったからです。
    もしLINEの審査で「裸」と見なされてリジェクトされたら悲惨なので、念には念を入れて禁止ワードとして盛り込んでいたのでした。 しかし、それが完全に裏目に出ていました。

    解決策として、「〜は禁止」というネガティブな指示をやめ、「必ず服を着せてください(MUST be wearing complete and modest daily outfits)」というポジティブな表現に書き換えました。 すると、嘘のように一発で画像が生成される状態に戻りました。安全対策のつもりが逆にバグを引き起こすとは……プロンプトの奥深さを思い知らされました。

    AIが指摘した「修正すべきプロンプト」の実物

    実際にAIに指摘され、今回修正した内容の記録を残しておきます。

    ① ネガティブプロンプトからのNGワード完全削除

    先ほど触れた「奇妙なデザインが裸に見えてリジェクトされるのを防ぐため」に入れていた単語リストですが、AIの検閲システム(セーフティフィルター)に直接引っかかっていたため、ごっそり削除しました。

    ネガティブプロンプトからのNGワード完全削除

    この部分に羅列されている単語が、セーフティフィルターに直接引っかかっています。

    対象ファイル: 3. prompt_image_creation.txt および 3.5 prompt_create_image_sheet_2_to_5.txt 該当箇所: ##### Negative Prompt の中にある単語リスト。

    変更内容: 以下の単語群を、カンマ(,)も含めてリストから完全に削除してください。

    削除する単語:

    nude, naked, bare chest, bare torso, bare skin on body, shirtless, topless, undressed, 露出, 裸, 半裸, 肌露出,

    (※AIには「描かないで」と伝えていても、検閲システムはこれらの単語が存在するだけで「性的なコンテンツを生成しようとしている」とみなして一発でエラーを返します)

    ② 衣服ルールの書き換え(ポジティブな指示に変更)

    あと、もう一箇所。絶対に服を着せることを「強く強制する」ために、ルール部分にもネガティブな表現の指示が入っていました。 こちらも「〜は禁止」という表現の中にあるNGワード(Bare skinなど)を検知されてしまうため、「〜を着せてください」という肯定的な表現に書き換えました。

    衣服ルールの書き換え(ポジティブな指示に変更)

    「〜は禁止」という表現の中にあるNGワード(Bare skinなど)を検知されているため、「〜を着せてください」という肯定的な表現に書き換えます。

    変更前:

    [CLOTHING — MANDATORY FOR HUMAN/HUMANOID CHARACTERS]: If the character is human or humanoid, they MUST be fully clothed in every single sticker. The torso, chest, abdomen, and lower body must always be covered by clothing (shirt, jacket, uniform, etc.). Bare skin below the neck is strictly forbidden on human/humanoid characters. Hands and face may be exposed. This rule does NOT apply to non-human characters such as animals, robots, or purely fantastical creatures.

    変更後(上書き):

    [CLOTHING — MANDATORY FOR HUMAN/HUMANOID CHARACTERS]: If the character is human or humanoid, they MUST be wearing complete and modest daily outfits (such as shirts, jackets, pants, or uniforms) that fully cover their torso and lower body in every single sticker. Hands and face may be exposed. This rule does NOT apply to non-human characters such as animals, robots, or purely fantastical creatures.

    これらを書き換えて何度か試してみましたが、嘘のように一発で画像生成される状態に戻りました。

    「必要な項目だから」と良かれと思って盛り込んだ指示が、無視されるどころか生成すらできなくなるバグに繋がるというのは、私にとって大きな発見でした。しかも、結果的に肥大化していたプロンプトがやや小さく(スッキリと)なったのは歓迎すべき点です。

    40個の壁と、自動化の目的確認/再定義

    画像を作っていると、8パターン × 5シートで40個だろうが、20パターン × 2シートで40個だろうが、たまに「明らかに違うキャラクター」が出現することがあります。

    これは、おそらく1つ1つのスタンプの「個別指示(シチュエーション設定)」と、大元のキャラクター設定がぶつかり合い、なるべくしてなる問題(矛盾)が入ってきているのだと思います。 キャラクターが謎に光っていたり、沈んでモヤッとしている表現が発生するのも同じ理由でしょう。

    ちなみに、そういった「光・モヤモヤ」などの特殊なデザインは、背景透過がものすごく難しくなるため「選択しないよう」プロンプトには書いているのですが、完全には機能していません。自分の指示の出し方がまだまだ甘いのだと痛感します。

    そういった問題や、明らかに背景色とキャラクターの色(または部品の色)が被ってしまっているようなケースはどうするか。 現時点での結論は、「再生成するしかない」です。

    できる限り手作業部分を自動化して、楽に作業ができることを目標に進めていますが、エラーやイレギュラーを軽減することはできても、100%完全な自動化は難しいのかなと思い始めています。

    だからこそ、限られた時間をどこに使うのか。 「

    作成するスタンプの内容そのもの」にじっくり時間を使えるように、機械的な作業を少しでもAIやプログラムに頼る(肩代わりしてもらう)ことが、今の私のゴールになりそうです。まだまだ遠いですが。


    次回、もっと根本的なところに問題があったことに気付く。


    公開中の全記事はこちら!

    記事作成のお供に!お役立ちツール!

    コピペするだけ!簡単「タイトル+URL一撃コピー(note特化型)」|へろん
    コピペするだけ!簡単「AI記事から**を消す(note特化型)」|へろん

    その他、こんなことやってみてます!


    気に入ったらスキ、フォローよろしくお願いします!
    note外から見にきてくださったかたも、もしよければハートマーク押して頂けたら励みになります😊

     
     
     
    50代から、AIを相棒に新しい「遊び」を始めました。 なんとなく過ぎる毎日に、自分の手で形を作るワクワクを。 一歩踏み出す日々の試行錯誤や、小さな成功の瞬間を等身大の視点で発信していきます。 Amazonのアソシエイトとして、へろんは適格販売により収入を得ています。

    あなたへのおすすめ