Browse Source

Update dialogue_manager: send alert if human intervention detected

StrayWarrior 4 days ago
parent
commit
9918597b18
3 changed files with 48 additions and 32 deletions
  1. 44 28
      dialogue_manager.py
  2. 1 1
      toolkit/base.py
  3. 3 3
      toolkit/lark_alert_for_human_intervention.py

+ 44 - 28
dialogue_manager.py

@@ -6,6 +6,7 @@ from enum import Enum, auto
 from typing import Dict, List, Optional, Tuple, Any
 from typing import Dict, List, Optional, Tuple, Any
 from datetime import datetime
 from datetime import datetime
 import time
 import time
+import textwrap
 
 
 import chat_service
 import chat_service
 import prompt_templates
 import prompt_templates
@@ -21,6 +22,7 @@ from history_dialogue_service import HistoryDialogueService
 
 
 from chat_service import ChatServiceType
 from chat_service import ChatServiceType
 from message import MessageType, Message
 from message import MessageType, Message
+from toolkit.lark_alert_for_human_intervention import LarkAlertForHumanIntervention
 from user_manager import UserManager
 from user_manager import UserManager
 from prompt_templates import *
 from prompt_templates import *
 
 
@@ -330,49 +332,51 @@ class DialogueManager:
 
 
     def _trigger_human_intervention(self, reason: str) -> None:
     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"""
         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:
         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:
     def resume_from_human_intervention(self) -> None:
         """从人工介入状态恢复"""
         """从人工介入状态恢复"""
         if self.current_state == DialogueState.HUMAN_INTERVENTION:
         if self.current_state == DialogueState.HUMAN_INTERVENTION:
             self.do_state_change(DialogueState.CHITCHAT)
             self.do_state_change(DialogueState.CHITCHAT)
-            self.human_intervention_triggered = False
             self.consecutive_clarifications = 0
             self.consecutive_clarifications = 0
             self.complex_request_counter = 0
             self.complex_request_counter = 0
 
 
@@ -385,6 +389,18 @@ class DialogueManager:
             })
             })
 
 
     def generate_response(self, llm_response: str) -> Optional[str]:
     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"""
         """根据当前状态处理LLM响应,如果处于人工介入状态则返回None"""
         # 如果处于人工介入状态,不生成回复
         # 如果处于人工介入状态,不生成回复
         if self.current_state == DialogueState.HUMAN_INTERVENTION:
         if self.current_state == DialogueState.HUMAN_INTERVENTION:

+ 1 - 1
toolkit/base.py

@@ -1,7 +1,7 @@
 from typing import List, Optional
 from typing import List, Optional
 import functools
 import functools
 import threading
 import threading
-from function_tool import FunctionTool
+from toolkit.function_tool import FunctionTool
 
 
 def with_timeout(timeout=None):
 def with_timeout(timeout=None):
     r"""Decorator that adds timeout functionality to functions.
     r"""Decorator that adds timeout functionality to functions.

+ 3 - 3
toolkit/lark_alert_for_human_intervention.py

@@ -1,7 +1,7 @@
 from typing import List
 from typing import List
 
 
-from base import BaseToolkit
-from function_tool import FunctionTool
+from toolkit.base import BaseToolkit
+from toolkit.function_tool import FunctionTool
 import requests
 import requests
 
 
 
 
@@ -25,7 +25,7 @@ class LarkAlertForHumanIntervention(BaseToolkit):
         req_body = {
         req_body = {
             "msg_type": "text",
             "msg_type": "text",
             "content": {
             "content": {
-                "text": f'[Agent需人工介入]{message}'
+                "text": f'[Agent告警]{message}'
             }
             }
         }
         }
         try:
         try: