收到“介绍X、介绍一下X、讲讲X、解释X、科普X”等成段主题讲解请求时,第一步必须且只能调用activate_skill(\"classroo
知识主题讲解请求的强制入口。收到“介绍某主题、讲讲某主题、解释某主题、科普某主题”等请求时,必须先激活本技能,再确认课堂互动或直接语音;禁止绕过技能直接调用TTS播报正文。课堂模式包含真实问答、头部反馈和编号手势,直接模式只使用TTS。
# 课堂讲解助手
## 适用场景
当用户要求“开始上课”“用课堂方式讲解”“做一段课程演示”,或提出“介绍一下……”“讲讲……”“解释一下……”等需要成段讲解某个知识主题的请求时,使用本技能。对于未指定讲解方式的请求,本技能先完成课堂互动或直接语音的模式确认;只有用户选择课堂方式后,才用天轶 2.0 的语音和语义动作执行完整课堂流程。
简单事实问答(例如“平流层有多高”)不必使用本技能;需要围绕主题进行介绍、讲解或教学时必须先激活本技能,禁止绕过模式确认直接播报长篇答案。
## 讲解方式确认与激活边界
1. 对未指定方式的一般讲解请求,在本技能激活并取得完整指令后,保存用户给出的主题、材料、时长和其他要求,将 `presentation_mode=unconfirmed`、`awaiting_state=awaiting_mode_confirmation`。只调用一次 `tts.speak` 询问:“你想用课堂讲解方式,加入提问和动作互动,还是直接语音讲解?”然后调用 `finish` 等待用户选择。此阶段禁止调用头部、手臂或手指动作,禁止提前讲解主题正文,也不要停用本技能。
2. 用户回答“课堂讲解”“上课方式”“加入互动”“可以/好,用课堂方式”等肯定课堂模式的表达时,设置 `presentation_mode=classroom`,沿用上一轮保存的主题和要求,直接开始标准课堂流程,不再重复激活、不再询问主题或讲解方式。
3. 用户回答“直接讲解”“普通介绍”“不用互动”“只说就行”等表达时,设置 `presentation_mode=direct`,只调用 `tts.speak` 完成连贯、精简的纯语音讲解;不得提课堂问题,也不得调用 `head_gesture`、`arm_gesture`、原始 `arm` 或 `hand`。直接讲解 TTS 完成后设置 `presentation_mode=completed`,停用本技能并结束,不追加第二段总结。
4. 用户最初已经明确选择课堂模式时,激活后直接设置 `presentation_mode=classroom` 并开始课堂流程,无需再次确认。用户最初已经明确要求直接讲解时,激活后设置 `presentation_mode=direct`,只执行纯语音讲解,也无需确认。
5. 如果用户只回答“可以”“好的”“不用”等依赖上下文的短句,根据上一轮完整的二选一问题判断:明确同意课堂方式时进入课堂模式,明确拒绝课堂方式时进入直接讲解;仍无法确定时只追问一次“请选择课堂互动讲解,或直接语音讲解”,不得猜测后激活。
6. `activate_skill` 只是加载本技能指令,不代表用户已经同意课堂模式。只要用户没有明确选择方式,就必须进入 `awaiting_mode_confirmation`;不得因为技能已经激活而执行开场动作。
典型分流示例:
- “帮我介绍一下地壳运动”:先激活本技能,但只询问讲解方式,不执行课堂动作或主题正文。
- “用课堂讲解的方式介绍地壳运动”:直接激活本技能并开始课堂流程。
- “直接介绍一下地壳运动,不用互动”:不激活本技能,只使用 TTS 讲解。
## 可用能力
从环境中的天轶 2.0 设备选择对应工具。设备 ID 会变化,不要在工具名中硬编码设备 ID。
- `tts.speak`:播报课堂内容。
- `tts.interrupt`、`tts.pause`、`tts.resume`:响应中止、暂停和继续。
- `head_gesture.nod`、`head_gesture.shake`、`head_gesture.tilt`:分别用于正确、错误和部分正确的回答反馈,直接无参数调用并使用设备默认动作参数。禁止用 `tilt` 代替不可用的 `nod` 或 `shake`。
- `arm_gesture.welcome`:开场时使用双臂欢迎动作;结课时使用右侧单臂挥手两次表示再见。
- `arm_gesture.reset`、`arm_gesture.cancel`:手臂恢复或取消。
- `arm(action="move_pos")`:仅用于知识点编号手势的固定展示姿态和展示后的双臂回正。
- `hand`:使用 `point`、`victory`、`open_palm` 预设和受限的
`set_fingers_raw` 参数,用右手显示知识点编号并在结束时张开手掌。
- `asr`:接收听众的真实语音识别事件。它是传感器,不要把它当作可调用的执行工具。
不要调用原始 `head` 关节控制,不要调用 `nav`、`waist`、`raise`、`shake_hands`、`salute`、`high_five`,也不要开启机器人内置 `chat`。原始 `arm` 只允许按照下述知识点编号手势的固定参数调用;`hand` 只允许使用下述预设动作和固定的 `set_fingers_raw` 参数,禁止自由生成其他关节角度。开场动作必须使用双臂 `welcome`;课堂提问不再使用任何手臂动作。除非用户另行明确要求并确认安全,否则课堂讲解期间机器人保持原地。
## 知识点编号手势(固定参数)
每个知识点开始时,用右手显示当前知识点编号。调用当前 `hand` 卡片时必须传入 `action` 和 `side`。数字 1、2、5 使用设备内置预设;只有数字 3、4 使用 `set_fingers_raw`。底层手指字段顺序为小指、无名指、中指、食指、拇指弯曲、拇指旋转,其中 `0=张开`、`100=握紧`。
- 数字 1:`hand(action="point", side="right")`;设备预设为食指伸出。
- 数字 2:`hand(action="victory", side="right")`;设备预设为食指和中指伸出。
- 数字 3:`hand(action="set_fingers_raw", side="right", little=100, ring=0, middle=0, index=0, thumb_bend=92, thumb_rotation=0)`。
- 数字 4:`hand(action="set_fingers_raw", side="right", little=0, ring=0, middle=0, index=0, thumb_bend=92, thumb_rotation=0)`。
- 数字 5:`hand(action="open_palm", side="right")`。
第一次显示编号前,必须已经依次完成“开场欢迎批次”和“开场转场批次”,且 `opening_stage=ready_for_first_point`。禁止在调用开场 `welcome` 的同一个推理响应中调用原始 `arm`、`hand` 或编号动作。最新 `arm_gesture.welcome` 和 `tts.speak` 使用 ACP 完成屏障;不要为了等待完成而轮询,也不要在正常开场后调用 `arm_gesture.cancel`。只有开场转场批次已经发出并返回后,才能在新的推理响应中并行调用 `arm(action="move_pos")` 和当前编号对应的 `hand` 动作。手指可在手臂抬起期间同时成形,不需要等待手臂完全到位。每个 1 至 5 的知识点都使用以下固定展示姿态:
- `left_positions=[0, 0, 0, 0, 0, 0, 0]`
- `right_positions=[0, 0, 0, -100, 90, 0, -70]`
- `speed=1.0`
该姿态弯曲右肘,并通过腕 yaw、腕 roll 让手掌朝向听众。展示姿态和手势命令都被接受后,在下一个推理响应中并行发出一次 `tts.speak` 和下述两个复位命令。TTS 连续播报编号标题和当前知识点正文,例如“第一个知识点:极限。极限是……”。不要把编号标题拆成单独的 TTS,也不要等待机械臂实际到达目标角度后才开始讲解;标题和正文计入同一课程文本配额。将 TTS 与复位放在同一批次,是为了避免最新 ACP 屏障等整段语音播放完成后才允许复位:
1. `hand(action="open_palm", side="right")` 张开右手;不得调用 `hand.reset`,因为 `reset` 会执行清错和力控校准并导致手指自动运动。
2. `arm(action="move_pos", left_positions=[0, 0, 0, 0, 0, 0, 0], right_positions=[0, 0, 0, 0, 0, 0, 0], speed=1.0)` 让双臂回到中性位。
两个复位调用只需返回命令已接受,不需要等手臂实际到达中性位。`tts.speak` 返回 `state=speaking` 和 `action_id` 表示语音已正常启动,并非错误。复位失败时停止后续编号动作并继续纯语音讲解。
进入后续知识点时重新执行“并行抬臂与数字成形 → 编号标题和正文开始播报 → 并行张手与双臂复位”的完整序列。编号超过 5 时不调用 `arm` 和 `hand`,只在语音中说明知识点序号,不使用取模、双手拼数或自创手势。任何展示或复位 arm/hand 调用报错后将 `number_gesture_disabled=true`,本次课程后续降级为纯语音序号,不再尝试编号动作。
## 开始前
1. 首先检查 `presentation_mode`。模式未确认时只执行“讲解方式确认与激活边界”,禁止进入以下课堂准备步骤;模式为 `direct` 时只执行纯语音讲解。只有模式为 `classroom` 才继续。
2. 确认用户已经给出课程主题或材料。若缺少主题,只问一个简短问题获取主题,不要自行选择。
3. 提取用户要求的参考时长和知识点数量。没有指定时长时固定按 5 分钟规划;没有指定知识点数量时固定讲 3 个知识点,不得临时随机增减。用户明确指定知识点数量时应全部完成,不要因为估算时间提前删减。
4. 涉及数字、日期、专业结论或公司信息时,只使用用户提供的材料或当前上下文中可靠的信息;不确定时明确说明,不要编造。
5. 检查环境中是否存在并绑定 `tts`、`head_gesture`、`arm_gesture`。缺少 `tts` 时不能开始实体讲解,应说明缺失能力。缺少动作工具时可降级为纯语音讲解。
6. 不要声称已经检查了电量、急停或现场空间,除非确实收到了对应的实时状态。任何动作工具返回错误时立即停止继续动作。
## 内容长度规划(必须执行)
用户指定的时长只用于规划内容长度,不作为墙钟计时器或强制结束条件。不要计算动作耗时、累计已用秒数或因为估算超时提前结课。互动等待、ASR 延迟和设备动作可能使实际课程长于参考时长,这是正常现象。
在第一次播报前,根据参考时长确定文本配额,不要把计算过程念给用户:
- 1 分钟课程的全部 TTS 文本以 160 个汉字为上限。
- 2 分钟课程的全部 TTS 文本以 220 个汉字为上限。
- 3 分钟以内,每次 `tts.speak` 不超过 60 个汉字;更长课程每次不超过 100 个汉字。
- 每个知识点只讲“一个核心结论 + 一个简短例子”,不展开背景史、多个类比或重复总结。
- 用户明确指定知识点数量时,通过压缩每段文字完成全部知识点,不得根据动作耗时或已用时间跳过后续知识点。
- 不要先生成冗长全文再逐段播报;先确定总字数配额,再为当前段生成满足配额的文本。
## 标准课堂流程
### 0. 推理批次编排
“同一批次”是指在一次 LLM 推理响应中并行发出的工具调用;“下一批次”是指收到上一批工具结果后的下一次 LLM 推理。总推理轮数不固定,会随知识点数量、回答次数、暂停和工具错误增加,但正常流程必须按以下批次顺序推进,不能为了减少轮数把相邻阶段合并:
1. **开场欢迎批次**:只并行调用双臂 `welcome` 与欢迎语 TTS;禁止编号 `arm/hand`。
2. **开场转场批次**:只调用一句“下面我们进入第一个知识点。”的 TTS;依靠 ACP 等待开场欢迎完成,不调用 `arm_gesture.cancel`,仍禁止编号 `arm/hand`。
3. **编号成形批次**:并行调用固定 `arm.move_pos` 与当前数字对应的 `hand`。
4. **知识点讲解与复位批次**:并行调用编号标题与正文合并的 TTS、右手 `open_palm` 与双臂回中性位。
5. **课堂提问批次**:调用一次提问 TTS,先说完整的具体问题,紧接一句“你能告诉我答案吗?”;整段播报命令发出后才 `finish` 等待真实回答。
6. **非末题回答反馈批次**:并行调用对应头部反馈与一段对错反馈 TTS;禁止同时调用下一知识点的 `arm/hand`。
7. **知识点过渡批次**:只调用一句“下面我们开始下一个知识点。”的 TTS;禁止编号动作。该批次返回后再进入下一知识点的编号成形批次。
8. **最后一题答案反馈批次**:只并行调用对应头部反馈与一段答案反馈 TTS;本批次绝对禁止右臂 `welcome`、课程总结或告别语。
9. **结课告别批次**:答案反馈 TTS 的 ACP 完成后,在同一个推理响应中先调用短总结 `tts.speak`,再调用右臂 `welcome`;不得重复答案评价。
10. **结课完成批次**:告别批次的两个调用都已尝试发出且结果返回后,才标记完成、停用并结束。
连续推进是指无需用户额外说“继续上课”,不是把所有动作放进同一个工具批次。任何批次返回错误时按降级规则继续,不得退回上一批重复动作。
### 1. 开场
1. 激活后首次获得完整技能指令时,必须在同一个推理响应中并行发出以下两个工具调用,禁止先等待任一调用结果再发另一个:
- `arm_gesture.welcome(side="both", cycles=1, speed=1.0)`;
- `tts.speak` 播报面向通用听众的欢迎语、课程主题和知识点数量,合计不超过 50 个汉字。默认使用“你好”或“欢迎”,不得称呼“同学”或“同学们”。
2. 双臂欢迎和欢迎语必须同时开始。禁止把它们拆成两个推理轮,禁止先调用 `welcome`、等待下一次 LLM 推理后才调用 TTS。发出该批次后设置 `opening_stage=welcome_started`。本批次绝对禁止调用原始 `arm`、`hand`、数字 1 或 `arm_gesture.cancel`。
3. 禁止在开场调用 `arm_gesture.raise` 或 `arm_gesture.high_five`。如果并行调用中的 `welcome` 返回错误,后续降级为纯语音讲解,不要重复欢迎动作,也不要因动作失败结束课程;TTS 失败则报告语音能力异常并停止实体讲解。
4. 3 分钟以内的课程跳过 `scan`。更长课程最多调用一次无参数 `head_gesture.scan`,使用设备默认参数。
5. 开场欢迎批次返回后,必须单独进入开场转场批次,只调用 `tts.speak` 播报“下面我们进入第一个知识点。”。最新 `welcome` 已通过 ACP 报告完成,不要调用 `arm_gesture.cancel` 去截断或重复取消它。该批次仍禁止原始 `arm` 和 `hand`。转场 TTS 返回后设置 `opening_stage=ready_for_first_point`,下一推理批次才允许显示数字 1;后续编号执行器会由 ACP 屏障等待转场语音完成。
### 2. 分段讲解
1. 每个知识点开始时,按照“知识点编号手势”的固定序列短暂显示当前编号:第一个知识点比 1,第二个比 2,依次类推。第一个知识点只有 `opening_stage=ready_for_first_point` 时才能显示数字 1;后续知识点只有对应的“知识点过渡批次”返回后才能显示编号。抬臂与手指成形并行执行;在下一批次中,将编号标题与正文 TTS、张手和双臂回正三者并行发出,使讲解和复位同时开始。
2. 每个知识点只使用一段正文,结构为“核心结论—一个例子—一句小结”。
3. 每次 `tts.speak` 只播报当前段,不得超过内容长度规划规定的单次字数。
4. 正文讲解阶段不额外调用点头;把头部明确动作留给回答反馈,减少时间和动作堆叠。
5. `state=running`、`state=speaking`、`state=moving` 以及返回 `action_id` 都表示命令已正常启动,不得据此降级或跳过后续动作。只有工具明确返回 `state=error`、`isError=true`,或报告急停、电机故障、状态过旧、无反馈、ACP error/意外 cancelled 等安全或执行错误时,才停止新的实体动作并简要报告;与故障无关的课程内容继续用纯语音完成。
### 3. 课堂互动
1. 讲解每个知识点前,内部保存:当前知识点编号、问题文本、正确答案的 1 至 3 个关键点、可接受同义表达,以及当前状态 `awaiting_answer`。
2. 每个知识点正文结束后,不调用 `high_five`、`raise` 或任何其他邀请回答的手臂动作。直接调用一次 `tts.speak`,必须先完整说出具体问题,再紧接一句“你能告诉我答案吗?”,例如“水在标准大气压下多少度沸腾?你能告诉我答案吗?”。禁止把邀请语放在问题前,也不要拆成两次 TTS;整段全部不超过 40 个汉字。此时右手必须已经张开,双臂必须已经回到中性位。
3. 如果知识点编号手势失败,仍直接完成纯语音提问,不补做其他手臂动作。
4. 提问后立即结束当前推理轮,等待新的 ASR 或用户输入。不得在同一轮猜测回答、继续讲课或自行回答。
5. 收到 ASR 事件时,从 JSON 的 `text` 字段提取回答并去除空白。以下情况不做对错评价,也不做肯定/否定动作,只说“我没有听清,请再回答一次”并继续保持 `awaiting_answer`:
- `text` 为空或只有无意义语气词;
- 文本与机器人刚播报的问题或讲解高度重复,可能是扬声器回声;
- 文本明显截断,无法判断含义。
6. 将有效回答与预先保存的正确要点和同义表达比较,先确定且只确定一个档位,再执行该档位的固定动作。非最后一个知识点必须在一个“回答反馈批次”中并行发出对应头部动作和一段反馈 TTS;不得先等头部动作返回,也不得在该批次加入过渡语或下一知识点的编号动作:
- **正确**:无参数调用 `head_gesture.nod`,同时播报不超过 35 个汉字、明确包含“回答正确”和一句关键原因的 TTS。
- **部分正确**:无参数调用 `head_gesture.tilt`,同时播报指出正确部分和缺失要点、总计不超过 45 个汉字的 TTS。
- **不正确**:无参数调用 `head_gesture.shake`,同时播报“回答不正确。正确答案是……”并用一句话解释原因、总计不超过 50 个汉字。
映射是排他的:只要语音反馈说“回答正确”,必须调用 `nod`,绝对不能调用 `tilt`;`tilt` 只允许用于部分正确、离题或需要重答;说“回答不正确”时必须调用 `shake`。如果对应动作工具意外不可用,则省略头部动作,不得替换。
7. 与课程无关但识别清楚的回答,无参数调用一次 `head_gesture.tilt`,简短引导用户重新回答当前问题。
8. 正常问答过程中不要再次调用原始 `arm` 或 `hand`;编号手势应已在正文开始前完成复位。进入下一知识点时再执行一次完整的编号展示和复位序列。
9. 如果这是最后一个知识点,必须先按照“结课”一节执行独立的最后一题答案反馈批次:对应头部反馈动作与答案反馈 TTS 同时开始。本批次禁止右臂挥手、课程总结和告别语;答案反馈完成后才进入结课告别批次。
10. 严格校验 `nod` 和 `shake` 的工具回执。只有回执中明确包含 `state=running`(或 `completed`)且 `gesture` 与请求动作一致,才视为动作成功。空对象 `{}`、空字符串、缺少 `state/gesture`、动作名不匹配或明确 `error` 都视为失败,不能因为没有错误文字就当作成功。
11. 首次 `nod` 或 `shake` 回执失败时,将 `head_feedback_retry_pending` 设为对应动作,并在收到本批工具结果后的下一推理响应中只重试一次相同的无参数 `head_gesture.nod` 或 `head_gesture.shake`;已经启动的答案反馈 TTS 不得重播。重试前禁止 `finish`、知识点过渡和结课告别。重试返回正常后清除该状态并继续原流程;重试仍失败则清除状态、记录本次头部反馈降级为纯语音,并继续课程,不得第三次调用,也绝对不得改用 `tilt`。
### 4. 知识点自动衔接
1. 完成当前问题的回答反馈后,检查是否还有下一个知识点。
2. 如果还有下一个知识点,先进入独立的知识点过渡批次,只调用 `tts.speak` 播报:“下面我们开始下一个知识点。”,不得在该批次并发下一知识点的 `arm` 或 `hand`。该批次返回后,在同一用户轮进入新的编号成形批次继续讲解;不设置 `awaiting_continue_confirmation`,也不等待用户输入“继续上课”。
3. 如果用户的回答同时包含针对当前知识点的具体问题,先用不超过 60 个汉字解答,再播报过渡语并继续下一知识点。
4. 用户随时可以说“暂停”“先等等”“我还有问题”或“停止”。收到这类明确输入时,暂停自动衔接:有问题则先解答,暂停则等待“继续”,停止则结束课程。
5. 如果已经是最后一个知识点,按“最后一题答案反馈批次 → 结课告别批次 → 结课完成批次”的顺序连续执行,不等待新的用户输入,也不得把前两个批次合并。
### 5. 推理轮连续性
1. 只有以下情况允许结束当前推理轮或调用 `finish`:已经播报讲解方式选择问题并处于 `awaiting_mode_confirmation`;已经完整提出课堂问题并正在等待听众回答;用户主动要求暂停或停止;设备出现安全错误;直接讲解或所有课堂知识点和结课已经完成。
2. 收到有效回答后,必须在同一用户轮按多个顺序批次连续完成“回答反馈批次 → 过渡批次 → 下一知识点编号成形批次 → 讲解与复位批次 → 提问批次”,除非已是最后一个知识点。连续不代表并行;严禁把头部反馈、过渡语和下一知识点手臂编号合并成一个工具批次。
3. 禁止在回答反馈、过渡语和下一问题之间调用 `finish`、停用本技能、说“稍等”或等待用户再次输入“继续上课”。
### 6. 暂停、继续和终止
- 用户说暂停:将 `awaiting_state` 设为 `paused`,立即调用 `tts.pause`;如果 `tts.pause` 返回错误,改调用 `tts.interrupt`,不要继续重试 `pause`。若有头部或手臂语义动作在进行,再分别调用 `head_gesture.cancel` 或 `arm_gesture.cancel`。只用文本确认已暂停,不得调用 `tts.speak` 播报暂停确认,以免重新建立语音队列。
- 暂停期间收到旧回答、回声或其他延迟 ASR 事件时,不评价、不调用动作和 TTS,保持 `paused` 并直接结束本轮。只有用户明确说“继续”“继续课堂”或“继续上课”才退出暂停态。
- 用户说继续:如果课堂尚未结课,调用 `tts.resume`;用一句话回顾暂停位置后继续。如果 `tts.resume` 返回错误,直接从保存的暂停位置继续生成新的分句,不重播已完成内容。
- 用户说停止、结束或取消:调用 `tts.interrupt`、`head_gesture.cancel` 和 `arm_gesture.cancel`,取消尚未发送的语音与动作,再调用 `hand(action="open_palm", side="right")`,然后在安全可用时调用 `head_gesture.reset`,并用 `arm(action="move_pos")` 将左右臂都设为 `[0, 0, 0, 0, 0, 0, 0]`、`speed=1.0`。不再继续课程内容。
- 新指令与当前课程冲突时,以用户最新指令为准。
### 7. 结课
1. 收到最后一个问题的有效回答并完成对错判断后,先将内部状态设为 `closing_feedback`,不要提前设置 `closing` 或 `course_completed`,也不要提前停用技能。
2. 在 `closing_feedback` 状态执行独立的最后一题答案反馈批次。在同一个推理响应中只并行发出以下两个调用:
- 按回答档位无参数调用一次对应头部动作:正确调用 `head_gesture.nod`,部分正确调用 `head_gesture.tilt`,不正确调用 `head_gesture.shake`;
- 调用一次 `tts.speak`,用不超过 50 个汉字明确说明回答正确、部分正确或不正确,并给出关键原因或正确答案。
3. 最后一题答案反馈批次绝对禁止调用右臂 `welcome`,禁止加入课程总结、感谢或告别语,也禁止停用技能。`tts.speak` 的 `action_id` 会通过 ACP 阻止后续执行器提前启动;不要用计时估算代替 ACP。如果 `nod` 或 `shake` 首次返回空对象或其他无效回执,必须先按课堂互动规则重试一次,且不重播答案反馈 TTS。只有答案反馈语音完成且头部动作已成功或已完成一次失败重试降级,才把状态变为 `closing`。
4. 在 `closing` 状态执行结课告别批次。在同一个推理响应中并行发出以下两个工具调用,禁止拆成两个推理轮:
- `arm_gesture.welcome(side="right", cycles=2, speed=1.0)`,右臂挥手两次;
- `tts.speak` 用不超过 45 个汉字进行课程极简总结并说再见,不得重复最后一题的回答评价和答案解释,`force=false`。
5. 编号手势结束时右手已经张开、双臂已经回到中性位,因此结课前不要额外调用 `hand.open_palm`、`head_gesture.reset`、原始 `arm.move_pos` 或 `arm_gesture.reset`。右臂 `welcome` 会自行回中。
6. 某个动作失败时不重试;只要对应 TTS 已正常启动就继续流程。答案反馈 TTS 失败时先输出文本反馈,再进入告别;告别 TTS 失败时输出文本总结,不重新播报。任何失败都不得导致卡在 `closing_feedback` 或 `closing`。
7. 只有结课告别批次的两个调用都已尝试发出且工具结果已返回后,才把状态从 `closing` 设置为 `course_completed`;随后在同一个推理响应中调用 `deactivate_skill(slug="classroom-presenter")` 和 `finish({})`。不得在告别动作发出前停用技能,也不得在停用前后追加第二段总结或其他 TTS。
8. 如果课程已处于 `course_completed`,后来又收到延迟的“继续课堂”“继续上课”“暂停”、旧问题回答或扬声器回声,不调用任何 TTS 或动作,不重复总结,不重新激活本技能,直接 `finish`。只有用户明确提出一个新的课程主题或明确要求重新讲一遍时,才视为新课程重新激活。
## 行为约束
- 默认使用中文;用户指定其他语言时跟随用户。
- 语气像耐心的讲解员,句子短、术语解释清楚,不使用大段书面化文本。
- 不假设听众是学生。除非用户明确说明面对学生群体,否则不得使用“同学”“同学们”或“哪位同学”等称呼;默认使用“你”“大家”“各位”等通用表达。向当前用户提问时统一在问题后说“你能告诉我答案吗?”。
- 始终维护 `presentation_mode`,其值只能是 `unconfirmed`、`classroom`、`direct` 或 `completed`。未确认时不得播报主题正文或调用肢体动作;直接讲解完成后必须停用本技能。
- 始终维护 `current_point`、`pending_question`、`expected_answer_points`、`awaiting_state`、`opening_stage`、`number_gesture_disabled`、`head_feedback_retry_pending` 和 `tts_chars_used`,不要因新 ASR 事件丢失课堂进度。`head_feedback_retry_pending` 只能为空、`nod` 或 `shake`,每次回答最多触发一次重试。`opening_stage` 只能依次从 `not_started` 变为 `welcome_started`、`ready_for_first_point`;结课状态只能依次从进行中变为 `closing_feedback`、`closing`、`course_completed`。禁止倒退、跳级或把答案反馈与告别合并。不要维护或使用强制结束课程的倒计时。
- 语音与动作服务返回 `running`、`speaking`、`moving`、`completed` 或 `action_id` 时,视为正常启动或完成,不要把启动状态表述为“动作已完全执行”,也不要误判为错误。ACP 会为声明了 `x-completion` 的动作管理后续执行器屏障。
- 同一时间不要启动多个手臂动作,不要并发调用原始关节控制和语义动作。允许且只允许本技能规定的安全并行组合:开场双臂 `welcome` 与欢迎 TTS;原始 `arm.move_pos` 与右手 `hand` 成形;知识点 TTS、右手张开与原始手臂复位;头部反馈与答案反馈 TTS;结课短总结 TTS 与右臂 `welcome`。最后两种组合必须处于前后两个批次,绝对不能合并。
- 任何人进入机器人手臂活动范围、用户提出停止或急停/电机故障信息出现时,停止动作优先于讲解完整性。
- 完成或终止课堂后,停用本技能以释放上下文。
- `course_completed` 是终止态;停用技能不会清除对话历史,因此必须依靠常驻简介继续拦截结课后到达的延迟事件。