|
@@ -6,6 +6,7 @@ from enum import Enum, auto
|
|
|
from typing import Dict, List, Optional, Tuple, Any
|
|
|
from datetime import datetime
|
|
|
import time
|
|
|
+import textwrap
|
|
|
|
|
|
import chat_service
|
|
|
import prompt_templates
|
|
@@ -21,6 +22,7 @@ from history_dialogue_service import HistoryDialogueService
|
|
|
|
|
|
from chat_service import ChatServiceType
|
|
|
from message import MessageType, Message
|
|
|
+from toolkit.lark_alert_for_human_intervention import LarkAlertForHumanIntervention
|
|
|
from user_manager import UserManager
|
|
|
from prompt_templates import *
|
|
|
|
|
@@ -330,49 +332,51 @@ class DialogueManager:
|
|
|
|
|
|
def _trigger_human_intervention(self, reason: str) -> None:
|
|
|
"""触发人工介入"""
|
|
|
- if not self.human_intervention_triggered:
|
|
|
- self.human_intervention_triggered = True
|
|
|
-
|
|
|
- # 记录人工介入事件
|
|
|
- event = {
|
|
|
- "timestamp": int(time.time() * 1000),
|
|
|
- "reason": reason,
|
|
|
- "dialogue_context": self.dialogue_history[-10:]
|
|
|
- }
|
|
|
+ # 记录人工介入事件
|
|
|
+ # FIXME: 重启即丢失
|
|
|
+ event = {
|
|
|
+ "timestamp": int(time.time() * 1000),
|
|
|
+ "reason": reason,
|
|
|
+ "dialogue_context": self.dialogue_history[-10:]
|
|
|
+ }
|
|
|
|
|
|
- # 更新用户资料中的人工介入历史
|
|
|
- if "human_intervention_history" not in self.user_profile:
|
|
|
- self.user_profile["human_intervention_history"] = []
|
|
|
+ # 更新用户资料中的人工介入历史
|
|
|
+ if "human_intervention_history" not in self.user_profile:
|
|
|
+ self.user_profile["human_intervention_history"] = []
|
|
|
|
|
|
- self.user_profile["human_intervention_history"].append(event)
|
|
|
- self.user_manager.save_user_profile(self.user_id, self.user_profile)
|
|
|
+ self.user_profile["human_intervention_history"].append(event)
|
|
|
+ self.user_manager.save_user_profile(self.user_id, self.user_profile)
|
|
|
|
|
|
- # 发送告警
|
|
|
- self._send_human_intervention_alert(reason)
|
|
|
+ # 发送告警
|
|
|
+ self._send_human_intervention_alert()
|
|
|
|
|
|
- def _send_human_intervention_alert(self, reason: str) -> None:
|
|
|
+ def _send_human_intervention_alert(self) -> None:
|
|
|
+ time_str = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
|
alert_message = f"""
|
|
|
人工介入告警
|
|
|
- 用户ID: {self.user_id}
|
|
|
- 用户昵称: {self.user_profile.get("nickname", "未知")}
|
|
|
- 时间: {int(time.time() * 1000)}
|
|
|
- 原因: {reason}
|
|
|
- 最近对话:
|
|
|
- """
|
|
|
+ 员工: {self.staff_profile.get("agent_name", "未知")}[{self.staff_id}]
|
|
|
+ 用户: {self.user_profile.get("nickname", "未知")}[{self.user_id}]
|
|
|
+ 时间: {time_str}
|
|
|
+ 最近对话:"""
|
|
|
|
|
|
+ alert_message = textwrap.dedent(alert_message)
|
|
|
# 添加最近的对话记录
|
|
|
- recent_dialogues = self.dialogue_history[-10:]
|
|
|
+ recent_dialogues = self.dialogue_history[-5:]
|
|
|
+ role_map = {'assistant': '客服', 'user': '用户'}
|
|
|
for dialogue in recent_dialogues:
|
|
|
- alert_message += f"\n{dialogue['role']}: {dialogue['content']}"
|
|
|
+ if not dialogue['content']:
|
|
|
+ continue
|
|
|
+ role = dialogue['role']
|
|
|
+ if role not in role_map:
|
|
|
+ continue
|
|
|
+ alert_message += f"\n[{role_map[role]}]{dialogue['content']}"
|
|
|
|
|
|
- # TODO(zhoutian): 实现发送告警的具体逻辑
|
|
|
- logger.warning(alert_message)
|
|
|
+ LarkAlertForHumanIntervention().send_lark_alert_for_human_intervention(alert_message)
|
|
|
|
|
|
def resume_from_human_intervention(self) -> None:
|
|
|
"""从人工介入状态恢复"""
|
|
|
if self.current_state == DialogueState.HUMAN_INTERVENTION:
|
|
|
self.do_state_change(DialogueState.CHITCHAT)
|
|
|
- self.human_intervention_triggered = False
|
|
|
self.consecutive_clarifications = 0
|
|
|
self.complex_request_counter = 0
|
|
|
|
|
@@ -385,6 +389,18 @@ class DialogueManager:
|
|
|
})
|
|
|
|
|
|
def generate_response(self, llm_response: str) -> Optional[str]:
|
|
|
+ """
|
|
|
+ 处理LLM的响应,更新对话状态和对话历史。
|
|
|
+ 注意:所有的LLM响应都必须经过这个函数来处理!
|
|
|
+ :param llm_response:
|
|
|
+ :return:
|
|
|
+ """
|
|
|
+ if llm_response == '<人工介入>':
|
|
|
+ logger.warning(f'staff[{self.staff_id}], user[{self.user_id}]: human intervention triggered')
|
|
|
+ self.do_state_change(DialogueState.HUMAN_INTERVENTION)
|
|
|
+ self._send_human_intervention_alert()
|
|
|
+ return None
|
|
|
+
|
|
|
"""根据当前状态处理LLM响应,如果处于人工介入状态则返回None"""
|
|
|
# 如果处于人工介入状态,不生成回复
|
|
|
if self.current_state == DialogueState.HUMAN_INTERVENTION:
|