From 78e0076f4a1b81ad33cbe4a23e4cda72e6acdd79 Mon Sep 17 00:00:00 2001 From: 16337 <1633794139@qq.com> Date: Tue, 10 Mar 2026 10:32:50 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96VLM=E6=8F=90=E7=A4=BA?= =?UTF-8?q?=E8=AF=8D=EF=BC=8C=E8=BE=93=E5=87=BA=E6=9B=B4=E7=AE=80=E6=B4=81?= =?UTF-8?q?=EF=BC=8C=E4=BC=A0=E5=85=A5=E7=AE=97=E6=B3=95=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E5=92=8C=E5=8C=BA=E5=9F=9F=E5=90=8D=E7=A7=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - prompt要求≤15字直接说结论,不再描述画面 - 加入算法类型中文名(离岗/周界入侵)让VLM更准确判断 - roi_name改为查询区域名称,不再传UUID - 给出告警成立和误报的示例引导输出格式 Co-Authored-By: Claude Opus 4.6 --- app/services/notify_dispatch.py | 10 +++++++-- app/services/vlm_service.py | 38 ++++++++++++++++++++++++--------- 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/app/services/notify_dispatch.py b/app/services/notify_dispatch.py index 3a080b1..b77c29b 100644 --- a/app/services/notify_dispatch.py +++ b/app/services/notify_dispatch.py @@ -46,7 +46,11 @@ async def process_alarm_notification(alarm_data: Dict): # ========== 1. VLM 复核 ========== vlm_service = get_vlm_service() camera_name = alarm_data.get("camera_name", device_id) - roi_name = alarm_data.get("scene_id", "") + scene_id = alarm_data.get("scene_id", "") + + # 查找区域名称用于 VLM prompt(比 UUID 更有意义) + area_name_for_vlm, _ = _get_notify_persons(device_id, alarm_level) + roi_name = area_name_for_vlm if area_name_for_vlm != "未知区域" else scene_id # snapshot_url 可能是 COS object key,需转为可访问的预签名URL vlm_snapshot_url = snapshot_url @@ -77,7 +81,9 @@ async def process_alarm_notification(alarm_data: Dict): # ========== 2. 查表获取通知人员 ========== description = vlm_result.get("description", "") - area_name, persons = _get_notify_persons(device_id, alarm_level) + # 复用 VLM 阶段已查询的 area_name,重新查人员列表 + area_name = area_name_for_vlm + _, persons = _get_notify_persons(device_id, alarm_level) # 演示模式:数据库无人员时,使用配置的测试 userid if not persons and settings.wechat.test_uids: diff --git a/app/services/vlm_service.py b/app/services/vlm_service.py index 5e4c1a4..6ea9acd 100644 --- a/app/services/vlm_service.py +++ b/app/services/vlm_service.py @@ -13,23 +13,39 @@ from openai import AsyncOpenAI from app.utils.logger import logger +# 算法类型中文映射 +ALARM_TYPE_NAMES = { + "leave_post": "离岗", + "intrusion": "周界入侵", +} + # 算法类型 → VLM Prompt 模板 VLM_PROMPTS = { - "leave_post": """你是安防监控AI复核员。判断{roi_name}岗位区域内是否有人在岗。 -confirmed=true表示确实无人在岗(告警成立),false表示有人(误报)。 -description用≤25字描述画面。 + "leave_post": """你是安防监控AI复核员。算法类型:离岗检测,监控区域:{roi_name}。 +判断该区域是否有人在岗。 +- confirmed=true:无人在岗(告警成立) +- confirmed=false:有人在岗(误报) +description要求:≤15字,直接说结论。 + 告警成立示例:"该区域无人在岗" + 误报示例:"画面中无人员离岗情况" 仅输出JSON:{{"confirmed":true,"description":"..."}}""", - "intrusion": """你是安防监控AI复核员。判断{roi_name}周界区域内是否有人员入侵。 -confirmed=true表示确实有人入侵(告警成立),false表示无人(误报)。 -description用≤25字描述画面。 + "intrusion": """你是安防监控AI复核员。算法类型:周界入侵检测,监控区域:{roi_name}。 +判断该区域是否有人员入侵。 +- confirmed=true:有人入侵(告警成立) +- confirmed=false:无人入侵(误报) +description要求:≤15字,直接说结论。 + 告警成立示例:"有人员进入周界区域" + 误报示例:"画面中无周界入侵情况" 仅输出JSON:{{"confirmed":true,"description":"..."}}""", } # 通用降级 prompt(未知算法类型时使用) -DEFAULT_PROMPT = """你是安防监控AI复核员。边缘AI触发了{alarm_type}告警,判断告警是否属实。 -confirmed=true表示告警成立,false表示误报。 -description用≤25字描述画面。 +DEFAULT_PROMPT = """你是安防监控AI复核员。算法类型:{alarm_type_name},监控区域:{roi_name}。 +判断告警是否属实。 +- confirmed=true:告警成立 +- confirmed=false:误报 +description要求:≤15字,直接说结论。 仅输出JSON:{{"confirmed":true,"description":"..."}}""" @@ -102,10 +118,12 @@ class VLMService: # 选择 prompt 模板 template = VLM_PROMPTS.get(alarm_type, DEFAULT_PROMPT) + alarm_type_name = ALARM_TYPE_NAMES.get(alarm_type, alarm_type) prompt = template.format( camera_name=camera_name or "未知位置", - roi_name=roi_name or "未知区域", + roi_name=roi_name or "监控区域", alarm_type=alarm_type, + alarm_type_name=alarm_type_name, ) try: