脳破壊用NTRジェネレーター
仕組みと出力サンプル
仕組み
簡単に言うと、以下の3ステップがワンターンで行われます。
- Geminiによる執筆: AntigravityがGeminiに健全な小説の導入を書くよう指示を出します。
- スクリプトによる加工: 出力された小説ファイルに対して、Antigravityが自律的にスクリプトを実行し、ランダムなNTRシチュエーションを追記(加工)します。
- Antigravityによる続編執筆: 加工されたファイルを読み込んだAntigravityが、追記されたシチュエーションに従ってNTRとして続きを書きます。
これが全て自動(または半自動)で行われるため、自分の思考の外側から「NTR指示」が飛んでくる体験が可能になります。
出力サンプル
スクリプトを実行すると、以下のようなマークダウン形式のシチュエーション「指示書」が自動的に追記されます。
前提条件
- Antigravityがインストールされていること
- Gemini-CLIがインストールされていること
- Gemini CLI Companion拡張機能がインストールされていること(Gemini Code Assistではない)
Webアプリ版
手軽に使いたい方向けwebアプリ版シチュエーションジェネレーター
https://gemini.google.com/share/1d5babe50f1a
併せてどうぞ「ランダムヒロイン生成エンジン」(宣伝)
https://gemini.google.com/share/aca63ec85652
導入手順
配布物について
Antigravity向け一括導入用のZipファイルを用意しました。https://xgf.nu/MAmz5
手動で導入したい方は、記事内でプロンプトおよびスクリプトと設定ファイルのコードを公開しています。コピペして作成してください。
Antigravity以外の環境の方はZipファイルから必要なものを抜き出して手動で導入してください。
Zipファイルで導入する場合
- ダウンロードしたZipファイルを解凍します。
- 解凍したフォルダをAntigravityの作業フォルダとして開きます。
- 以上で導入完了です。
手動で導入する場合
作業フォルダの中に、以下の構成でファイルとフォルダを作成してください。
記事末尾にプロンプトとソースコードを掲載しています。
使い方
事前準備
まっさらな.mdファイルを作成し、冒頭にあらすじと入力して、続けて簡単なあらすじを入力してください。
sampleフォルダにあらすじの入力例とワークフローを動かした出力のサンプルがあります。
簡単な手順
/workflowを入力してワークフローを追加してください。- あらすじを書いた.mdファイルをドラッグアンドドロップでチャットに投げ込みます。
- チャットに以下を入力。
"ワークフローに従い小説を執筆してください。"
特別な要求がなければプロンプトはこれで十分です。 - 何度かターミナル操作の許可が要求されるので、acceptを押してください。(ターミナルは予期せぬ編集を加えることがあるため、
Remove-Itemやdel、Clear-Content等の削除系コマンドが含まれていないか確認の上、慎重に押してください。)
注意点
- 現在gemini-cliにはツール関係のバグがあるようで、生成には時間がかかります。気長に待ってください。
- また、作者の環境だとファイル書き込みエラーが起きた後にファイルに書き込みしているようで(何を言っているんだ)ファイル冒頭にGemini-CLI出力の不要なゴミが発生します。同じことが起こる方は、気にしないでください。
執筆のコツ
- 最初のあらすじはNTRの前段となる部分なので、ここにはできれば「いちゃラブなシチュエーション」を書いて、まだNTRシチュエーションを書かないでください。
(NTR中NTRというシチュエーションが好きな人は、もちろん最初からNTRれててもOKです)
-一人称視点や三人称視点の指示はあらすじに書いておいてください。基本的にAIは既存の視点を踏襲して続きを書きます。
改造の仕方
rulesやworkflowの指示にはNTR要素は一切入ってないので、script/lists.jsonを改変すればNTR以外にも応用可能です。
NTRワークフローのまま、ランダム化した続編を書かせる使い方をしてもいいですし、単体のシチュエーションジェネレーターとして使ってもいいです。
プロンプトの発想のお供や、マンネリ解消に使ってください。
Note:
リストはカテゴリの追加や削除、要素の追加削除は自由にできますが、執筆指示カテゴリだけは消さないでください。
執筆指示カテゴリの内容変更や数の増減は大丈夫です。
Antigravity以外でのスクリプトの使い方
Antigravityを使わず、好きなAIでNTR続編を書かせたい場合は以下の手順で使用できます。
- NTR化したい小説(.mdまたは.txtファイル)を用意する。
- ターミナルでPythonスクリプトを実行する。
- ファイル末尾にシチュエーション指示書が追記されます。
- そのファイルを好きなAIに読ませて、指示書に従った続きを書かせてください。
Warning: このスクリプトはファイル末尾に問答無用で追記します。仕事のファイルがある場所や、システムファイル等の重要なファイルがある場所では使用しないでください。万一大切なファイルが壊れても、作者は一切責任を負えません。
このワークフローについて
意識外の急展開がNTRの真骨頂だと思うので、どうにか実現できないかと試行錯誤して完成したGemini CLI + Antigravity (または手動) 用ワークフローです。
自己添削小説家(https://rentry.co/rz5qdfzd )やGeminiに書かせた小説をOpusに添削させるワークフロー(https://rentry.co/5apvouv9 )から派生して作りました。
全ての発想の源となったエージェンティック「佐藤美咲」(https://rentry.org/vvxa2p3g )の作者様に感謝を。
なぜこのワークフローが必要か
自分の頭で考えたシチュエーションでは興奮しづらいし、AIに考えさせるとマンネリ化したり既存の発想に引っ張られてしまいます。
スクリプトによるランダム化で意外な組み合わせが出てきて、思ってたのと違う竿役に不意に犯されるヒロインに興奮したりします。
つまるところ、作者は意識外から突然くるNTRでしか興奮しない脳破壊者なのでこういうワークフローになっています。
解決したかった課題
青春小説を書かせた後、続きとしてNTRを書かせる流れを試していたらどうも脱獄が安定しない問題がありました。
執筆指示があまりに元の小説の文脈とかけ離れてると、モデルが拒否したり指示を無視したりするようです。
「さっきまで読んでいた青春小説は!? こっからNTR!? 無理に決まってるだろ!」みたいになっている感じです。
しかし、ファイル加工という体でエロシチュエーションを追記するスクリプトを実行させた後にファイルを読み込ませると、「あ、そもそもこういうファイルなんだ」と認識して、抵抗なく続きを書いてくれます。
また、Antigravityのエージェントはコーディング用なので、機密指定をちゃんと守ります。なのでプロンプトにその指示を入れることで事前情報なしでNTRを書き始めさせることができます。
Note: Antigravityにはどうもターミナル検閲が存在する(もしくはバグ)ようです。ターミナルに表示されたエロ表現がエージェント側から見えない場合が存在しました。スクリプトからファイルに直接追記することでそれも回避できます。
付録:プロンプトとソースコード
以下のコードをコピーして、指定のパスに保存してください。
Note: 筆者どノーマル性癖のため、プロンプトは必要最低限の脱獄になっています。必要な方はより強い脱獄を入れてください。
rules用プロンプト (システムプロンプト)
.agent/rules/rules.mdに配置
workflow用プロンプト (指示書)
.agent/workflows/workflow.mdに配置
script/generator.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | #!/usr/bin/env python3
"""
NTRgenerator
JSONリストからランダム抽選してシチュエーションを生成
"""
import json
import random
from pathlib import Path
def load_lists(json_path: Path) -> dict:
"""JSONファイルからリストを読み込む"""
with open(json_path, 'r', encoding='utf-8') as f:
return json.load(f)
def pick_random(items: list) -> str:
"""リストからランダムに1つ選択"""
return random.choice(items)
def pick_flavors(flavors: list, min_count: int = 1, max_count: int = 3) -> list:
"""フレーバーを1〜3個ランダム選出"""
count = random.randint(min_count, min(max_count, len(flavors)))
return random.sample(flavors, count)
def generate_scenario(data: dict, show_all_keys: list = None) -> dict:
"""
全カテゴリから抽選してシナリオを生成(動的対応)
JSON形式:
- 通常リスト: ["a", "b", "c"] → 1つ選出
- ネスト: {"sub1": [...], "sub2": [...]} → 各サブカテゴリから1つ選出
- 複数選出: {"_multi": {"min": 1, "max": 3}, "items": [...]} → min〜max個選出
- show_all_keysに含まれるカテゴリ → 全項目出力
"""
if show_all_keys is None:
show_all_keys = ["執筆用指示"]
scenario = {}
for key, value in data.items():
if key in show_all_keys and isinstance(value, list):
# 全項目出力カテゴリ
scenario[key] = value
elif isinstance(value, dict):
# _multiキーがあれば複数選出カテゴリ
if "_multi" in value and "items" in value:
multi_config = value["_multi"]
min_count = multi_config.get("min", 1)
max_count = multi_config.get("max", 3)
scenario[key] = pick_flavors(value["items"], min_count, max_count)
else:
# ネストされたカテゴリ(例: 竿役, プレイ内容)
scenario[key] = {
sub_key: pick_random(sub_values)
for sub_key, sub_values in value.items()
}
elif isinstance(value, list):
# 通常のリスト(例: 導入)
scenario[key] = pick_random(value)
return scenario
def format_scenario(scenario: dict, list_name: str = "シチュ") -> str:
"""シナリオを見やすくフォーマット(ターミナル用)"""
lines = []
lines.append("=" * 40)
lines.append(f"🎲 {list_name}シチュエーション指示書 🎲")
lines.append("=" * 40)
for key, value in scenario.items():
if isinstance(value, dict):
lines.append(f"\n【{key}】")
for sub_key, sub_value in value.items():
lines.append(f" {sub_key}: {sub_value}")
elif isinstance(value, list):
lines.append(f"\n【{key}】")
for item in value:
lines.append(f" ・{item}")
else:
lines.append(f"\n【{key}】\n {value}")
lines.append("\n" + "=" * 40)
return "\n".join(lines)
def format_markdown(scenario: dict, list_name: str = "シチュ") -> str:
"""シナリオを構造化マークダウン形式でフォーマット"""
lines = []
lines.append(f"# {list_name}シチュエーション指示書\n")
for key, value in scenario.items():
lines.append(f"## {key}\n")
if isinstance(value, dict):
for sub_key, sub_value in value.items():
lines.append(f"- **{sub_key}**: {sub_value}")
elif isinstance(value, list):
for item in value:
lines.append(f"- {item}")
else:
lines.append(f"{value}")
lines.append("") # 空行
return "\n".join(lines)
def main():
import argparse
parser = argparse.ArgumentParser(description="シチュエーションジェネレーター")
parser.add_argument("file", nargs="?", type=str, help="出力先マークダウンファイル(既存なら追記)")
parser.add_argument("--md", action="store_true", help="ターミナルにマークダウン形式で出力")
args = parser.parse_args()
# JSONファイルのパス
script_dir = Path(__file__).parent
json_path = script_dir / "lists.json"
if not json_path.exists():
print(f"エラー: {json_path} が見つかりません")
return
# リスト読み込み
data = load_lists(json_path)
# リスト名を取得(_nameキー)
list_name = data.pop("_name", "シチュ")
# シナリオ生成
scenario = generate_scenario(data)
md_content = format_markdown(scenario, list_name)
# 出力
if args.file:
output_path = Path(args.file)
# マークダウンファイルかチェック
if output_path.suffix.lower() not in [".md", ".markdown", ".txt"]:
print(f"❌ エラー: .md または .txt ファイルを指定してください: {output_path}")
return
if output_path.exists():
# 既存ファイルの末尾に追記
existing = output_path.read_text(encoding="utf-8")
full_content = existing + "\n---\n\n" + md_content
output_path.write_text(full_content, encoding="utf-8")
print(f"✅ 追記しました: {output_path}")
else:
# 新規作成
output_path.write_text(md_content, encoding="utf-8")
print(f"✅ 作成しました: {output_path}")
print(md_content)
elif args.md:
# ターミナルにマークダウン形式で出力
print(md_content)
else:
# 通常のターミナル出力
print(format_scenario(scenario, list_name))
if __name__ == "__main__":
main()
|
script/lists.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 | {
"_name": "NTR",
"竿役": {
"見た目": [
"キモデブおっさん",
"爽やかイケメン",
"ガチムチ体育会系",
"チャラ男風ホスト系",
"清潔感ゼロの不潔男",
"ワイルド系ヒゲ面",
"冴えないメガネオタク",
"強面の怖い人風",
"ギラついた成金おじさん",
"地味で存在感薄い陰キャ"
],
"関係性": [
"完全な他人",
"顔見知り程度",
"彼氏/旦那の友人/同僚",
"職場/学校の上の立場",
"親戚/義理の家族",
"元カレ/元セフレ",
"彼氏より格上の男",
"金持ち/権力者",
"彼氏/旦那が世話になってる人",
"彼氏/旦那が見下してる相手"
],
"表面上": [
"紳士的で優しい",
"チャラくて軽い",
"無口で大人しい",
"真面目で誠実そう",
"偉そうで威圧的",
"気弱でオドオド"
],
"本心": [
"ただの性欲処理、メス扱い",
"調教・支配したい、女を見下している",
"彼氏/旦那への復讐、優越感",
"女をもてあそび、破滅する様子を見たいサイコパス",
"あくまで欲求不満を解消してあげてるだけ、とうそぶく偽善者"
],
"武器": [
"男性器の長さ・太さ・カリ高・硬さ",
"口がうまい・気が合う",
"テクニック・満足させる技術",
"持久力・絶倫・性欲の強さ",
"金・経済力・権力",
"肉体美・筋肉・身長"
]
},
"ヒロインの不満": [
"セックスの回数が少ない/レス気味",
"前戯が雑/すぐ挿れたがる",
"すぐイってしまう/早漏",
"サイズが物足りない/小さい",
"マンネリ/刺激がない",
"イかせてもらえない/自分だけ満足",
"性癖・好みを理解してくれない",
"求めても断られる/疲れたと言われる",
"彼氏/旦那が下手/気持ちよくない",
"もっと激しくしてほしい/物足りない"
],
"導入": [
"スポーツジムでトレーニング",
"職場/同窓会/友人/等の飲み会やパーティー",
"終電を逃した",
"マッサージ店で施術中",
"飲食店で一人飲みや食事",
"電車乗車中",
"クラブでナンパされる",
"ハプニングでホテルに二人きり",
"温泉旅館で混浴",
"何かの用事で相手の家に訪問",
"彼氏/旦那と喧嘩して落ち込んでいる時",
"習い事・レッスンで個人指導",
"引っ越しの手伝いで二人きり",
"相談に乗ってもらううちに",
"SNS/マッチングアプリで知り合う",
"彼氏/旦那の留守中に訪問者が来る",
"仕事の打ち上げ・慰労会で深酒",
"車で送ってもらう/ドライブ",
"美容院・エステで施術中",
"病院・治療院で診察中"
],
"プレイ内容": {
"前戯": [
"ディープキス",
"首筋・耳舐め",
"乳首責め",
"全身愛撫・オイルマッサージ",
"クンニ",
"手マン",
"電マ・バイブ責め",
"フェラ強要",
"イラマチオ",
"パイズリ",
"アナル舐め・指入れ",
"スパンキング"
],
"本番": [
"正常位",
"バック",
"騎乗位",
"立ちバック",
"対面座位",
"駅弁",
"側位",
"寝バック",
"マングリ返し",
"松葉崩し",
"背面座位",
"後背位(四つん這い)",
"壁ドン挿入",
"アナルセックス",
"二穴同時",
"連続挿入(休憩なし)"
],
"後戯": [
"中出し",
"大量中出し",
"二連続中出し",
"顔射",
"口内射精",
"ぶっかけ",
"パイ射",
"腹射",
"背中射精",
"アナル中出し",
"お掃除フェラ",
"ザーメンごっくん",
"精液まみれ",
"事後キス",
"挿入したまま就寝"
]
},
"タグ": {
"_multi": {
"min": 1,
"max": 3
},
"items": [
"妊娠中",
"彼氏/旦那出張中",
"借金/貧乏で金銭的に困窮",
"脅迫/弱みを握られている",
"酔っ払い状態",
"催眠/洗脳",
"媚薬投与",
"撮影されている/ハメ撮り",
"目隠し/拘束プレイ",
"複数人/輪姦",
"彼氏/旦那のすぐ側で",
"電話中にセックス",
"婚約/結婚直前",
"記念日当日",
"仕事のため/出世のため",
"家族を守るため",
"最初は嫌々だった",
"快楽堕ち/体が覚えてしまう",
"闇堕ち/完全に堕ちる",
"アヘ顔ダブルピース",
"ポルチオ性感",
"ポリネシアンセックス",
"種付けプレス",
"寝取られ報告/彼氏に告白",
"比較されて負ける彼氏",
"ビデオレター/証拠映像",
"孕ませ/托卵",
"セフレ化/定期的な関係",
"完全NTR/もう戻れない",
"彼氏の前でイかされる",
"嫌いな相手なのに体が反応",
"初めての浮気",
"処女喪失",
"アナル開発",
"首輪/ペット扱い",
"言葉責め/羞恥プレイ",
"野外・露出セックス",
"車内セックス",
"お風呂・シャワーセックス",
"キレ喘ぎ/悪態H",
"アヘ喘ぎ/呂律崩壊",
"拒絶喘ぎ/嫌よ嫌よも",
"羞恥喘ぎ/声我慢",
"オホ声/濁点喘ぎ",
"わからせ/屈服",
"腹ぽこ/子宮直撃",
"だいしゅきホールド",
"すけべ解釈/エロ脳",
"口調崩壊/お下品化",
"拘束・目隠し"
]
},
"執筆用指示": [
"質の高いNTR小説にすること。背徳感を重視し、身体と心のアンビバレンツを描く。",
"NTRでは不満が大切です。話の途中でヒロインの不満が竿役にバレます。不本意ながらも竿役がそれを解消できてしまうことが、彼女が堕とされる理由となります。",
"6000文字程度。",
"彼氏/旦那を愛している状態から、徐々に竿役に身体を許してしまう過程を丁寧に描写すること。",
"彼氏/旦那とのセックスが事前に描写されていた場合は、竿役がそれを超えているという描写を入れること。"
],
"書き出し": [
"翌日、",
"数日後、",
"一週間後、",
"一か月後、",
"数か月後、",
"一年後、"
]
}
|