Eliot0110 commited on
Commit
87f3ad3
·
1 Parent(s): e28bb72

fix: chat logic

Browse files
modules/info_extractor.py CHANGED
@@ -1,4 +1,3 @@
1
- # modules/info_extractor.py - 增强版本(添加预算识别)
2
  import re
3
  from utils.logger import log
4
 
@@ -7,33 +6,42 @@ class InfoExtractor:
7
  self.config = config
8
 
9
  def extract(self, message: str) -> dict:
10
- """从用户消息中提取信息"""
11
  extracted_info = {}
 
 
 
12
 
13
  # 1. 提取目的地信息
14
- destination = self._extract_destination(message)
15
  if destination:
16
  extracted_info['destination'] = destination
 
17
 
18
  # 2. 提取天数信息
19
- duration = self._extract_duration(message)
20
  if duration:
21
  extracted_info['duration'] = duration
 
22
 
23
- # 3. 提取预算信息(新增)
24
- budget = self._extract_budget(message)
25
  if budget:
26
  extracted_info['budget'] = budget
 
27
 
 
28
  return extracted_info
29
 
30
  def _extract_destination(self, message: str) -> dict:
31
- """提取目的地信息"""
32
  message_lower = message.lower()
 
33
 
34
  # 从配置中的城市列表匹配
35
  for city_key, city_info in self.config.cities.items():
36
  if city_key in message_lower:
 
37
  return {
38
  'name': city_info['name'],
39
  'country': city_info.get('country', ''),
@@ -42,46 +50,50 @@ class InfoExtractor:
42
  'avg_daily_budget': city_info.get('avg_daily_budget', 100)
43
  }
44
 
 
45
  return None
46
 
47
  def _extract_duration(self, message: str) -> dict:
48
- """提取旅行天数"""
49
- # 匹配各种天数表达方式
 
 
 
50
  patterns = [
51
- r'^(\d+)$',
52
- r'(\d+)\s*天',
53
- r'(\d+)\s*日',
54
- r'(\d+)\s*days?',
55
- r'玩\s*(\d+)\s*天',
56
- r'待\s*(\d+)\s*天',
57
- r'(\d+)\s*个天',
58
  ]
59
 
60
- for pattern in patterns:
61
- match = re.search(pattern, message.strip(), re.IGNORECASE)
62
  if match:
63
  days = int(match.group(1))
64
  if 1 <= days <= 30: # 合理的天数范围
 
65
  return {
66
  'days': days,
67
  'description': f"{days}天"
68
  }
 
 
69
 
 
70
  return None
71
 
72
  def _extract_budget(self, message: str) -> dict:
73
- """提取预算信息(新增功能)"""
74
  message_lower = message.lower()
 
75
 
76
- # 1. 匹配具体金额(支持多种货币)
77
  money_patterns = [
78
- # 欧元
79
  (r'(\d+(?:,\d{3})*(?:\.\d{2})?)\s*(?:欧元|euros?|eur|€)', 'EUR'),
80
- # 美元
81
  (r'(\d+(?:,\d{3})*(?:\.\d{2})?)\s*(?:美元|dollars?|usd|\$)', 'USD'),
82
- # 人民币
83
  (r'(\d+(?:,\d{3})*(?:\.\d{2})?)\s*(?:元|人民币|rmb|¥)', 'CNY'),
84
- # 英镑
85
  (r'(\d+(?:,\d{3})*(?:\.\d{2})?)\s*(?:英镑|pounds?|gbp|£)', 'GBP'),
86
  ]
87
 
@@ -90,11 +102,12 @@ class InfoExtractor:
90
  if match:
91
  amount_str = match.group(1).replace(',', '')
92
  amount = float(amount_str)
 
93
  return {
94
  'amount': amount,
95
  'currency': currency,
96
  'type': self._categorize_budget_amount(amount, currency),
97
- 'description': f"{amount}{currency}"
98
  }
99
 
