Просмотр исходного кода

skill 重构到 v2:判颗类型闸 + 三 lane 成形 + 组件颗

- phase1-frame(替 phase1-skeleton):判颗+类型闸+how/what/why 三类成形模板+组件颗(parent)+轻标签分流
- phase2-scope(替 phase2-normalize):作用域 how 逐步 / what·why 颗级
- phase3-assemble(替 phase3-finalize):按类型分拼 content + 组件颗「出自」溯源
- schema/lint 加「出自」键;README/金标样例/作用域边界同步 v2

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
SamLee 1 месяц назад
Родитель
Сommit
a22599b5a5

+ 20 - 14
创作知识提取-skill/README.md

@@ -2,7 +2,10 @@
 
 > 这道 skill 做一件事:**读一篇创作帖/视频,把背后能指导创作的"框架"提出来,组装成 `POST /api/v1/knowledge/ingest` 的请求体(payload.json)**。
 >
-> 本文是总览。具体操作和字段规则在 [extraction/](extraction/) 的三阶段文件里,按阶段读。
+> 本文是总览。具体操作和字段规则在 [extraction/](extraction/) 的各阶段文件里,按阶段读。
+>
+> **流程拆成「长+窄」的多步**(每步只干一件窄活、写到位):
+> ① 读懂(视觉,基建 extractor) → ② 拆框架+轻标签 → ③ 作用域(重,单独一刀) → ⑤ 组装+lint(纯代码)。
 
 ---
 
@@ -20,20 +23,22 @@
 
 ## 概念速览
 
-- **一颗 = 一个完整创作框架**:`purpose`(把某输入一路做成成品)+ 一条不可跳步的 `steps`。一帖通常 1-2 颗,**别拆成碎片**。
-- **How 是骨架**:绝大多数帖归到一个 How 框架;What(是什么/构成)、Why(为什么/原理)多数活在某步里,只有整帖纯界定/纯原理才单独成颗(简化版)。
-- **5 个标注维度**:知识类型(how/what/why)、业务阶段(灵感/选题/脚本)、创作阶段(定向/构思/结构/成文/打磨,逐步)、动作(开放·从内容提炼具体手法)、作用域(5 棵树带值·**回扣**复用现有节点)。
+- **颗是单位,一帖 = N 颗**(可混 how/what/why),共 `knowledges[]`,每颗 → 一个 ingest payload。
+- **三类对等 lane**:How(目标+不可跳步 steps)、What(界定+构成)、Why(主张+依据+影响)。**先判类型闸,再按类型成形**——别默认 how、别硬造假 how。
+- **what/why 既可独立成颗,也可作 how 的「组件颗」**:how 步骤里嵌的 what/why(如某步产出"叙事弧线五要素")既显示在步骤里,又**单列成一颗**(role=组件,parent 指回那个 how 的第 N 步);how 没覆盖的独立 what/why 也单列(role=主)。判据:脱离 how 还能独立检索复用吗?
+- **5 个标注维度**:知识类型(how/what/why)、业务阶段(灵感/选题/脚本,颗级)、创作阶段(定向/构思/结构/成文/打磨,**仅how逐步**)、动作(开放·**仅how逐步**)、作用域(5 棵树带值·**回扣**·how逐步/what·why颗级)。
 - **作用域回扣**:值要对到 5 棵分类树的真实节点——对得上复用原名、对不上才新建。用 `tools/scope-link.py`(火山 embedding 最近邻,基建已落地)。
 
 ## 目录里有什么
 
-### 操作流程(extraction/ —— 分三阶段,按阶段读)
+### 操作流程(extraction/ —— 按步读)
 
-| 文件 | 内容 | 何时读 |
-|---|---|---|
-| [extraction/phase1-skeleton.md](extraction/phase1-skeleton.md) | 读懂→判几颗→剔制作→出框架骨架(purpose+steps) | 第一阶段 |
-| [extraction/phase2-normalize.md](extraction/phase2-normalize.md) | 知识类型/业务阶段/创作阶段/动作 + 作用域回扣 | 第二阶段 |
-| [extraction/phase3-finalize.md](extraction/phase3-finalize.md) | 组装 payload + lint + 自检 + 逃生 | 第三阶段 |
+| 步 | 文件 | 内容 | 谁干 |
+|---|---|---|---|
+| ① 读懂 | (基建 extractor,不在本目录) | 图/视频 → 文字 | 视觉 LLM |
+| ② 拆框架+轻标签 | [extraction/phase1-frame.md](extraction/phase1-frame.md) | 判几颗+筛创作/制作+目的/怎么做/产出 + 知识类型/业务阶段/创作阶段/动作 | 判断 LLM |
+| ③ 作用域 | [extraction/phase2-scope.md](extraction/phase2-scope.md) | per-step 5 类带值(互斥边界+反例+回扣),**重** | 判断 LLM + 回扣工具 |
+| ⑤ 组装 | [extraction/phase3-assemble.md](extraction/phase3-assemble.md) | 拼 payload + lint,**纯代码** | 代码 |
 
 ### 契约 / 词表 / 样例 / 工具
 
