feat: 交互Agent + VLM优化 + 企微演示模式

- 新增交互Agent调度器(意图识别 + 工单/查询/报表/闲聊4个Handler)
- 新增工单服务、Excel报表生成器、企微消息加解密模块
- VLM提示词优化(角色设定、≤25字描述、布尔值优先输出)
- VLM降级策略(入侵默认放行、离岗默认拦截)
- 企微演示模式(WECHAT_TEST_UIDS兜底 + SERVICE_BASE_URL修复)
- 新增Agent回调路由和测试接口

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-09 10:42:32 +08:00
parent 1d84456c0f
commit 7cc4f604d0
13 changed files with 827 additions and 54 deletions

View File

@@ -69,6 +69,14 @@ async def process_alarm_notification(alarm_data: Dict):
description = vlm_result.get("description", "")
area_name, persons = _get_notify_persons(device_id, alarm_level)
# 演示模式:数据库无人员时,使用配置的测试 userid
if not persons and settings.wechat.test_uids:
test_uids = [uid.strip() for uid in settings.wechat.test_uids.split(",") if uid.strip()]
if test_uids:
persons = [{"person_name": "测试用户", "wechat_uid": uid, "role": "TEST"} for uid in test_uids]
area_name = "演示区域"
logger.info(f"演示模式: 使用测试用户 {test_uids}")
if not persons:
logger.warning(f"未找到通知人员: camera={device_id}, 跳过企微推送")
return
@@ -95,7 +103,7 @@ async def process_alarm_notification(alarm_data: Dict):
snapshot_url=snapshot_url,
event_time=event_time_str,
alarm_level=alarm_level,
service_base_url=f"http://{settings.app.host}:{settings.app.port}",
service_base_url=settings.wechat.service_base_url or f"http://{settings.app.host}:{settings.app.port}",
)
logger.info(f"告警通知完成: {alarm_id}{len(persons)}")
@@ -110,12 +118,12 @@ def _save_vlm_result(alarm_id: str, vlm_result: Dict):
try:
analysis = AlarmLlmAnalysis(
alarm_id=alarm_id,
llm_model=vlm_result.get("model", "qwen3-vl-flash"),
llm_model="qwen3-vl-flash",
analysis_type="REVIEW",
summary=vlm_result.get("description", ""),
is_false_alarm=not vlm_result.get("confirmed", True),
confidence_score=0.0 if vlm_result.get("skipped") else 0.9,
suggestion=None,
confidence_score=None if vlm_result.get("skipped") else 0.9,
suggestion="VLM跳过" if vlm_result.get("skipped") else None,
)
db.add(analysis)
db.commit()