diff --git a/app/services/agent/prompts.py b/app/services/agent/prompts.py index ecd3bd0..57620ea 100644 --- a/app/services/agent/prompts.py +++ b/app/services/agent/prompts.py @@ -25,6 +25,7 @@ SYSTEM_PROMPT = """你是VSP物业AI助手,通过企业微信协助物业人 ## 交互规则 - 用户发图片时,如果有待处理工单,询问是否作为处理结果上传 - 用户说"处理完了"并附带描述,自动提交结单 +- 如果用户已经在当前会话里发送过处理结果图片,绝对不要再次要求用户提供图片URL或COS链接,直接使用系统暂存图片 - 回复简洁,适合手机阅读 - 重要信息用【】标注 - 禁止使用markdown语法(如![](url)、**加粗**、# 标题),企微聊天不支持 diff --git a/app/services/agent_dispatcher.py b/app/services/agent_dispatcher.py index 2aef6a0..a5773b9 100644 --- a/app/services/agent_dispatcher.py +++ b/app/services/agent_dispatcher.py @@ -59,6 +59,7 @@ class AgentDispatcher: normalized_content = content.strip() try: + self._maybe_mark_close_photo_intent(session, normalized_content) reply = self._maybe_start_manual_order_from_text(session, normalized_content) if reply is None: reply = await self._handle_manual_order_message(user_id, session, normalized_content) @@ -106,6 +107,14 @@ class AgentDispatcher: del presign_url return await self._start_manual_order_flow(session, permanent_url) + if session.state == "waiting_close_photo": + del presign_url + session.pending_images.append(permanent_url) + return ( + f"已收到图片,当前已暂存 {len(session.pending_images)} 张处理结果图片。\n" + "请继续告诉我工单编号或序号,并补充处理描述;无需再提供图片URL。" + ) + # 3. 检查用户是否有待处理工单 handling_alarm_id = self._find_handling_alarm(user_id) if handling_alarm_id: @@ -143,6 +152,19 @@ class AgentDispatcher: async def _langgraph_chat(self, user_id: str, content: str) -> str: """LangGraph 图调用""" + session = get_session_manager().get(user_id) + graph_content = content + hints: List[str] = [] + if session.state == "waiting_close_photo": + hints.append("系统提示:用户当前正在补充工单处理结果图片。") + if session.pending_images: + hints.append( + f"系统提示:用户已上传 {len(session.pending_images)} 张图片,后台已有永久URL。" + "不要再要求用户提供图片URL或COS链接。若要提交处理结果,直接调用 submit_order_result,image_urls 可留空。" + ) + if hints: + graph_content = f"{content}\n\n" + "\n".join(hints) + config = { "configurable": { "thread_id": f"wechat-{user_id}", @@ -152,7 +174,7 @@ class AgentDispatcher: result = await self._graph.ainvoke( { - "messages": [{"role": "user", "content": content}], + "messages": [{"role": "user", "content": graph_content}], "user_id": user_id, "pending_images": [], "user_uploaded_images": [], @@ -223,6 +245,29 @@ class AgentDispatcher: session.state = "waiting_manual_order_image" return "请先上传现场图片,我会在收到图片后引导您选择区域并补充备注。" + @staticmethod + def _maybe_mark_close_photo_intent(session, content: str) -> None: + """用户明确表示要上传处理结果图片时,优先保留该意图。""" + trigger_phrases = ( + "上传完结图片", + "上传完结的图片", + "上传完结照片", + "上传处理结果", + "提交处理结果", + "补传图片", + "补传照片", + "结单图片", + "完结图片", + ) + if any(phrase in content for phrase in trigger_phrases): + if session.state not in { + "waiting_manual_order_image", + "waiting_manual_order_area", + "waiting_manual_order_remark", + "waiting_manual_order_confirm", + }: + session.state = "waiting_close_photo" + async def _handle_manual_order_message(self, user_id: str, session, content: str) -> Optional[str]: """处理手动工单创建状态机。""" if session.state == "waiting_manual_order_image":