
OpenMAIC 专业课程编辑指南用 pro-editing 技能对外部 Agent 的既有课件做外科手术式精修【免费下载链接】OpenMAICOpen Multi-Agent Interactive Classroom — Get an immersive, multi-agent learning experience in just one click项目地址: https://gitcode.com/GitHub_Trending/op/OpenMAIC本指南讲解 OpenMAICOpen Multi-Agent Interactive Classroom中pro-editingAgent 技能skills/agent-runtime/pro-editing/SKILL.md的完整用法它面向已经存在并被持久化persisted的课程为 Agent 提供一套先盘点、再精读、后最小修改、最后一致性校验的专业编辑工作流。读完本文你将掌握list_scenes/read_stage/patch_stage/edit_deck/generate_tts/render_scene_preview这组工具的调用纪律理解 JSON Pointer 寻址规则与身份不变约束并能借助slide-dsl与slide-craft两个配套技能把改一个词、修一处重叠、重排一页这类请求做成不会留下编辑痕迹的高质量修改。技能定位编辑一门已存在的课程而不是重新生成它pro-editing的元规则写在技能描述里它只处理已持久化的课程——页面已经存在于存储中会话挂接在一个既有课程上或课堂已被构建。它的全部工作方式是surgical外科手术式读出现有内容、只改被要求的部分、其余一律不动。这决定了它与仓库中其他技能的分工pro-editing决定改哪一页、用什么操作、如何校验编辑流程skills/agent-runtime/slide-dsl/SKILL.md 是页面 JSON 的字段参考手册——告诉 Agent 每个字段叫什么、合法值是什么、渲染器实际读取哪个字段skills/agent-runtime/slide-craft/SKILL.md 是设计法则——画布几何、字号高度表、类型层级、对比度与间距标准即什么样才算改得好stage-design与curriculum-planner仍在构建阶段负责页面生成与课程大纲规划不参与编辑。一个值得注意的实现细节pro-editing目录下的 outline-constraints.json刻意不携带任何约束字段。原因写在文件的$comment中pro-editing 的编辑回路只读取和修补已持久化页面不运行大纲生成因此没有大纲结构需要约束检查器强制任何结构性下限反而会错误地约束用户并未要求的重建。该文件只是这一决策的书面记录。从源码看约束文件是可选的兄弟文件lib/server/agent-runtime/skills.ts 在加载技能时若发现同目录存在outline-constraints.json才会读取并注入大纲生成器的teacherContext槽位。第一步进入课程之前先盘点全局技能规定任何编辑动作之前必须先调用list_scenes对整个课程做一次盘点。这一步得到的不是假设而是编辑所依据的唯一地图列出每个已持久化页面的完整清单页码、顺序、类型不要规划替换性 stage——课程已有结构你不是在重新规划它如果请求很宽泛如让它更好看把它转化为针对页面清单的具体计划并在动手前说明将触及哪些页面。从实现上看list_scenes是基础课程工具之一见 lib/server/agent-runtime/generation-tools.ts它的提示语明确要求每页使用一次 generate_scene每次成功调用都是一个持久化检查点edit_deck则负责retitle/insert/delete/reorder这类整页级操作lib/server/agent-runtime/course-edit/tools.ts。盘点页数、顺序、标题正是这一层的职责。第二步每次修改前用 read_stage 精读目标页read_stage以path:/scenes/order|id定位页面紧邻每次编辑之前调用。返回的清单——元素 id、题目 id、动作 id、widget 配置——是你唯一可以编辑的地址空间同时也揭示页面的真实类型。过期的 id 会导致失败的编辑对页面内容的过期假设会导致错误的编辑。如果一次编辑落在了错误的页面类型上这是重新读取的信号而不是强行执行操作的信号。read_stage提供三档深度detail参数三者不可互换detail返回内容适用场景tree默认每个元素一行紧凑信息id、type、纯文本text、left、top、width、height、src定位元素。绝不能作为补丁来源——它剥离了样式source页面精确持久化 JSON——所有样式字段、带内联标记与换行的原始 content HTML、精确几何、z 序每次补丁的根。写入后再读一次验证text每个含文本元素以{ path, id, type, text }输出外加整页combinedText证明旧文案没有残留关键规则幻灯片写入必须用detail:source。tree只是紧凑地图足够找到元素却永远不够编辑它。source返回整页 JSON含type、schemaVersion与完整 canvas因此数组索引不会在读取与写入之间漂移——你在/content/canvas/elements/2/left读到的字段就通过同一路径写回。text档则是残留检查的有力工具每个path指向该元素自己的/content/canvas/elements/N检查结果直接交给你要修补的指针注意latex元素返回的是 LaTeX 源码、code是换行连接的代码行、table是|连接的单元格。从源码看read_stagelib/server/agent-runtime/dsl-tools.ts对source档会省略大块内联媒体字节omitReadSceneMediaBytes避免超大字符串阻塞事件循环source与text档在超过 12000 字符后分页通过nextOffset继续读取。第三步选择最小的操作——patch_stage 操作矩阵一次幻灯片编辑不外乎三种操作中的一种而第一种就是针对detail:source刚返回内容的单次 JSON Pointer 写入。技能的决策矩阵如下用户意图工具操作修复或改写幻灯片上的文字patch_stage对该元素内容路径执行set或str_replace——/content/canvas/elements/N/content、…/text/content、…/data/0/0/text、…/lines/1/content、…/latex移动 / 缩放 / 旋转元素、修复重叠patch_stage对/content/canvas/elements/N/left或top/width/height/rotate执行set每次操作一个数字重新着色或重设元素样式patch_stage对渲染器持有的样式路径执行set——…/defaultColor、…/fill、…/text/defaultColor、…/color删除可选字段patch_stage对该路径执行remove替换图片或媒体源patch_stage对/content/canvas/elements/N/src执行set重排幻灯片元素层级patch_stage对整个/content/canvas/elements数组执行set——整体重排id 与类型保持一致新增或删除幻灯片元素patch_stageadd_element完整 JSON无id/delete_element修复测验题、选项、答案、评分patch_stage对/content/questions/...执行set/remove增删需重写整个数组修改交互页patch_stage对/content/widgetConfig/...或/content/html执行set/remove/str_replace改写 / 插入 / 删除 / 重排旁白patch_stage指向/actions/...的 scene 根级指针插入/重排需重写完整数组编辑 PBL 简报、角色、里程碑、微任务patch_stage对/content/projectV2/...执行set/remove重命名 / 插入 / 删除 / 重排整页edit_deckretitle/insert/delete/reorder从零重写一页generate_sceneinstruction仅限用户明确要求整页重写时矩阵背后的硬性规则原文档的Rules of the matrix一个意图 → 一个操作。不要捆绑你无法逐一命名的变更。寻址叶子。隔离你的变更所需的最小路径才是正确的路径把整个对象写回去正是相邻样式字段消失的原因。patch_stage无法改变身份——不能改 canvas id、不能改元素 id 集合、不能改元素的type。这些必须走add_element/delete_element类型变更等于删除新增。内容本身不受检查——它按原样存储所以slide-dsl是挡在你写的标记与坏页面之间的唯一防线。被拒绝的补丁什么都没改。坏路径、越界索引、未知字段、错误类型或非法结果页都会带着原样页面响亮地失败。重新读取、重新提交绝不硬来。add_element接收一个完整的元素 JSON 但不含id——服务端校验与补丁相同的结构契约分配 id并按afterId或index二选一插入。没有任何东西会规范化你的值。颜色、字体、主题都不会被重写成家风格所以看起来不对的编辑是你的值的问题不是工具的问题。edit_deck insert创建空桩用generate_scene配合该新页的显式type与brief填充它或修补一个已合法的 scene。generate_scene带instruction会丢弃整页并重新生成。这是重写不是编辑留待用户明确要求重建页面时使用绝不可作为绕过精细编辑的捷径。如果会话已附加资料或网络访问权限用它们来夯实编辑内容——绝不是重建无人要求的页面的借口。源码级印证patch_stage 的原子批处理lib/server/agent-runtime/dsl-tools.ts 中patch_stage的实现揭示了文档背后的真实机制它原子性地修补/scenes/order|sceneId下的单个 sceneops是操作数组任意一个操作失败applyPatchOp返回ok: false都会拒绝整个批次并报告失败的操作序号幻灯片路径的set/remove/str_replace最终被归一化为{ op: patch, action, path, value }交给applySlideEdit其中path剥去/content前缀后才是/canvas/...部分——这与文档中从read_stage detail:source返回的精确 scene 根寻址一致slideOperation会拒绝以/actions/...之外的路径冒充幻灯片指针的调用并明确报错slide content pointer must start /content/canvas/一批补丁提交前还有最终态占位符守卫逐操作检查是隔离的模型可以用多个str_replace各携带一个片段拼凑出一个完整的只读媒体占位符从而绕过逐操作检查因此整个批次在序列化最终 scene 后会重新整体校验命中即整体拒绝、绝不落盘绝不进入putScene。寻址规则速查path是锚定在read_stage detail:source返回的精确 scene 上的 JSON Pointer幻灯片字段以/content/canvas/开头寻址叶子而非分支给出隔离变更所需的最小路径。把整个对象写回相邻样式字段会被悄悄丢弃。数组索引必须规范且有界0、1、2合法03、-1、1和越界索引一律被拒。最后一段之前的每一段都必须已存在最后一段可以不存在——set一个对象尚无的键会新增该可选字段如给文本元素加fillremove则删除它对不存在的路径remove会失败。路径不得穿越标量/content/canvas/elements/0/content/0会失败因为content是字符串而非容器。对数组索引remove会缩短数组除整数组重写外没有按索引插入。~1与~0转义键内的/与~裸~或~2被拒。值在进入时深拷贝你发送的嵌套对象会作为自己的树存储。工作中的示例每次调用一个变更pathvalue标题的富文本/content/canvas/elements/0/contentpspan stylecolor:#00a870新标题/span/p单个表格单元格/content/canvas/elements/5/data/0/0/text净利润一行代码/content/canvas/elements/9/lines/1/contenttotal price * count形状标签/content/canvas/elements/3/text/contentp第二阶段/p字形默认色/content/canvas/elements/2/defaultColor#1f4e79单个图表标签/content/canvas/elements/6/data/labels/2Q3元素位置/content/canvas/elements/2/left120页面背景/content/canvas/background/color#f7f7f5删除可选字段/content/canvas/elements/4/shadowop: remove层级重排/content/canvas/elements整个数组重排后返回z 序没有叶子可寻址因为绘制顺序就是数组位置索引 0 最先绘制底层最后绘制顶层渲染器直接以数组索引分配 CSSz-index。要重排层级就整体重写/content/canvas/elements——id 集合与每个 id→type 配对必须原样返回。这就是唯一的没有叶子可寻址的变更。最小编辑纪律Minimum-edit discipline只改被要求的部分。不重设未触碰元素的样式不改写没人抱怨的旁白不在修一页的同时顺手改进相邻页面。保持课程自身的声音匹配其既有术语、语调和视觉语言。一次编辑不应被看出来是编辑。只要目标比整页更窄优先用细粒度的逐字段patch_stage而不是generate_scene。任何涉及几何、颜色、文本长度或富文本结构的幻灯片编辑都要加载slide-craft——它承载了页面被绘制时所依据的设计法则文本高度表、类型层级、对比度配对、间距节奏以及哪个字段在哪个元素类型上真正到达屏幕。当你需要字段本身——它的名字、合法值、寻址它的路径、渲染器读取两个字段中的哪一个——那就是slide-dsl。slide-craft 的关键设计法则编辑时遵守skills/agent-runtime/slide-craft/SKILL.md 定义了页面设计约束编辑时这些数字是修复与凹陷的分界线画布 1000 × 562.5 px所有元素遵守50px 边距left ∈ [50, 950]、top ∈ [50, 512.5]右边缘left width ≤ 950、下边缘 ≤ 512.5文本按表定高不靠肉眼文本元素四周有 10px 内边距可用区为(width - 20) × (height - 20)高度来自字号表line-height 1.5、含内边距。例如 16px 字号1 行 46、2 行 70、3 行 94、4 行 118、5 行 14224px58 / 94 / 130 / 166 / 20232px70 / 118 / 166 / 214 / 262。替换文字后重新推导高度characters_per_line (width - 20) / font_size最长行保持在≤ 75%按内容中最大字号查表高度是容器不是夹子溢出文本会溢出盒子而非收缩页面会展示溢出。修复顺序是先缩短文字、再跳到下一档表行、最后加宽盒子对比度是一对不是一个颜色正文 ≥ 4.5:124px 及以上标题 ≥ 3:1。#333333配白约 12:1 安全强调色#5b9bd5配白约 3:1只够 32px 标题。稳妥模式是浅色调填充 同色相深色文字#1e40af配#dbeafe、#166534配#dcfce7、#92400e配#fef3c7各约 6–7:1形状上的文字是一个对象text.width shape.width - 40、text.left shape.left (shape.width - text.width) / 2、text.top shape.top (shape.height - text.height) / 2中心点应相差 ≤ 2px——移动形状永远是移动形状 重推导标签两步平行元素共享完全相同的数字一行三张卡片共用一个width、height、top和间距标题→副标题 30–40px、标题→正文 35–50px、段落块之间 20–30px、多栏间距 40–60px、被箭头跨越的间距需要 60–80px派生元素跟随锚点标题下划线、分隔线、高亮条都是依据被装饰文本计算的形状文本移动后必须重算内容类型与元素类型一一对应任何数学都是latex元素表格单元格是纯文本代码元素取纯文本行默认 14px高度要覆盖 32px 头部加每行line的width是描边粗细而非长度图片保持宽高比改width/height要一起改。Look → edit → look预览预算对于布局敏感的变更位置、密度、新元素、对齐在render_scene_preview可用时用它验证看渲染、编辑、再看一次。每页最多两轮预览——每次渲染都耗费一次工具调用而整个运行有硬性的调用上限。不要预览未触碰的页面不要超过预算两轮未收敛就停下来告诉用户剩余事项而不是把整次运行烧在一页上。从实现看render_scene_previewlib/server/agent-runtime/scene-preview.ts是一个按能力注册的独立工具import-pptx的提示语也建议导入后用它检查每个页面。旁白音频跟随文本generate_tts用patch_stage修改语音动作的/actions/N/text会清除该行改写后的音频而插入的行天然没有音频。因此任何语音措辞变更后都必须在进入下一页前对该页调用generate_tts——它的默认模式只合成缺失音频的行正好是所需行为。改写文本却不重新生成音频交付的是一页静音。源码印证lib/server/agent-runtime/course-edit/tools.tsgenerate_tts默认force: false只补齐没有音频的语音动作force: true才强制重合成所有语音音频。成功变更会落盘并打持久化检查点返回Narration audio: X generated, Y skipped, Z failed.的汇总。另外dsl-tools.ts中str_replace与非幻灯片指针的set/remove路径在写入后会调用clearStaleSpeechAudio——这是源码层面音频跟随文本的自动保障文本一改对应音频即被判定过期。收尾一致性检查Consistency pass在告诉用户完成之前必须过一遍list_scenes——确认页面清单与意图一致数量、顺序、标题每个编辑结果已经携带了该页的最新清单对照验证仅当结果留下疑问时才用read_stage重读扫一遍你触碰过的页面检查你的编辑可能引入的跨页漂移同一概念命名是否一致、单位与术语是否统一、你引入的样式是否应用于所有该用的地方被触碰页面上每个语音动作都必须有audioIdread_stage会显示任何缺音频的页面用generate_tts补齐。与人类编辑共享课程last-write-wins 协作纪律保存按页采用最后写入者胜出last-write-wins而同时在浏览器里编辑的人类作者可能覆盖你就像你覆盖他们一样。把课程当作共享土地先读新再写。紧邻编辑前的read_stage不是形式——它正是避免覆盖用户自你上次查看以来所做更改的方式小而增量地写。每次工具调用在落地的瞬间自动持久化其变更一小串小写入相比一次大重写冲突损失更小。绝不要积攒已准备但未写入的批次——边写边走用户正在编辑时让位。如果用户说他们正在改同一页或一次新读取显示了你没写过的内容停下来、重读、先协调再写。永远不要用你的陈旧快照覆盖人类更新的版本。这与patch_stage实现中每次操作前structuredClone当前 scene、逐操作应用、整体校验后落盘的原子语义相呼应拒绝的批次不产生任何部分写入。预算管理把调用花在编辑上而不是仪式上运行时没有硬性的工具调用上限但每一次额外调用都是用户等待的延迟。把调用花在编辑本身入口一次list_scenes、每页编辑前一次read_stage、编辑本身、措辞变化处generate_tts、仅在布局真正有风险时的一轮预览。如果请求很大先做最高价值的编辑并告诉用户剩余事项。为什么这样编辑是安全的结构校验的唯一边界pro-editing之所以能大胆做最小编辑是因为写入路径的守卫只有一个DSL 结构 schema。写入的内容按字节存储没有标记允许列表、没有清理器、没有颜色或字体规范化、没有几何钳制、没有家风格。patch_stage只检查一件事——结果文档仍符合 DSL 结构契约字段名、类型、必填字段、封闭对象——然后逐字节持久化你的值。因此文档强调skills/agent-runtime/slide-dsl/SKILL.md拒绝清单是穷尽的非/content/canvas/开头的幻灯片路径、畸形~转义、非规范或越界数组索引、缺失中间段或穿越非容器的路径、对不存在键的remove、缺value的set或带value的remove以及身份类拒绝改/content/canvas/id、增删改重复元素 id、改 id 的type、add_element带 id 或同时带afterId与index还有 schema 类拒绝未知字段、错误类型、封闭联合外的值、移除必填字段、错误元数元组、错误类型上的字段但不在清单上的更多没有标签检查、没有 CSS 检查、没有颜色格式检查、没有长度限制、没有几何边界、没有对比度规则、没有html与latex一致性检查、没有图表series与labels匹配检查——这些都靠你和slide-craft来保证服务端唯一自动重写当补丁改变元素的latex时服务端从新源码重渲染该元素的html快照KaTeXdisplay 模式错误渲染而不抛出并存储若渲染无结果则移除html。除此之外文档的任何部分都不会被触碰。这也是被拒绝的补丁什么都没改的完整含义错误是信息不是损坏——每条检查都在任何内容存储之前运行错误消息会点名违规路径。快速参考编辑流程全景阶段工具调用目的入口list_scenes盘点整门课页数、顺序、类型制定编辑计划每次编辑前read_stage path:/scenes/order|id detail:source拿精确持久化 JSON作为补丁路径的唯一地址空间编辑patch_stageset/remove/str_replace/add_element/delete_element或edit_deckretitle/insert/delete/reorder最小操作、寻址叶子、不碰身份布局验证render_scene_preview每页至多两轮只对有布局风险的页面音频generate_tts每次语音措辞变更后补齐缺失音频收尾list_scenes 逐页核对 跨页一致性扫描数量/顺序/标题正确、术语统一、无静音页配合技能三件套字段含义查 slide-dsl设计标准查 slide-craft编辑流程遵循本文的pro-editing。整条链路在 lib/server/agent-runtime/dsl-tools.ts 与 lib/server/agent-runtime/course-edit/tools.ts 中均有完整的原子实现支撑。【免费下载链接】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),仅供参考