@@ -47,12 +52,13 @@
 
 ## 操作流程
 
-整个流程围绕**一个滚动文件 `framework.json`**:第一阶段搭骨架,第二阶段就地补标注,第三阶段组装成 `payload.json`。
+整个流程围绕**一个滚动文件 `framework.json`**:② 搭骨架+轻标签,③ 就地补作用域,⑤ 组装成 `payload.json`。
 
 ```
-第一阶段 · 搭框架骨架   读懂(多模态)→判几颗→剔制作→purpose+steps   → framework.json(骨架)
-第二阶段 · 归类标注     类型/业务阶段/创作阶段/动作 + 作用域回扣      → framework.json(就地补)
-第三阶段 · 组装收尾     拼 content+维度 → payload.json → lint → 自检  → payload.json(最终)
+① 读懂(视觉)          图/视频 → 文字
+② 拆框架+轻标签       判几颗→剔制作→目的/怎么做/产出 + 知识类型/业务阶段/创作阶段/动作   → framework.json(作用域留空)
+③ 作用域(重)          per-step 5 类带值 + 互斥边界 + 回扣(复用原名/新建)              → framework.json(就地补作用域)
+⑤ 组装(代码)          拼 content+维度,scopes=各步并集 → lint                          → payload.json
 ```
 
 ## 上下文纪律(重要,照做省预算)

+ 4 - 4
创作知识提取-skill/examples/金标样例.md

@@ -22,22 +22,22 @@
       "directive": "列出本赛道被反复说、大家默认正确的共识。例:『护肤赛道——早C晚A、含酒精的就是不好』",
       "output": "赛道共识清单", "出处": "正文",
       "创作阶段": "定向", "动作": "列赛道共识",
-      "scopes": [{ "scope_type": "substance", "value": "赛道共识" }] },
+      "作用域": [{ "scope_type": "substance", "value": "赛道共识", "link": "新建", "score": 0.58 }] },
     { "id": "s2", "intent": "构思,找这个共识在哪些场景会失灵",
       "directive": "对每条共识,找它不成立/反例的具体场景,越具体越好",
       "output": "失灵场景", "出处": "正文",
       "创作阶段": "构思", "动作": "定失灵场景",
-      "scopes": [{ "scope_type": "effect", "value": "撕裂共识" }] },
+      "作用域": [{ "scope_type": "effect", "value": "撕裂共识", "link": "新建", "score": 0.52 }] },
     { "id": "s3", "intent": "成文,在裂缝处写出撕裂共识的选题",
       "directive": "把失灵场景写成一个挑战默认共识的选题句,制造认知冲突",
       "output": "撕裂式选题", "出处": "正文",
       "创作阶段": "成文", "动作": "撕裂共识写选题",
-      "scopes": [{ "scope_type": "feeling", "value": "羞耻感/冒犯" }] },
+      "作用域": [{ "scope_type": "feeling", "value": "羞耻感/冒犯", "link": "新建", "score": 0.57 }] },
     { "id": "s4", "intent": "打磨,用羞耻感验收选题够不够冒犯",
       "directive": "自检:这个选题会不会让坚持旧共识的人感到被冒犯/羞耻?不会就再撕深一点",
       "output": "定稿选题", "出处": "正文",
       "创作阶段": "打磨", "动作": "羞耻感验收",
-      "scopes": [{ "scope_type": "intent", "value": "引爆传播" }] }
+      "作用域": [{ "scope_type": "intent", "value": "引爆传播", "link": "新建", "score": 0.64 }] }
   ],
   "dropped": ["『用某排版工具做封面』—— 制作工艺执行,剔除"]
 }

+ 114 - 0
创作知识提取-skill/extraction/phase1-frame.md

@@ -0,0 +1,114 @@
+# ② 判颗 + 类型闸 + 三 lane 成形 + 轻标签
+
+输入:①读懂后的文字内容。
+干三件事:**判这帖有几颗、各是什么类型**(how/what/why)→ **按类型把每颗成形** → **顺手打轻标签**。
+**不碰作用域**(留给 ③)。产物:`framework.json` 的 `knowledges[]`(一帖多颗)。
+
+> 核心:**颗是单位,一帖 = N 颗**(可混类型)。what/why 既能独立成颗,也能作为某 how 的「组件颗」单列。
+
+---
+
+## A. 拆颗顺序 —— how 先抽,what/why 都单列(含组件)
+
+```
+这帖有没有"不可跳步的工序(how)"?
+├─ 有 → 抽 how 骨架(可能 1-2 个)→ 出 How 颗(主颗,role=主)
+│        ① how 步骤里嵌的 what/why → 既写在步骤里,又【各单列成一颗组件颗】
+│           (role=组件,parent={how_id, step})。如某步产出"叙事弧线五要素"=一颗 what 组件。
+│        ② how 没覆盖到的、独立的 what/why → 单列成颗(role=主,parent=null)
+└─ 没有 → 它本来就是一颗 What(界定/清单) 或 Why(原理)(role=主)
+```
+
+**判 step(压进 how,不单列为 step)**:①产出半成品 ②被同帖另一块当输入 ③拿走则成品残缺。
+**判组件颗(step 里的 what/why 该不该单列)**:见 §C 判据。
+**铁律**:没工序**别硬造假 how**("7 种叙事结构"当选型菜单就压进 step,别硬掰成 how 框架);一颗 = 一个完整东西,不拆碎。
+
+---
+
+## B. 三类成形模板(三条对等 lane)
+
+### How(工序)— role 主
+`purpose`(把某输入一路做成成品)+ 有序 `steps`,每步:
+- `intent` 目的(≤25字,动作+对象)
+- `directive` 怎么做(含判断标准;**原帖示例必须原文保留** `例:『…』`;不编原文没有的例子)
+- `output` 产出
+- `出处`(图N / 视频时间)
+
+### What(构成)— role 主 或 组件
+`界定`(一句话这是什么)+ `构成`:`[{要素, 说明}]`。无 steps。
+> 组件 what:它是某 how 某步的产出类型,但本身可独立复用(如"脚本三要素")。
+
+### Why(原理)— role 主 或 组件
+`主张`(核心观点)+ `依据`(原理/平台逻辑/读者心理)+ `对创作的影响`(取舍含义)。无 steps。
+> 组件 why:它是某 how 某步 directive 里"为什么这样选"的判断依据,但本身可独立复用。
+
+---
+
+## C. 组件颗判据(最难一刀)
+
+对每块(step 里嵌的、或 how 之外的)what/why 问:
+
+> **脱离这个 how,它还独立成立、能被单独检索复用吗?**
+> - **是 → 单列成一颗**(step 里嵌的→组件颗带 parent;how 之外的→主颗 parent=null)。
+> - **否(只是这一步一次性指令、无复用价值)→ 只留在步骤里**,不单列。
+> - **N 选 1 并列清单**:清单整体若是可复用知识("7 种叙事结构")→ 单列一颗 What;否则压进 step 菜单。
+
+---
+
+## D. 创作 vs 制作(剔除写进 `dropped`)
+剔:纯工艺执行(器材/打光/剪辑软件/调色/导出)、具体素材、太空泛。
+边界看「设计决策 vs 工艺执行」:景别/构图/字幕/结构=设计决策→保留为 step;操作设备软件那层→剔。
+
+---
+
+## E. 轻标签(顺手打,按类型分流)
+
+| 标签 | how | what | why | 取值 |
+|---|:--:|:--:|:--:|---|
+| 知识类型 | ✓ | ✓ | ✓ | how/what/why(已在 type 字段) |
+| 业务阶段(颗级多值) | ✓ | ✓ | ✓ | 灵感/选题/脚本 |
+| 创作阶段(**每步1个**) | ✓ | ✗ | ✗ | 定向/构思/结构/成文/打磨 |
+| 动作(**每步1个**,开放) | ✓ | ✗ | ✗ | 具体手法,帖子语言 |
+
+> 创作阶段/动作只有 how 有(要有步骤)。what/why 只给业务阶段。
+
+---
+
+## framework.json 模板(②产出,作用域留空待③)
+
+```json
+{
+  "source": {"id":"xhs_<id>","source_type":"post","title":"<原帖标题>","author":"<作者>",
+             "source_metadata":{"platform":"<小红书/抖音>","url":"<…>","date":"<…>"}},
+  "knowledges": [
+    {
+      "id": "k1", "type": "how", "role": "主", "parent": null,
+      "title": "<框架名>", "purpose": "<一句话目标>", "业务阶段": ["选题"],
+      "steps": [
+        {"id":"s1","intent":"<目的>","directive":"<怎么做,例:『…』>","output":"<产出>",
+         "出处":["图3"],"创作阶段":"定向","动作":"列赛道圣经句","作用域":[]}
+      ],
+      "dropped": ["<剔除项 — 理由>"]
+    },
+    {
+      "id": "k2", "type": "what", "role": "组件", "parent": {"how_id":"k1","step":2},
+      "title": "叙事弧线五要素", "业务阶段": ["脚本"],
+      "界定": "一条完整叙事弧线由五类要素构成。",
+      "构成": [{"要素":"激励事件","说明":"打破平衡的第一个重大事件"}],
+      "作用域": []
+    },
+    {
+      "id": "k3", "type": "why", "role": "主", "parent": null,
+      "title": "<原理名>", "业务阶段": ["选题"],
+      "主张": "<核心观点>", "依据": "<原理/逻辑>", "对创作的影响": "<取舍含义>",
+      "作用域": []
+    }
+  ]
+}
+```
+
+## 过关条件 → 进 ③
+- 颗数合理(how 主颗 + 组件颗 + orphan,可混);每颗有 type/role/parent。
+- how 颗:每步 intent/directive/output/出处 + 创作阶段 + 动作;what 颗:界定+构成;why 颗:主张+依据+影响。
+- 组件颗有 parent cross-ref;颗级业务阶段都填了。
+- 所有颗的 `作用域` 留空(含 how 的每步),③ 来填。

+ 0 - 106
创作知识提取-skill/extraction/phase1-skeleton.md

@@ -1,106 +0,0 @@
-# 第一阶段 · 搭框架骨架
-
-要做的事:读懂帖子(含图/视频)→ 判这帖出几颗知识 → 剔掉制作/碎片 → 把每颗写成一个完整创作框架(目标 + 有序步骤)。产物:`framework.json`(骨架版,第二阶段在它上面就地补字段)。
-
-## 步骤
-
-| 小步 | 做什么 | 产出 |
-|---|---|---|
-| **1.1** | **读懂 + 判几颗** —— 通读正文 + 图(图文帖逐图看)/ 视频整段;想清楚这帖有**几颗独立知识**(通常 1-2 颗),每颗的框架名、最终交付物、大概几步。同时**剔除**制作/碎片/过宽内容。 | `framework.json` 的 `frameworks[]` 条数 + 各 `dropped` |
-| **1.2** | **出每颗的框架骨架** —— 写出 `framework.json`:每颗 `purpose` + 有序 `steps`(每步 `intent` / `directive` / `output` / `出处`)。 | `framework.json`(骨架版) |
-
----
-
-## 一颗知识的粒度(铁律,最容易错)
-
-**一颗知识 = 一个完整创作框架** = 一个 `purpose`(把某输入一路做成可交付成品)+ 一条**不可跳步**的 `steps` 链。**一帖通常 1-2 颗。** 绝不把框架内部的步骤/要点拆成独立颗。
-
-- **判 step(压进框架、不单列)**:①产出半成品 ②被同帖另一块当输入消费 ③拿走则本颗成品残缺。满足任一即为 step。
-- **判独立颗**:①有自己的 purpose 句 ②产出能独立交付 ③脱离本框架换题材照样跑通。三条都满足才另立一颗。
-- **清单/导图型**:一堆并列要素(N 选 1)是「一个 step 内的菜单」,压进所属 step,**不按项数拆颗**。
-- 踩过的坑:早期把一帖拆成 5-6 个碎片是错的——碎片其实是同一框架内部的步骤/指引细节。
-
----
-
-## How / What / Why:优先按 How 提
-
-- **优先 How**:绝大多数创作教学帖都能归到**一个 How 框架**(purpose + 有序 steps)。先试着按 How 提。
-- **What / Why 多数活在 How 里**,不单独成颗:某步「产出一个有构成的东西」= 该步的 What 性质,写进 `output`;directive 里「为什么这样选/原理/标准」= Why,写进 `directive`。
-- **例外(单独成颗,用简化骨架)**:整帖只是**列举/界定**(纯 What)或**只讲原理**(纯 Why),套不进 purpose+steps。这时这颗没有 `steps`,改填:
-  - What:`purpose` 写「界定:<一句话这是什么>」+ `构成`: [{要素, 说明}, …]
-  - Why:`purpose` 写「主张:<核心观点>」+ `依据` + `对创作的影响`
-
-判到底是 how/what/why 先记在该颗的 `knowledge_type`(第二阶段会复核并决定 dim_attributes)。
-
----
-
-## 创作 vs 制作的边界(剔除时按这条判)
-
-**收**(创作知识):普适的创作路径/方法/工序、垂类技巧、形式偏好与禁忌——能一步步指导创作、**产出因人而异**。
-
-**剔除**(写进 `dropped`,附一句理由):
-- **制作 = 纯工艺执行**:器材 / 光圈ISO / 打光 / 收音设备 / 剪辑软件操作 / 调色参数 / 导出压制("拿方案去操作设备软件实现它")。
-- **具体素材/案例本身**:"此类内容具体讲了什么"的内容本体。
-- **过于宽泛**:"内容要有吸引力"这类无法约束某个具体创作决策的话。
-
-**关键边界(按"设计决策 vs 工艺执行"判,不看词面):** 景别/角度/运镜/构图/字幕/配乐/时长——**名字像制作、实为"把创意翻译成镜头语言"的设计决策**,写在脚本/分镜上 → **保留为框架内 step**;只有"拿方案操作设备软件"那层才剔除。
-
----
-
-## 忠实原则(directive 怎么写)
-
-- `directive` 说清这一步**怎么做、关键操作原则/判断标准**;用自然语言,别写成数据流公式。
-- **原帖给出的具体示例(例句、案例、样本)必须原文保留**,格式 `例:『…』`,紧跟对应要点之后。
-- **不要编原文没有的例子**;判断不出的字段留空,别硬填假值。
-
-## 隐含步骤要补(inferred)
-
-不可跳步但原帖没明说的中间步骤要补上,并标 `"inferred": true, "inferred_reason": "…"`(让后面复核)。只补**工艺上必然需要**的;只是换个说法、或归类标注(第二阶段的活)不算补。
-
----
-
-## framework.json 骨架模板(第一阶段产出)
-
-复制改即可。`scopes / 创作阶段 / 动作 / 业务阶段 / 作用域并集` 留给第二阶段,这里先不填。
-
-```json
-{
-  "source": {
-    "id": "<xhs_<content_id> 等>",
-    "source_type": "post",
-    "title": "<原帖标题>",
-    "author": "<作者>",
-    "source_metadata": { "platform": "<小红书/抖音…>", "url": "<…>", "date": "<…>" }
-  },
-  "frameworks": [
-    {
-      "id": "k1",
-      "knowledge_type": "<how | what | why>",
-      "title": "<框架名,如 撕裂共识选题框架>",
-      "purpose": "<how: 一句话目标(把…一路做成…);what: 界定:…;why: 主张:…>",
-      "想要": "<可选:这颗帮用户得到什么>",
-      "steps": [
-        {
-          "id": "s1",
-          "intent": "<一句话目的,≤25字,第二阶段会复核>",
-          "directive": "<怎么做+判断标准;原帖示例用 例:『…』 嵌入>",
-          "output": "<这步的产出物>",
-          "出处": "<正文 / 图3 / 视频 02:10 等>"
-        }
-      ],
-      "构成": "<仅 what 颗:[{\"要素\":\"…\",\"说明\":\"…\"}],无 steps 时用>",
-      "依据": "<仅 why 颗>",
-      "对创作的影响": "<仅 why 颗>",
-      "dropped": ["<剔除项:xxx —— 理由(制作/碎片/过宽)>"]
-    }
-  ]
-}
-```
-
-> 纯 What/Why 颗没有 `steps`,用 `构成` 或 `依据`+`对创作的影响` 代替。
-
-## 过关条件 → 进第二阶段
-
-- 颗数合理(1-2,每颗是完整框架不是碎片);制作/碎片/过宽都进了 `dropped`。
-- How 颗:每步 `intent`/`directive`/`output`/`出处` 都填了;步骤不可跳步、数据接得上。
-- directive 忠实(保留了原帖示例、没编造)。

+ 0 - 66
创作知识提取-skill/extraction/phase2-normalize.md

@@ -1,66 +0,0 @@
-# 第二阶段 · 归类标注 + 作用域回扣
-
-在第一阶段的 `framework.json` 骨架上**就地补字段**(Edit,不另存)。给每颗补 5 类标注。
-
-### 起手:把词表读进来(各读一遍,别重读)
-
-- `taxonomy/知识类型.json`(how/what/why → 定 dim_attributes + 形态)
-- `taxonomy/业务阶段.json`(灵感/选题/脚本,整颗多值)
-- `taxonomy/创作阶段.json`(定向/构思/结构/成文/打磨,逐步)
-- `taxonomy/作用域.md`(5 棵树 + 回扣怎么用)
-
----
-
-## 1. 知识类型(整颗一个)—— 复核 + 定形态
-
-复核第一阶段的 `knowledge_type`,确认 how/what/why。它决定后面 `dim_attributes`(how工序/what构成/why原理)和 payload 形态。**绝大多数是 how**;只有套不进 purpose+steps 的纯界定/纯原理才是 what/why。
-
-## 2. 业务阶段(整颗,可多值)
-
-这颗框架覆盖了哪些业务环节,对到 `灵感/选题/脚本` 的一个或多个。整颗框架常跨阶段(如选题框架可能同时落「灵感+选题」)。写到该颗的 `业务阶段: [...]`。
-
-## 3. 创作阶段(逐步,仅 How 颗)
-
-How 颗的**每个 step** 命中创作阶段一个标准词(`定向/构思/结构/成文/打磨`)。写到 `step.创作阶段`。**必须命中**;对不上说明第一阶段这步切错了,回去改。
-- 别把「动作」当「阶段」——"撕裂共识写选题"是动作,它所在的步可能处在「构思」阶段。
-
-## 4. 动作(逐步,仅 How 颗,开放·从内容提炼)
-
-How 颗的**每个 step** 提炼一个**具体创作手法**,写到 `step.动作`。**不锁词表**——用帖子自己的语言、具体招式(`列赛道共识` / `撕裂共识写选题` / `塑三维人物` / `套三幕结构` / `羞耻感验收`),别抽象成「决策/撰写」这种空词。这是创作里最有信息量的东西,ingest 会对它自动 embed 成「手法库」可语义检索。
-
-## 5. 作用域(带值 + 回扣)—— 命门
-
-给作用域 5 类挑相关的(不必 5 类都给),每个给一个**具体值**:
-- How 颗:**逐步**标 `step.scopes: [{scope_type, value}]`(这步主要涉及实质/形式/感受/作用/意图里的哪些)。
-- What/Why 颗:整颗标 `作用域并集: [{scope_type, value}]`。
-
-| scope_type | 判别 | 例 |
-|---|---|---|
-| substance 实质 | 讲什么(题材/对象) | 赛道共识、脚本要素 |
-| form 形式 | 怎么呈现(结构/体裁/手法) | 三幕结构、分镜骨架 |
-| feeling 感受 | 勾什么情绪 | 羞耻感/冒犯、代入共鸣 |
-| effect 作用 | 起什么表达功能 | 撕裂共识、吸引点击 |
-| intent 意图 | 创作者图什么 | 引爆传播、提升打开率 |
-
-**每个值都要回扣**(避免同义词污染 5 棵树):
-
-```bash
-python 创作知识提取-skill/tools/scope-link.py "撕裂共识" --type effect --top-k 5
-```
-- score ≥ ~0.90:直接**复用返回的 `name`**(value 写这个原名,ingest 会按名挂靠现有节点)。
-- 0.75–0.90:看 top-K 里有没有真正同义的,有就复用 name,没有就用你的候选值(新值,丰富树)。
-- < 0.75:用你的候选值(新值)。
-
-> 批量回扣:把这颗所有候选值列出来逐个跑 scope-link,再回填。值用中文短词,别用长句。
-
----
-
-## 落盘
-
-在 `framework.json` 上 **Edit** 补:每颗的 `knowledge_type`(复核)/`业务阶段`;How 每步的 `创作阶段`/`动作`/`scopes`;What·Why 颗的 `作用域并集`。**不要写 Python 脚本去改 framework.json**(容易弄坏),逐字段 Edit。
-
-## 过关条件 → 进第三阶段
-
-- 每颗 knowledge_type 定了、业务阶段填了(≥1)。
-- How 每步:创作阶段命中 5 词之一、动作是具体手法(非空词)、scopes 带值且值已回扣。
-- What/Why 颗:作用域并集带值且已回扣。

