Spaces:
Sleeping
Sleeping
improve: chat stream
Browse files- modules/info_extractor.py +2 -1
- modules/response_generator.py +61 -16
- utils/validators.py +0 -1
modules/info_extractor.py
CHANGED
|
@@ -48,6 +48,7 @@ class InfoExtractor:
|
|
| 48 |
"""提取旅行天数"""
|
| 49 |
# 匹配各种天数表达方式
|
| 50 |
patterns = [
|
|
|
|
| 51 |
r'(\d+)\s*天',
|
| 52 |
r'(\d+)\s*日',
|
| 53 |
r'(\d+)\s*days?',
|
|
@@ -57,7 +58,7 @@ class InfoExtractor:
|
|
| 57 |
]
|
| 58 |
|
| 59 |
for pattern in patterns:
|
| 60 |
-
match = re.search(pattern, message, re.IGNORECASE)
|
| 61 |
if match:
|
| 62 |
days = int(match.group(1))
|
| 63 |
if 1 <= days <= 30: # 合理的天数范围
|
|
|
|
| 48 |
"""提取旅行天数"""
|
| 49 |
# 匹配各种天数表达方式
|
| 50 |
patterns = [
|
| 51 |
+
r'^(\d+)$',
|
| 52 |
r'(\d+)\s*天',
|
| 53 |
r'(\d+)\s*日',
|
| 54 |
r'(\d+)\s*days?',
|
|
|
|
| 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: # 合理的天数范围
|
modules/response_generator.py
CHANGED
|
@@ -19,22 +19,43 @@ class ResponseGenerator:
|
|
| 19 |
data = json.load(f)
|
| 20 |
return data.get('personas', {})
|
| 21 |
|
| 22 |
-
def generate(self, user_message: str, session_state: dict) -> str:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
try:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
|
|
|
|
|
|
|
| 25 |
if not session_state.get("destination"):
|
| 26 |
-
|
|
|
|
| 27 |
|
| 28 |
-
|
| 29 |
-
|
|
|
|
| 30 |
|
| 31 |
-
|
| 32 |
-
|
|
|
|
| 33 |
|
| 34 |
-
|
| 35 |
separator = '*' * 60
|
| 36 |
|
| 37 |
-
|
| 38 |
|
| 39 |
{separator}
|
| 40 |
|
|
@@ -43,24 +64,48 @@ class ResponseGenerator:
|
|
| 43 |
🤝 **社交分享型** - 重视与朋友分享,喜欢拍照打卡和热闹的体验
|
| 44 |
|
| 45 |
🎨 **深度体验型** - 追求地道文化体验,避开商业化景点"""
|
| 46 |
-
|
| 47 |
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
except Exception as e:
|
| 52 |
log.error(f"❌ 响应生成失败: {e}", exc_info=True)
|
| 53 |
return "抱歉,我在处理您的请求时遇到了问题,请稍后再试。"
|
| 54 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 55 |
def _generate_persona_enhanced_plan(self, user_message: str, session_state: dict) -> str:
|
| 56 |
"""根据persona和完整信息生成定制化的旅行计划"""
|
| 57 |
-
|
| 58 |
-
# 1. 获取知识库上下文
|
| 59 |
search_query = self._build_search_query(session_state)
|
| 60 |
relevant_knowledge = self.kb.search(search_query)
|
| 61 |
knowledge_context = self._format_knowledge_context(relevant_knowledge)
|
| 62 |
-
|
| 63 |
-
# 2. 根据persona构建定制化prompt
|
| 64 |
persona_prompt = self._build_persona_enhanced_prompt(session_state, knowledge_context)
|
| 65 |
|
| 66 |
# 3. 使用AI生成回答
|
|
|
|
| 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 |
|
|
|
|
| 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生成回答
|
utils/validators.py
CHANGED
|
@@ -1,4 +1,3 @@
|
|
| 1 |
-
# utils/validators.py - 更新版本
|
| 2 |
from pydantic import BaseModel
|
| 3 |
from typing import List, Optional, Dict, Any
|
| 4 |
|
|
|
|
|
|
|
| 1 |
from pydantic import BaseModel
|
| 2 |
from typing import List, Optional, Dict, Any
|
| 3 |
|