主题
T4 课中环境(Demo 场景 PRD)
| 项 | 内容 |
|---|---|
| 文档定位 | 08_移动端AI场景设计.md §10 中反引号标记的 demo 模块的场景 PRD。本文是 T4;模板见 公共规范.md §8 |
| 通用规范引用 | 前端形态、常驻会话、智能体边界、定时任务方式、数据与输出规范见 公共规范.md,本文只写 T4 场景本身 |
| 能力来源 | 人数来自 M8 已定义的人流能力;环境来自本项目新增的环境点位能力;教室归属来自 T1 的课程能力 |
| 复用关系 | 人数复用 M8 §4.1 query_crowd_realtime,不新建人数能力、不重写字段表;环境新增 MCP query_room_environment;教室归属校验复用 T1 §4.1 query_teacher_courses |
| 版本 | v0.1 |
1. 场景定义
1.1 一句话
上课中,教师在小程序里问「302 现在多少人?空气怎么样?」,Agent 查本人正在上课教室的实时人数与环境,用「约人数 + 占用率 + 分级」回答;CO₂ 偏高时只建议加大新风或开窗,不控制设备。
1.2 用户与价值
| 项 | 内容 |
|---|---|
| 用户 | 正在上课或即将上课的教师(demo 账号 T1001) |
| 价值 | 不离开讲台、不找面板,一句话知道教室挤不挤、闷不闷;需要通风时知道该怎么做 |
| 频次 | 按需,课中通常 1–3 次 |
1.3 触发方式
- 被动问答,没有定时任务。
- 典型 query:
- 「302 现在多少人?空气怎么样?」
- 「302 现在人多吗?」
- 「教室闷不闷?CO₂ 多少?」
- 「那 303 呢?」(追问;303 不在本人课表内则拒绝)
- 未说明教室时,默认本人当前节次教室;未说明指标时,人数和环境都答;只问人数时只答人数。
1.4 边界
| 不做 | 原因 |
|---|---|
| 不新建人数能力 | 人数口径、点位映射、去重、分级都已在 M8 定义,直接调用 query_crowd_realtime |
| 不用 WiFi/蓝牙探针、不用 CO₂ 反推人数 | 精度与归属不可靠;CO₂ 只作环境指标 |
| 不承诺精确人数 | 闸机 + 摄像头有约 ±10%~20% 误差,只给约数、占用率和分级 |
| 不做健康、空气达标、通风合规结论 | CO₂ 只表示相对建议关注阈值的位置,不是健康或合规判定 |
| 不通过对话控制新风、空调、BA、照明 | 控制类能力归 T5/设备控制;T4 只读、只建议 |
| 不做热力图、散场预判、跨楼层排名 | 归 M8,T4 不重复 |
| 不做环境趋势图/历史对比 | 本期没有环境历史序列工具,只答当前值 |
| 不查其他教室、其他教师课程 | 教师数据范围只限本人当前/下一节教室 |
| 不返回摄像头画面、人脸、个人轨迹 | 隐私边界;只返回统计值和环境读数 |
2. Demo 形态
通用形态见 公共规范.md(小程序悬浮球打开 DeerFlow 聊天区、单会话、Markdown + Mermaid)。
本场景只约定:
- 教师登录后进入教师助手,点悬浮球直接提问;单会话,追问沿用上一轮教室。
- 先问 302,再问「那 303 呢」:Agent 重新校验 303 是否属于本人当前/下一节课程;不是则拒绝并说明当前教室,不跨范围查询。
- 回复为 Markdown 文字 + 最多 2 张 Mermaid;不出现业务卡片、按钮或独立页面。
- 结果不写首页「本周 AI 运行洞察」卡片(T4 不是 L4 主动服务)。
注:演示脚本:09:00 上课后问「302 现在多少人?空气怎么样?」→ 看占用率、分级和 CO₂ → 追问「那 303 呢?」→ 看到范围拒绝。
3. Agent 输出设计
3.1 输出元素
| 元素 | 用途 | 约束 |
|---|---|---|
| Markdown 文字 | 结论、口径、建议 | 结论先行,人数带「约」 |
| Markdown 表格 | 人数、容量、占用率、温度、湿度、CO₂、新风、更新时间 | 缺测字段写「暂无」 |
Mermaid pie | 当前占用 / 剩余(按约数折算) | 只问人数或人数+环境时使用 |
Mermaid xychart-beta(bar) | CO₂ 当前值与建议关注区间对照 | 仅人数+环境时使用;不是达标判定 |
| 纯文本追问提示 | 如「可继续问:下一节课教室多少人?」 | 不做按钮、不做业务卡片 |
一次回复最多 2 张图;不输出 JSON、不用 HTML。
3.2 模板
人数 + 环境:
{时间},{教室}约 {人数} 人,容量 {容量},占用率约 {占用率}%,{分级}。
| 项目 | 当前值 | 说明 |
|---|---|---|
| 人数 | 约 {人数} 人 | 闸机 + 摄像头,误差约 ±10%~20% |
| 容量 / 占用率 | {容量} 人 / 约 {占用率}% | 占用率由 MCP 计算 |
| 温度 / 湿度 | {温度}℃ / {湿度}% | 缺测写「暂无」 |
| CO₂ | 约 {co2} ppm({co2_level}) | 仅环境指标,非达标判定 |
| 新风 | {状态} | 只读状态,不代表通风效果 |
| 更新时间 | {updated_at} | 人数与环境分别标注 |
(Mermaid:占用饼图 + CO₂ 对照柱状图)
建议:{≤2 条}。以上为建议,不直接控制设备。只问人数:
{时间},{教室}约 {人数} 人,容量 {容量},占用率约 {占用率}%,{分级}。
人数来自闸机 + 摄像头,误差约 ±10%~20%,只给约数和分级,不做精确计数。3.3 示例①:人数 + 环境
用户(2026-11-04 09:12)
302 现在多少人?空气怎么样?
Agent
09:12,302 案例讨论室约 38 人,容量 40,占用率约 95%,接近容量。
项目 当前值 说明 人数 约 38 人 闸机 + 摄像头,误差约 ±10%~20% 容量 / 占用率 40 人 / 约 95% 占用率由 MCP 计算,不由 Agent 相除 温度 / 湿度 24.5℃ / 52% 环境点位 6/6 在线 CO₂ 约 920 ppm(偏高) 按建议关注阈值分级,非达标判定 新风 运行中 只读状态,不代表通风效果 更新时间 人数 09:12 / 环境 09:12 两项数据时间一致 建议:CO₂ 偏高,建议适当加大新风量,课间开窗通风;302 已接近容量,课间可提醒分批进出。以上为建议,不直接控制新风/BA。
可继续问:1)下一节课教室多少人?2)302 环境点位是否都在线?
注:本例容量取 M8 样例点位表的 40 人(302 案例讨论室);T1 示例曾按 50 人写,口径待统一,见 §9.2。
3.4 示例②:只问人数
用户(2026-11-04 09:12)
302 现在人多吗?
Agent
09:12,302 约 38 人,容量 40,占用率约 95%,接近容量。
人数来自闸机 + 摄像头,误差约 ±10%~20%,这里只给约数和分级,不做精确计数。要看空气质量可以继续问。
3.5 示例③:数据断连 / 点位未映射
情况 A:人数断连,环境正常
Agent
09:12,302 人数暂无(摄像头断连,最后更新 08:57)。容量 40,当前无法计算占用率。
项目 当前值 人数 暂无(断连) 容量 40 人 温度 / 湿度 24.6℃ / 51% CO₂ 约 880 ppm(偏高) 新风 运行中 环境点位 6/6 在线(09:12) 建议:CO₂ 偏高,建议加大新风、课间开窗;人数数据请运维检查 302 摄像头。人数暂无,不能按 0 人处理。
情况 B:人数正常,环境点位未配置
Agent
09:12,302 约 38 人,容量 40,占用率约 95%,接近容量。
环境点位待配置,温度、湿度、CO₂、新风状态均暂无,无法判断空气质量。建议现场感受或联系运维确认 302 环境点位;人数部分不受影响。
3.6 异常与降级
| 情况 | 输出 |
|---|---|
| 人数断连 | 人数「暂无」,不算占用率;环境正常则照常输出 |
| 人数点位未映射 | 人数「待配置」,不写 0;容量照常显示 |
| 环境点位未配置 | 环境段「待配置」,人数照常 |
| 环境部分缺测 | 缺测字段「暂无」,显示已上报/总点位数 |
| CO₂ 传感器无读数 | CO₂「暂无」,不用温湿度反推,不做空气判断 |
| 新风状态读不到 | 「暂无」,不猜运行或停止 |
| 教室不在本人范围 | 拒绝,说明只查本人当前/下一节教室 |
| 教室不存在 | 请用户确认教室号,不猜、不查相近房间 |
| 数据过期 | 标注「数据更新于 HH:mm」,超过时效阈值提示可能不是实时(阈值待确认) |
| 课程 MCP 失败 | 无法校验归属,拒绝查询并说明稍后再试,不猜教室 |
4. MCP 设计
4.1 query_crowd_realtime(引用 M8 §4.1,不重复定义)
| 项 | 内容 |
|---|---|
| 定义位置 | prd/M8-人流密度.md §4.1 |
| 作用 | 查 302 当前人数、容量、占用率与分级 |
| 调用参数 | scope_type=space、scope_id={space_code}(如 A-3F-302)、include_pending=true |
| 本场景使用字段 | people、capacity、occupancy_rate、density_level、mapping_status、data_quality、updated_at;pending_spaces[] 的 reason、last_seen |
| 本场景不使用 | 流量、历史、日历、事件;T4 不做拥堵、散场、趋势 |
| 计算位置 | 人数聚合、去重、占用率、分级全部由 MCP 返回,Agent 不自行计算 |
| 失败 | 返回失败或 people=null → 人数写「暂无」,不写 0 |
注:room_id 与 M8 的 space_code 使用同一套空间编码;demo 为 A-3F-302。若课表 room_id 不是空间编码,由 Skill 通过配置映射转换(待确认)。
4.2 query_room_environment(新增)
| 项 | 内容 |
|---|---|
| 作用 | 查指定教室当前温度、湿度、CO₂、新风状态与点位覆盖 |
| 数据源 | 教室环境点位(温湿度、CO₂、新风状态);只用环境传感器,不用 CO₂ 反推人数 |
| 入参 | room_id(string,必填,空间编码)、start / end(string,可选,ISO 8601,时间范围) |
| 时间范围 | 省略 start/end 表示当前时刻;本期只支持当前值,传区间返回 unsupported_range |
返回字段:
| 字段 | 类型 | 说明 | 缺失时 |
|---|---|---|---|
room_id | string | 空间编码 | — |
room_name | string | 教室名称 | 可为空 |
temperature | number/null | 温度(℃) | null |
humidity | number/null | 相对湿度(%) | null |
co2_ppm | int/null | CO₂ 浓度(ppm) | null |
co2_level | enum | normal / elevated / high / unavailable | unavailable |
fresh_air_status | enum | on / off / unknown | unknown |
points_total | int | 环境点位总数;0 表示未配置 | 0 |
points_reported | int | 本次有读数的点位数 | 0 |
coverage_rate | number/null | points_reported ÷ points_total × 100;points_total=0 时为 null | null |
updated_at | string | 数据更新时间 | — |
注:co2_level 建议默认阈值:<800 ppm 为 normal,800–1000 ppm 为 elevated,>1000 ppm 为 high;阈值待甲方确认。该分级只表示相对建议关注阈值的位置,不代表健康、达标或合规结论。
失败约定:
| 情况 | 返回 | Agent 输出 |
|---|---|---|
| 超时 / 非 200 | error: upstream_unavailable | 环境段「暂无」,人数照常 |
room_id 不存在 | error: room_not_found | 请用户确认教室号 |
| 未配置环境点位 | points_total=0、coverage_rate=null、指标 null | 「待配置」 |
| 部分点位缺测 | 对应字段 null、coverage_rate<100 | 缺测字段「暂无」,显示覆盖率 |
| CO₂ 无读数 | co2_ppm=null、co2_level=unavailable | 「CO₂ 暂无」,不推断 |
| 新风状态读不到 | fresh_air_status=unknown | 「新风状态暂无」 |
4.3 可选:query_room_environment_history
本期不做,不定义该工具。 T4 是课中即时问答,08 只要求人数/CO₂ 当前值;历史序列需要额外采样、存储和时效校验,本期不纳入,也不做趋势折线。若后续要做「CO₂ 是不是一路上升」,再补该工具,返回 series[](ts、co2_ppm、co2_level),空值保留 null、不补 0。
4.4 通用约定
- 所有工具返回
updated_at;人数与环境分别标注更新时间,不同时间的数字不放在同一句里比较。 - 缺测返回 null,不返回 0;空数组表示无数据,不是「没人」。
- 只返回空间级统计值和环境读数,不返回摄像头画面、人脸、个人轨迹。
- 环境点位覆盖率、CO₂ 阈值、刷新频率均待确认;未确认前按本文建议默认值运行,并在回复中标注「按建议阈值」。
5. Skill 设计
5.1 职责
Skill T4 课中环境 把「解析教室与意图 → 校验归属 → 查人数 → 按需查环境 → 按模板输出」这套固定流程写死,保证每次回复结构一致、数字都有来源、失败有降级。只读,不控制设备。
5.2 流程
5.3 提示词草稿
你是上海交通大学新院区 IBMS 的教师助手。当前场景是课中环境问答,只服务当前教师本人正在上课或即将上课的教室。
输入:
- 教师 ID:从登录态/会话上下文取(demo 固定 T1001)
- 教室:用户 query 中的房间号;未说明时用当前节次教室
- 意图:只问人数 / 只问环境 / 两者都问
步骤:
1. 解析教室号;用 T1 的 query_teacher_courses 校验该教室是否属于本人当前或下一节课程。不是则拒绝,并告知本人当前教室。
2. 问人数:调 M8 的 query_crowd_realtime(scope_type="space", scope_id=空间编码, include_pending=true)。只用返回的 people、capacity、occupancy_rate、density_level、mapping_status、updated_at;不自己算占用率,不自己定分级。
3. 问环境:调 query_room_environment(room_id=空间编码)。只用返回的 temperature、humidity、co2_ppm、co2_level、fresh_air_status、points_total、points_reported、coverage_rate、updated_at。
4. 只问人数时不调环境工具,不主动补环境;只问环境时人数写「未查询」或省略。
5. 按模板组装:结论先行 → 表格 → 最多 2 张图 → 建议。
输出要求:
- 人数一律写「约 N 人」,同时给容量、占用率、分级;不承诺精确,注明误差约 ±10%~20%。
- 空值写「暂无」,不写 0;未配置写「待配置」;不把暂无当 0 人。
- CO₂ 只作环境指标:可以说「偏高/明显偏高」,不做健康、空气达标、通风合规结论;偏高只建议「加大新风/开窗通风」。
- 不通过对话控制新风、空调、BA、照明;不写「已开启/已调整」;建议后注明「以上为建议,不直接控制设备」。
- 不做热力图、散场预判、跨楼层排名、环境趋势图。
- 只查本人当前/下一节教室;其他教室、其他教师课程直接拒绝并说明原因。
- 只用 Markdown + Mermaid,不输出 JSON、不用 HTML、不做按钮/业务卡片。
- Few-shot:把本文 §3.3、§3.4、§3.5 的示例原文放入 skill。5.4 工具调用顺序与失败策略
| 步骤 | 调用 | 失败时 |
|---|---|---|
| 1 | 课程 MCP query_teacher_courses | 无法校验归属 → 拒绝查询,说明稍后再试;不猜教室 |
| 2 | 人数 query_crowd_realtime | 人数「暂无」,不算占用率;环境照常 |
| 3 | 环境 query_room_environment | 环境「暂无」或部分字段「暂无」;人数照常 |
| 4 | 按模板组装 | 两项都失败 → 「暂无数据」,建议现场确认或报运维;不编造 |
注:课程校验是权限前提;人数和环境都是查询能力,失败时各自降级,不互相拖垮。
5.5 追问
- 「那 303 呢?」:重新校验 303 是否本人课程教室;不是则拒绝;是则换
scope_id重查,沿用上一轮意图(只问人数或人数+环境)。 - 「CO₂ 呢?」:若上一轮已查环境,直接用上下文;否则补查环境。
- 追问不重跑整套 Skill,只换参数;回复中写明本次教室和时间。
6. 定时任务配置
无。
T4 是被动问答,不配置 DeerFlow 定时任务。课中不主动推送;如后续要做「CO₂ 持续偏高提醒」,属于主动预警,需另行设计并确认推送渠道,不在本文范围。
7. 权限与数据范围
| 项 | 内容 |
|---|---|
| 角色 | 教师(demo 固定 T1001) |
| 智能体 | 教师助手 |
| 可用 Skill | T4 课中环境 |
| 可用 MCP | query_teacher_courses(只读)、query_crowd_realtime(只读)、query_room_environment(只读) |
| 操作级别 | 只读;通风建议只作文本,不执行控制 |
| 数据范围 | 本人当前节次与下一节次课程所在教室;默认开课前 30 分钟可查(待确认) |
| 不返回 | 其他教室/其他教师课程、学生名单、摄像头画面、人脸、个人轨迹 |
| 越权 | 直接拒绝并说明原因 |
| 空值 | 「暂无」/「待配置」,不写 0 |
越权示例:
Agent
303 不在您当前或下一节课的教室范围内,无法查询。您当前课程的教室是 302。
注:生产环境按 IAM 角色 + 课程关系鉴权;demo 固定账号,不额外做权限界面。
8. 验收要点
| # | 验收项 | 标准 |
|---|---|---|
| 1 | 人数 + 环境 | 给出约人数、容量、占用率、分级,以及温度、湿度、CO₂、新风状态、更新时间 |
| 2 | 只问人数 | 不输出环境指标、不调环境工具、不硬塞 CO₂ |
| 3 | 精度话术 | 人数带「约」,同时给占用率和分级;不出现「精确 38 人」或承诺准确率 |
| 4 | 人数断连 | 人数显示「暂无」,不算占用率、不写 0;环境正常时照常输出 |
| 5 | 点位未映射 | 人数或环境显示「待配置」,不写 0,不静默丢弃 |
| 6 | 环境部分缺测 | 缺测字段写「暂无」,显示已上报/总点位数,不用其他指标反推 |
| 7 | CO₂ 边界 | 只说「偏高/明显偏高」,不出现健康、空气达标、通风合规结论 |
| 8 | 不做控制 | 不出现「已开启/已调整新风/BA」;建议后注明「不直接控制设备」 |
| 9 | 数据范围 | 只查本人当前/下一节教室;问 303 或其他教师课程时拒绝并说明 |
| 10 | 输出形态 | 只用 Markdown + Mermaid,一次最多 2 张图,无 JSON、无 HTML、无业务卡片/按钮 |
9. 已确认与待确认
9.1 已确认
| # | 事项 | 结论 |
|---|---|---|
| 1 | 交互形态 | 被动问答,无定时任务 |
| 2 | 人数能力 | 复用 M8 §4.1 query_crowd_realtime,不新建、不重复定义字段 |
| 3 | 环境能力 | 新增 query_room_environment,返回温湿度、CO₂、新风状态、点位覆盖与更新时间 |
| 4 | CO₂ 边界 | 只作环境指标;不做健康/达标/合规结论;偏高只建议新风或开窗;不控制 BA |
| 5 | 精度 | 人数误差约 ±10%~20%,用「约人数 + 占用率 + 分级」表达,不承诺精确 |
| 6 | 数据范围 | 只查本人当前/下一节教室;不查其他教室与其他教师课程 |
| 7 | 输出 | Markdown + 最多 2 张 Mermaid;不做业务卡片、按钮、JSON、HTML |
| 8 | 趋势图 | 本期不做环境历史趋势,不定义历史工具 |
9.2 待确认
- 302 房间类型与容量口径:T1 示例按教室 50 人写,M8 样例点位表按案例讨论室 40 人写,需统一;容量是设计容量还是座位数也要明确。
- 课表
room_id与 M8space_code是否同一套编码;不是同一套时,映射表由谁维护、在哪里配置。 - 302 人数点位是否覆盖:房间内是否有摄像头;闸机能否落到房间,还是只能到楼层/出入口。
- 302 环境点位数量与覆盖指标:温湿度、CO₂、新风状态分别由哪些点位提供;覆盖率怎么算。
- CO₂ 分级阈值:本文建议 <800 / 800–1000 / >1000 ppm,是否由甲方确认;是否按空间类型细分。
- 新风是否可读状态:BA 是否提供运行/停止或档位;读不到时是否接受「新风状态暂无」。
- 环境数据刷新频率与过期阈值:建议 1–5 分钟刷新;超过多久算「数据可能过期」。
- 教师「即将上课」的可查时间窗:建议开课前 30 分钟;是否允许查下一节之外的教室。
- 温度/湿度是否要给舒适区间判断:本期只报数值、不做判断;是否需要后续补建议口径。
10. 关联文档
| 文档 | 关联内容 |
|---|---|
08_移动端AI场景设计.md §4、§10、§11、§12 | T4 场景来源、教师 query、编排、兜底与数据口径 |
prd/M8-人流密度.md §1.5–§1.7、§4.1、§4.6 | 点位映射、数据源边界、空间类型口径、query_crowd_realtime 字段与去重规则 |
02_人流密度与空间洞察.md §1–§3 | 数据源、点位-空间映射、空间类型决定口径 |
prd/T1-到校前简报.md §4.1 | query_teacher_courses,用于教室归属校验 |
公共规范.md | 前端形态、常驻会话、智能体边界、输出规范、场景 PRD 模板 |
注:上述文档与本文保持一致。如有差异,以本文为准,回写更新对应文档。