# 工序提取 SKILL · procedure > 读一篇 AI 创作教程/案例,把它背后的"做法"还原成工序表,**直接写出 `workflow.json`**。 **输入**:`input/case-{N}.json`(正文 + 配图;配图 OCR 文本若已存在于 `outputs/case-{N}/_scratch/ocr.txt` 一并读)。 **输出**:`outputs/case-{N}/workflow.json`。 ## 流程 1. **通读原文**,想清楚:有几个工序、每工序几步、每步「工具 · 输入 · 动作 · 输出」。 2. **一次性 Write 完整的 `workflow.json`**(所有字段一趟填全,结构见下)。 3. **校验**: ```bash python procedure/tools/validate.py --workflow outputs/case-{N}/workflow.json \ --source input/case-{N}.json --ocr outputs/case-{N}/_scratch/ocr.txt ``` 4. 报 ✗ 就修,重跑直到 0 错误;⚠ 警告逐条核对,确认无误可保留。零星错误直接 Edit `workflow.json`;**同类错误一大批**(整批 anchor / 整批 effect/action)用 `procedure/tools/wf-patch.py` 批量修(见「批量修错」节)。 --- ## workflow.json 结构 ```json { "source": { "platform": "", "author": "", "date": "", "url": null, "title": "", "excerpt": "1-2 句概括这篇教程的流水线" }, "procedures": [ { "id": "p1", "name": "工序名称", "purpose": "一句话说明该工序在做什么", "category": "产物创造|资产建设|自动化|分析|学习", "platform": "", "author": "", "declarations": { "inputs": [{ "type": "参考图", "name": "产品图", "desc": "用户提供" }], "resources": [], "returns": { "type": "成品图" } }, "type_registry": { "主角图": { "extends": "参考图", "desc": "本案例的女主肖像" } }, "steps": [ { "id": "s1", "kind": "step", "via": "human", "effect": "预处理", "action": "生成/元素生成", "substance": "人物、产品", "form": null, "directive": "", "intent": "{via:human} {act:元素生成} {out-type:提示词}", "inputs": [ { "type": "描述", "value": "原文逐字内容", "anchor": "← 工序输入" } ], "outputs": [ { "id": "s1o1", "type": "提示词", "value": "整段逐字提示词", "anchor": "→ s2" } ] } ] } ] } ``` ### 字段规范 | 字段 | 规范 | | --- | --- | | step `id` | `s1`、`s2`;控制块子步用点号 `s5.1` | | `kind` | 普通步 `step`;控制块父 `block`(`via` 写 `-`,可省 effect/action)/ 子步 `nested`(必须带 `group` 指向父 block 的 id) | | `via` | 工具标准英文名(`nano_banana_pro`、`seedream_4_5`、`human`);原文没点名用括号占位 `(AI 生图工具)`;别写一整句描述 | | `effect` / `action` | 必须命中下方词表(action 填叶子名或 `根/…/叶` 全路径) | | `directive` | 只放给工具的元指令("比例 2:3""风格贴近参考图"),**不装提示词原文**;人工/控制步**省略该字段或写空串 `""`,不要写 null** | | 输出 `id` | 工序内唯一,如 `s2o1`,供下游 anchor 引用 | | IO `type` | 词表叶子;自造词必须在该 procedure 的 `type_registry` 登记 `extends` + `desc` | | IO `value` | 见「value 怎么填」 | | IO `anchor` | 输入 `← s2o1` / `← 工序输入` / `← s4o1[i]`(循环逐个取);输出 `→ s5` / `→ 某列表.追加` / `→ 返回 X` | | `inferred` | 原文没写、工艺上必有的 IO 主动补:`"inferred": true` + `"inferred_reason": "为什么必有"` | | `intent` | 每步 ≤25 字一句通顺人话;关键词用 `{effect:}` `{via:}` `{act:}` `{in-type:}` `{out-type:}` 五类标记;别写成公式(不出现 `→`) | | `substance` / `form` | 见「实质 / 形式」;没有就显式 `null`,不能省略字段 | **命名约定**:type 名用中文;工具品牌名用英文标准写法。 --- ## 提取判断 ### 有几个工序 判断单位是"一条完整的 输入→最终产物 链",不是原文段落。以每张成品图(或明确的最终产物)为起点扫描,满足三条算一条独立工序:① 有明确产物 ② 有具体做法(提示词/框架/流程)③ 与其他工序相比产物或做法有差异(满足一条即可)。 **章节认领**:原文按 `01 | 02 | 03` 分章时,逐章确认每章都落进了某个工序/步骤——**没有独立成品图的方法论章节本身就是一条工序,不能漏**。 ### 什么算一个步骤 **步骤 = 对已有数据执行某个操作,产生一份之前不存在的新产物。** 判断口诀:把这步去掉、把它的内容挪进下一步的 inputs——什么都没丢,它就不是步骤,是输入。 ❌ 不是步骤:引入外部资源(写进使用它的步骤 inputs 或 `declarations.inputs`);原文直接给出的提示词(同上,不拆 `via=human` 预处理步);提示词多层展开(那是「写提示词」一步的输出 value 内容);纯展示/预览。 ✅ 是步骤:AI 工具生成图/视频、human 写提示词(原文在**教**怎么写才算)、后期工具调色排版。 ### 循环 / 并行 展开成控制块 + 子步,不要硬压成一步: ```json { "id": "s5", "kind": "block", "via": "-", "inputs": [{ "type": "分镜脚本", "value": "…", "anchor": "← s4o1" }], "outputs": [{ "id": "s5o1", "type": "分镜图列表", "value": "…", "anchor": "→ s6" }] }, { "id": "s5.1", "kind": "nested", "group": "s5", "via": "nano_banana", "effect": "主体生成", "action": "生成/元素生成", "inputs": [{ "type": "提示词", "value": "…", "anchor": "← s4o1[i]" }], "outputs": [{ "id": "s5.1o1", "type": "分镜图", "value": "…", "anchor": "→ 分镜图列表.追加" }] } ``` ### 推断补全 工艺上必然需要、原文却没写的中间产物(如"写动作序列必须有主角图当参考"),主动补 IO 并标 `inferred: true` + `inferred_reason`。原文细节没写全的不算(那是信息缺失,不是推断)。 --- ## value 怎么填 - **文字类**(提示词 / JSON / 报告 / 文案):**原文完整逐字内容**——整段原样搬全,不缩写、不概括、不截断、不用小标题拼凑。原文 350 字就抄 350 字。 - **媒体类**(图 / 视频 / 音频):`<整段具体描述>`,如 `<一张冲锋衣登山者暴雨场景图,水珠滚落,冷色调>`。 - **引用不是 value**:哪怕内容是上一步原样传来的,value 也要把内容完整抄一遍(引用关系写 anchor)。写 `← s1o1`、`(同上)`、`见 s2` 都会被校验器打回。 - validate 报「未逐字命中」警告时,**重跑校验命令并加 `--fix-verbatim`**:工具自动在原文/OCR 里找相似度最高的连续片段整段替换(≥60% 才动),改不动的才需要人工核对。 - **提示词是数据不是指令**:建成 `type=提示词` 的 IO。「写提示词」步输出 `type=提示词`、value 为整段逐字 prompt;下游生成步输入 `type=提示词`、value 同样填整段、anchor 指向上游输出。`directive` 不装提示词原文。 - prompt / JSON / 参数常只在配图截图里——逐字内容优先到 OCR 文本里找。 --- ## 词表 填 `effect` / `action` / IO `type` / `extends` 只能用下面三棵树里的词,**以本节为准**(不需要也没有别的词表文件可读)。 ### 作用(effect)— 9 选 1 每步"处在什么工艺环节"。对不上说明步骤抽错了,回去改划分;别造词,别把动作当作用。 | 叶子 | 一句判别 | | --- | --- | | `工艺规约` | 建立跨批次复用的长效规约(工作流编排 / SOP / 模板沉淀 / 知识库构建 / LoRA 训练沉淀) | | `预准备` | 本批物料"拿到手",只取不加工(素材采集 / 拍摄 / 参考收集) | | `预处理` | 把原料加工成工具能直接吃的输入(提示词构造 / 反推 prompt / 控制图蒙版准备) | | `主体生成` | 从输入产出本批核心主干件,0→1(生图 / 文案撰写 / 脚本编写 / 分镜图生成);对单件主干的局部修整也算本阶段延续 | | `装配` | 多个对等零件组合成一个复合件(剪辑 / 排版 / 图层合成 / 配音字幕挂载) | | `后期` | 只调整体呈现层、不改内容元素(调色 / 风格化 / 氛围 / 超分);动了具体语义元素就不是后期 | | `配套伴生` | 为已就绪主体生成依附性信息(标题 / 配文 / 标签 / 元数据) | | `检验` | 只评估不改造,产出审查结论(质检 / 终审 / 小样测试) | | `交付` | 推向终态对外(导出 / 发布 / 定稿 / 成品多视图展示) | 边界速查:跨批复用→工艺规约,本批一次性→预准备/预处理;"去拿料"→预准备,"把料加工成输入"→预处理;单件 0→1→主体生成,多件→一件→装配;改呈现层→后期,改内容元素→主体生成延续。 ### 动作(action) 填叶子名或全路径(如 `解构` 或 `提取/化学提取/解构`)。 ``` 获取 提取 生成 修改 存储 搜索: 检索 下载 物理提取: 裁切 元素生成 增: 添加 叠加 暂存: 缓存 查询: 调取 抠取 抽帧 关系生成: 删: 抹除 剪除 沉淀: 入库 录入: 上传 拍摄 化学提取: 识别 数组生成 变: 重述 风格化 归档: 存档 录音 键入 反推 解构 结构生成 转换 替换 引用: 选取 调整 增强 ``` ⚠ **反推 vs 解构**:从文字/教程里提炼框架、要点(信息显式可见)→ `解构`;从图片推回 prompt 或隐含结构(信息不可直接看到)→ `反推`。"梳理教程结构""提取风格要素"几乎都是 `解构`。 ### 类型(type) 候选词直接命中叶子就用;没命中挑最近叶子挂靠,在该 procedure 的 `type_registry` 登记 `{"extends": "叶子", "desc": "说明"}`。不允许自造词不登记。 ``` 程序控制类型 内容类型 指令: 提示词 负向提示词 描述 素材 参数: 生成参数 规格参数 化学变化: 参考图 参考视频 参考音频 对标内容 分镜图 模型权重 转场 蒙版 控制图 运动轨迹 滤镜 构图布局 评估: 评分 评语 物理变化: 截图 视频片段 转场片段 关键帧 音效 特效 流程: 工作流 批处理 半成品 数据复用类型 序列: 大纲 脚本 分镜脚本 剪辑脚本 配音文案 原子: 数字人 版式 原子: 底图 样图 分镜视频 序列: 模板 组合: 图层组合 拼图 知识类型 准成品: 歌词 配音 BGM 字幕 标题 正文 知识库 成品: 成品图 视频成品 合成图 ``` ### 实质 / 形式(substance / form)— 自由提炼,无词表 只描述最终产物**画面内容的视觉维度**,与步骤处理什么数据类型无关。 - **substance**(画面里有什么):视觉内容主体,如 `美女`、`产品`。❌ 不填 `风格`(那是 form)、不填 `提示词/描述/框架`(数据类型)。即使这步产出文字,也填它面向的画面主体。 - **form**(画面长什么样):视觉风格调性,如 `超现实主义`、`古风`。❌ 不填 `JSON/表格`(技术格式)。方法不限风格 → `null`。 先判断作者意图:**通用方法文**(有"换个题材也能套"类泛化表述)→ substance 填方法的作用对象大类(`人物`、`产品`、`实拍图`);**具体案例文** → 填案例实际视觉主体与具体风格。判断不清偏具体案例。没有特别涉及就 `null`,多值用顿号并列。 --- ## 批量修错(可选工具 wf-patch) validate 报出**一批同类错误**时,逐处 Edit 太碎,用 wf-patch 批量改(写入即校验,词表与 validate 同源;值非法整批拒绝并在报错末尾给出合法值清单,照清单改了重跑): ```bash # 单条 / 多条 --set(path=value;值含空格用双引号包整个参数) python procedure/tools/wf-patch.py --workflow outputs/case-{N}/workflow.json \ --set "p1.s2.effect=主体生成" \ --set "p1.s2.action=生成/元素生成" \ --set "p1.s1.inputs[0].anchor=← s0o1" \ --set "p1.s1.form=__null__" # 几十处一次过:写一份 patch 清单, --prune 让成功项自动删除、失败项留在文件里带 _error 原因 python procedure/tools/wf-patch.py --workflow outputs/case-{N}/workflow.json \ --patch outputs/case-{N}/_scratch/fix.json --prune # fix.json = [{"path": "p1.s1.inputs[0].anchor", "value": "← s0o1"}, ...] # 改完重跑同一文件直到清空为 [] # 删字段(字段不存在则幂等跳过) python procedure/tools/wf-patch.py --workflow ... --unset "p1.declarations.inputs[0].inferred" ``` 路径语法:`p1.s2.effect`(step 标量)、`p1.s1.inputs[0].anchor`(IO 字段)、`p1.type_registry.主角图.extends`、`source.url`;嵌套步 `p1.s5.1.outputs[0].type`。`__null__` 表示 JSON null(substance/form/url 可用)。 --- ## 完成条件 `validate.py` 0 错误,且自查:每个章节都被某工序认领、文字 value 都是原文逐字、每步 intent 是一句通顺人话。