OpenMAIC 任务引擎(Task Engine)职业实训课程设计指南:从 procedural-skill 工作流到 GO/STOP 安全判定
【免费下载链接】OpenMAICOpen Multi-Agent Interactive Classroom — Get an immersive, multi-agent learning experience in just one click项目地址: https://gitcode.com/GitHub_Trending/op/OpenMAIC
导读
本文基于 OpenMAIC 仓库内置的vocational技能(职业实训)文档,完整讲解「任务引擎(Task Engine)」模式的课程设计方法:它如何把一条真实职业任务拆解为任务简报、操作工位(procedural-skill)、GO/STOP 决策关卡与完成核验,而不是一堂概念课。读完本文,你将掌握SKILL.md的场景结构与命名规范、outline-constraints.json机器可校验的硬约束、widgetOutline的真实字段契约,以及生成侧(大纲、场景内容、教师动作序列、路由归一化)的完整调用链与约束门控,可以直接据此为 OpenMAIC 设计或评审职业实训课程。
一、技能是什么:vocational的任务引擎定位
OpenMAIC(Open Multi-Agent Interactive Classroom)的 Agent 运行时通过skills/目录向教学 Agent 注入可复用的课程设计能力。每个技能是一个目录,包含SKILL.md与可选的outline-constraints.json结构性约束文件,加载与调用机制实现在 lib/server/agent-runtime/skills.ts:
- Agent 发现:pi 的
loadSkills()解析 frontmatter,formatSkillsForSystemPrompt()把 name/description/location 写入系统提示词; - 大纲注入:技能正文与渲染后的约束一起被注入大纲生成器的
teacherContext槽位(skillOutlineContext()),由独立的大纲 LLM 调用在技能约束下规划; - 生成后校验:
checkOutlineAgainstSkill()用约束文件对返回的大纲做机器检查,违规项作为工具结果诊断返回给 Agent,由 Agent 决定是否重新规划。
vocational技能的定义位于 skills/agent-runtime/vocational/SKILL.md,其 frontmatter 明确了触发条件:
Vocational / technical training courses. Plans the course as a hands-on work task with an operation flow, tool and equipment state, safety boundaries and GO/STOP judgements, instead of a concept lecture. Use when the requirement names a real occupational task, a piece of equipment, a clinical or industrial procedure, or a certification skill.
它面向的是:真实职业任务、设备操作、临床或工业流程、考证技能。学习者的可见名称是「任务引擎」(Task Engine),内部 widget 名称(如procedural-skill)不得暴露给学习者,但大纲 JSON 必须携带渲染器需要的真实 widget 契约。
二、场景结构:一次职业任务,而不是一堂课
SKILL.md明确了任务引擎场景的四段式骨架:
| 位置 | 场景类型 | 职责 |
|---|---|---|
| 开头 | 恰好 1 个slide | 任务简报:工作任务、任务边界、培训目标、关键步骤、安全边界/风险提示、完成标准(GO/STOP 标准)。不是行业历史或概念定义页 |
| 主体 | 操作工位序列 | 同一任务的按序操作阶段:准备与设备检查 → 逐步操作 → 验证、测量或记录 → 交接/完成核验 |
| 主体 | ≥ 3 个interactive且widgetType: "procedural-skill" | 动手阶段:学习者对照工具与状态逐步操作,不安全或乱序操作会得到后果反馈 |
| 主体 | ≥ 1 个quiz定位为 GO/STOP 决策检查点 | 面对异常读数或不安全条件:继续、复查还是停机。不是词汇测验 |
| 结尾 | 完成核验 | 以完成标准收尾,而不是概念总结 |
2.1 场景命名:读起来像操作步骤
场景标题应按工作步骤而非主题命名:
- 好:「断电确认与验电」「绝缘电阻测量与判读」「异常读数:继续还是停线」
- 差:「什么是低压配电柜」「配电柜的发展历史」「本课总结」
2.2 禁止项(Prohibited)
- 纯理论场景、概念讲座、公式推导;
- 泛泛的「课程总结」/「回顾」收尾页;
- 把所有动手场景做成同一个勾选清单(checklist)。要变化呈现方式:检查单、测量仪表盘、步骤排序、故障排查等。
2.3 非职业实训场景的降级
如果需求没有操作流、没有工具或设备状态、没有安全或通过/失败判定(例如数学推导、诗歌赏析),Agent 需要在对话中一句话说明,并规划普通课程;不要强行给无流程的主题套用procedural-skill。对应实现中,生成服务通过sanitizeNonTaskEngineOutline()把非任务引擎模式下的procedural-skill大纲强制降级为diagram(见下文第五节)。
三、机器可校验的硬约束:outline-constraints.json
与SKILL.md同目录的 skills/agent-runtime/vocational/outline-constraints.json 是技能的可机检部分。它被同时用于两处:渲染进大纲提示词 + 对模型输出做检查,违规会作为工具结果诊断返回,让 Agent 重新规划。完整内容:
{ "$comment": "Structural constraints for the vocational skill. Rendered into the outline prompt AND checked against the model's output; violations come back to the agent as a tool-result diagnostic so it can re-plan. See lib/server/agent-runtime/skills.ts.", "allowedTypes": ["slide", "quiz", "interactive"], "firstSceneType": "slide", "typeMix": [ { "type": "interactive", "min": 3 }, { "type": "quiz", "min": 1 }, { "type": "slide", "max": 3 } ], "requiredWidgetTypes": ["procedural-skill"], "requiredWidgetOutlineFields": ["task", "steps", "successCriteria"] }逐项解读:
allowedTypes:整门课只允许slide、quiz、interactive三种场景类型;firstSceneType: "slide":第 1 场必须是任务简报幻灯片;typeMix:interactive至少 3 场、quiz至少 1 场、slide至多 3 场;requiredWidgetTypes:interactive 场景中必须至少出现一次procedural-skill;requiredWidgetOutlineFields:每个 interactive 场景的widgetOutline必须填充task、steps、successCriteria三个字段。
对应校验器在 lib/server/agent-runtime/skills.ts 的checkOutlineAgainstSkill():逐条核对场景数、类型白名单、首场景类型、类型配比、必需 widget 类型、widgetOutline必填字段以及「相邻 interactive 场景不得复用同一 widgetType」。值得注意的设计取舍是只报诊断、不自动改写:一份规划是一个连贯整体,机械翻转场景类型去满足配比会产生"由 linter 拼装"的课程,因此违规列表交给 Agent 判断修复。renderConstraints()负责把约束渲染成提示词中的人类可读文本(例如 "At least 3 scenes of type `interactive`."、"Every interactive scene's `widgetOutline` must populate: task, steps, successCriteria.")。
持久化场景也有一条对应检查路径checkScenesAgainstSkill(),仅做诊断、永不回滚持久化;其中requiredWidgetOutlineFields属于计划期字段,因持久化场景不保留 widget-outline 草稿而被显式剔除。
四、procedural-skill 场景的 widgetOutline 契约
SKILL.md要求每个procedural-skill场景用真实契约填充widgetOutline:
| 字段 | 说明 | 取值/要求 |
|---|---|---|
procedureType | 流程类型 | 枚举:repair、assembly、inspection、operation、custom |
task | 当前工位执行的具体任务 | 具体操作描述 |
tools | 该工位需要的工具、仪表、PPE 或材料 | 列表 |
steps | 该工位的有序操作 | 至少包含一个判断/决策步骤 |
successCriteria | 学习者如何判定本工位通过 | 阈值、读数、状态,而不是"理解了概念" |
errorConsequences | 跳步或不安全操作的后果 | 风险检出、不安全状态、检查受阻、需复查、偏差检出、告警/报警、条件未解除不得继续 |
类型层面的契约可进一步对照 DSL 参考文档 skills/agent-runtime/stage-dsl/references/widget.md 中procedural-skill一节:根字段为type: "procedural-skill"、task、description、可选tools: string[]、steps: ProceduralSkillStep[]、可选successCriteria: string[];每个 step 必须含id、title、description,可选tools与successCriteria。类型声明不强制 step 工具名出现在根tools、id 唯一或 successCriteria 可机检——这些是语义责任,需要作者自行保证。
4.1 一个可落地的 widgetOutline 示例
{ "id": "scene_8", "type": "interactive", "title": "绝缘电阻测量与判读", "description": "学习者完成验电后对线路进行绝缘电阻测量并对照安全阈值判读结果。", "keyPoints": ["测量步骤", "阈值判读", "安全完成条件"], "order": 8, "widgetType": "procedural-skill", "widgetOutline": { "procedureType": "inspection", "task": "对已完成断电确认的低压配电柜出线回路测量绝缘电阻并判读", "tools": ["绝缘电阻表(兆欧表)", "绝缘手套", "验电器", "工作票"], "steps": [ "确认回路已断电并验电", "选择正确的量程并校表", "按顺序连接测试线并测量", "记录读数并对照安全阈值判读" ], "successCriteria": ["绝缘电阻读数不低于安全阈值", "测量记录完整", "无跳步或未验电情况"], "errorConsequences": ["未验电直接测量导致触电风险", "读数低于阈值仍送电将造成设备损坏", "乱序操作触发告警并要求复查"] } }五、从技能到大纲:生成链路与门控
vocational技能不是孤立的一份提示词,而是嵌入在完整的任务引擎生成链路中。相关实现集中在 app/api/generate/scene-outlines-stream/route.ts 与 lib/prompts/templates/task-engine-outlines/(system.md/user.md大纲提示词模板)。
5.1 适配性闸门(Suitability Gate)
任务引擎大纲提示词第一步是判断需求是否为职业流程任务。适合的特征包括:真实或模拟的工作任务、含步骤/检查/测量/记录/交接的操作流、存在工具/设备/材料/环境/患者/车辆/机器/人员状态、存在安全边界/质量标准/阈值/风险状态/完成标准、存在有意义的 GO/STOP、安全/不安全、通过/失败、复查、受阻、继续等决策、以及不安全或错误操作的真实后果。
适合的示例:NEV 电池包更换前的安全确认、低压配电柜送电前安全确认与绝缘检查、静脉输液患者身份核验与滴速设置训练、气体保护焊工前设备检查与试焊参数确认。不适合的示例:勾股定理讲解、牛顿第二定律介绍、诗歌赏析、机器学习基础概念。
5.2 任务引擎混合结构(10–14 场)
对适合的任务,大纲提示词要求生成 10–14 场的完整实训序列(默认 10–12 场),并且:
- 第 1 场必须是
slide简报页,覆盖任务目的、边界、培训目标、关键步骤、安全边界、完成标准/GO-STOP 标准;使用稳定的 PPT 布局:顶部标题+一句话目标、中部恰好 3 张信息卡(任务目的 / 关键风险 / 任务边界)、中下部 4–6 个宏观训练阶段、底部 1 条紧凑 GO/STOP 标准,安全红线须独立成卡; - 5–7 场
procedural-skill操作/确认工位; - 2–4 场说明场景(
slide,至多 1 场diagram); - 2–4 场挑战场景(
interactive+game); - 任务引擎混合结构中不得输出 code、simulation、visualization3d、pbl 或普通 quiz 场景。
场景分解要求把整个任务拆成可训练的操作段:风险识别/工单确认、PPE/工具/仪表检查、隔离/停机/设置/校准/检查/验证、测量/阈值/读数判读、异常处理或返工、GO/STOP 安全决策、完成核验或交接确认。提示词中还给出了一个 NEV-A12 的 12 场示例结构,可作为设计蓝本。
5.3 路由归一化与门控
scene-outlines-stream路由对任务引擎模式输出做归一化(normalizeTaskEngineOutline):
slide场景剥除widgetType/widgetOutline/interactiveConfig;procedural-skill场景用兜底值补齐widgetOutline:procedureType缺省inspection、task缺省用户需求、tools缺省['required PPE', 'task checklist']、steps缺省三段式、successCriteria与errorConsequences亦有缺省;- 普通 widget 类型原样保留。
同时,sanitizeNonTaskEngineOutline()对非任务引擎模式返回的procedural-skill做净化降级:删除procedureType/task/tools/steps/successCriteria/errorConsequences,并把widgetType改为diagram——源码注释明确写道 "procedural-skill is gated behind taskEngineMode to protect ordinary MAIC generation",即procedural-skill被门控在任务引擎模式之后,以保护普通 MAIC 生成。lib/server/agent-runtime/generation-tools.ts中的交互页面工具同样注明procedural-skill仅限任务引擎模式使用。
六、场景内容生成:procedural-skill widget 的完整 HTML 契约
大纲定稿后,每个procedural-skill工位会生成一个自包含 HTML 文档(通过 iframesrcDoc渲染),生成契约完整定义在 packages/@openmaic/generation/templates/procedural-skill-content/system.md 与 user.md。
6.1 核心原则:流程实操,不是勾选清单
- 程序性练习,不是静态说明;
- 任务完成,不是步骤计分;
- 有状态的练习,不是被动讲解;
- 轻量操作代理,不是完整物理/机械模拟。
学习者必须做出至少一次决策、判断、测量或工具选择——"点完成"不能是唯一有意义的交互。
6.2 内嵌配置 Schema
生成的 HTML 必须内嵌<script type="application/json" id="widget-config">配置:
{ "type": "procedural-skill", "task": "...", "description": "...", "tools": ["..."], "steps": [ { "id": "step-1", "title": "...", "description": "...", "tools": ["..."], "successCriteria": ["..."] } ], "successCriteria": ["..."], "errorConsequences": ["..."] }要求:type必须精确为"procedural-skill";step id 使用稳定的 DOM 友好 id(step-1、step-2…);输入只有纯步骤字符串时须转换为最小 step 对象;保留输入的 error consequences 用于不安全/错误反馈路径;配置保持通用,不得硬编码演示场景。
6.3 交互要求(可机检的硬性标准)
- 可见步骤控件:
#step-1-control等必须是真实可点击控件(<button>/<input>/<select>或带显式点击与键盘处理器),包含可见文本("Complete step""Check""Measure""Choose""Go""Stop"),禁止空容器<div id="step-1-control"></div>;点击必须至少更新一个可见状态(#progress-display、步骤行 class、#feedback-panel、#state-panel或成功标准门控); - 反馈面板:
#feedback-panel为必选项,#state-panel不能替代它;状态面板须随交互变化,reset 时恢复初始状态,不得是静态装饰文本; - 判断/决策步骤:至少一个步骤是判断型交互,模式包括选择正确工具、判断读数是否在安全阈值内、输入/确认测量值、决定失败检查是否需返工或复查、判断设备/任务安全与否、按当前状态选择下一步操作;
- 后果反馈:至少一条错误/不安全路径要显示真实后果或状态变化(风险检出、不安全状态、检查受阻、需复查、偏差检出、告警/报警、条件未解除不得继续),不得只用 "Correct"/"Wrong"/"Try again",也不得用分数替代后果;
- 操作代理:至少一个轻量操作代理(带安全阈值范围的测量读数、仪表/表盘/指示灯/状态信号、工具使用状态、检查结果、安全状态信号),简单、确定性、本地化,不加载外部资源、不做复杂机械模拟;
- 成功标准门控:成功标准必须基于真实状态更新,初次加载不得显示已完成;1/N 步完成不得把整体成功标准标记为完成;reset 须把成功标准恢复为 pending;
- 重置:可见、可点、可用的
#reset-btn必须调用中央resetState()或等效全量重置路径,恢复completedSteps、进度、反馈、状态/风险/决策/代理值、步骤行 class、成功标准与初始控件启停状态——不是仅改一个文本节点。
6.4 运行时状态同步与 postMessage 契约
生成的 JavaScript 必须让"学习者点击"与"平台 widget 动作"共享同一状态模型:单一中央状态对象 + 单一renderState()/updateUI()渲染路径。点击处理与SET_WIDGET_STATE不得维护两套互不兼容的更新逻辑。
平台经 iframe 消息下发动作时,event.data.type为消息类型字段,生成代码只允许支持四种既有类型:
| 消息类型 | 读取字段 | 行为 |
|---|---|---|
SET_WIDGET_STATE | data.state(支持data.state.completedSteps) | 同步内部状态并按共享渲染路径重绘步骤行、进度、反馈、状态面板与成功标准 |
HIGHLIGHT_ELEMENT | data.target | 对目标元素施加临时可见轮廓 |
ANNOTATE_ELEMENT | data.target(data.content可选) | 在目标附近显示临时注释;无 content 时不抛错 |
REVEAL_ELEMENT | data.target | 使隐藏目标可见 |
稳定教师动作目标(stable selectors):#task-panel、#tool-list、#step-list、[data-step-id="step-1"]、#step-1-control、#step-1-feedback、#success-criteria、#progress-display、#feedback-panel、#reset-btn。规则明确:禁止window.parent.postMessage、禁止发明新消息类型、禁止引入 iframe→平台回调。DOM 操作必须空值安全(const el = document.querySelector(...); if (!el) return;),缺失的可选元素不得导致Cannot set properties of null。
6.5 视觉风格多样化
procedural-skill是训练机制,不是固定视觉风格。模板明确要求不要把每个 widget 都做成深色仪表盘或勾选面板,可选的呈现方向包括:浅色步骤卡板、工单台、安全检查站、测量站、流程看板、模拟器式控制台、GO/STOP 决策站、交接检查板、故障排查站。无论视觉风格如何,都必须保留任务操作、状态、决策、反馈、进度、重置、完成核验、稳定选择器与 postMessage 兼容,不得把视觉变化变成只读 PPT。
6.6 教师动作序列
交互场景还需生成教师动作序列(模板见 packages/@openmaic/generation/templates/interactive-actions/system.md)。输出为 JSON 数组,type:"text"为教师旁白,type:"action"使用四种合法动作名:widget_highlight、widget_setState、widget_annotation、widget_reveal。对 procedural-skill widget 推荐优先使用[data-step-id="step-1"]、#step-1-control、#progress-display、#reset-btn等稳定目标,widget_setState的状态字段建议completedSteps、currentStep、feedback。设计原则要求单一教师声音、同会话连续性(首页问候、中间页自然过渡、末页收尾),3–8 条为自然教学节奏。
七、测试保障:契约的可验证性
仓库通过多层测试固化上述契约,可作为实现的直接证据:
- tests/prompts/task-engine-outlines.test.ts 与 tests/generation/task-engine-outline-route.test.ts:验证任务引擎大纲的结构(首场 slide 简报、10–14 场、procedural-skill 配比、widgetOutline 字段完整性);
- tests/generation/scene-content-route-vocational-gate.test.ts:验证
procedural-skill在非任务引擎模式被门控/降级; - tests/prompts/procedural-skill-content-quality-contract.test.ts 与 tests/generation/procedural-skill-content-gates.test.ts:验证 widget 内容的质量契约(决策交互、后果反馈、操作代理、成功标准门控、稳定选择器、reset 全量恢复、
SET_WIDGET_STATE同步渲染等); - tests/agent-runtime/generation-tools.test.ts:覆盖技能发现、约束渲染与大纲校验回路。
这些测试与 lib/server/agent-runtime/skills.ts、app/api/generate/scene-outlines-stream/route.ts、packages/@openmaic/generation/templates/procedural-skill-content/system.md 共同构成「技能文档 → 可机检约束 → 生成提示词 → 内容契约 → 校验门控」的完整证据链。
八、实战检查清单
为一个职业实训需求设计任务引擎课程时,建议按如下顺序自检:
- 适配性:需求是否有操作流、工具/设备状态、安全与通过/失败判定?没有则走普通课程,不使用
procedural-skill; - 结构:首场是否为
slide任务简报(任务目的/关键风险/任务边界 3 卡 + 4–6 个宏观阶段 + 1 条 GO/STOP 标准)?总场次是否在 10–14 之间?interactive ≥ 3、quiz ≥ 1、slide ≤ 3? - 工位:每个 procedural-skill 场景的
widgetOutline是否填全procedureType/task/tools/steps/successCriteria/errorConsequences?steps 是否含至少一个判断步骤? - 命名:场景标题是否读起来像工作步骤而非主题?
- 差异化:是否避免了所有动手场景都是同一勾选清单/深色仪表盘?quiz 是否是 GO/STOP 决策而非词汇测验?
- 收尾:是否以完成核验/交接确认收尾,而非概念总结?
遵循以上检查项,即可用 OpenMAIC 的「任务引擎」模式把任意真实职业任务转化为可交互、可判定、有安全边界的实训课程。
【免费下载链接】OpenMAICOpen Multi-Agent Interactive Classroom — Get an immersive, multi-agent learning experience in just one click项目地址: https://gitcode.com/GitHub_Trending/op/OpenMAIC
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考