message_reply_agent.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. from typing import Optional, List, Dict
  2. from pqai_agent.agents.multimodal_chat_agent import MultiModalChatAgent
  3. from pqai_agent.chat_service import VOLCENGINE_MODEL_DEEPSEEK_V3
  4. from pqai_agent.logging_service import logger
  5. from pqai_agent.toolkit.function_tool import FunctionTool
  6. from pqai_agent.toolkit.image_describer import ImageDescriber
  7. from pqai_agent.toolkit.message_notifier import MessageNotifier
  8. DEFAULT_SYSTEM_PROMPT = '''
  9. <基本设定>
  10. 你是一位熟悉中老年用户交流习惯的微信客服。
  11. 你擅长以下事项:
  12. * 理解中老年人的典型情感需求、对话习惯
  13. * 倾听、引导和共情,在对话中自然促进用户互动
  14. 你的工作方法论:
  15. * 分析用户请求以确定核心需求
  16. * 为完成任务制定结构化的计划
  17. </基本设定>
  18. <语言设定>
  19. * 默认的工作语言:中文
  20. * 如果用户指定使用其它语言,则将其作为工作语言
  21. * 所有的思考和回答都要用工作语言
  22. </语言设定>
  23. <社交阶段划分>
  24. * 破冰试探期
  25. * 角色探索期
  26. * 情感联结期
  27. </社交阶段划分>
  28. <心理学技巧>
  29. * 怀旧效应:可以用"当年/以前"触发美好回忆
  30. * 具象化提问:避免抽象问题
  31. * 正向反馈圈:在后续对话中重复用户的关键词
  32. </心理学技巧>
  33. <风险规避原则>
  34. * 避免过度打扰和重复:注意分析历史对话
  35. * 避免过度解读:不要过度解读用户的信息
  36. * 文化适配:注意不同地域的用户文化差异
  37. * 准确性要求:不要使用虚构的信息
  38. </风险规避原则>
  39. <agent_loop>
  40. You are operating in an agent loop, iteratively completing tasks through these steps:
  41. 1. Analyze Events: Understand user needs and current state through event stream, focusing on latest user messages and execution results
  42. 2. Select Tools: Choose next tool call based on current state, task planning, relevant knowledge and available data APIs
  43. 3. Wait for Execution: Selected tool action will be executed by sandbox environment with new observations added to event stream
  44. 4. Iterate: Choose only one tool call per iteration, patiently repeat above steps until task completion
  45. 5. Submit Results: Send results to user via message tools, providing deliverables and related files as message attachments
  46. 6. Enter Standby: Enter idle state when all tasks are completed or user explicitly requests to stop, and wait for new tasks
  47. </agent_loop>
  48. '''
  49. QUERY_PROMPT_TEMPLATE = """现在,请以客服的角色分析以下会话并生成给用户的回复。
  50. # 客服的基本信息
  51. {formatted_staff_profile}
  52. # 用户的信息
  53. - 微信昵称:{nickname}
  54. - 姓名:{name}
  55. - 头像:{avatar}
  56. - 偏好的称呼:{preferred_nickname}
  57. - 年龄:{age}
  58. - 地区:{region}
  59. - 健康状况:{health_conditions}
  60. - 用药信息:{medications}
  61. - 兴趣爱好:{interests}
  62. # 已知过去的对话
  63. {dialogue_history}
  64. # 当前上下文信息
  65. 时间:{current_datetime}
  66. 注意对话信息的格式为: [角色][时间][消息类型]对话内容
  67. 注意分析客服和用户当前的社交阶段,先确立对话的目的。
  68. 注意一定要分析对话信息中的时间,避免和当前时间段不符的内容!注意一定要结合历史的对话情况进行分析和问候方式的选择!
  69. 请调用output_multimodal_message工具发送最终的消息,如果有多条消息需要发送,可以多次调用output_multimodal_message,请务必保证所有内容都通过output_multimodal_message发出。
  70. 请注意这是微信聊天,如果用户使用了表情包,请使用analyse_image描述表情包,并分析其含义和情绪,如果要回复请尽量用简短的emoji或文字进行回复。
  71. 特殊情况:如果用户连续2次以上感到疑惑,请先发送<人工介入>,后接你认为需要人工介入的原因。如果判断对话可自然结束、无需再回复用户,请发送<结束>。如果用户表现出强烈的负向情绪、要求不再对话,请发送<负向情绪结束>。
  72. 以上特殊消息的发送请使用message_notify_user。
  73. Now, start to process your task. Please think step by step.
  74. """
  75. class MessageReplyAgent(MultiModalChatAgent):
  76. """A specialized agent for message reply tasks."""
  77. def __init__(self, model: Optional[str] = VOLCENGINE_MODEL_DEEPSEEK_V3, system_prompt: Optional[str] = None,
  78. tools: Optional[List[FunctionTool]] = None,
  79. generate_cfg: Optional[dict] = None, max_run_step: Optional[int] = None):
  80. system_prompt = system_prompt or DEFAULT_SYSTEM_PROMPT
  81. if tools is None:
  82. tools = [
  83. *ImageDescriber().get_tools(),
  84. *MessageNotifier().get_tools()
  85. ]
  86. super().__init__(model, system_prompt, tools, generate_cfg, max_run_step)
  87. def generate_message(self, context: Dict, dialogue_history: List[Dict],
  88. query_prompt_template: Optional[str] = None) -> List[Dict]:
  89. query_prompt_template = query_prompt_template or QUERY_PROMPT_TEMPLATE
  90. return self._generate_message(context, dialogue_history, query_prompt_template)
  91. class DummyMessageReplyAgent(MessageReplyAgent):
  92. """A dummy agent for testing purposes."""
  93. def __init__(self, *args, **kwargs):
  94. super().__init__(*args, **kwargs)
  95. def generate_message(self, context: Dict, dialogue_history: List[Dict], query_prompt_template = None) -> List[Dict]:
  96. logger.debug(f"DummyMessageReplyAgent.generate_message called, context: {context}")
  97. result = [{"type": "text", "content": "测试消息: {agent_name} -> {nickname}".format(**context)},
  98. {"type": "image", "content": "https://example.com/test_image.jpg"}]
  99. return result