Spaces:
Sleeping
Sleeping
improve: chat logic
Browse files- modules/response_generator.py +213 -131
modules/response_generator.py
CHANGED
|
@@ -1,154 +1,236 @@
|
|
| 1 |
import json
|
| 2 |
from .ai_model import AIModel
|
| 3 |
-
from .
|
| 4 |
from utils.logger import log
|
| 5 |
-
import re
|
| 6 |
|
| 7 |
class ResponseGenerator:
|
| 8 |
-
def __init__(self, ai_model: AIModel):
|
| 9 |
self.ai_model = ai_model
|
|
|
|
| 10 |
self.personas = self._load_personas()
|
| 11 |
|
| 12 |
-
def _load_personas(self)
|
|
|
|
|
|
|
| 13 |
|
| 14 |
-
with open(
|
| 15 |
data = json.load(f)
|
| 16 |
-
log.info(f"✅ 成功加载 {len(data.get('personas', {}))} 个
|
| 17 |
return data.get('personas', {})
|
| 18 |
-
|
| 19 |
-
def generate(self, session_state: SessionState) -> str:
|
| 20 |
-
"""
|
| 21 |
-
根据当前会话状态,生成一个完全符合选定 Persona 风格的智能回复。
|
| 22 |
-
"""
|
| 23 |
-
try:
|
| 24 |
-
persona_key = session_state.persona or "planner" # 如果未选择,则默认为 planner
|
| 25 |
-
persona_config = self.personas.get(persona_key, self.personas.get("planner"))
|
| 26 |
|
| 27 |
-
|
| 28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 29 |
if next_question:
|
| 30 |
-
#
|
| 31 |
-
if
|
| 32 |
-
|
| 33 |
-
# 否则,先确认已知信息,再提问
|
| 34 |
else:
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 42 |
|
| 43 |
except Exception as e:
|
| 44 |
-
log.error(f"❌
|
| 45 |
-
return "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 46 |
|
| 47 |
-
def
|
| 48 |
-
"""
|
|
|
|
|
|
|
| 49 |
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
if not session_state.destination:
|
| 53 |
-
# 根据不同 persona 定制提问方式
|
| 54 |
-
if persona_config.get('name', '').startswith("高效"):
|
| 55 |
-
return "您好,为了开始规划,请首先提供您的目的地城市。"
|
| 56 |
-
elif persona_config.get('name', '').startswith("社交"):
|
| 57 |
-
return "哈喽!准备好开启一场超棒的旅行了吗?快告诉我你们想去哪里呀?目的地是哪里呀?🌍"
|
| 58 |
-
else: # 默认或体验型
|
| 59 |
-
return "您好!很高兴能为您服务。请问这次您渴望探索哪个目的地呢?"
|
| 60 |
-
|
| 61 |
-
if not session_state.duration:
|
| 62 |
-
dest_name = session_state.destination
|
| 63 |
-
if persona_config.get('name', '').startswith("高效"):
|
| 64 |
-
return f"目的地已确认为 {dest_name}。请提供计划的旅行总天数。"
|
| 65 |
-
elif persona_config.get('name', '').startswith("社交"):
|
| 66 |
-
return f"哇!{dest_name}!听起来就超赞的!你们打算一起玩几天呀?🥳"
|
| 67 |
-
else:
|
| 68 |
-
return f"{dest_name},一个充满故事的地方。您希望在这片土地上沉浸几天呢?"
|
| 69 |
-
|
| 70 |
-
if not session_state.budget:
|
| 71 |
-
if persona_config.get('name', '').startswith("高效"):
|
| 72 |
-
return "为了进行精确的预算分配,请明确您的预算等级(例如:经济型、舒适型、豪华型)或大致的总金额。"
|
| 73 |
-
elif persona_config.get('name', '').startswith("社交"):
|
| 74 |
-
return "最后一个问题!这次出去玩的预算大概是多少呀?是小资轻奢还是尽情嗨皮呢?💰"
|
| 75 |
-
else:
|
| 76 |
-
return "为了让体验更贴合您的期望,可以分享一下这次旅行的预算范围吗?"
|
| 77 |
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 86 |
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
return f"收到。目的地:{dest}。"
|
| 91 |
-
elif persona_config.get('name', '').startswith("社交"):
|
| 92 |
-
if days:
|
| 93 |
-
return f"收到啦!{days} 天的行程,一定能玩得超开心!"
|
| 94 |
-
return f"好嘞!目的地 {dest} 已锁定!"
|
| 95 |
-
else:
|
| 96 |
-
if days:
|
| 97 |
-
return f"明白了,一段为期 {days} 天的旅程。"
|
| 98 |
-
return f"好的,我们将围绕 {dest} 展开探索。"
|
| 99 |
-
|
| 100 |
-
def _generate_persona_enhanced_plan(self, session_state: SessionState, persona_config: dict) -> str:
|
| 101 |
-
"""调用AI模型,使用 persona 模板生成最终的旅行计划。"""
|
| 102 |
-
prompt = self._build_prompt(session_state, persona_config)
|
| 103 |
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
# --- 当前用于演示的临时返回 ---
|
| 112 |
-
# 它会清晰地展示我们是如何根据persona构建prompt的
|
| 113 |
-
return f"✨ **计划生成预览** ✨\n\n我将使用下面的指令为您生成计划:\n\n```prompt\n{prompt}\n```"
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
def _build_prompt(self, session_state: SessionState, persona_config: dict) -> str:
|
| 117 |
-
"""
|
| 118 |
-
【核心升级】
|
| 119 |
-
一个更健壮、更灵活的 prompt 构建方法。
|
| 120 |
-
它会安全地填充模板,即使 session_state 中的信息不完整。
|
| 121 |
-
"""
|
| 122 |
-
template = persona_config.get('prompt_template')
|
| 123 |
-
if not template:
|
| 124 |
-
log.warning(f"Persona '{persona_config.get('name')}' 缺少 'prompt_template',将使用通用模板。")
|
| 125 |
-
# 此处可以返回一个通用的后备 prompt
|
| 126 |
-
return f"请为我规划一个去 {session_state.destination} 的 {session_state.duration} 天行程。"
|
| 127 |
-
|
| 128 |
-
# 1. 从 session_state 收集所有可能用到的信息
|
| 129 |
-
context = {
|
| 130 |
-
"location": session_state.destination,
|
| 131 |
-
"days": session_state.duration,
|
| 132 |
-
"budget": session_state.budget,
|
| 133 |
-
"date": session_state.get_specific_info('date', '近期'), # 假设 session_state 有此方法
|
| 134 |
-
"user_tags": ", ".join(session_state.get_specific_info('tags', [])),
|
| 135 |
-
"commercial_preference": session_state.get_specific_info('commercial', '适中'),
|
| 136 |
-
"group_description": session_state.get_specific_info('group', '个人'),
|
| 137 |
-
"tags": ", ".join(session_state.get_specific_info('tags', []))
|
| 138 |
-
}
|
| 139 |
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
# 这种方法比 .format(**context) 更安全,因为它只替换存在的占位符,
|
| 145 |
-
# 并且如果 context 中缺少某个键,它不会抛出 KeyError。
|
| 146 |
-
for key in placeholders:
|
| 147 |
-
value = context.get(key)
|
| 148 |
-
if value is not None:
|
| 149 |
-
template = template.replace(f'{{{key}}}', str(value))
|
| 150 |
-
else:
|
| 151 |
-
# 如果 context 中没有这个值,可以选择留空或使用默认值
|
| 152 |
-
template = template.replace(f'{{{key}}}', '(未提供)')
|
| 153 |
|
| 154 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
import json
|
| 2 |
from .ai_model import AIModel
|
| 3 |
+
from .knowledge_base import KnowledgeBase
|
| 4 |
from utils.logger import log
|
|
|
|
| 5 |
|
| 6 |
class ResponseGenerator:
|
| 7 |
+
def __init__(self, ai_model: AIModel, knowledge_base: KnowledgeBase):
|
| 8 |
self.ai_model = ai_model
|
| 9 |
+
self.kb = knowledge_base
|
| 10 |
self.personas = self._load_personas()
|
| 11 |
|
| 12 |
+
def _load_personas(self):
|
| 13 |
+
|
| 14 |
+
personas_path = "./config/personas.json"
|
| 15 |
|
| 16 |
+
with open(personas_path, 'r', encoding='utf-8') as f:
|
| 17 |
data = json.load(f)
|
| 18 |
+
log.info(f"✅ 成功加载 {len(data.get('personas', {}))} 个persona配置。")
|
| 19 |
return data.get('personas', {})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 20 |
|
| 21 |
+
def _get_current_persona_config(self, session_state: dict) -> dict:
|
| 22 |
+
"""安全地获取当前会话的persona配置字典"""
|
| 23 |
+
persona_key = session_state.get("persona", {}).get("key")
|
| 24 |
+
if persona_key and persona_key in self.personas:
|
| 25 |
+
return self.personas[persona_key]
|
| 26 |
+
# 如果没有找到指定的persona,返回一个中立的默认配置
|
| 27 |
+
return {
|
| 28 |
+
"name": "旅行助手",
|
| 29 |
+
"tone": ["专业", "友好"],
|
| 30 |
+
"style": "中立"
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
def generate(self, user_message: str, session_state: dict, extracted_info: dict) -> str:
|
| 34 |
+
"""生成智能响应,整个过程融入Persona风格"""
|
| 35 |
+
try:
|
| 36 |
+
response_parts = []
|
| 37 |
+
|
| 38 |
+
# 1. 生成带有人格风格的确认反馈
|
| 39 |
+
acknowledgement = self._generate_acknowledgement(extracted_info, session_state)
|
| 40 |
+
if acknowledgement:
|
| 41 |
+
response_parts.append(acknowledgement)
|
| 42 |
+
|
| 43 |
+
# 2. 检查信息完整性,用人格化的方式询问缺失信息
|
| 44 |
+
next_question = self._get_next_question(session_state)
|
| 45 |
+
|
| 46 |
+
# 只有在有下一步问题时才加入回复列表
|
| 47 |
if next_question:
|
| 48 |
+
# 如果已有确认信息,为了避免语气生硬,加个连接词
|
| 49 |
+
if response_parts:
|
| 50 |
+
response_parts.append("那么," + next_question[0].lower() + next_question[1:])
|
|
|
|
| 51 |
else:
|
| 52 |
+
response_parts.append(next_question)
|
| 53 |
+
|
| 54 |
+
# 3. 如果所有信息都齐全,并且没有追问,则生成最终计划
|
| 55 |
+
if not next_question:
|
| 56 |
+
plan = self._generate_persona_enhanced_plan(user_message, session_state)
|
| 57 |
+
# 如果已有确认信息,用换行符分隔,使计划更突出
|
| 58 |
+
if response_parts:
|
| 59 |
+
response_parts.append("\n\n" + plan)
|
| 60 |
+
else:
|
| 61 |
+
response_parts.append(plan)
|
| 62 |
+
|
| 63 |
+
return " ".join(response_parts)
|
| 64 |
|
| 65 |
except Exception as e:
|
| 66 |
+
log.error(f"❌ 响应生成失败: {e}", exc_info=True)
|
| 67 |
+
return "抱歉,我在处理您的请求时遇到了问题,请稍后再试。"
|
| 68 |
+
|
| 69 |
+
def _get_next_question(self, session_state: dict) -> str:
|
| 70 |
+
"""根据Persona的风格,获取下一个需要询问的问题"""
|
| 71 |
+
persona_config = self._get_current_persona_config(session_state)
|
| 72 |
+
persona_style = persona_config.get("style", "")
|
| 73 |
+
destination_name = session_state.get('destination', {}).get('name', '那里')
|
| 74 |
+
days = session_state.get('duration', {}).get('days', '几')
|
| 75 |
+
|
| 76 |
+
# --- 按优先级检查缺失信息,并根据Persona风格提问 ---
|
| 77 |
+
|
| 78 |
+
# 1. 目的地
|
| 79 |
+
if not session_state.get("destination"):
|
| 80 |
+
if "社交" in persona_style:
|
| 81 |
+
return "哈喽!准备好去哪里嗨皮了吗?告诉我想去哪个城市,我们来一场刷爆朋友圈的旅行吧!✨"
|
| 82 |
+
if "体验" in persona_style:
|
| 83 |
+
return "你好,旅行者。为了开启一段独特的深度体验,你心中的目的地是哪里?"
|
| 84 |
+
# 默认使用规划师或中立风格
|
| 85 |
+
return "您好!为了高效地开始规划,请首先明确您的目的地城市。"
|
| 86 |
+
|
| 87 |
+
# 2. 天数
|
| 88 |
+
if not session_state.get("duration"):
|
| 89 |
+
if "社交" in persona_style:
|
| 90 |
+
return f"{destination_name}超棒的!打算和小伙伴们在那玩几天呀?"
|
| 91 |
+
if "体验" in persona_style:
|
| 92 |
+
return f"感知到了,{destination_name}。你希望在这片土地上沉浸多少个日夜?"
|
| 93 |
+
return f"目的地已锁定:{destination_name}。请提供计划的旅行天数。"
|
| 94 |
+
|
| 95 |
+
# 3. 预算
|
| 96 |
+
if not session_state.get("budget"):
|
| 97 |
+
if "社交" in persona_style:
|
| 98 |
+
return f"太棒啦,{days}天的行程!这次出去玩,预算大概是多少呀?是经济实惠,还是想来个轻奢体验呢?"
|
| 99 |
+
if "体验" in persona_style:
|
| 100 |
+
return f"{days}天的探索之旅,听起来很不错。对于这次旅行的开销,你有什么样的构想?"
|
| 101 |
+
return f"已记录:行程共{days}天。请明确您的预算范围(例如:经济型、舒适型,或具体金额)。"
|
| 102 |
+
|
| 103 |
+
return "" # 所有信息已收集完毕
|
| 104 |
|
| 105 |
+
def _generate_acknowledgement(self, extracted_info: dict, session_state: dict) -> str:
|
| 106 |
+
"""根据Persona的风格,生成对新提取信息的确认反馈"""
|
| 107 |
+
if not extracted_info:
|
| 108 |
+
return ""
|
| 109 |
|
| 110 |
+
persona_config = self._get_current_persona_config(session_state)
|
| 111 |
+
persona_style = persona_config.get("style", "")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 112 |
|
| 113 |
+
ack_parts = []
|
| 114 |
+
if "destination" in extracted_info:
|
| 115 |
+
name = extracted_info['destination'].get('name', '目的地')
|
| 116 |
+
if "社交" in persona_style: ack_parts.append(f"目的地锁定{name}!已经开始期待啦!💖")
|
| 117 |
+
elif "体验" in persona_style: ack_parts.append(f"我感知到了,{name},一个充满故事的地方")
|
| 118 |
+
else: ack_parts.append(f"确认:目的地已记录为{name}")
|
| 119 |
+
|
| 120 |
+
if "duration" in extracted_info:
|
| 121 |
+
days = extracted_info['duration'].get('days', '几')
|
| 122 |
+
if "社交" in persona_style: ack_parts.append(f"玩{days}天,时间超充裕的")
|
| 123 |
+
elif "体验" in persona_style: ack_parts.append(f"{days}个日夜,足够深入探索了")
|
| 124 |
+
else: ack_parts.append(f"行程时长已设定为{days}天")
|
| 125 |
+
|
| 126 |
+
if "budget" in extracted_info:
|
| 127 |
+
budget_desc = self._format_budget_info(extracted_info['budget'])
|
| 128 |
+
if "社交" in persona_style: ack_parts.append(f"{budget_desc}的预算,妥妥的")
|
| 129 |
+
elif "体验" in persona_style: ack_parts.append(f"了解,{budget_desc}的投入,追求的是价值而非价格")
|
| 130 |
+
else: ack_parts.append(f"预算已明确为{budget_desc}")
|
| 131 |
+
|
| 132 |
+
return ",".join(ack_parts) + "。" if ack_parts else ""
|
| 133 |
+
|
| 134 |
+
# --- 以下方法保留您原有的优秀实现,无需修改 ---
|
| 135 |
+
|
| 136 |
+
def _generate_persona_enhanced_plan(self, user_message: str, session_state: dict) -> str:
|
| 137 |
+
persona_config = self._get_current_persona_config(session_state)
|
| 138 |
+
destination = session_state.get("destination", {})
|
| 139 |
+
duration = session_state.get("duration", {})
|
| 140 |
+
budget = session_state.get("budget", {})
|
| 141 |
|
| 142 |
+
location = destination.get('name', '目的地')
|
| 143 |
+
days = duration.get('days', '几')
|
| 144 |
+
budget_info = self._format_budget_info(budget)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 145 |
|
| 146 |
+
if self.ai_model.is_available():
|
| 147 |
+
prompt = self._build_prompt(session_state, persona_config)
|
| 148 |
+
log.info(f"🚀 使用Persona '{persona_config.get('name')}' 构建的Prompt进行生成。")
|
| 149 |
+
return self.ai_model.generate(user_message, prompt)
|
| 150 |
+
else:
|
| 151 |
+
log.warning("⚠️ AI模型不可用,生成备用计划。")
|
| 152 |
+
return self._generate_fallback_plan(session_state)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 153 |
|
| 154 |
+
def _build_prompt(self, session_state: dict, persona_config: dict) -> str:
|
| 155 |
+
destination = session_state.get("destination", {})
|
| 156 |
+
duration = session_state.get("duration", {})
|
| 157 |
+
budget = session_state.get("budget", {})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 158 |
|
| 159 |
+
location = destination.get('name', '目的地')
|
| 160 |
+
days = duration.get('days', '几')
|
| 161 |
+
budget_info = self._format_budget_info(budget)
|
| 162 |
+
|
| 163 |
+
template = persona_config.get('prompt_template')
|
| 164 |
+
if template:
|
| 165 |
+
try:
|
| 166 |
+
# 填充模板所需的所有潜在变量
|
| 167 |
+
return template.format(
|
| 168 |
+
location=location,
|
| 169 |
+
days=days,
|
| 170 |
+
budget=budget_info,
|
| 171 |
+
date=session_state.get('date', '近期'),
|
| 172 |
+
user_tags=", ".join(session_state.get('user_tags', [])),
|
| 173 |
+
commercial_preference=session_state.get('commercial_preference', '适中'),
|
| 174 |
+
group_description=session_state.get('group_description', '个人'),
|
| 175 |
+
tags=", ".join(session_state.get('tags', []))
|
| 176 |
+
)
|
| 177 |
+
except KeyError as e:
|
| 178 |
+
log.warning(f"Persona模板格式化失败,缺少键: {e}。将使用通用模板。")
|
| 179 |
+
# Fallback to generic prompt if template fails
|
| 180 |
+
return self._build_generic_prompt(session_state)
|
| 181 |
+
return self._build_generic_prompt(session_state)
|
| 182 |
+
|
| 183 |
+
def _format_budget_info(self, budget: dict) -> str:
|
| 184 |
+
if not budget: return "未指定"
|
| 185 |
+
if budget.get('amount') and budget.get('currency'): return f"{budget['amount']}{budget['currency']}"
|
| 186 |
+
if budget.get('description'): return budget['description']
|
| 187 |
+
if budget.get('type'):
|
| 188 |
+
type_map = {'economy': '经济型', 'comfortable': '舒适型', 'luxury': '豪华型'}
|
| 189 |
+
return type_map.get(budget['type'], budget['type'])
|
| 190 |
+
return "未指定"
|
| 191 |
+
|
| 192 |
+
def _build_generic_prompt(self, session_state: dict, knowledge_context: str = "") -> str:
|
| 193 |
+
# (此方法及以下方法保持您原有的实现)
|
| 194 |
+
destination = session_state.get("destination", {})
|
| 195 |
+
duration = session_state.get("duration", {})
|
| 196 |
+
budget = session_state.get("budget", {})
|
| 197 |
+
location = destination.get('name', '目的地')
|
| 198 |
+
days = duration.get('days', '几')
|
| 199 |
+
budget_info = self._format_budget_info(budget)
|
| 200 |
+
prompt = f"""你是一个专业的旅游助手。请为用户生成一个详细的旅行计划。
|
| 201 |
+
【基本信息】
|
| 202 |
+
- 目的地:{location}
|
| 203 |
+
- 旅行天数:{days}天
|
| 204 |
+
- 预算:{budget_info}
|
| 205 |
+
【要求】
|
| 206 |
+
- 提供具体的景点推荐和路线安排
|
| 207 |
+
- 包含交通、住宿、餐饮建议
|
| 208 |
+
- 确保所有推荐都在预算范围内
|
| 209 |
+
- 提供实用的旅行贴士"""
|
| 210 |
+
if knowledge_context:
|
| 211 |
+
prompt += f"\n\n【背景信息】\n{knowledge_context}"
|
| 212 |
+
prompt += "\n\n请生成一份实用、详细的旅行计划。"
|
| 213 |
+
return prompt
|
| 214 |
+
|
| 215 |
+
def _generate_fallback_plan(self, session_state: dict, knowledge_context: str = "") -> str:
|
| 216 |
+
# (此方法保持您原有的实现)
|
| 217 |
+
destination = session_state.get("destination", {})
|
| 218 |
+
duration = session_state.get("duration", {})
|
| 219 |
+
budget = session_state.get("budget", {})
|
| 220 |
+
persona_config = self._get_current_persona_config(session_state)
|
| 221 |
+
location = destination.get('name', '目的地')
|
| 222 |
+
days = duration.get('days', '几')
|
| 223 |
+
budget_info = self._format_budget_info(budget)
|
| 224 |
+
persona_name = persona_config.get('name', '旅行者')
|
| 225 |
+
plan = f"为您推荐 {location} {days}天旅行计划:\n\n"
|
| 226 |
+
plan += f"👤 旅行者类型:{persona_name}\n"
|
| 227 |
+
plan += f"💰 预算范围:{budget_info}\n\n"
|
| 228 |
+
if knowledge_context: plan += f"📚 {knowledge_context}\n\n"
|
| 229 |
+
highlights = destination.get('highlights', '精彩景点等待您的探索')
|
| 230 |
+
plan += f"🎯 主要景点:{highlights}\n\n"
|
| 231 |
+
persona_key = session_state.get("persona", {}).get("key")
|
| 232 |
+
if persona_key == 'planner': plan += "📋 建议制定详细的每日行程表。\n"
|
| 233 |
+
elif persona_key == 'social': plan += "📸 推荐寻找热门打卡点!\n"
|
| 234 |
+
elif persona_key == 'experiential': plan += "🎨 建议深入当地社区,寻找地道体验。\n"
|
| 235 |
+
plan += "\n如需更详细的个性化规划,请告诉我您的具体需求!"
|
| 236 |
+
return plan
|