| 小步 | 做什么 | 产出 |
|---|---|---|
| 1.1 | 读懂 + 判断有几个工序 —— 通读原文(含配图)想清楚:(a) 这篇案例里有几条独立的做法(一条还是多条);多条时,把每条的名字、最终产物、大概几步、属于什么工艺各列出来。(b) 认出最终产物、用到的外部工具、以及那些"没明说但少不了"的前置准备。 | understanding.md(按工序分章节写) |
| 1.2 | 切步骤 + 填单步骨架 —— 一次性写出 workflow.json 骨架 |
workflow.json(骨架版) |
| 1.3 | 把数据流连起来 —— 给每个输入输出补上"来源/去处":输入写 ← 上游某输出的编号(如 ← s2o1)、← 工序输入、← 某编号[i](循环里逐个取);输出写 → sN、→ 某列表.追加。连完自查:每个输入引用的编号都能在前面找到对应输出。连错就回 1.2 改。几十处要连时用 wf-patch.py 一次过(见下),别写脚本硬塞。 |
workflow.json(补好"来源/去处") |
一个 workflow.json 描述一篇案例,里面可以有一个或多个工序(比如一篇文章同时讲了"简单做法"和"进阶做法",那就是两个工序)。
{
"source": 原帖信息, # 平台/作者/日期/标题/摘要;正文和配图由 --source-input 自动补
"procedures": [ 一个或多个工序 ] # 只有一个工序时也用长度为 1 的数组
}
# page_title 不写进文件,由第三阶段 --page-title 命令传入
每个工序长这样:
{
"id": "p1",
"name": 工序名字,
"purpose": 一句话说明这个工序在做什么,
"category": 类别(产物创造 / 资产建设 / 自动化 / 分析 / 学习),
"platform": 平台, "author": 作者,
"declarations": 这个工序需要哪些外部输入和长期资源,最后返回什么,
"type_registry": 这个工序自己造的类型词(没有可不写),第二阶段归类时填,
"steps": [ 一步步的操作 ],
"return_row": 表格最后一行,写明最终交付什么(可不写)
}
每个工序填:id / name / purpose / category / platform / author / declarations / steps。
| 字段 | 什么意思 | 怎么填 | 别这样 |
|---|---|---|---|
id |
第几步 | s1、s2;控制块子步用点号 s6.1 |
— |
kind |
步骤类型 | 普通步写 step;控制块用 block / nested(见下) |
— |
via |
用了哪个具体工具/产品 | 写工具标准名:manus、nano_banana_pro、human(人工);原文没点名就括号占位 (AI 生图工具);控制块写 - |
写一句话描述(那是 directive 的活) |
directive |
真正喂给工具的提示词/命令 | 把原文里的提示词原样引过来;"给工具的指示"(如"严格反推,别发挥"、"比例 2:3")也归这里;纯人工/控制块步留空 | 把画面内容描述写进来(那是输入的 value) |
| 字段 | 什么意思 | 怎么填 | 别这样 |
|---|---|---|---|
type |
这份数据是什么角色(参考图?提示词?) | 从类型词表里挑;词表没有就自造,但要在工序 type_registry 里说明它"算作"哪个标准词 |
既不在词表、又没挂靠 |
value |
数据内容本身 | 文字类完整写出;图片/视频用尖括号写描述 <一张床上女性的人像> |
写"见上一步"这种引用;写"[图3显示]"这种说明 |
anchor |
来源 / 去处 | 输入写来源:← 工序输入、← s2o1、← s2o1[i](循环逐个取);输出写去处:→ s7、→ 某列表.追加、→ 返回 X |
在这里描述内容(那是 value 的活) |
id(输出专属) |
输出的编号 | 工序内唯一,如 s2o1;只有一个输出时 s2 也行 |
重复编号 |
⚠ 值一定要写真实内容:哪怕某个输入就是上一步输出原样传过来的,"值"里也要把内容完整抄一遍,不能写"(同上)""见 s2o1"。嫌麻烦的话:只在源头填一次真内容,其余地方把"来源"写对,然后跑一次
wf-patch.py --resolve-passthrough,它会顺着编号自动把内容抄过去。
输入不用编号——没人会反过来引用一个输入。
seedream_4_5,不要写成 ByteDance-Seedream-4.5)。type_registry 里写明它"算作"哪个标准词 + 一句说明,例如 "主角图": {"extends": "参考图", "desc": "本案例的女主肖像"}。⚠ 跟原文的章节标题无关:不管原文把某段叫"案例示范"还是"进阶玩法",只要满足下面三条,就算一条独立工序。判断的单位是"一条完整的 输入→最终产物 链",不是原文的段落结构。
怎么扫:以原文里每一张出现的成品图(或明确写出的最终产物)为起点,逐个看它有没有对应的"输入→做法"链条。有就记为一个候选工序,再用下面三条筛。别按段落扫。
边界判断:
真实教程经常会省略一些理所当然的中间产物。比如某步要"自己写动作序列",原文没提它得先有一张主角图当参考——但工艺上这张图必不可少。这种该有却没写出来的输入/输出,要主动补上并标注推断原因;某个字段实在判断不出就留空,不要硬编一个假的。
原文常省略的几类:
补出来的输入输出标上 inferred: true 和原因(让后面复核),别悄悄塞进去:
{
"type": "参考图",
"value": "<一张主角肖像>",
"anchor": "← s2o1",
"inferred": true,
"inferred_reason": "原文只说'自己写动作',没提主角图;但写动作序列需要它当角色参考"
}
declarations 上(那里只收 type/name/desc 三个字段)。原文里如果有"对每个 X 重复""同时做几个版本""分情况",切步骤时要展开成控制块 + 子步,别硬压成一个步骤:
"kind": "block"):via 写 -,块的输入输出表达"整个循环在做什么"。"kind": "nested",并写上 "group": "块的编号"):编号带点号(块是 s5,子步就是 s5.1),表达"每一次具体怎么做"。{ "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", "directive":"按场景提示词生成,保持主角一致",
"inputs": [{"type":"提示词","value":"...","anchor":"← s4o1[i]"},
{"type":"参考图","value":"...","anchor":"← s5o1[-1]"}],
"outputs":[{"id":"s5.1o1","type":"分镜图","value":"...","anchor":"→ 分镜图列表.追加"}] }
← s4o1[i](逐个取)、← s5o1[-1](取上一次的产出,做"接力"参考)。→ 分镜图列表.追加。directive 里说明即可。← 某编号)都能找到已存在的输出编号,或是 ← 工序输入、字面量。[i] 在循环里,[-1] 指最近一项)。workflow.json 由你直接演化,绝不写 Python 脚本去生成/批改它(脚本拼 JSON 容易踩转义坑、把文件弄坏)。几十处"来源/去处"用 wf-patch.py 一次搞定:
_scratch/anchors.json —— [{"path":"p1.s1.inputs[0].anchor","value":"← s0o1"}, ...],每条都是你的判断(连到哪个编号是语义决定,不是机械套用);python spec/tools/wf-patch.py --workflow workflow.json --patch _scratch/anchors.json。工具负责安全写 JSON + 检查格式(有一条不合法就整批不写),你从不直接碰 JSON 文本。零星单处改,用 Edit 就行。路径写法见 tools.md。
"来源"连好后,跑一次 python spec/tools/wf-patch.py --workflow workflow.json --resolve-passthrough。对那些"原样接收上游输出"的输入(来源是 ← 某编号),你不用手抄上游内容——只在源头那个输出里填一次真内容,工具会顺着编号把它逐字抄到所有引用处("值"先留空即可)。别把"(同上)"这种引用当最终内容留着(检查会报)。
复制下方模板改即可。
{
"source": {
"platform": "<填:原文平台 e.g. wechat-gzh>",
"author": "<填:原文作者>",
"date": "<填:发布日期 e.g. 2026 上半年>",
"url": "<填:原文 URL>",
"title": "<填:原文标题>",
"excerpt": "<填:摘要 1-3 句>"
},
"procedures": [
{
"id": "p1",
"name": "<填:工序名 e.g. 产品场景图生成>",
"purpose": "<填:一句话目的>",
"category": "<填:产物创造|资产建设|自动化|分析|学习>",
"platform": "<填:平台>",
"author": "<填:作者>",
"declarations": {
"inputs": [{ "type": "<填:类型>", "name": "<填:声明名>", "desc": "<填:说明 (可选)>" }],
"resources": [],
"returns": { "type": "<填:返回类型>" }
},
"steps": [
{
"id": "s1",
"kind": "step",
"via": "<填:工具名 e.g. human / nano_banana / (AI 生图工具)>",
"directive": "<填:给工具的 prompt 文本 (可选;人工/控制流步留空)>",
"inputs": [
{
"type": "<填:类型>",
"value": "<填:数据内容本身>",
"anchor": "<填:← 工序输入 / ← s1o1>"
}
],
"outputs": [
{
"id": "s1o1",
"type": "<填:类型>",
"value": "<填:数据内容本身>",
"anchor": "<填:→ s2 / → 返回 X>"
}
]
}
]
}
]
}
有循环 / 并行 / 分支时,用控制块写法(无则不需要):
{
"id": "s1",
"kind": "block",
"via": "-",
"inputs": [{ "type": "<填:类型>", "value": "<填>", "anchor": "<填:← 上游 id>" }],
"outputs": [{ "id": "s1o1", "type": "<填:类型>", "value": "<填:累积结果>", "anchor": "<填:→ sN>" }]
},
{
"id": "s1.1",
"kind": "nested",
"group": "s1",
"via": "<填:工具名>",
"directive": "<填:给工具的 prompt (可选)>",
"inputs": [{ "type": "<填:类型>", "value": "<填>", "anchor": "<填:← 被遍历序列 id[i]>" }],
"outputs": [{ "id": "s1.1o1", "type": "<填:类型>", "value": "<填:单次产出>", "anchor": "<填:→ 累积结果.追加>" }]
}