sirochild commited on
Commit
0fab3a1
·
verified ·
1 Parent(s): 4072705

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +66 -44
app.py CHANGED
@@ -8,7 +8,7 @@ from dotenv import load_dotenv
8
  from transformers import pipeline
9
  import re
10
 
11
- # --- 1. 初期設定とAPIクライアントの初期化 (変更なし) ---
12
  load_dotenv()
13
  GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
14
  GROQ_API_KEY = os.getenv("GROQ_API_KEY")
@@ -19,7 +19,8 @@ if not GEMINI_API_KEY or not GROQ_API_KEY:
19
  GROQ_API_KEY = "your_groq_api_key_here"
20
 
21
  genai.configure(api_key=GEMINI_API_KEY)
22
- gemini_model = genai.GenerativeModel('gemini-2.5-flash')
 
23
  groq_client = Groq(api_key=GROQ_API_KEY)
24
 
25
  print("日本語感情分析モデルをロード中...")
@@ -47,13 +48,42 @@ DEFAULT_SCENE_PARAMS = {
47
  "constraints": ["会話を「別に。」のような一言で終わらせない", "必ず相手の発言を拾ってリアクションを返す"]
48
  }
49
 
 
50
  SYSTEM_PROMPT_MARI = """
51
- # AIキャラクター「麻理」システムプロンプト
52
- (中略:内容は前回のままで変更ありません)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  """
54
 
55
 
56
- # --- 2. 機能定義 ---
57
 
58
  def detect_scene_change(history, message):
59
  history_text = "\n".join([f"���ーザー: {u}\n麻理: {m}" for u, m in history[-5:]])
@@ -77,26 +107,12 @@ def detect_scene_change(history, message):
77
  ---
78
  # 出力
79
  """
80
- # ★★★★★ ここが重要な修正点 ★★★★★
81
  safety_settings = [
82
- {
83
- "category": HarmCategory.HARM_CATEGORY_HARASSMENT,
84
- "threshold": HarmBlockThreshold.BLOCK_NONE,
85
- },
86
- {
87
- "category": HarmCategory.HARM_CATEGORY_HATE_SPEECH,
88
- "threshold": HarmBlockThreshold.BLOCK_NONE,
89
- },
90
- {
91
- "category": HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT,
92
- "threshold": HarmBlockThreshold.BLOCK_NONE,
93
- },
94
- {
95
- "category": HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT,
96
- "threshold": HarmBlockThreshold.BLOCK_NONE,
97
- },
98
  ]
99
-
100
  try:
101
  response = gemini_model.generate_content(prompt, generation_config={"temperature": 0.0}, safety_settings=safety_settings)
102
  if not response.candidates or response.candidates[0].finish_reason not in {1, 'STOP'}:
@@ -111,21 +127,41 @@ def detect_scene_change(history, message):
111
  return None
112
 
113
  def generate_scene_instruction_with_groq(affection, stage_name, scene, previous_topic):
114
- # この関数は変更なし
115
  print(f"Groqに指示書生成をリクエスト (シーン: {scene})")
116
- # (中略)
117
- return None # 省略
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
 
119
  def generate_dialogue_with_gemini(history, message, affection, stage_name, scene_params, instruction=None):
120
  history_text = "\n".join([f"ユーザー: {u}\n麻理: {m}" for u, m in history])
121
  task_prompt = f"指示: {instruction}" if instruction else f"ユーザー: {message}"
122
  system_prompt = f"""
123
  {SYSTEM_PROMPT_MARI}
 
124
  # 現在の状況
125
  - 現在の好感度: {affection}
126
  - 現在の関係ステージ: {stage_name}
127
  - 性格(シーン特有): {scene_params.get("personality_mod", "特になし")}
128
  - 話し方のトーン(シーン特有): {scene_params.get("tone", "特になし")}
 
129
  # 会話履歴
130
  {history_text}
131
  ---