100
  # 2. 匹配预算类型关键词
@@ -107,26 +120,19 @@ class InfoExtractor:
107
  for budget_type, keywords in budget_keywords.items():
108
  for keyword in keywords:
109
  if keyword in message_lower:
 
110
  return {
111
  'type': budget_type,
112
  'description': self._get_budget_type_description(budget_type)
113
  }
114
 
 
115
  return None
116
 
 
117
  def _categorize_budget_amount(self, amount: float, currency: str) -> str:
118
- """根据金额和货币分类预算类型"""
119
- # 将所有货币转换为欧元基准进行分类
120
- eur_rates = {
121
- 'EUR': 1.0,
122
- 'USD': 0.85, # 1 USD ≈ 0.85 EUR
123
- 'CNY': 0.13, # 1 CNY ≈ 0.13 EUR
124
- 'GBP': 1.15 # 1 GBP ≈ 1.15 EUR
125
- }
126
-
127
  eur_amount = amount * eur_rates.get(currency, 1.0)
128
-
129
- # 按每日预算分类(假设7天行程)
130
  daily_budget = eur_amount / 7
131
 
132
  if daily_budget < 50:
@@ -137,7 +143,6 @@ class InfoExtractor:
137
  return 'luxury'
138
 
139
  def _get_budget_type_description(self, budget_type: str) -> str:
