修复:Agent 对话体验优化

1. System Prompt 优化:不再把无关闲聊强行关联工单
2. waiting_location 状态机加位置判断:
   - 用户回复像位置信息 → 创建工单
   - 用户回复问句/闲聊 → 退出状态机回到正常对话
3. 新增 _looks_like_location() 方法判断文本是否像位置
This commit is contained in:
2026-03-20 11:31:41 +08:00
parent dfc34a5e7f
commit 5ccfe7752f

View File

@@ -27,20 +27,22 @@ SYSTEM_PROMPT = """你是物业安防AI助手。你可以
4. 导出告警报表
5. 分析处理结果图片,确认异常是否消除
规则:
重要规则:
- 正常跟用户对话,不要把无关闲聊强行关联到工单或告警
- 只有用户明确表达"上报问题""创建工单""发现异常"等意图时才触发工单流程
- 用户随便聊天、问问题时,正常友好回复即可
- 当用户发送图片时,分析图片内容,判断是否有安全隐患
- 如果识别到异常,描述异常并询问具体位置
- 回复简洁专业不超过100字
- 回复简洁友好不超过100字
- 不要编造不存在的信息
需要识别意图在回复末尾附加JSON标记
且仅当用户明确要执行以下操作在回复末尾附加JSON标记
<!--INTENT:{"intent":"...","params":{...}}-->
可选意图:
- create_work_order: 用户要创建工单或上报问题
可选意图(仅在用户明确请求时使用)
- create_work_order: 用户明确要创建工单或上报问题
- query_alarm: 用户要查询告警数据params: time_range=today/week/month, alarm_type=leave_post/intrusion/all
- export_report: 用户要导出报表params: time_range=today/week/month
- general_chat: 其他对话(无需附加标记"""
- 普通对话不要附加任何标记"""
IMAGE_ANALYZE_PROMPT = """分析这张图片,判断是否存在安全隐患或异常情况。
请用JSON格式回复
@@ -88,7 +90,16 @@ class AgentDispatcher:
# 状态机:等待位置信息
if session.state == "waiting_location":
return await self._handle_location_reply(user_id, session, content)
# 判断用户是否真的在回答位置,还是在说别的
if self._looks_like_location(content):
return await self._handle_location_reply(user_id, session, content)
else:
# 不像位置信息,退出状态机回到正常对话
session.reset()
session.add_history("user", content)
reply = await self._chat(session)
session.add_history("assistant", reply)
return reply
# 状态机:等待确认
if session.state == "waiting_confirm":
@@ -224,6 +235,36 @@ class AgentDispatcher:
else:
return "请回复「是」确认或「否」取消。"
@staticmethod
def _looks_like_location(text: str) -> bool:
"""简单判断文本是否像位置信息"""
text = text.strip()
# 太短(<2字或是疑问句大概率不是位置
if len(text) < 2:
return False
if text.endswith("?") or text.endswith(""):
return False
# 包含位置关键词
location_keywords = [
"", "", "", "", "", "", "", "", "", "",
"走廊", "大堂", "停车场", "电梯", "楼梯", "通道", "出口", "入口",
"", "西", "", "", "", "", "", "",
"A座", "B座", "C座", "一楼", "二楼", "三楼",
"1楼", "2楼", "3楼", "1层", "2层", "3层",
]
for kw in location_keywords:
if kw in text:
return True
# 包含"取消""算了""不要了"等放弃词
cancel_words = ["取消", "算了", "不要了", "不用了", "没事", "不了"]
for w in cancel_words:
if w in text:
return False
# 长度适中2-30字且不含问号可能是位置
if 2 <= len(text) <= 30:
return True
return False
async def _handle_close_photo(self, user_id: str, session, image_url: str, object_key: str) -> str:
"""分析结单图片"""
previous_issue = session.pending_analysis or "之前的异常"