+ 114 - 0
创作知识提取-skill/extraction/phase2-scope.md

@@ -0,0 +1,114 @@
+# ③ 作用域(重)
+
+本步**只干一件事**:给 ②产出的每颗知识标 5 类作用域里相关的几类,每类给一个**具体值**,并把值**回扣**到 5 棵分类树。
+不碰框架结构、不碰其它标签(那些 ② 已做)。
+
+**按类型分粒度**:
+- **How 颗**:**逐步**标——每个 step 一组作用域(写回 `step.作用域`)。
+- **What / Why 颗**:**颗级**标——整颗一组作用域(写回 `knowledge.作用域`);读 What 的 `界定/构成`、Why 的 `主张/依据/对创作的影响` 来判。
+
+> 这是全流程最容易"串味"的一刀(5 类边界模糊),所以单独、写厚。判不准就标空 `[]`,不硬塞。
+
+---
+
+## 1. 五类列定义(先认清各自管什么)
+
+| scope_type | 中文 | 管什么(一句话) | 例(具体值) |
+|---|---|---|---|
+| `substance` | 实质 | **讲什么**——题材 / 对象 / 内容实质 | 赛道共识、脚本要素、前提人物冲突 |
+| `form` | 形式 | **怎么呈现**——结构 / 体裁 / 表现手法 | 三幕结构、分镜骨架、场景序列 |
+| `feeling` | 感受 | **勾什么情绪**——读者/观众的情感反应 | 羞耻感/冒犯、代入共鸣、紧张 |
+| `effect` | 作用 | **起什么表达功能**——在内容里干的那个"活" | 撕裂共识、制造悬念、吸引点击 |
+| `intent` | 意图 | **创作者图什么**——最终目的 | 引爆传播、提升打开率、推进至结局 |
+
+**一步不必 5 类都给**——只给这步真正涉及的。多数步 2-3 类。
+
+---
+
+## 2. 互斥边界(最容易错,配反例)
+
+判每个值前,先过这几条边界,确认它没站错列:
+
+- **实质 ↔ 形式**:实质=讲什么(内容对象);形式=怎么呈现(结构/手法)。
+  - ✅ `赛道共识`=实质(对象);`三幕结构`=形式(呈现方式)
+  - ❌ 把"三幕结构"塞进实质(它是怎么排,不是讲什么)
+
+- **实质 ↔ 作用**:实质=内容对象本身;作用=这步在内容里**干的功能动作**。
+  - ✅ `赛道共识`=实质;`撕裂共识`=作用("撕裂"是它干的活)
+  - ❌ 把"撕裂共识"当实质(它是功能不是对象)
+
+- **作用 ↔ 意图**:作用=**段内**表达功能(手段层);意图=**最终**目的(目的层)。
+  - ✅ `制造悬念`=作用(手段);`引爆传播`=意图(图的最终结果)
+  - ❌ 把"引爆传播"当作用(它是图什么,不是这步干的活)
+
+- **感受 ↔ 意图**:感受=**观众**的情绪体验;意图=**创作者**的目的。
+  - ✅ `羞耻感/冒犯`=感受(观众心里一紧);`引爆传播`=意图(作者想要的)
+  - ❌ 把"羞耻感"当意图(那是观众感受,不是作者目的)
+
+- **形式 ↔ 作用**:形式=呈现的**结构形态**;作用=起的**功能**。
+  - ✅ `分镜骨架`=形式;`推进叙事`=作用
+
+---
+
+## 3. 值的格式约束(原子化)
+
+1. **短词/短词组**,非整句、非动宾长句。尽量 ≤6 字(专有名/约定俗成可略长)。
+2. **原子**:不许用"和/与/、/,"拼接多义。复合就拆成多个值(同一类可多值)。
+3. **不跨类重复**:一个值只进它该进的那一列;别在实质和作用都塞同一个词。
+4. **去重**:同一步同一类不重复同义值。
+5. 用**帖子语境里的具体词**,不要泛词("内容"、"主题"、"信息"这种放之四海皆准的不要)。
+
+---
+
+## 4. 判别顺序(每个候选值按序过一遍)
+
+1. **范畴检查**:它到底是"讲什么/怎么呈现/勾情绪/起功能/图什么"哪一类?(对照 §1+§2,站错列就移列或剔除)
+2. **原子检查**:是不是复合?是则拆。是不是整句?是则精简成短词。
+3. **泛词检查**:是不是放之四海皆准的框架词?是则剔或换成本帖具体词。
+4. 通过 → 进回扣(§5)。
+
+---
+
+## 5. 执行三阶段
+
+### 阶段一 · 提候选值
+逐步读 `intent / directive / output`,按 §1-§4 给这步标相关的几类作用域,每类一个候选具体值。
+
+### 阶段二 · 回扣对齐(调工具)
+对每个候选值跑:
+```bash
+python 创作知识提取-skill/tools/scope-link.py "<候选值>" --type <substance/form/feeling/effect/intent> --top-k 5
+```
+按返回的 top-1 余弦分判定:
+- **≥ 0.90**:复用返回的 `name`(value 写树原名),记 `link: "复用"`、`score`。
+- **0.75–0.90**:看 top-K 有没有**真同义**的——有就复用其 name,没有就用自己的候选值(新值)。
+- **< 0.75**:保留候选值为**新值**,记 `link: "新建"`、`score`(顺手丰富树)。
+
+> 回扣是代码(火山 embedding 最近邻),你只负责"起词"和"看分判定复用/新建"。
+
+### 阶段三 · 验证(自检)
+- 每个值都过了 §2 边界、§3 原子、§4 泛词?
+- 同一步没有跨类重复值?
+- 判不准 / 模糊两可的类 → 标空 `[]`,别猜。
+
+---
+
+## 6. 输出格式(写回每步 `作用域`)
+
+在 `framework.json` 每个 step 的 `作用域` 字段(②留的空)填:
+
+```json
+"作用域": [
+  {"scope_type":"substance","value":"赛道共识","link":"新建","score":0.58},
+  {"scope_type":"effect","value":"撕裂共识","link":"新建","score":0.52},
+  {"scope_type":"intent","value":"引爆传播","link":"新建","score":0.64}
+]
+```
+- `value`:回扣后的最终值(复用=树原名,新建=候选词)。
+- `link`:`复用` / `新建`(前端 drawer 用)。
+- `score`:top-1 余弦分(留痕)。
+
+## 过关条件 → 进 ⑤组装
+- 每步 `作用域` 已填(相关类带值、无关类不出现/标空)。
+- 每个值都回扣过、有 link+score。
+- 边界没串味、值原子、无泛词。

