Eliot0110 commited on
Commit
6d36a0d
·
1 Parent(s): 520908e

improve: intent classifier

Browse files
modules/info_extractor.py CHANGED
@@ -10,10 +10,15 @@ class InfoExtractor:
10
 
11
  def _build_prompt_template(self) -> str:
12
 
13
- return """你是一个顶级的旅游信息提取专家。
14
- 你的任务是从用户的输入中,精准地提取出【目的地】、【旅行天数】和【预算】这三项核心信息。
15
- 请严格按照下面的JSON格式返回结果,不要添加任何额外的解释或说明。
16
- 如果某项信息不存在,请将对应的值设为 null。
 
 
 
 
 
17
 
18
  {{
19
  "destination": {{
 
10
 
11
  def _build_prompt_template(self) -> str:
12
 
13
+ return """你是一个专业的旅游信息提取AI。
14
+ 你的任务是仔细阅读用户的请求,并从中提取出关键的旅行信息。
15
+
16
+ 请严格按照以下嵌套的JSON格式返回
17
+ ---
18
+ **重要规则**
19
+ 1. 如果某个信息在用户请求中没有明确提及,请将对应的值设为 null。
20
+ 2. **如果用户的请求只是简单的问候 (例如 "hi", "你好"),或者完全不包含任何目的地、时间、预算等旅行信息,请必须返回一个空的JSON对象,即 `{}`。**
21
+ ---
22
 