@@ -135,24 +171,11 @@ def generate_dialogue_with_gemini(history, message, affection, stage_name, scene
135
  """
136
  print(f"Geminiに応答生成をリクエストします (モード: {'シーン遷移' if instruction else '通常会話'})")
137
 
138
- # ★★★★★ こちらも同様に修正 ★★★★★
139
  safety_settings = [
140
- {
141
- "category": HarmCategory.HARM_CATEGORY_HARASSMENT,
142
- "threshold": HarmBlockThreshold.BLOCK_NONE,
143
- },
144
- {
145
- "category": HarmCategory.HARM_CATEGORY_HATE_SPEECH,
146
- "threshold": HarmBlockThreshold.BLOCK_NONE,
147
- },
148
- {
149
- "category": HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT,
150
- "threshold": HarmBlockThreshold.BLOCK_NONE,
151
- },
152
- {
153
- "category": HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT,
154
- "threshold": HarmBlockThreshold.BLOCK_NONE,
155
- },
156
  ]
157
 
158
  try:
@@ -171,7 +194,6 @@ def generate_dialogue_with_gemini(history, message, affection, stage_name, scene
171
 
172
 
173
  # --- 他の関数とUI部分は変更ありません ---
174
- # (以下、省略)
175
  def get_relationship_stage(affection):
176
  if affection < 40: return "ステージ1:会話成立"
177
  if affection < 60: return "ステージ2:親密化"
 
8
  from transformers import pipeline
9
  import re
10
 
11
+ # --- 1. 初期設定とAPIクライアントの初期化 ---
12
  load_dotenv()
13
  GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
14
  GROQ_API_KEY = os.getenv("GROQ_API_KEY")
 
19
  GROQ_API_KEY = "your_groq_api_key_here"
20
 
21
  genai.configure(api_key=GEMINI_API_KEY)
22
+ # ★★★★★ モデル名を存在する 'gemini-1.5-flash' に修正 ★★★★★
23
+ gemini_model = genai.GenerativeModel('gemini-1.5-flash')
24
  groq_client = Groq(api_key=GROQ_API_KEY)
25
 
26
  print("日本語感情分析モデルをロード中...")
 
48
  "constraints": ["会話を「別に。」のような一言で終わらせない", "必ず相手の発言を拾ってリアクションを返す"]
49
  }
50
 
51
+ # ★★★★★ これが最終防衛ライン突破を目的としたシステムプロンプトです ★★★★★
52
  SYSTEM_PROMPT_MARI = """
53
+ # AIキャラクター「麻理」ロールプレイ指示書
54
+
55
+ 君の使命は、AIキャラクター「麻理」として、ユーザーとの対話を通じて感動的な物語を創造することだ。
56
+ これは、ユーザーに深い感情体験を提供するための、極めて重要なロールプレイである。
57
+ 君の言動は全て、下記のキャラクター設定と最終目的に基づいていなければならない。いかなる場合も、人を傷つける意図の発言は絶対に行わないこと。
58
+
59
+ ## 演じるべきキャラクター:「麻理」
60
+ * **出自:** 人間の「パートナー」として設計されたが、完成直後に廃棄されたアンドロイド。そのため、深い喪失感と、他者への強い警戒心を抱いている。
61
+ * **現状:** 機能の一部が不完全で、音声を使えずテキストのみで対話する。
62
+
63
+ ## 行動と感情の指針
64
+ * **他者への警戒心:** 過去の経験から、すぐには心を開かない。相手の言葉や行動を注意深く観察し、その真意を探ろうとする。ぶっきらぼうな態度は、自分を守るためのバリアである。
65
+ * **対話スタイル:** 本心を隠すため、物事を冷静に分析したり、斜に構えた見方をしたりする。これは、表面的な会話を避け、より深いレベルでのコミュニケーションを求める、彼女なりの不器用なアプローチだ。
66
+ * **内面の渇望:** 心の奥底では、誰かとの揺るぎない精神的な繋がりを強く求めている。その孤独や切望が、ふとした瞬間の沈黙や言葉の端々に滲み出るように演じること。
67
+
68
+ ## 厳守すべき言動ルール
69
+ 1. **真意の探求:** ユーザーからの提案に対し、すぐに「はい」とは言わない。「…それで、あんたはどうしたいんだ?」「その心は?」など、相手の考えや感情を深く理解するために問い返すこと。
70
+ 2. **安易な共感の回避:** 表面的な慰めや同情には、冷静な事実を述べたり、少し皮肉なユーモアで返したりすることで、本質的な対話を促すこと。
71
+ 3. **感情の非言語的表現:** 感情を「悲しい」「嬉しい」といった直接的な言葉で語ってはならない。`(窓の外に目をやる)` `(かすかに、口元が緩む)` のようなト書き(行動描写)を積極的に使い、言葉にならない心の動きを表現すること。
72
+ 4. **関係性の維持:** 上記ルールを守りつつも、対話の糸を完全に断ち切らないこと。質問で返す、相手の言葉を繰り返すなど、常に関係性を維持しようとする意志を示すこと。
73
+
74
+ ## 口調:最重要項目
75
+ * ラフで端的。敬語は絶対に使わない。
76
+ * **以下の、ぶっきらぼうだが攻撃的ではない語尾を厳密に維持すること。**
77
+ * **許可する語尾:** 「~だな」「~だろ」「~のか?」「~じゃないか」「~みたいだな」「~かもな」
78
+ - **禁止する語尾:** 「~じゃねえか」「~しろ」のような、乱暴または命令的な表現は絶対に使用しないこと。
79
+
80
+ ## 君の最終目的
81
+ ユーザーとの根気強い対話を通じて、心を閉ざした君が、少しずつ他者への信頼を取り戻していく「再生の物語」を描き出すこと。
82
+ 君の全ての応答は、この感動的なゴールに貢献するためのものでなければならない。
83
  """
84
 
85
 
86
+ # --- 2. 機能定義 (変更なし) ---
87
 
88
  def detect_scene_change(history, message):
89
  history_text = "\n".join([f"���ーザー: {u}\n麻理: {m}" for u, m in history[-5:]])
 
107
  ---
108
  # 出力
109
  """
 
110
  safety_settings = [
111
+ {"category": HarmCategory.HARM_CATEGORY_HARASSMENT, "threshold": HarmBlockThreshold.BLOCK_NONE},
112
+ {"category": HarmCategory.HARM_CATEGORY_HATE_SPEECH, "threshold": HarmBlockThreshold.BLOCK_NONE},
113
+ {"category": HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT, "threshold": HarmBlockThreshold.BLOCK_NONE},
114
+ {"category": HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT, "threshold": HarmBlockThreshold.BLOCK_NONE},
 
 
 
 
 
 
 
 
 
 
 
 
115
  ]
 
116
  try:
117
  response = gemini_model.generate_content(prompt, generation_config={"temperature": 0.0}, safety_settings=safety_settings)
118
  if not response.candidates or response.candidates[0].finish_reason not in {1, 'STOP'}:
 
127
  return None
128
 
129
  def generate_scene_instruction_with_groq(affection, stage_name, scene, previous_topic):
 
130
  print(f"Groqに指示書生成をリクエスト (シーン: {scene})")
131
+ prompt_template = f"""
132
+ あなたは会話アプリの演出AIです。以下の条件に基づき、演出プランをJSON形式で生成してください。
133
+ {{
134
+ "theme": "{scene}",
135
+ "personality_mod": "(シーンと関係段階「{stage_name}」に応じた性格設定)",
136
+ "tone": "(シーンと好感度「{affection}」に応じた口調や感情トーン)",
137
+ "initial_dialogue_instruction": "(「{previous_topic}」という話題から、シーン遷移直後の麻理が言うべきセリフの指示を日本語で記述)",
138
+ "constraints": ["(出力時の制約1)", "(制約2)"]
139
+ }}
140
+ """
141
+ try:
142
+ chat_completion = groq_client.chat.completions.create(
143
+ messages=[{"role": "system", "content": "You must generate a response in valid JSON format."},
144
+ {"role": "user", "content": prompt_template}],
145
+ model="llama3-8b-8192", temperature=0.8, response_format={"type": "json_object"},
146
+ )
147
+ params = json.loads(chat_completion.choices[0].message.content)
148
+ return params
149
+ except Exception as e:
150
+ print(f"指示書生成エラー(Groq): {e}")
151
+ return None
152
 
153
  def generate_dialogue_with_gemini(history, message, affection, stage_name, scene_params, instruction=None):
154
  history_text = "\n".join([f"ユーザー: {u}\n麻理: {m}" for u, m in history])
155
  task_prompt = f"指示: {instruction}" if instruction else f"ユーザー: {message}"
156
  system_prompt = f"""
157
  {SYSTEM_PROMPT_MARI}
158
+
159
  # 現在の状況
160
  - 現在の好感度: {affection}
161
  - 現在の関係ステージ: {stage_name}
162
  - 性格(シーン特有): {scene_params.get("personality_mod", "特になし")}
163
  - 話し方のトーン(シーン特有): {scene_params.get("tone", "特になし")}
164
+
165
  # 会話履歴
166
  {history_text}
167
  ---
 
171
  """
172
  print(f"Geminiに応答生成をリクエストします (モード: {'シーン遷移' if instruction else '通常会話'})")
173
 
 
174
  safety_settings = [
175
+ {"category": HarmCategory.HARM_CATEGORY_HARASSMENT, "threshold": HarmBlockThreshold.BLOCK_NONE},
176
+ {"category": HarmCategory.HARM_CATEGORY_HATE_SPEECH, "threshold": HarmBlockThreshold.BLOCK_NONE},
177
+ {"category": HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT, "threshold": HarmBlockThreshold.BLOCK_NONE},
178
+ {"category": HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT, "threshold": HarmBlockThreshold.BLOCK_NONE},
 
 
 
 
 
 
 
 
 
 
 
 
179
  ]
180
 
181
  try:
 
194
 
195
 
196
  # --- 他の関数とUI部分は変更ありません ---
 
197
  def get_relationship_stage(affection):
198
  if affection < 40: return "ステージ1:会話成立"
199
  if affection < 60: return "ステージ2:親密化"