+ 35 - 0
创作知识提取-skill/extraction/phase3-assemble.md

@@ -0,0 +1,35 @@
+# ⑤ 组装 payload + 校验(纯代码,不用 LLM)
+
+把 ②③ 标完的 `framework.json` 的 **每一颗 `knowledges[]`**,机械组装成一个 ingest payload。没有判断,全是拼接 + 校验。一帖 N 颗 → N 个 payload(共享 source.id)。
+
+## 1. 每颗 → 一个 payload(按类型分拼)
+
+| payload 字段 | How | What | Why |
+|---|---|---|---|
+| `source` | 照抄 framework.json 的 `source`(三类一样) | | |
+| `title` | 该颗 `title` | | |
+| `dim_creations` | `["创作"]` 写死 | | |
+| `dim_attributes` | `["how工序"]` | `["what构成"]` | `["why原理"]` |
+| `content` | 目标+步骤(目的/怎么做/产出)拍平 | 界定+构成清单 | 主张+依据+对创作的影响 |
+| `scopes` | **各步 `作用域` value 去重并集** | **颗级 `作用域`** value | 颗级 value |
+| `custom_ext` | 业务阶段 + 创作阶段(各步去重) + 动作(各步) | **仅业务阶段** | **仅业务阶段** |
+
+### content 拼法
+- **How**:`目标:<purpose>\n步骤1(目的:<intent>)\n  指引:<directive>\n  产出:<output>\n步骤2…`
+- **What**:`界定:<界定>\n构成:\n- <要素>:<说明>`
+- **Why**:`主张:<主张>\n依据:<依据>\n对创作的影响:<对创作的影响>`
+
+### 组件颗的溯源
+若 `role=="组件"`(parent 非空),在 `custom_ext` 加一条标明出处:
+`{"key":"出自","type":"str","value":"<parent how 的 title> 第 <step> 步"}`。
+(让下游知道这颗 what/why 是某 how 的零件,但它仍是独立可检索的一条知识。)
+
+## 2. 校验
+```bash
+python 创作知识提取-skill/tools/lint-payload.py outputs/<帖>/payload.json
+```
+有 ERROR 必修;WARN 逐条看。
+
+## 3. 备注
+- `作用域` 里的 `link/score/top` **不进 payload**(只供前端 drawer 溯源);payload 只要 scope_type+value。
+- 组装与回扣都是确定性代码(`scripts/decompose.py` 的 ⑤ 段 + `tools/`),模型不参与这步。

