refactor(prompt): Prompt 集中化 - 新增 fam-edge ai_orchestrator/prompts.py(视频分析/智能问答/人物合并三模板共享,消除 gemini/nvidia 两份发散);gemini/nvidia _build_video_prompt 改调共享函数并注入 camera_name;person_service 改调 build_person_merge_prompt;fam-core chat_handler 独立 prompts.py(跨模块风格一致)替代内联 CHAT_SYSTEM_PROMPT;输出硬约束(首字符{/禁markdown)、3 秒密度抽取、people_mentioned 一致性强制、描述 7 维度、人物合并唯一性约束
This commit is contained in:
@@ -20,6 +20,8 @@ from .base_adapter import BaseModelAdapter
|
||||
from .circuit_breaker import CircuitBreaker
|
||||
from ..logger import setup_logger
|
||||
from ..ai_orchestrator.json_parser import parse_vlm_json, VLMOutputInvalidError
|
||||
from ..ai_orchestrator.prompts import build_video_prompt
|
||||
from ..config_loader import load_config
|
||||
|
||||
logger = setup_logger('fam-edge.gemini_adapter')
|
||||
|
||||
@@ -317,32 +319,8 @@ class GeminiAdapter(BaseModelAdapter):
|
||||
}
|
||||
|
||||
def _build_video_prompt(self, known_members: str, event_start_time: str) -> str:
|
||||
start_hint = ""
|
||||
if event_start_time:
|
||||
start_hint = f"\n视频开始时间(北京时间)约为:{event_start_time}。"
|
||||
return f"""你是家庭监控视频分析助手。下面是一段完整监控录像(已整段上传)。
|
||||
请观看整段视频,提取其中有用的信息,只输出合法 JSON(不要 markdown、不要任何解释文字),结构如下:
|
||||
|
||||
{{
|
||||
"global_summary": "整个时段的整体摘要,简体中文,2-4 句,客观描述人物与主要活动",
|
||||
"events": [
|
||||
{{
|
||||
"timestamp": "事件在视频内的相对时间点(格式 HH:MM:SS,从视频开头 00:00:00 算起)",
|
||||
"description": "该时间点的画面/动作信息摘要(谁、在做什么、位置)",
|
||||
"people": ["出现在该时刻的人物,用已知成员真名或'人物A'/'人物B'"],
|
||||
"is_attention_event": false
|
||||
}}
|
||||
],
|
||||
"people_mentioned": ["本视频出现过的所有人物标识/真名"]
|
||||
}}{start_hint}
|
||||
|
||||
规则:
|
||||
1. 只描述客观画面,不要猜测或想象。
|
||||
2. events 提取视频中"有意义的时间点"(人物出现/动作变化/异常),不要逐秒罗列;timestamp 必须是"视频内相对时间"(如 00:05:23 表示视频开始后 5 分 23 秒),不要输出绝对日期时间。
|
||||
3. 已知家庭成员(按特征匹配,匹配到用 real_name,否则用"人物X"):
|
||||
{known_members or '(暂无已知成员)'}
|
||||
4. is_attention_event:是否为跌倒、危险、异常哭闹等需关注事件(没有则为 false)。
|
||||
5. 没有人物出现的时段不要单独成 event;people 留空数组。"""
|
||||
camera = load_config().get('gdrive_sync', {}).get('camera_name', '')
|
||||
return build_video_prompt(known_members, event_start_time, camera)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# 智能问答:纯文本
|
||||
|
||||
@@ -19,6 +19,8 @@ from typing import Dict, List, Optional
|
||||
from .base_adapter import BaseModelAdapter
|
||||
from .circuit_breaker import CircuitBreaker
|
||||
from ..logger import setup_logger
|
||||
from ..ai_orchestrator.prompts import build_video_prompt
|
||||
from ..config_loader import load_config
|
||||
|
||||
logger = setup_logger('fam-edge.nvidia_adapter')
|
||||
|
||||
@@ -244,31 +246,8 @@ class NvidiaVisionAdapter(BaseModelAdapter):
|
||||
return None
|
||||
|
||||
def _build_video_prompt(self, known_members: str, event_start_time: str) -> str:
|
||||
start_hint = ""
|
||||
if event_start_time:
|
||||
start_hint = f"\n视频开始时间(北京时间)约为:{event_start_time}。"
|
||||
return f"""你是家庭监控视频分析助手。下面是一段完整监控录像(已整段上传)。
|
||||
请观看整段视频,提取其中有用的信息,只输出合法 JSON(不要 markdown、不要解释),结构如下:
|
||||
|
||||
{{
|
||||
"global_summary": "整个时段的整体摘要,简体中文,2-4 句",
|
||||
"events": [
|
||||
{{
|
||||
"timestamp": "事件在视频内的相对时间点(格式 HH:MM:SS,从视频开头 00:00:00 算起)",
|
||||
"description": "该时刻画面/动作信息摘要",
|
||||
"people": ["出现在该时刻的人物,用已知成员真名或'人物A'"],
|
||||
"is_attention_event": false
|
||||
}}
|
||||
],
|
||||
"people_mentioned": ["本视频出现过的所有人物标识/真名"]
|
||||
}}{start_hint}
|
||||
|
||||
规则:
|
||||
1. 只描述客观画面,不猜测。
|
||||
2. events 提取有意义的时间点(人物出现/动作变化/异常),timestamp 必须是"视频内相对时间"(如 00:05:23 表示视频开始后 5 分 23 秒),不要输出绝对日期时间。
|
||||
3. 已知家庭成员(按特征匹配,匹配到用 real_name,否则用"人物X"):
|
||||
{known_members or '(暂无已知成员)'}
|
||||
4. is_attention_event:跌倒、危险、异常哭闹等需关注事件(没有则为 false)。"""
|
||||
camera = load_config().get('gdrive_sync', {}).get('camera_name', '')
|
||||
return build_video_prompt(known_members, event_start_time, camera)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# 智能问答:纯文本
|
||||
|
||||
Reference in New Issue
Block a user