23
  {{
24
  "destination": {{
modules/intent_classifier.py ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import logging
2
+ from .ai_model import AIModel
3
+
4
+ class IntentClassifier:
5
+ """
6
+ 一个专门用于识别用户输入意uto的分类器。
7
+ 它使用LLM来判断用户的消息属于预定义的哪个类别。
8
+ """
9
+
10
+ def __init__(self, ai_model: AIModel):
11
+ self.ai_model = ai_model
12
+ self.VALID_INTENTS = ['PROVIDING_TRAVEL_INFO', 'GREETING', 'OTHER']
13
+
14
+ def _build_prompt(self, message: str) -> str:
15
+ """构建用于意图分类的、轻量级的Prompt。"""
16
+ return f"""
17
+ 你的任务是分析用户的单条消息,并判断其意图。
18
+ 请从以下几个意图中选择一个最匹配的,并且只返回这个意图的字符串,不要添加任何其他解释或标点符号。
19
+
20
+ 可用意图:
21
+ - PROVIDING_TRAVEL_INFO: 用户明确提到了旅行相关的具体信息,如目的地、时间、预算、人数等。例如:"我想去巴黎玩一周" 或 "预算5000块钱"。
22
+ - GREETING: 用户只是在打招呼或进行简单的问候。例如:"你好", "hi", "在吗?"。
23
+ - OTHER: 不属于以上任何一种的通用查询或闲聊。例如:"法国有什么好玩的?" 或 "帮我订票"。
24
+
25
+ 用户消息:
26
+ ---
27
+ {message}
28
+ ---
29
+
30
+ 你的判断结果 (请只返回一个意图字符串):
31
+ """
32
+
33
+ def classify(self, message: str) -> str:
34
+ """对给定的消息进行意图分类。"""
35
+ log.info(f"🚀 开始对消息进行意图分类: '{message[:30]}...'")
36
+ prompt = self._build_prompt(message)
37
+
38
+ try:
39
+ response = self.ai_model.chat_completion(
40
+ model="gpt-3.5-turbo",
41
+ messages=[{"role": "user", "content": prompt}],
42
+ temperature=0.0,
43
+ max_tokens=10
44
+ )
45
+ intent = response.strip().replace("'", "").replace("\"", "")
46
+
47
+ if intent in self.VALID_INTENTS:
48
+ log.info(f"✅ 意图分类成功: {intent}")
49
+ return intent
50
+ else:
51
+ log.warning(f"⚠️ LLM返回了未知的意图 '{intent}',将回退到 'OTHER'")
52
+ return 'OTHER'
53
+ except Exception as e:
54
+ log.error(f"❌ 意图分类时发生错误: {e}", exc_info=True)
55
+ return 'OTHER'
modules/travel_assistant.py CHANGED
@@ -2,6 +2,7 @@
2
  from .config_loader import ConfigLoader
3
  from .ai_model import AIModel
4
  from .knowledge_base import KnowledgeBase
 
5
  from .info_extractor import InfoExtractor
6
  from .session_manager import SessionManager
7
  from .response_generator import ResponseGenerator
@@ -15,7 +16,8 @@ class TravelAssistant:
15
  self.kb = KnowledgeBase()
16
  self.ai_model = AIModel()
17
  self.session_manager = SessionManager()
18
- self.info_extractor = InfoExtractor(self.ai_model)
 
19
  self.response_generator = ResponseGenerator(self.ai_model, self.kb)
20
  log.info("✅ Travel Assistant 核心模块全部初始化完成!")
21
 
@@ -43,17 +45,32 @@ class TravelAssistant:
43
  session_state = self.session_manager.get_or_create_session(current_session_id)
44
  log.info(f"✅ 设置persona: {persona_info['name']}")
45
 
46
- # 3. 提取信息
47
- extracted_info = self.info_extractor.extract(message)
48
- log.info(f"🔍 提取信息: {list(extracted_info.keys()) if extracted_info else '无'}")
 
 
49
 
50
- # 4. 更新会话状态
51
- if extracted_info:
52
- self.session_manager.update_session(current_session_id, extracted_info)
53
- session_state = self.session_manager.get_or_create_session(current_session_id)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
 
55
- # 5. 生成回复
56
- bot_response = self.response_generator.generate(message, session_state, extracted_info)
57
 
58
  # 6. 返回结果
59
  status_info = self.session_manager.format_session_info(session_state)
 
2
  from .config_loader import ConfigLoader
3
  from .ai_model import AIModel
4
  from .knowledge_base import KnowledgeBase
5
+ from .intent_classifier import IntentClassifier
6
  from .info_extractor import InfoExtractor
7
  from .session_manager import SessionManager
8
  from .response_generator import ResponseGenerator
 
16
  self.kb = KnowledgeBase()
17
  self.ai_model = AIModel()
18
  self.session_manager = SessionManager()
19
+ self.info_extractor = InfoExtractor(self.ai_model)
20
+ self.intent_classifier = IntentClassifier(self.ai_model)
21
  self.response_generator = ResponseGenerator(self.ai_model, self.kb)
22
  log.info("✅ Travel Assistant 核心模块全部初始化完成!")
23
 
 
45
  session_state = self.session_manager.get_or_create_session(current_session_id)
46
  log.info(f"✅ 设置persona: {persona_info['name']}")
47
 
48
+ # 3. 意图识别 (前置守卫)
49
+ intent = self.intent_classifier.classify(message)
50
+ log.info(f"🔍 用户意图识别结果: '{intent}'")
51
+
52
+ extracted_info = {}
53
 
54
+ # 4.: 根据意图进行逻辑分流
55
+ if intent == 'PROVIDING_TRAVEL_INFO':
56
+ # 场景A: 用户提供了旅行信息,执行完整的信息提取
57
+ extracted_info = self.info_extractor.extract(message)
58
+ if extracted_info:
59
+ self.session_manager.update_session(current_session_id, extracted_info)
60
+ session_state = self.session_manager.get_or_create_session(current_session_id)
61
+
62
+ # 无论是否提取成功,都让 response_generator 来生成上下文感知的回复
63
+ bot_response = self.response_generator.generate(message, session_state, extracted_info)
64
+
65
+ else:
66
+ # 场景B: 用户意图是问候或其它,直接生成引导性回复,完全绕过信息提取
67
+ log.info(f"💬 意图为 '{intent}',绕过信息提取,直接生成引导性回复。")
68
+ if intent == 'GREETING':
69
+ bot_response = "您好!很高兴能为您规划旅程。请问您想去哪里,玩几天,预算大概是多少呢?"
70
+ else: # 'OTHER'
71
+ # 对于其它问题,可以调用通用的生成器,让它决定如何回复
72
+ bot_response = self.response_generator.generate(message, session_state, {})
73
 
 
 
74
 
75
  # 6. 返回结果
76
  status_info = self.session_manager.format_session_info(session_state)