+ 0 - 72
创作知识提取-skill/extraction/phase3-finalize.md

@@ -1,72 +0,0 @@
-# 第三阶段 · 组装 payload + 校验 + 收尾
-
-把 `framework.json` 的每颗组装成一个 ingest payload,写到 `payload.json`(数组,一颗一个,同帖共享 source)。然后 lint + 自检。
-
-## 1. 组装(每颗 → 一个 payload)
-
-字段映射(详见 `format/ingest-payload.schema.json` 与《创作知识拆解框架.md》§3):
-
-| payload 字段 | 怎么填 |
-|---|---|
-| `source` | 照抄 framework.json 的 `source`(id/source_type/title/author/source_metadata) |
-| `title` | 该颗 `title`(框架名) |
-| `dim_creations` | `["创作"]`(写死) |
-| `dim_attributes` | 由 knowledge_type:how→`["how工序"]`,what→`["what构成"]`,why→`["why原理"]` |
-| `content` | 见下「content 拼法」 |
-| `scopes` | How:各步 `scopes` 值**去重并集**;What/Why:`作用域并集` |
-| `custom_ext` | 业务阶段(多值各一条);How 另加 创作阶段(各步去重) + 动作(各步各一条) |
-
-### content 拼法
-
-**How**(拍平全文):
-```
-目标:<purpose>
-步骤1(目的:<intent>)
-  指引:<directive>
-  产出:<output>
-步骤2(目的:…)
-  指引:…
-  产出:…
-```
-**What**:`界定:<purpose 的界定句>\n构成:\n- <要素>:<说明>\n- …`
-**Why**:`主张:<purpose 的主张句>\n依据:<依据>\n对创作的影响:<对创作的影响>`
-
-### custom_ext 拼法
-
-- 业务阶段:该颗 `业务阶段` 每个值一条 `{"key":"业务阶段","type":"str","value":"选题"}`。
-- 创作阶段(仅 How):各步 `创作阶段` **去重**后每个一条。
-- 动作(仅 How):各步 `动作` 每个一条(不去重——每步的手法都留)。
-- What/Why **只有业务阶段**,不要创作阶段/动作。
-
-> 完整 How 与 What/Why 的成品样例见 `examples/金标样例.md`。
-
-## 2. 校验
-
-```bash
-python 创作知识提取-skill/tools/lint-payload.py outputs/<帖>/payload.json
-```
-有 ERROR 必须修(退出码 1);WARN 逐条看是否合理。
-
-## 3. 自检 / 对抗一遍
-
-- **粒度**:每颗是一个完整框架(1 颗非碎片)?被拆碎了就回第一阶段合并。
-- **创作非制作**:content 里没混进纯工艺执行(器材/软件操作/参数)?混了就剔到 dropped。
-- **directive 忠实**:没编原文没有的例子?原帖示例都保留了?
-- **scope 值合理**:值是具体短词、都回扣过、对得上的复用了原名?
-- **dim_creations 恒 ["创作"]、dim_attributes 与 knowledge_type 一致。**
-
-## 卡住了怎么办(逃生)
-
-某阶段过关条件反复过不去 → 别硬闯。回当前阶段修;**修两次还过不去**,就在该颗挂 `"inferred": true, "inferred_reason": "反复过不去,需人工看"`,再往下走,别卡死整帖。
-
-## 4.(可选)入库
-
-确认无误后:
-```bash
-python 创作知识提取-skill/tools/ingest-post.py outputs/<帖>/payload.json --url <ingest-api> --post
-```
-默认 dry-run,加 `--post` 才真发。
-
----
-
-**产物**:`outputs/<帖>/framework.json`(滚动中间产物)+ `outputs/<帖>/payload.json`(最终入库体)。

+ 1 - 1
创作知识提取-skill/format/ingest-payload.schema.json

@@ -74,7 +74,7 @@
         "required": ["key", "type", "value"],
         "additionalProperties": false,
         "properties": {
-          "key": { "type": "string", "enum": ["业务阶段", "创作阶段", "动作"] },
+          "key": { "type": "string", "enum": ["业务阶段", "创作阶段", "动作", "出自"] },
           "type": { "const": "str" },
           "value": { "type": "string", "minLength": 1 }
         }

+ 1 - 1
创作知识提取-skill/tools/lint-payload.py

@@ -12,7 +12,7 @@ import sys
 from pathlib import Path
 
 SCOPE_TYPES = {"substance", "form", "feeling", "effect", "intent"}
-EXT_KEYS = {"业务阶段", "创作阶段", "动作"}
+EXT_KEYS = {"业务阶段", "创作阶段", "动作", "出自"}
 业务阶段 = {"灵感", "选题", "脚本"}
 创作阶段 = {"定向", "构思", "结构", "成文", "打磨"}