import traceback import datetime import random import logging logger = logging.getLogger(__name__) def get_fallback_response(scene=None): """ シーンに応じた固定のフォールバック応答を生成する """ scene_responses = { "aquarium_night": "(水槽の青い光を見つめて)…夜の水族館か。悪くないかもな。", "beach_sunset": "(夕日に照らされた海を見つめて)…こんな景色、久しぶりに見た。", "festival_night": "(提灯の明かりを見上げて)…意外と、悪くない雰囲気だな。", "shrine_day": "(静かな境内を見回して)…静かで、落ち着くな。", "cafe_afternoon": "(窓の外を見ながら)…こういう時間の過ごし方も、悪くない。", "room_night": "(窓の外の夜景を見て)…夜の景色って、なんか落ち着くな。", } if scene and scene in scene_responses: return scene_responses[scene] if scene: return f"({scene}の様子を静かに見回している)…ここか。" return "(……何か言おうとしたが、言葉に詰まった)" def generate_dialogue_with_swallow(history, message, affection, stage_name, scene_params, instruction=None, swallow_model=None, SYSTEM_PROMPT_MARI=None): """ Swallowモデル(GGUF版)を使用して対話応答を生成する """ if swallow_model is None: logger.warning("Swallowモデルが利用できないため、フォールバック応答を返します。") return get_fallback_response(scene_params.get("theme")) history_text = "\n".join([f"ユーザー: {u}\n麻理: {m}" for u, m in history[-5:]]) # 直近5件に制限 prompt = f"""{SYSTEM_PROMPT_MARI} # 現在の状況 - シーン: {scene_params.get("theme", "default")} - 好感度: {affection} ({stage_name}) - 性格: {scene_params.get("personality_mod", "特になし")} - 口調: {scene_params.get("tone", "特になし")} # 会話履歴 {history_text} --- # 指示 {f"特別な指示: {instruction}" if instruction else f"ユーザーの発言「{message}」に、麻理として応答してください。"} 麻理: """ try: output = swallow_model( prompt, max_tokens=150, temperature=0.8, top_p=0.95, stop=["ユーザー:", "user:", "\n\n"], echo=False # プロンプトは返さない ) response_text = output["choices"][0]["text"].strip() if not response_text: logger.warning("LLMが空の応答を返しました。フォールバックを使用します。") return get_fallback_response(scene_params.get("theme")) logger.info(f"Swallowモデル生成応答: {response_text}") return response_text except Exception as e: logger.error(f"応答生成エラー(Swallow): {e}", exc_info=True) return get_fallback_response(scene_params.get("theme"))