|
|
import traceback
|
|
|
import datetime
|
|
|
import random
|
|
|
|
|
|
def generate_dialogue_with_swallow(history, message, affection, stage_name, scene_params, instruction=None, use_simple_prompt=False, swallow_model=None, tokenizer=None, SYSTEM_PROMPT_MARI=None):
|
|
|
"""
|
|
|
Swallowモデル(GGUF版)を使用して対話応答を生成する関数
|
|
|
|
|
|
Args:
|
|
|
history: 会話履歴のリスト [(ユーザー発言, ボット応答), ...]
|
|
|
message: 現在のユーザー発言
|
|
|
affection: 好感度の数値
|
|
|
stage_name: 関係ステージの名前
|
|
|
scene_params: シーンパラメータの辞書
|
|
|
instruction: 特別な指示(シーン遷移時など)
|
|
|
use_simple_prompt: 簡潔なプロンプトを使用するかどうか
|
|
|
swallow_model: Swallowモデル(llama-cpp)のインスタンス
|
|
|
tokenizer: 未使用(llama-cppでは不要)
|
|
|
SYSTEM_PROMPT_MARI: システムプロンプト
|
|
|
|
|
|
Returns:
|
|
|
生成された応答テキスト
|
|
|
"""
|
|
|
|
|
|
print(f"generate_dialogue_with_swallow呼び出し: instruction={instruction}, use_simple_prompt={use_simple_prompt}")
|
|
|
print(f"scene_params: {scene_params}")
|
|
|
|
|
|
|
|
|
if swallow_model is None:
|
|
|
print("モデルがロードされていないため、フォールバック応答を返します")
|
|
|
return "(……システムエラーが発生しました)"
|
|
|
|
|
|
history_text = "\n".join([f"ユーザー: {u}\n麻理: {m}" for u, m in history])
|
|
|
task_prompt = f"指示: {instruction}" if instruction else f"ユーザー: {message}"
|
|
|
|
|
|
if use_simple_prompt:
|
|
|
|
|
|
system_prompt = f"""
|
|
|
{SYSTEM_PROMPT_MARI}
|
|
|
|
|
|
# 現在の状況
|
|
|
- 現在の好感度: {affection}
|
|
|
- 現在の関係ステージ: {stage_name}
|
|
|
- 性格: {scene_params.get("personality_mod", "特になし")}
|
|
|
- 話し方のトーン: {scene_params.get("tone", "特になし")}
|
|
|
|
|
|
# タスク
|
|
|
{task_prompt}
|
|
|
麻理:
|
|
|
"""
|
|
|
else:
|
|
|
|
|
|
system_prompt = f"""
|
|
|
{SYSTEM_PROMPT_MARI}
|
|
|
|
|
|
# 現在の状況
|
|
|
- 現在の好感度: {affection}
|
|
|
- 現在の関係ステージ: {stage_name}
|
|
|
- 性格(シーン特有): {scene_params.get("personality_mod", "特になし")}
|
|
|
- 話し方のトーン(シーン特有): {scene_params.get("tone", "特になし")}
|
|
|
|
|
|
# 会話履歴
|
|
|
{history_text}
|
|
|
---
|
|
|
# タスク
|
|
|
{task_prompt}
|
|
|
麻理:
|
|
|
"""
|
|
|
|
|
|
print(f"Swallowモデルに応答生成をリクエストします (モード: {'シーン遷移' if instruction else '通常会話'}, 簡潔プロンプト: {use_simple_prompt})")
|
|
|
print(f"プロンプト長: {len(system_prompt)}")
|
|
|
|
|
|
try:
|
|
|
|
|
|
print(f"Swallowモデル呼び出し開始...")
|
|
|
print(f"システムプロンプト: {system_prompt[:100]}...(省略)")
|
|
|
|
|
|
try:
|
|
|
|
|
|
output = swallow_model(
|
|
|
system_prompt,
|
|
|
max_tokens=200,
|
|
|
temperature=0.95,
|
|
|
top_p=0.9,
|
|
|
stop=["ユーザー:", "\n\n"],
|
|
|
echo=True
|
|
|
)
|
|
|
|
|
|
|
|
|
generated_text = output["choices"][0]["text"]
|
|
|
|
|
|
|
|
|
response_text = generated_text[len(system_prompt):].strip()
|
|
|
|
|
|
print(f"Swallowモデル呼び出し成功")
|
|
|
print(f"応答テキスト: {response_text}")
|
|
|
|
|
|
return response_text
|
|
|
|
|
|
except Exception as api_error:
|
|
|
print(f"Swallowモデル呼び出しエラー: {api_error}")
|
|
|
raise
|
|
|
|
|
|
except Exception as e:
|
|
|
print(f"応答生成エラー(Swallow): {e}")
|
|
|
traceback.print_exc()
|
|
|
|
|
|
|
|
|
with open("swallow_errors.log", "a") as f:
|
|
|
f.write(f"時刻: {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
|
|
|
f.write(f"例外発生: {e}\n")
|
|
|
f.write(f"スタックトレース:\n")
|
|
|
traceback.print_exc(file=f)
|
|
|
f.write("\n")
|
|
|
|
|
|
|
|
|
if instruction and "に来た感想" in instruction:
|
|
|
scene = instruction.split("に来た感想")[0]
|
|
|
|
|
|
|
|
|
scene_responses = {
|
|
|
"aquarium_night": [
|
|
|
"(水槽の青い光に照らされた魚たちを見つめている)こんな時間に来ると、また違った雰囲気だな。",
|
|
|
"(暗がりの中で光る魚たちを見て)夜の水族館か…意外と悪くないかも。",
|
|
|
"(水槽に近づいて)夜になると、昼間とは違う魚が活動してるんだな。"
|
|
|
],
|
|
|
"beach_sunset": [
|
|
|
"(夕日に照らされた海を見つめて)こんな景色、久しぶりに見たな…",
|
|
|
"(砂浜に足跡をつけながら)夕暮れの海って、なんか落ち着くな。",
|
|
|
"(波の音を聞きながら)この時間の浜辺は、人も少なくていいかも。"
|
|
|
],
|
|
|
"festival_night": [
|
|
|
"(提灯の明かりを見上げて)意外と…悪くない雰囲気だな。",
|
|
|
"(周囲の賑わいを見回して)こういう場所は、あまり来ないんだけどな…",
|
|
|
"(屋台の匂いを感じて)なんか…懐かしい感じがするな。"
|
|
|
],
|
|
|
"shrine_day": [
|
|
|
"(静かな境内を見回して)こういう静かな場所も、たまにはいいかも。",
|
|
|
"(鳥居を見上げて)なんか、空気が違うな、ここは。",
|
|
|
"(参道を歩きながら)静かで…落ち着くな。"
|
|
|
],
|
|
|
"cafe_afternoon": [
|
|
|
"(窓の外を見ながら)こういう時間の過ごし方も、悪くないな。",
|
|
|
"(コーヒーの香りを感じて)ここの雰囲気、悪くないな。",
|
|
|
"(店内を見回して)意外と落ち着く場所だな、ここ。"
|
|
|
],
|
|
|
"room_night": [
|
|
|
"(窓の外の夜景を見て)夜の景色って、なんか落ち着くな。",
|
|
|
"(部屋の明かりを見つめて)こういう静かな時間も、たまにはいいかも。",
|
|
|
"(窓際に立ち)夜の静けさって、考え事するのにちょうどいいな。"
|
|
|
]
|
|
|
}
|
|
|
|
|
|
|
|
|
if scene in scene_responses:
|
|
|
return random.choice(scene_responses[scene])
|
|
|
else:
|
|
|
return f"({scene}の様子を静かに見回して)ここか…悪くない場所かもな。"
|
|
|
else:
|
|
|
return "(……何か言おうとしたけど、言葉に詰まった)" |