# 工序提取 SKILL · 总览 > 这道 skill 做一件事:**读一篇 AI 创作教程/案例,把它背后的"做法"还原成一张工序表,存成 `workflow.json`,再渲染成一个网页**。 > > 本文是总览。具体操作和字段规则在 [extraction/](extraction/) 子目录的三个阶段文件里,按阶段读即可。 --- **本目录是一个自包含的 skill**:跑提取流程时需要的所有说明都在这里。外部的案例原文(`input/case-N-raw.json`)和你产出的成果(`outputs/case-N/`)不算 skill 的一部分。 ## 输入 / 输出 **输入**:任意一篇创作案例——公众号 / 小红书 / 推文 / 博客(正文 + 配图)、视频教程(带转写)、或你自己的工作复盘。 **输出**:一个网页 `outputs/case-{N}/case-{N}-.html`。 --- ## 概念速览 读懂这几条,就能看懂工序表在表达什么。 **工序表把"一步操作"拆成几个层面**(对应 `workflow.json` 里的字段): | 层面 | 通俗讲 | 在 workflow.json 里 | |---|---|---| | 数据类型 | 这份数据算什么角色(参考图/提示词…) | 输入输出的 `type` | | 用的工具 | 哪个具体产品(manus/nano_banana…) | 步骤的 `via` | | 做的动作 | 干了什么(生成/反推…) | 步骤的 `action` | | 工序位置 | 处在流水线哪个环节(预处理/主体生成…) | 步骤的 `effect` | | 内容实质 | 这步本质上涉及什么(人物/场景/观念…) | 步骤的 `substance` | | 呈现形式 | 内容怎么组织(光影/构图/叙事…) | 步骤的 `form` | | 工序模板 | 一整套可复用的做法 | 一个 `procedure` | | 实际内容 | 这次具体填进去的真实值 | 输入输出的 `value` | | 目的 | 一句话概括这步在干嘛 | 步骤的 `intent` | **一篇案例可以有多个工序**:比如一篇文章同时讲"简单做法"和"进阶做法",那就是两个工序,放在顶层 `procedures: []` 数组里(只有一个时也用长度 1 的数组)。 **自造的类型要"挂靠"**:类型词表里没有的词,要在这个工序的 `type_registry` 里写明它"算作"哪个标准词,例如 `主角图` 挂靠 `参考图`。这样既能自由起名,又不弄乱标准词表。 **命名约定**:类型名、动作名用中文;工具品牌名用英文(`nano_banana_pro`);每个输出都要有不重复的编号(如 `s2o1`)供后面引用。其中"作用 / 实质 / 形式 / 动作 / 目的"是**整步一个**,"类型 / 值 / 来源 / 编号"是**每个输入输出各一个**。 > 三个分类词表(作用/动作/类型 要对到它们):作用 = [effect.json](taxonomy/effect.json)、动作 = [action.json](taxonomy/action.json)、类型 = [type.json](taxonomy/type.json)。**实质/形式 没有词表**——读懂步骤后直接提炼,不查词表。 --- ## 目录里有什么 ### 操作流程(extraction/ —— 分三阶段,按阶段读) | 文件 | 内容 | 什么时候读 | |---|---|---| | [extraction/phase1-skeleton.md](extraction/phase1-skeleton.md) | 第一阶段:搭骨架(判断有几个工序 / 切步骤 / 连数据流);含第一阶段字段说明 | 第一阶段 | | [extraction/phase2-normalize.md](extraction/phase2-normalize.md) | 第二阶段:归类标注 + 填目的列;含第二阶段字段说明 | 第二阶段 | | [extraction/phase3-finalize.md](extraction/phase3-finalize.md) | 第三阶段:检查 + 渲染出网页 | 第三阶段 | ### 格式契约(format/) | 文件 | 内容 | |---|---| | [case-data.schema.json](format/case-data.schema.json) | **给机器看的字段清单**(必填项/可选值的最终裁判) | ### 分类词表(taxonomy/ —— 作用/动作/类型 三个受控词表) | 文件 | 维度 | 规模 | 怎么用 | |---|---|---|---| | [effect.json](taxonomy/effect.json) | 作用 | 9 个词 | 第二阶段读,把每步的作用对上 | | [action.json](taxonomy/action.json) | 动作 | 30+ 个词 | 同上 | | [type.json](taxonomy/type.json) | 类型 | 50 个词 | 同上;自造类型写进 `workflow.json` 的 `type_registry` | | [type_suggestions.md](taxonomy/type_suggestions.md) | 新类型登记 | 只增不改 | 第三阶段跑 `lint-case.py` 时**工具自动登记**,不用手写 | > **实质/形式 没有词表**:第二阶段直接提炼,不查词表。 ### 工具(tools/) [tools.md](tools.md) 是各脚本(建骨架/批量改 `wf-patch` · 原文捞引 `quote-source` · 渲染 `render-case` · 检查 `lint-case`)的**接口手册**。脚本本身**不用读源码**,会用就行;渲染网页的样式(`renderer.py`/`styles.css`/`script.js`)也不用碰。 --- ## 🛠 运行时约定(开工前必看) ### 通用(所有执行引擎) - **workflow.json 全程用 `wf-patch.py`,绝不手写 / edit 改它**(手写嵌套 JSON 易漏逗号崩、edit 在 p1/p2 重复结构上会撞「多个匹配」): - **建骨架**:写一份扁平 patch(`[{"path":...,"value":...}]`),**proc/step 头 + 每个 step 的 `inputs[i]`/`outputs[i]` 的 type、value、anchor 都写进同一份**,跑 `wf-patch.py --patch <清单>`——缺的 procedure/step/IO **默认自动建**(upsert)、output 的 id 自动补、文件不存在也从空建。路径**统一用 id 式 `p1.s1.inputs[0].type`**(下标式 `procedures[0].steps[0].inputs[0].type` 工具也接受)。**`--set` 别用单引号包参数**(cmd.exe 不剥 → 路径会带 `'`;值含空格用双引号,或写进 `--patch` 文件)。 - **填 / 改字段**:`wf-patch.py --set 'path=值'` 或 `--patch <清单>`。缺路径默认自动建,所以填 IO 不会撞「越界」;**想严格抓路径 typo,加 `--no-create`**(纯填已存在结构时用)。 - **填真实 value/directive:你只挑锚点,工具取原文**——把值写成 `@quote|<起锚>|<止锚>`(或 `@quote|<关键词>`),patch 时带 `--resolve-quotes --source <原文json> --ocr /_scratch/ocr.txt`,工具自动把标记换成原文 / 配图 OCR 里的真实内容。别自己读原文、粘长内容。 - **文本类 value(提示词/数据/报告/JSON)必须是【完整逐字】真内容**——整段 prompt / 整段 JSON 原样搬全,**别概括/截断/只填一句**(长内容用 `@quote|<起锚>|<止锚>` 框整段, 工具逐字回填)。⚠️ 第三阶段 `render-case.py` 见到文本类 `<占位>` value 会**拒绝出 HTML**。原文确实没有 → value 写成 `<占位>(原文未提供)`(或标 `inferred:true`)即可放行;媒体类(图/视频/音频)用 `<具体描述>` 不受此限。 - **分阶段读**:每进一阶段**先读对应 phase 文件**(phase1/2/3),别只读本总览 + tools.md 就开干(操作细则都在阶段文件里)。 - **第一阶段别碰归类**:type 随便起个描述标签即可(不查词表、不注册 type_registry);作用/动作/类型归类 + 自造类型挂靠 type_registry 是**第二阶段**的活(那时才读三张词表)。 ### 仅 Cyber Agent 引擎(执行引擎是 Claude Code 则跳过本节) - **工具名**:`Read→read_file` · `Write→write_file` · `Edit→edit_file` · `Bash→bash_command` · `Glob→glob_files` · `Grep→grep_content` · 看本地图 `read_images`。 - **`bash_command` 是 cmd.exe**:一条命令一次调用;别用 `;` 串(要串用 `&&`);别加 `| cat` / `; type ...` / `$?` 这类尾巴(返回已含 stdout+stderr+exit code);路径用正斜杠、含空格的值用双引号。 - **`goal` 规划工具**:`focus` 只认计划里的**纯数字序号**(`goal(focus="4")`,不是标题);`goal(done="总结")` 完成当前焦点(须先 focus 成功)。报错只改成纯数字重试一次,别反复换写法(会死循环烧回合)。 - **路径**:cwd 是 `procedure-dsl/`(不是 spec/),spec 文档里的相对链接(`extraction/x.md`)读取时补 `spec/` 前缀。read_file 有 2000 字/行、50KB/次 上限会**静默截断**长内容,长文本用 `quote-source.py`(读全文件)别 read_file 通读。 --- ## 操作流程 整个流程围绕**一个文件 `workflow.json`** 滚动演化——从第一阶段搭好骨架,后面每阶段都在它上面**就地补字段**,不另存新文件。 ``` 第一阶段 · 搭骨架(结构) 1.0 读懂案例 → 规划工序和步骤 → 建干骨架 (只有结构 + type 标签;value / anchor / directive 全空) (Cyber 引擎: 调 plan_procedures 工具,自动生成骨架; 其他引擎: 写 understanding.md 再建) 第二阶段 · 填内容 + 归类标注 2.0 填值/指令(value / directive,用 @quote 拽原文) → 连数据流(anchor) → 跑 verify-io 校验 2.1 作用/动作/类型 归到分类词表 2.2 实质/形式 直接提炼元素点(没有涉及的设 null) 2.3 自造类型登记 → 写进 type_registry 2.4 每步填目的列(intent) 第三阶段 · 检查收尾 · 跑 lint-case.py 检查 · 跑 render-case.py 渲染出网页 ``` ### 起手(只做一次) 把本文读**一遍**,之后**别再回头读它**——需要某阶段细节时直接读对应的阶段文件。再把 [tools.md](tools.md) 读一遍(后面要调的脚本接口都在那),也别重读。 ### 重要:读过的文件别重复读 上下文是累积的,**你读过的文件内容会一直留在记忆里**。**不要**因为某处写了"详见 tools.md"就又去读一遍;**不要**进了第二阶段又去重读阶段文件。需要时从记忆里翻,别重复 Read——那会白白浪费预算。 ### 第一阶段 · 搭骨架(新读这些) 要做的事:通读案例 → 想清楚有几个工序、每个工序怎么走 → 切步骤 → 填骨架 → 把数据流连起来。 | 该读(还没读过的) | 干嘛用 | |---|---| | [extraction/phase1-skeleton.md](extraction/phase1-skeleton.md) | 第一阶段具体怎么做 + 字段填写规则 | | `input/case-{N}-raw.json` | 案例原文(你的素材) | 产物(写到 `outputs/case-{N}/`):`workflow.json`——先调 `plan_procedures` 工具交计划(几个工序 / 每工序步骤展开 / 每工序认领哪些 `0N` 章节),Cyber 引擎据此自动生成骨架;再用 `wf-patch.py` 在骨架上填 value/directive、补"来源/去处"(别增删工序/步骤)。 过关条件:workflow.json 自查通过(数据流都连上了、类型一致)→ 进第二阶段。 ### 第二阶段 · 归类标注(新读这些) 要做的事:把"作用/动作/类型"归到分类词表;把"实质/形式"直接提炼成元素点;填每步的目的列。 | 新读 | 干嘛用 | |---|---| | [extraction/phase2-normalize.md](extraction/phase2-normalize.md) | 第二阶段怎么做 | | [taxonomy/effect.json](taxonomy/effect.json) / [action.json](taxonomy/action.json) / [type.json](taxonomy/type.json) | 三张分类词表 | 产物:用 `wf-patch.py`(`--set`/`--patch`)在 `workflow.json` 上补 作用/动作/类型 + 实质/形式 + 自造类型登记 + 目的列。**别 edit/手写改它,也不要另存新文件**。 过关条件:每步的作用/动作都命中标准词、每个类型要么命中词表要么登记了挂靠、每步该有的实质/形式都提炼好、每步都有目的列 → 进第三阶段。 ### 第三阶段 · 检查 + 渲染(新读这些) 要做的事:跑检查 → 渲染出网页(脚本自动组装,不另存中间文件)。 | 新读 | 干嘛用 | |---|---| | [extraction/phase3-finalize.md](extraction/phase3-finalize.md) | 检查清单 + 脚本命令 | | [format/case-data.schema.json](format/case-data.schema.json) | 字段的机器清单(最终裁判) | 脚本命令: ```bash # 1. 检查 + 自动登记新类型(轻量, 不卡流程); 带 --source 才查「章节覆盖」+「value 逐字」 python spec/tools/lint-case.py --workflow outputs/case-{N}/workflow.json --case-id {N} \ --source input/case-{N}.json --ocr outputs/case-{N}/_scratch/ocr.txt # 2. 渲染网页(脚本在内存里组装好数据直接出 HTML) python spec/tools/render-case.py \ --workflow outputs/case-{N}/workflow.json \ --source-input input/case-{N}-raw.json \ --page-title "Case {N} · <主题>" \ --case-id {N} \ --out outputs/case-{N}/case-{N}-.html ``` 产物:`outputs/case-{N}/case-{N}-.html`(唯一产物)。 ### 每次 Read 前自查 - 这个文件**之前读过吗**?读过就别再读。 - 只想确认"提没提过某概念"?用 Grep,别整篇 Read。 - 只想看"目录里有啥"?用 Glob。 - 中断后接着做:用户**可能改过**的 `workflow.json`(及 `understanding.md` 草稿,若有)要重读;spec 没变,不用重读。 ### 卡住了怎么办 某阶段的过关条件过不去 → **别硬闯下一阶段**,回当前阶段修。修两次还过不去 → 在产物里挂个 `inferred: true, inferred_reason: "反复过不去, 需人工看"` 标记,再往下走。