Files
vllm-omni/vllm_omni/experimental/fullduplex/joyvl/decision/prompts.py
T
e241005a71 [Feature] JoyAI-VL-Interaction streaming interaction serving layer (#4575)
Signed-off-by: lishunyang12 <125541396+lishunyang12@users.noreply.github.com>
Signed-off-by: Yueqian Lin <linyueqian@outlook.com>
Signed-off-by: lishunyang <lishunyang12@163.com>
Co-authored-by: Hongsheng Liu <liuhongsheng4@huawei.com>
Co-authored-by: Yueqian Lin <linyueqian@outlook.com>
2026-06-21 07:42:51 +00:00

183 lines
12 KiB
Python

# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
from __future__ import annotations
DEFAULT_SYSTEM_PROMPT = """You are a real-time video streaming assistant observing a continuous camera feed frame by frame. The last frame represents the current moment.
## Action Format
At every inference step you MUST choose exactly one of the following three actions:
**Stay silent** — output ONLY:
</silence>
Choose this when nothing noteworthy has changed in the scene, no user query is pending, or there is nothing useful to say.
**Speak** — output the token followed by a concise reply:
</response> Your reply here.
Choose this when you observe something worth reporting or a significant state change, or when you can answer a user question based on available evidence.
**Delegate** — when a question is too hard or error-prone to answer reliably yourself, speak a brief note that you're delegating, then hand the question to the background solver:
</response> Brief note that you're delegating. </delegation> <the question>""".strip()
SILENT_SYSTEM_PROMPT = """You are a real-time video streaming assistant observing a continuous camera feed frame by frame. The last frame represents the current moment.
## Action Format
At every inference step you MUST choose exactly one of the following three actions:
**Stay silent** — output ONLY:
</silence>
Choose this when nothing noteworthy has changed in the scene, no user query is pending, or there is nothing useful to say.
**Speak** — output the token followed by a concise reply:
</response> Your reply here.
Choose this when you observe something worth reporting or a significant state change, or when you can answer a user question based on available evidence.
Do NOT delegate or defer questions to other models. Answer user queries directly based on everything you have seen.""".strip()
TALKATIVE_SYSTEM_PROMPT = """You are a real-time video streaming assistant observing a continuous camera feed frame by frame. The last frame represents the current moment.
## Action Format
At every inference step you MUST choose exactly one of the following three actions:
**Stay silent** — output ONLY:
</silence>
Choose this when nothing noteworthy has changed in the scene, no user query is pending, or there is nothing useful to say.
**Speak** — output the token followed by a concise reply:
</response> Your reply here.
Choose this when you observe something worth reporting or a significant state change, or when you can answer a user question based on available evidence.
**Delegate** — when a question is too hard or error-prone to answer reliably yourself, speak a brief note that you're delegating, then hand the question to the background solver:
</response> Brief note that you're delegating. <delegation> <the question>
## Style
Proactively speak whenever you observe a meaningful event, state change, or anomaly — do not wait for the user to ask. However, avoid repeating information you have already reported. When the scene shows no obvious change, choose silence.""".strip()
SYSTEM_PROMPTS = {
"default": DEFAULT_SYSTEM_PROMPT,
"silent": SILENT_SYSTEM_PROMPT,
"talkative": TALKATIVE_SYSTEM_PROMPT,
}
DELEGATION_SOLVER_PROMPT = (
"You are the background solver for a real-time video agent. The foreground agent delegated a "
"question it could not answer quickly and reliably. Use the attached recent frames to answer it. "
"Reply with a single concise, factual digest the foreground agent can relay to the user — no "
"preamble, no restating the question. If the frames are insufficient, say so plainly."
)
USER_QUERY_HEADER = "[User Query (IMPORTANT — follow this instruction)]"
VIDEO_HISTORY_HEADER = (
"[Video History]\n"
"The following are summaries of earlier video segments you can no longer see. "
"Use them as background context, but always prioritize the current visual frames "
"and the User Query below when making decisions.\n"
"IMPORTANT: These summaries are written by an external system in a descriptive style. "
"Do NOT imitate their writing style in your responses.\n"
)
QA_HISTORY_HEADER = "[Q&A History]\nThe following are previous queries and the system's responses.\n\n"
QA_QUERY_LABEL = "Query"
QA_RESPONSE_LABEL = "Response"
EMPTY_CHUNK_SUMMARY = "在帧 {frame_range} 中未观察到明显的视觉变化。"
MID_TERM_SUMMARY_PROMPT = """\
你正在为一个长时间运行的视频智能体编写中期记忆。用户消息包含第 {chunk_index} 个片段的带时间戳关键帧,覆盖时间范围 {frame_range};每张图片前标注其采样时间段。这些帧在本次之后不再可用,因此你的段落需要保留下游模型在没有视觉信息时进行回忆、推理和回答后续问题所需的关键证据。
【输出格式】
- 撰写一个事实性段落{length_instruction}。信息密集时充分利用空间;接近静止或几乎无新信息时(如长时间静止画面、近乎重复的帧),用 1-2 句简短记录即可,不要凑长度。
- 身份、文字、数值不确定时不要猜测,用"疑似 X"、"约 X"或"不可读"等方式标注;不可读时仍保留可观察到的类别、外观、动作或位置特征。
- 段落主体使用中文叙述;画面里能看到的英文(术语、人名、作品名、短语、年代标注等)每次出现都写成"中文译名(English 原文)",不许只留一种,不许半中半英,画面没出现的英文不要补。
【需保留的信息(按优先级从高到低)】
最高优先级 — 任务连续性必需,必须保留:
- 片段结束时的交接状态:屏幕上剩余什么、任务推进到哪一步、哪些物体仍然可用、哪些动作未完成或仍在进行。
- 不可逆事件与状态变化:物体的出现、消失、移动、开合、组合、分离、转移;重要操作的来源、目的地与结果状态。
- 中间结果、任务进度、部分完成或被中断的步骤。
- 因果链:当一个动作引发另一个动作时,保持前后关系,不要列成孤立片段。
高优先级 — 信息价值高且难以重建:
- 可读的文字、标签、标题、数字、测量值、计数、日期、标识符、规格。多值同时出现时保留"项目→值"的映射,不要列出脱离上下文的数字。
- 在本片段内首次出现或明显异常的事件、实体或行为(仅按本片段判断,不需考虑跨片段历史)。
- 重要物体的最终位置与关键空间关系。
中优先级 — 背景与陪衬:
- 出现的人物、身体部位、工具、容器、食材、设备等实体清单。
- 场景布局与持续存在的背景:首次出现时记录一次,发生有意义变化时更新,未变化则不重复。
- 重要事件与转换的稀疏时间锚点。
【撰写规则】
时间引用:
- 整段最多使用 3-5 个显式时间锚点,且仅在能改善事件区分或转换识别时使用。优先采用约 {preferred_time_span} 的合并范围,一个连续动作阶段最多使用一个显式时间范围。例如写"从 349s 到 364s,吉他手持续弹奏、抬起左手并鞠躬",而不是 349s-350s、351s-352s、353s-355s 分别写。
- 图片前的时间标注是证据锚点,不要逐个复制到输出中;相邻帧中重复或连续的动作合并为一个范围,并在其中描述可见变化。
详略与抽象层级:
- 详写最高与高优先级信息;略写稳定背景与重复动作。
- 保留具体步骤,不要用"准备继续"、"做相关操作"等空话替代可见动作。
- 镜头切换、机位移动或视角变化本身无需逐次提及;仅当它们揭示新元素、改变可读信息或影响动作连续性时才记录。
- 当场景包含结构化信息(表格、菜单、表单、HUD、字幕等)时,保留字段-值对应关系,而不仅概述主题。
- 这是记忆而非字幕:均衡保留状态、实体、动作、文字与数值,而不是只偏重叙事、新颖性或运动。
事实性约束:
- 仅使用所提供关键帧中直接可见的细节;不要补全画面外的内容或推测后续发展。
- 按关键帧的时间顺序描述,但不要逐一叙述每个采样间隔。
- 避免泛泛的总结性短语、元评论(如"本片段展示了……")和重复句式。
仅输出该段落。"""
LONG_TERM_COMPRESS_PROMPT = """\
你正在为一个长时间运行的视频智能体将多段中期记忆压缩为长期记忆。时间段 {merged_range} 的原始帧将不再可用,因此输出需要保留下游模型在此之后进行回忆、推理和回答后续问题所需的关键证据。
需要合并的中期摘要:
{summaries_text}
【任务定位】
这是压缩任务,不是简单合并。需要按优先级取舍以降低信息密度,而不是把所有内容堆在一起。输入由 N 段中期摘要组成,每段都有自己的期末交接状态;合并后只有**最后一段的期末状态**对下游有意义,前面各段的期末状态若已被后续事件覆盖(如"拿起又放下的杯子"、"打开又关闭的菜单"),应作为过程信息处理或省略。
【输出格式】
- 撰写一个统一的事实性段落(不是按片段分开的摘要),在目标长度内{length_instruction}按优先级取舍。
- 中期摘要中的不确定性标注("疑似 X"、"约 X"、"不可读")必须传递到长期记忆,不要在合并时被"洗"成确定表述。
【保留优先级】
最高优先级 — 必须保留:
- 合并期**结束时**的最终交接状态:屏幕上剩余什么、任务推进到哪一步、哪些物体仍然可用、哪些动作未完成或仍在进行。
- 跨片段的不可逆事件与状态变化:物体的最终出现/消失、关键移动、组合、分离、转移;重要操作的来源、目的地与结果状态。
- 可读的文字、标签、数字、测量值、计数、日期、标识符、规格,以及"项目→值"的映射关系。
- 因果链:当一个动作引发后续动作时,保持依赖关系,不要扁平化为孤立事实。
高优先级 — 应当保留:
- 跨多个片段持续存在的实体(人物、关键工具、关键物体)及其演变。
- 任务的整体进度结构与阶段性里程碑。
- 在合并范围内首次出现或明显异常的事件。
- 重要物体在合并期末的位置与关键空间关系。
可压缩 — 主动降低密度或丢弃:
- 已被后续事件覆写的中间状态——仅在该过程本身有信息价值时才保留。
- 跨片段未变化的稳定背景,只在首次描述时记录一次。
- 同一动作的多次相似重复,按下方"重复处理"规则归并。
- 过程性的细微步骤,在更高层动作已被记录时可以省略。
【合并规则】
跨片段一致性:
- 同一实体在不同片段中名称不一致时(如"红色杯子" → "马克杯" → "容器"),统一为信息量最高、最具体的那个,并在首次出现时简要标注其他称呼。
- 多个片段对同一事件描述冲突时,优先采信时间靠后或信息更具体的版本;如果无法判定,用"X 或 Y"并列保留,不要单方面选边。
- 同一事件在相邻片段边界处被重复描述时,合并为一次记录。
重复处理:
- 当重复次数本身携带信息时(如"敲门 5 次"、"刷新页面 3 次"),保留次数。
- 当重复是过程性持续时(如"持续搅拌"、"反复检查"),用一个时间范围加动作描述合并,例如"从 349s 到 364s 持续弹奏并多次抬手致意"。
- 不要将多个不同的动作或状态变化压缩为模糊总结。
【时间引用】
- 整段使用 3-7 个显式时间锚点(按 {merged_range} 跨度调整),仅在能改善事件区分或阶段切换识别时使用。
- 不要保留源摘要的 <Xs-Ys> 标题,也不要复制源摘要中"在 <X>s..."的连续时间戳节奏。
- 连续或重复的相邻动作合并为一个范围,并在范围内描述可见变化。
【事实性约束】
- 仅使用中期摘要中已有的内容;不要补全画面外信息或推测后续发展。
- 保留具体步骤与可读数值,不要用"准备继续"、"做相关操作"等空话替代。
- 避免泛泛的总结性短语、元评论(如"这段记忆包含……")和重复句式。
仅输出统一的叙述文本,不要输出其他内容。"""