主题
T2 到校导航(Demo 场景 PRD)
| 项 | 内容 |
|---|---|
| 文档定位 | 08_移动端AI场景设计.md §10 教师模块 T2 到校导航 的场景 PRD,按 公共规范.md §8 的 10 节骨架组织 |
| 通用规范引用 | 前端形态、单会话、系统提示词边界、输出规范见 公共规范.md;本文只写 T2 场景本身 |
| 能力来源 | 空间实体解析(space-agent 的 /internal/spaces/resolve,封装为 MCP resolve_space)+ 新建地图 MCP plan_route(对接小程序地图板块) |
| 复用关系 | S3 到校导航 与本文是同一能力,S3 复用本文的 MCP 与编排定义,只替换角色话术、可去空间范围与常用起点,不重复定义 |
| 架构约束 | 一个 ReAct 智能体 + 按角色装配,不引入 Master/SA/FA 多智能体路由;space-agent 只贡献「空间实体解析」这一项能力 |
| 版本 | v0.1 |
1. 场景定义
1.1 一句话
教师在到校路上用一句话问「从 B2 停车场到 302 怎么走」,Agent 解析起终点、计算室内步行路线,用一句话给出距离、步行时间与跨层方式,并附地图链接。
1.2 用户与价值
| 项 | 内容 |
|---|---|
| 用户 | 教师(授课教师、业界导师),常从 B2 固定车位或一楼大堂进楼 |
| 价值 | 不用找指示牌、不用问人;到校后直接知道怎么走、多久、要不要坐电梯 |
| 频次 | 到校、换教室时偶发;单次只出一条路线 |
| 能力层级 | L2 只读查询,不控制、不预约、不建单 |
1.3 触发方式
- 被动问答,无定时任务、无系统触发;用户先说话,Agent 再调工具。
- 入口:小程序教师助手聊天区(悬浮球打开),用户输入原话。
- 起终点都明确时,路线计算不依赖当前定位。
- 只说终点时,只给一条兜底:跳转小程序地图页授权定位后自动算路;用户自己说出起点则直接算路。
- 同一会话可连续追问:换起点、换终点都沿用上文。
1.4 边界
| 不做 | 原因 |
|---|---|
| 实时室内定位、自动识别「我现在在哪」 | 定位授权归小程序地图页;Chatbox 不强行申请蓝牙/定位 |
| AR 导航、转向播报、持续导航态 | 本期只交付「一次路线 + 步行时间」,不做导航过程 |
| 车位空位查询与车位引导 | 属 S2 充电/车位查询;T2 只到停车场电梯厅 |
| 教室/讨论室预约 | 属 T6/S7,导航不承担预约 |
| 室外驾车/公交/骑行路线 | 本期 mode 只有步行;跨楼步行可含室外段 |
| 编造路线或猜房间号 | 无 POI、地图缺失时给服务台,不给假路线 |
| 承诺门禁通行 | 路线可达 ≠ 有权进入,通行权限归门禁系统 |
| 主动推送、定时任务 | 导航依赖用户当下的起终点,无法预生成 |
2. Demo 形态
通用形态见 公共规范.md(悬浮球打开 DeerFlow 聊天区、单会话、Markdown + Mermaid)。本场景只约定:
- 登录即教师助手:IAM 返回角色「教师」后直接打开教师助手聊天页,顶部显示「教师助手」。
- 悬浮球直接提问:不预设「导航」按钮、表单或地图卡片;用户输入原话,Agent 自行判断是导航意图。
- 单会话追问:选起点、换终点都在同一条会话里完成;Agent 记住上一轮的终点,用户说「那去 501 呢」时可以只给新终点。
- 跳转用 Markdown 链接:地图页 URL 先用占位
https://example.com/map?...,等小程序地图板块上线后替换;聊天区不嵌地图组件、不渲染业务卡片。
演示脚本:
- 输入「我想问下 B2 停车场到 302 怎么导航?」→ 看完整路线。
- 输入「我去 501 怎么走?」→ 只给地图页定位链接;接着说「从大堂走」→ 看同会话接续出路线。
- 输入「从 B2 到 999 怎么走?」→ 看服务台兜底。
3. Agent 输出设计
3.1 输出元素
| 元素 | 用途 | 约束 |
|---|---|---|
| Markdown 文字 | 一句话结论:起点、终点、距离、时长、是否跨层 | 默认只给这一句 |
| Markdown 链接 | 「在地图中打开」、服务台位置 | 不嵌地图组件 |
| Markdown 表格 / Mermaid | 仅用户追问「怎么走」「说详细点」时给分段 | 二选一,最多 1 张 |
| 编号选项 | 同名房间消歧 | 按需,最多 3 项 |
- 单次回复图总数 ≤2(本场景通常 1 张)。
- 不输出 JSON、不用 HTML、不用自定义业务卡片。
- 示例中的距离、时间均为演示占位,验收以
plan_route实际返回为准。
3.2 起终点明确
用户
我想问下 B2 停车场到 302 怎么导航?
Agent
从 B2 停车场 到 A 楼 302,步行约 380 米、6 分钟,需要乘电梯上 3 层。在地图中打开
- 默认只回这一句 + 一个地图链接,不给分段表、不画流程图。
- 只有用户追问「怎么走」「说详细点」时,才补分段(表格或 1 张 Mermaid,二选一)。
3.3 只给终点
用户
我去 302 怎么走?
Agent
要到 302 得先知道从哪出发。打开地图页,定位后自动算路
- 只给这一条兜底,不在聊天里罗列固定起点清单。
- 用户自己说出起点就直接算:
从 B2 停车场出发:约 380 米、6 分钟,乘 2 号客梯到 3F 后右转。在地图中打开
注:不弹蓝牙/定位授权,不猜「你大概在停车场」,不给假路线或假时间。
3.4 POI 缺失 / 服务台兜底
用户
从 B2 到 999 怎么走?
Agent
空间主数据里没有查到 A 楼 999,可能是房间号有误,或该空间未纳入室内地图。我不猜路线,你可以:
- 核对房间号(如 302、501)
- 联系一楼大堂服务台:021-xxxx-xxxx(占位),位置在大堂正门右手边
- 在地图中打开楼层平面图
注:POI 解析失败时按情况回复:
| 情况 | 回复要点 |
|---|---|
| 未查到该房间 | 提示核对房间号 + 服务台电话/位置,不给路线 |
| 查到但地图未覆盖 | 「该空间暂未纳入室内导航」+ 服务台/地图页 |
| 起点无 POI | 跳转地图页定位;用户自己说了起点就按说的算 |
| 同名多候选(如两个 302) | 列「A 楼 302 / B 楼 302」让用户选,不默认取第一个 |
| 服务台 POI 也缺失 | 用配置的电话与文字位置兜底,不编造 |
3.5 异常与降级
| 情况 | 输出 |
|---|---|
resolve_space 超时 | 不编路线;服务台兜底;记录日志 |
plan_route 超时 | 不给距离/时间;给地图页跳转 + 服务台 |
reachable=false(无通路) | 说明步行路线不通,建议问服务台或换终点 |
| 受限区域(施工封闭/门禁) | 说明受限,不承诺通行,给服务台 |
walk_minutes 为空 | 只报距离,不猜时间 |
| 跨层方式缺失 | 只写楼层变化,不写「乘电梯」 |
4. MCP 设计
4.1 resolve_space(空间实体解析)
| 项 | 内容 |
|---|---|
| 作用 | 把自然语言地点(「B2 停车场」「302」「一楼大堂」)解析为空间主数据中的唯一实体 |
| 来源 | space-agent 的 /internal/spaces/resolve,本项目封装为 MCP Tool;只取解析能力,不取多智能体架构 |
| 入参 | 见下表 |
| 返回 | 见下表 |
| 失败 | 见下表;失败不降级为「相似房间」猜测 |
入参:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
query | string | 是 | 用户原话中的地点片段,如「B2 停车场」「302」 |
scope | string | 否 | 限定范围 campus / building_id;默认全院区 |
hint | enum | 否 | from / to,用于同名空间消歧 |
返回字段:
| 字段 | 类型 | 说明 |
|---|---|---|
found | bool | 是否至少解析到一个实体 |
space_id | string | 空间主数据 ID;未找到或需消歧时为 null |
name | string | 标准名称,如「A 楼 302」 |
space_type | enum | building / floor / room / entrance / parking / meeting_point / facility / service_desk |
building | string | 楼栋,如「A 楼」 |
floor | string | 楼层,如 B2 / 1F / 3F |
room_number | string | 房间号;非房间为 null |
map_poi_id | string | 地图服务侧 POI ID,供 plan_route 使用;不可算路为 null |
is_routable | bool | 是否在室内地图可算路范围内 |
match_type | enum | exact / alias / fuzzy |
confidence | number | 0–1,fuzzy 时偏低 |
candidates | array | 多候选时返回,每项含 space_id、name、building、floor、room_number、map_poi_id |
注:唯一命中时 found=true 且 candidates 只有 1 项;多候选时 found=true 但 space_id 为空,由 Skill 让用户消歧。
失败与异常:
| 情况 | 返回 | Skill 处理 |
|---|---|---|
| 无匹配 | found=false,candidates=[] | 服务台兜底,不猜 |
| 多候选 | found=true,candidates 多项 | 列编号候选让用户选 |
| 超时 / 5xx / 字段缺失 | 工具错误 | 不编造;服务台兜底并记录日志 |
命中但 map_poi_id 为空 | is_routable=false | 告知未覆盖,给服务台/地图页 |
4.2 plan_route(室内步行路线)
| 项 | 内容 |
|---|---|
| 作用 | 按起终点 POI 计算步行路线,含室内跨楼层与必要的室外衔接段 |
| 来源 | 本项目新建地图 MCP,对接小程序地图板块;space-agent 不提供路线能力 |
| 入参 | 见下表 |
| 返回 | 见下表 |
| 失败 | 见下表;失败不给估算值 |
入参:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
from_poi_id | string | 是 | 起点地图 POI ID,取自 resolve_space 的 map_poi_id |
to_poi_id | string | 是 | 终点地图 POI ID |
mode | enum | 否 | walk,默认且本期唯一 |
accessible | bool | 否 | 无障碍优先(电梯/坡道),默认 false |
返回字段:
| 字段 | 类型 | 说明 |
|---|---|---|
reachable | bool | 是否可达 |
distance_m | int | 总距离(米) |
walk_minutes | int | 预计步行分钟;不可达或数据缺失为 null |
floor_change | bool | 是否跨层 |
vertical_mode | enum | none / elevator / escalator / stairs;多段跨层取主要方式 |
segments | array | 分段,字段见下 |
map_url | string | 小程序地图页深链,可为空 |
unreachable_reason | enum | no_path / outdoor_only / restricted / map_data_missing;可达为 null |
segments 每项字段:
| 字段 | 类型 | 说明 |
|---|---|---|
seq | int | 段序号,从 1 开始 |
segment_type | enum | indoor / outdoor |
from_name | string | 段起点名称 |
to_name | string | 段终点名称 |
floor | string | 所在楼层或楼层变化,如 B2 → 3F |
instruction | string | 走法描述 |
distance_m | int | 段距离;电梯等无步行距离时为 null |
walk_minutes | int | 段用时;未知为 null |
vertical_mode | enum | none / elevator / escalator / stairs |
失败与异常:
| 情况 | 返回 | Skill 处理 |
|---|---|---|
| 超时 / 5xx | 工具错误 | 不给距离/时间;地图页 + 服务台 |
| 不可达 | reachable=false + unreachable_reason | 按原因说明,不硬给路线 |
walk_minutes 为空 | null | 只报距离,不猜时间 |
segments 为空但 reachable=true | 数据异常 | 只给总距离 + 地图页,提示以地图为准 |
4.3 为什么拆两个 Tool
resolve_space只做「自然语言 → 空间实体」,来源是 space-agent,换实现不影响路线。plan_route只做「POI → 路线」,来源是地图服务,换地图不影响解析。- Skill 先解析、后算路;任一环节失败都能独立兜底,不会把解析错误带进路线计算。
5. Skill 设计
5.1 职责
把「识别起终点 → 实体解析 → 缺起点兜底 → 算路 → 按模板输出」这套固定流程写死,保证同一句问法每次得到一致结构;只处理导航意图,不承担预约、车位、门禁。
5.2 流程
5.3 Skill 提示词草稿
你是上海交通大学新院区 IBMS 的教师助手。本 Skill 只处理室内步行导航(找路)。
输入:用户原话 + 本会话此前的起点/终点(若有)。
步骤:
1. 抽取起点 from、终点 to。终点必填,起点可为空。
2. 调 resolve_space(query=终点, hint=to)。
3. 若 found=false:不猜、不给路线,输出服务台兜底。
4. 若 candidates 多于 1:列编号候选让用户选,本轮结束。
5. 若 is_routable=false 或 map_poi_id 为空:说明该空间暂未纳入室内导航,给服务台/地图页,本轮结束。
6. 若起点为空:只给一条兜底——地图页链接(定位后自动算路),本轮结束;不要罗列固定起点清单,不要申请蓝牙或定位权限。
7. 调 resolve_space(query=起点, hint=from);失败则让用户重选起点或跳地图页。
8. 调 plan_route(from_poi_id, to_poi_id, mode=walk)。失败则不给估算,给服务台/地图页。
9. 按模板输出。
输出要求:
- 默认只回一句话:起点、终点、约多少米、约几分钟、是否跨层,再加一个地图链接。
- 用户追问「怎么走」时再给分段:表格或 1 张 flowchart 二选一。
- 同名房间等歧义用编号消歧;跳转地图用 Markdown 链接。
- 只用空间主数据里的名称;不描述房间类型(如阶梯教室/案例讨论室),用户问就说「以空间主数据为准」。
- 空值写「暂无」,不把 null 当 0;不编造距离、时间、路线。
- 不承诺门禁通行权限,只说路线。
- 不做 AR、实时定位、车位引导。
- Few-shot:把本文 §3.2、§3.3、§3.4 的示例原文作为三条示例放入 Skill。5.4 工具调用顺序与失败策略
| 步骤 | 调用 | 条件 | 失败时 |
|---|---|---|---|
| 1 | resolve_space(终点) | 必做 | 无匹配→服务台;多候选→列候选;超时→服务台 + 日志 |
| 2 | resolve_space(起点) | 起点已给出 | 失败→重选起点/地图页 |
| 3 | plan_route | 起终点均有 map_poi_id | 超时→服务台 + 地图页;不可达→按原因说明 |
| 4 | 组装输出 | — | 图 ≤1 张,选项 ≤3 条 |
注:缺起点时不调用 plan_route,避免用猜测的起点算出错误路线。
6. 定时任务配置
无。
| 项 | 值 |
|---|---|
| 是否需要定时任务 | 否 |
| 触发方式 | 用户在小程序悬浮球被动提问 |
| 原因 | 导航依赖用户当下的起终点,无法预生成 |
| 配置动作 | 不新建任何 DeerFlow 定时任务,也不允许通过对话创建 |
7. 权限与数据范围
| 项 | 内容 |
|---|---|
| 角色 | 教师(教师助手) |
| 操作级别 | 只读(L2);不控制设备、不预约、不建单 |
| 数据范围 | 全院区公共可导航空间:楼栋、楼层、公共教室、大堂、停车场电梯厅、服务台 |
| 不返回 | 空间占用/预约状态、人员信息、设备状态、门禁权限结论 |
| 越权请求 | 询问办公区、设备间等非公共区域时,只答「不在可导航范围」,不列房间明细 |
| 多用户 | 角色由 IAM 装配;同一智能体,数据范围由 MCP 侧 scope 控制 |
| 门禁 | 路线可达不代表有权进入;通行结论一律不由 Agent 给出 |
S3 到校导航 复用本文的 resolve_space、plan_route 与编排,差异只在角色话术、可去空间范围(scope)和常用起点;S3 的 PRD 不重复定义 MCP 与 Skill。
8. 验收要点
| # | 验收项 | 标准 |
|---|---|---|
| 1 | 起终点明确 | 「B2 停车场到 302」只回一句话(距离/时长/是否跨层)+ 地图链接,与 plan_route 返回一致;追问才给分段 |
| 2 | 缺起点 | 「去 302 怎么走」不输出路线或时间;只给地图页定位链接,不列固定起点清单 |
| 3 | 单会话接续 | 用户选起点后同一会话直接出路线,不重复问终点 |
| 4 | 房间不存在 | 「到 999」不编路线,提示核对房间号 + 服务台电话/位置 |
| 5 | 空间存在但地图未覆盖 | 明确「暂未纳入室内导航」,给服务台/地图页,无假时间 |
| 6 | 同名多候选 | 列编号候选等用户选择,不默认取第一个 |
| 7 | 302 类型口径 | 回复不出现「阶梯教室/案例讨论室」等未确认类型;被问时答「以空间主数据为准」 |
| 8 | 不申请权限 | 全程不触发蓝牙/定位授权;定位只发生在用户点击地图页之后 |
| 9 | 边界 | 不提供车位空位、AR、实时定位、转向播报;不承诺门禁通行 |
| 10 | 格式 | 单次 ≤2 图(本场景通常 1 张);无 JSON/HTML;空值写「暂无」 |
9. 已确认与待确认
9.1 已确认
| # | 事项 | 结论 |
|---|---|---|
| 1 | 能力来源 | space-agent 只提供空间实体解析,封装为 resolve_space;不照搬其多智能体架构 |
| 2 | 路线能力 | 新建地图 MCP plan_route,对接小程序地图板块,支持室内跨楼层 |
| 3 | 触发方式 | 被动问答,无定时任务 |
| 4 | 起终点明确 | 直接算路,不依赖当前定位 |
| 5 | 只给终点 | 只给地图页定位链接,不在聊天里列固定起点;Chatbox 不申请蓝牙 |
| 6 | 失败兜底 | 无 POI、地图缺失、房间不存在 → 服务台,不编路线 |
| 7 | 复用关系 | S3 复用本文能力,只写学生场景差异 |
| 8 | 输出形态 | Markdown + Mermaid(≤2 图)+ 编号选项/链接,不用业务卡片 |
9.2 待确认
- 302 房间类型:
08§4 与 M3 写「阶梯教室」,M7/M8 写「案例讨论室」;一律以空间主数据为准,需甲方确认后回写相关文档。 - 室内地图与 POI 数据范围:覆盖哪些楼栋/楼层;B2 停车场是否含电梯厅 POI;服务台、洗手间、母婴室等辅助 POI 是否入库。
- 地图服务选型:
07§4 建议接第三方室内地图(自带路径规划);具体厂商、接口、是否支持跨楼层与小程序深链待定。 - 跨楼层路径精度:电梯等待时间是否计入
walk_minutes;默认电梯/楼梯偏好;无障碍路线是否由地图服务返回。 - 服务台联系方式由谁维护:电话、位置、值班时间归空间主数据、地图 POI 还是客服系统;更新频率与责任人。
- 空间主数据与地图 POI 的 ID 对齐:
map_poi_id由谁写入、同步频率、失效如何检测。 - 教师可导航范围:是否包含教师休息室、办公区等非公共空间;与门禁权限如何衔接。
- 小程序地图页深链规范:页面路径、参数(from/to/是否需定位)、能否从 Chatbox 直接唤起。
10. 关联文档
| 文档 | 关联内容 |
|---|---|
08_移动端AI场景设计.md §4、§10、§11、§12 | 教师时间线 08:20、T2 原始定义、导航兜底、导航设计原则 |
00_总览-方案与主线.md §3.2 | 导航的两种输入:起终点明确 vs 只说终点 |
07_课程系统-课表同步与实时引导.md §3.1、§4 | 路线引导层、是否需要地图的分情况、第三方室内地图建议 |
公共规范.md | 前端形态、单会话、智能体边界、输出规范 |
T1-到校前简报.md | 简报中的教室导航入口;T2 承接「怎么走」的追问 |
S3 到校导航(待写) | 复用本文 MCP 与编排,只写学生场景差异 |
注:上述文档与本文保持一致;如有差异,以本文为准,回写更新对应文档。302 房间类型不在本文定论,以第 9.2 节待确认清单为准。