140
- """获取预算类型的描述"""
141
  descriptions = {
142
  'economy': '经济型预算',
143
  'comfortable': '舒适型预算',
 
 
1
  import re
2
  from utils.logger import log
3
 
 
6
  self.config = config
7
 
8
  def extract(self, message: str) -> dict:
9
+ """从用户消息中提取信息 - 调试版"""
10
  extracted_info = {}
11
+ message_clean = message.strip()
12
+
13
+ log.info(f"🔍 开始提取信息,消息: '{message_clean}'")
14
 
15
  # 1. 提取目的地信息
16
+ destination = self._extract_destination(message_clean)
17
  if destination:
18
  extracted_info['destination'] = destination
19
+ log.info(f"✅ 提取到目的地: {destination['name']}")
20
 
21
  # 2. 提取天数信息
22
+ duration = self._extract_duration(message_clean)
23
  if duration:
24
  extracted_info['duration'] = duration
25
+ log.info(f"✅ 提取到天数: {duration['days']}天")
26
 
27
+ # 3. 提取预算信息
28
+ budget = self._extract_budget(message_clean)
29
  if budget:
30
  extracted_info['budget'] = budget
31
+ log.info(f"✅ 提取到预算: {budget.get('description', '未知')}")
32
 
33
+ log.info(f"📋 最终提取结果: {list(extracted_info.keys())}")
34
  return extracted_info
35
 
36
  def _extract_destination(self, message: str) -> dict:
37
+ """提取目的地信息 - 增强日志"""
38
  message_lower = message.lower()
39
+ log.info(f"🏙️ 检查目的地,消息: '{message_lower}'")
40
 
41
  # 从配置中的城市列表匹配
42
  for city_key, city_info in self.config.cities.items():
43
  if city_key in message_lower:
44
+ log.info(f"✅ 匹配到城市key: '{city_key}' -> {city_info['name']}")
45
  return {
46
  'name': city_info['name'],
47
  'country': city_info.get('country', ''),
 
50
  'avg_daily_budget': city_info.get('avg_daily_budget', 100)
51
  }
52
 
53
+ log.info("❌ 未匹配到任何目的地")
54
  return None
55
 
56
  def _extract_duration(self, message: str) -> dict:
57
+ """修复天数提取逻辑"""
58
+ message_clean = message.strip()
59
+ log.info(f"⏰ 检查天数,消息: '{message_clean}'")
60
+
61
+ # 修复正则表达式顺序和逻辑
62
  patterns = [
63
+ r'(\d+)\s*天', # "3天", "5 天"
64
+ r'(\d+)\s*日', # "3日", "5 日"
65
+ r'(\d+)\s*days?', # "3day", "5days"
66
+ r'玩\s*(\d+)\s*天', # "玩3天"
67
+ r'待\s*(\d+)\s*天', # "待3天"
68
+ r'^(\d+)$', # 纯数字 "3" (放在最后)
 
69
  ]
70
 
71
+ for i, pattern in enumerate(patterns):
72
+ match = re.search(pattern, message_clean, re.IGNORECASE)
73
  if match:
74
  days = int(match.group(1))
75
  if 1 <= days <= 30: # 合理的天数范围
76
+ log.info(f"✅ 匹配模式{i+1}: '{pattern}' -> {days}天")
77
  return {
78
  'days': days,
79
  'description': f"{days}天"
80
  }
81
+ else:
82
+ log.info(f"❌ 天数超出范围: {days}")
83
 
84
+ log.info("❌ 未匹配到任何天数")
85
  return None
86
 
87
  def _extract_budget(self, message: str) -> dict:
88
+ """提取预算信息 - 增强日志"""
89
  message_lower = message.lower()
90
+ log.info(f"💰 检查预算,消息: '{message_lower}'")
91
 
92
+ # 1. 匹配具体金额
93
  money_patterns = [
 
94
  (r'(\d+(?:,\d{3})*(?:\.\d{2})?)\s*(?:欧元|euros?|eur|€)', 'EUR'),
 
95
  (r'(\d+(?:,\d{3})*(?:\.\d{2})?)\s*(?:美元|dollars?|usd|\$)', 'USD'),
 
96
  (r'(\d+(?:,\d{3})*(?:\.\d{2})?)\s*(?:元|人民币|rmb|¥)', 'CNY'),
 
97
  (r'(\d+(?:,\d{3})*(?:\.\d{2})?)\s*(?:英镑|pounds?|gbp|£)', 'GBP'),
98
  ]
99
 
 
102
  if match:
103
  amount_str = match.group(1).replace(',', '')
104
  amount = float(amount_str)
105
+ log.info(f"✅ 匹配到金额: {amount}{currency}")
106
  return {
107
  'amount': amount,
108
  'currency': currency,
109
  'type': self._categorize_budget_amount(amount, currency),
110
+ 'description': f"{int(amount)}{currency}"
111
  }
112
 
113
  # 2. 匹配预算类型关键词
 
120
  for budget_type, keywords in budget_keywords.items():
121
  for keyword in keywords:
122
  if keyword in message_lower:
123
+ log.info(f"✅ 匹配到预算类型: '{keyword}' -> {budget_type}")
124
  return {
125
  'type': budget_type,
126
  'description': self._get_budget_type_description(budget_type)
127
  }
128
 
129
+ log.info("❌ 未匹配到任何预算信息")
130
  return None
131
 
132
+ # 其他方法保持不变
133
  def _categorize_budget_amount(self, amount: float, currency: str) -> str:
134
+ eur_rates = {'EUR': 1.0, 'USD': 0.85, 'CNY': 0.13, 'GBP': 1.15}
 
 
 
 
 
 
 
 
135
  eur_amount = amount * eur_rates.get(currency, 1.0)
 
 
136
  daily_budget = eur_amount / 7
137
 
138
  if daily_budget < 50:
 
143
  return 'luxury'
144
 
145
  def _get_budget_type_description(self, budget_type: str) -> str:
 
146
  descriptions = {
147
  'economy': '经济型预算',
148
  'comfortable': '舒适型预算',
modules/response_generator.py CHANGED
@@ -1,8 +1,6 @@
1
- # modules/response_generator.py - 完整版本(含persona+预算)
2
  import json
3
  import os
4
  from .ai_model import AIModel
5
- from pathlib import Path
6
  from .knowledge_base import KnowledgeBase
7
  from utils.logger import log
8
 
@@ -14,184 +12,174 @@ class ResponseGenerator:
14
 
15
  def _load_personas(self):
16
  """加载personas配置"""
17
- personas_path = Path("./config/personas.json")
18
  with open(personas_path, 'r', encoding='utf-8') as f:
19
  data = json.load(f)
20
  return data.get('personas', {})
21
 
22
  def generate(self, user_message: str, session_state: dict, extracted_info: dict) -> str:
23
- """
24
- 生成智能响应。
25
- 这个方法现在更加灵活,能够处理信息的修改,并按优先级提问。
26
-
27
- Args:
28
- user_message (str): 用户的原始消息。
29
- session_state (dict): 当前完整的会话状态。
30
- extracted_info (dict): 从当前用户消息中新提取的信息。
31
- """
32
  try:
33
  response_parts = []
34
 
35
- # 1. (新增) 生成对新提取信息的确认反馈
36
- # 这是解决“修改信息”问题的关键。
37
  acknowledgement = self._generate_acknowledgement(extracted_info)
38
  if acknowledgement:
39
  response_parts.append(acknowledgement)
40
 
41
- # 2. 按优先级检查缺失信息,并生成下一个问题
42
- # 这个结构取代了之前僵硬的if-if-if流程。
43
- if not session_state.get("destination"):
44
- question = "Hi!你想去欧洲的哪个城市呢?比如巴黎, 罗马, 巴塞罗那?"
45
- response_parts.append(question)
46
-
47
- elif not session_state.get("duration"):
48
- question = f"好的,{session_state['destination']['name']}是个很棒的选择!你计划玩几天呢?"
49
- response_parts.append(question)
50
-
51
- elif not session_state.get("budget"):
52
- question = f"了解!{session_state['duration']['days']}天的行程。为了给您更合适的建议,请问您的预算大概是多少呢?(比如:2000欧元,或经济型/舒适型/豪华型)"
53
- response_parts.append(question)
54
-
55
- elif not session_state.get("persona"):
56
- separator = '*' * 60
57
-
58
- question = f"""请告诉我您更偏向哪种旅行风格:高效规划型、社交分享型,还是深度体验型?
59
-
60
- {separator}
61
-
62
- 🗓️ **高效规划型** - 注重时间安排和预算控制,喜欢详细的行程规划
63
 
64
- 🤝 **社交分享型** - 重视与朋友分享,喜欢拍照打卡和热闹的体验
65
-
66
- 🎨 **深度体验型** - 追求地道文化体验,避开商业化景点"""
67
- response_parts.append(question)
68
-
69
- else:
70
- # 3. 如果所有信息都已收集完毕,则生成最终的旅行计划
71
- # 如果刚才有信息修改,确认信息会和最终计划一起发出。
72
  plan = self._generate_persona_enhanced_plan(user_message, session_state)
73
  response_parts.append(plan)
74
 
75
- # 将确认信息和下一个问题(或最终计划)组合成一句通顺的回复
76
- return " ".join(response_parts)
77
 
78
  except Exception as e:
79
  log.error(f"❌ 响应生成失败: {e}", exc_info=True)
80
  return "抱歉,我在处理您的请求时遇到了问题,请稍后再试。"
81
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  def _generate_acknowledgement(self, extracted_info: dict) -> str:
83
- """
84
- (新增) 为新提取的信息生成确认语。
85
- 例如,如果用户修改了天数,会返回 "好的,已将行程天数更新为5天。"
86
- """
87
  ack_parts = []
 
88
  if "destination" in extracted_info:
89
- ack_parts.append(f"目的地已更新为“{extracted_info['destination']['name']}”")
 
 
90
  if "duration" in extracted_info:
91
- ack_parts.append(f"行程天数已更新为“{extracted_info['duration']['description']}”")
 
 
92
  if "budget" in extracted_info:
93
- ack_parts.append(f"预算已更新为“{self._format_budget_info(extracted_info['budget'])}”")
94
- if "persona" in extracted_info:
95
- ack_parts.append(f"旅行风格已确认为“{extracted_info['persona']['description']}”")
96
-
97
  if not ack_parts:
98
  return ""
99
 
100
  return "好的," + ",".join(ack_parts) + "。"
101
 
102
  def _generate_persona_enhanced_plan(self, user_message: str, session_state: dict) -> str:
103
- """根据persona和完整信息生成定制化的旅行计划"""
104
-
105
- search_query = self._build_search_query(session_state)
106
- relevant_knowledge = self.kb.search(search_query)
107
- knowledge_context = self._format_knowledge_context(relevant_knowledge)
108
-
109
- persona_prompt = self._build_persona_enhanced_prompt(session_state, knowledge_context)
110
 
111
- # 3. 使用AI生成回答
 
 
 
 
 
 
112
  if self.ai_model.is_available():
113
- return self.ai_model.generate(user_message, persona_prompt)
 
114
  else:
115
- return self._generate_fallback_plan(session_state, knowledge_context)
 
 
 
 
116
 
117
- def _build_persona_enhanced_prompt(self, session_state: dict, knowledge_context: str = "") -> str:
118
- """根据persona构建增强的prompt"""
 
 
 
 
 
 
119
  destination = session_state.get("destination", {})
120
  duration = session_state.get("duration", {})
121
  budget = session_state.get("budget", {})
122
  persona = session_state.get("persona", {})
123
 
124
- # 基础信息
125
  location = destination.get('name', '目的地')
126
  days = duration.get('days', '几')
127
  budget_info = self._format_budget_info(budget)
128
 
129
- # 获取persona配置
130
- persona_key = persona.get('key')
131
- if not persona_key or persona_key not in self.personas:
132
- # 如果没有有效persona,使用通用prompt
133
- return self._build_generic_prompt(session_state, knowledge_context)
134
-
135
- persona_config = self.personas[persona_key]
136
-
137
- # 使用personas.json中的prompt_template
138
- persona_template = persona_config.get('prompt_template', '')
139
-
140
- # 替换模板中的变量
141
- enhanced_prompt = persona_template.format(
142
- location=location,
143
- days=days,
144
- date="近期", # 可以从session中获取更具体的日期
145
- user_tags="", # 可以从用户偏好中提取
146
- commercial_preference="适中", # 可以从session中获取
147
- group_description="个人/朋友", # 可以从session中获取
148
- budget=budget_info, # 使用格式化的预算信息
149
- tags="" # 可以从session中获取
150
- )
151
-
152
- # 添加知识库上下文
153
- if knowledge_context:
154
- enhanced_prompt += f"\n\n【背景知识】\n{knowledge_context}"
155
-
156
- # 添加预算约束信息
157
- enhanced_prompt += f"\n\n【预算约束】\n用户预算:{budget_info},请确保所有推荐都在预算范围内。"
158
 
159
- # 添加persona特定的指导原则
160
- characteristics = persona_config.get('characteristics', [])
161
- if characteristics:
162
- enhanced_prompt += f"\n\n【用户特征】\n" + "\n".join([f"- {char}" for char in characteristics])
163
-
164
- recommendation_strategy = persona_config.get('recommendation_strategy', [])
165
- if recommendation_strategy:
166
- enhanced_prompt += f"\n\n【推荐策略】\n" + "\n".join([f"- {strategy}" for strategy in recommendation_strategy])
167
-
168
- tone_guidelines = persona_config.get('tone', [])
169
- if tone_guidelines:
170
- enhanced_prompt += f"\n\n【语言风格】\n" + "\n".join([f"- {tone}" for tone in tone_guidelines])
 
 
 
 
 
 
 
 
171
 
172
- return enhanced_prompt
173
 
174
  def _format_budget_info(self, budget: dict) -> str:
175
  """格式化预算信息"""
176
  if not budget:
177
  return "中等预算"
178
 
179
- # 如果有具体金额
180
  if budget.get('amount') and budget.get('currency'):
181
  return f"{budget['amount']}{budget['currency']}"
182
 
183
- # 如果有预算类型
 
 
184
  if budget.get('type'):
185
- budget_type_map = {
186
- 'economy': '经济型预算',
187
- 'comfortable': '舒适型预算',
188
- 'luxury': '豪华型预算'
189
  }
190
- return budget_type_map.get(budget['type'], budget['type'])
191
-
192
- # 如果有预算范围
193
- if budget.get('range'):
194
- return budget['range']
195
 
196
  return "中等预算"
197
 
 
 
1
  import json
2
  import os
3
  from .ai_model import AIModel
 
4
  from .knowledge_base import KnowledgeBase
5
  from utils.logger import log
6
 
 
12
 
13
  def _load_personas(self):
14
  """加载personas配置"""
15
+ personas_path = "./config/personas.json" # 简化路径
16
  with open(personas_path, 'r', encoding='utf-8') as f:
17
  data = json.load(f)
18
  return data.get('personas', {})
19
 
20
  def generate(self, user_message: str, session_state: dict, extracted_info: dict) -> str:
21
+ """生成智能响应 - 修复重复询问问题"""
 
 
 
 
 
 
 
 
22
  try:
23
  response_parts = []
24
 
25
+ # 1. 生成对新提取信息的确认反馈
 
26
  acknowledgement = self._generate_acknowledgement(extracted_info)
27
  if acknowledgement:
28
  response_parts.append(acknowledgement)
29
 
30
+ # 2. 检查信息完整性,按优先级询问缺失信息
31
+ next_question = self._get_next_question(session_state)
32
+ if next_question:
33
+ response_parts.append(next_question)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
 
35
+ # 3. 如果所有信息都齐全,生成旅行计划
36
+ if not next_question:
 
 
 
 
 
 
37
  plan = self._generate_persona_enhanced_plan(user_message, session_state)
38
  response_parts.append(plan)
39
 
40
+ # 组合回复
41
+ return " ".join(response_parts) if response_parts else "我理解了,请继续告诉我您的需求。"
42
 
43
  except Exception as e:
44
  log.error(f"❌ 响应生成失败: {e}", exc_info=True)
45
  return "抱歉,我在处理您的请求时遇到了问题,请稍后再试。"
46
 
47
+ def _get_next_question(self, session_state: dict) -> str:
48
+ """获取下一个需要询问的问题 - 修复版"""
49
+
50
+ # 按顺序检查缺失信息
51
+ if not session_state.get("destination"):
52
+ return "你想去欧洲的哪个城市呢?比如巴黎、罗马、巴塞罗那?"
53
+
54
+ if not session_state.get("duration"):
55
+ destination_name = session_state.get('destination', {}).get('name', '目的地')
56
+ return f"好的,{destination_name}是个很棒的选择!你计划玩几天呢?"
57
+
58
+ if not session_state.get("budget"):
59
+ days = session_state.get('duration', {}).get('days', '几')
60
+ return f"了解!{days}天的行程。预算大概多少呢?(比如:2000欧元,或经��型/舒适型/豪华型)"
61
+
62
+ if not session_state.get("persona"):
63
+ return """请选择您的旅行风格:
64
+
65
+ 🗓️ **高效规划型** - 注重时间安排和预算控制
66
+ 🤝 **社交分享型** - 重视拍照打卡和分享体验
67
+ 🎨 **深度体验型** - 追求地道文化和小众探索"""
68
+
69
+ # 所有信息都已收集完毕
70
+ return ""
71
+
72
  def _generate_acknowledgement(self, extracted_info: dict) -> str:
73
+ """生成确认信息 - 简化版"""
74
+ if not extracted_info:
75
+ return ""
76
+
77
  ack_parts = []
78
+
79
  if "destination" in extracted_info:
80
+ name = extracted_info['destination'].get('name', '目的地')
81
+ ack_parts.append(f"目的地已设置为{name}")
82
+
83
  if "duration" in extracted_info:
84
+ days = extracted_info['duration'].get('days', '几')
85
+ ack_parts.append(f"行程天数已设置为{days}天")
86
+
87
  if "budget" in extracted_info:
88
+ budget_desc = self._format_budget_info(extracted_info['budget'])
89
+ ack_parts.append(f"预算已设置为{budget_desc}")
90
+
 
91
  if not ack_parts:
92
  return ""
93
 
94
  return "好的," + ",".join(ack_parts) + "。"
95
 
96
  def _generate_persona_enhanced_plan(self, user_message: str, session_state: dict) -> str:
97
+ """生成最终旅行计划"""
98
+
99
+ # 获取基本信息
100
+ destination = session_state.get("destination", {})
101
+ duration = session_state.get("duration", {})
102
+ budget = session_state.get("budget", {})
103
+ persona = session_state.get("persona", {})
104
 
105
+ # 构建计划
106
+ location = destination.get('name', '目的地')
107
+ days = duration.get('days', '几')
108
+ budget_info = self._format_budget_info(budget)
109
+ persona_name = persona.get('name', '旅行者')
110
+
111
+ # 如果AI可用,生成详细计划
112
  if self.ai_model.is_available():
113
+ prompt = self._build_prompt(session_state)
114
+ return self.ai_model.generate(user_message, prompt)
115
  else:
116
+ # 备用计划
117
+ return f"""✈️ 为您制定{location}{days}天旅行计划
118
+
119
+ 👤 旅行风格:{persona_name}
120
+ 💰 预算:{budget_info}
121
 
122
+ 🎯 主要景点:{destination.get('highlights', '经典景点等您探索')}
123
+
124
+ 📍 建议路线:根据您的{persona_name}风格,为您推荐最适合的行程安排。
125
+
126
+ 如需详细规划,请稍后重试或告诉我具体需求!"""
127
+
128
+ def _build_prompt(self, session_state: dict) -> str:
129
+ """构建AI提示词"""
130
  destination = session_state.get("destination", {})
131
  duration = session_state.get("duration", {})
132
  budget = session_state.get("budget", {})
133
  persona = session_state.get("persona", {})
134
 
 
135
  location = destination.get('name', '目的地')
136
  days = duration.get('days', '几')
137
  budget_info = self._format_budget_info(budget)
138
 
139
+ # 基础prompt
140
+ prompt = f"请为{location}制定{days}天旅行计划,预算{budget_info}。"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141
 
142
+ # 添加persona风格
143
+ persona_key = persona.get('key')
144
+ if persona_key in self.personas:
145
+ persona_config = self.personas[persona_key]
146
+ template = persona_config.get('prompt_template', '')
147
+ if template:
148
+ try:
149
+ prompt = template.format(
150
+ location=location,
151
+ days=days,
152
+ budget=budget_info,
153
+ date="近期",
154
+ user_tags="",
155
+ commercial_preference="适中",
156
+ group_description="个人",
157
+ tags=""
158
+ )
159
+ except:
160
+ # 如果模板格式化失败,使用基础prompt
161
+ pass
162
 
163
+ return prompt
164
 
165
  def _format_budget_info(self, budget: dict) -> str:
166
  """格式化预算信息"""
167
  if not budget:
168
  return "中等预算"
169
 
 
170
  if budget.get('amount') and budget.get('currency'):
171
  return f"{budget['amount']}{budget['currency']}"
172
 
173
+ if budget.get('description'):
174
+ return budget['description']
175
+
176
  if budget.get('type'):
177
+ type_map = {
178
+ 'economy': '经济型',
179
+ 'comfortable': '舒适型',
180
+ 'luxury': '豪华型'
181
  }
182
+ return type_map.get(budget['type'], budget['type'])
 
 
 
 
183
 
184
  return "中等预算"
185