elksmmx 2 часов назад
Родитель
Сommit
cbe63e7e91

+ 5 - 4
examples/process_pipeline/prompts/apply_to_grounding.prompt

@@ -29,10 +29,11 @@
 - 只选择你有信心认为与 apply_to_draft 和 capability.body 直接相关的节点;一般每侧不超过 3 项。
 - 不确定时选较粗分类;如果仍然没有信心或 body 中没有直接证据,可以置空数组,不要编造。
 - rationale 用一句话说明为什么该 draft/body 证据落在该节点。
-- 每个 apply_to 条目和 suggest_apply_to 条目都必须包含 body_excerpt 和 body_excerpt_note 字段;这两个字段可以为空字符串。
+- 每个 apply_to 条目和 suggest_apply_to 条目都必须包含 body_excerpt、body_excerpt_note、body_excerpt_type 字段;这三个字段可以为空字符串。
 - 如果填写 body_excerpt,它必须逐字摘自输入 capability.body 的连续原文片段,不允许改写、概括、拼接、补词或翻译。
 - body_excerpt_note 是把原文片段改写成语义完整、能让人看明白的句子:保留 body_excerpt 的核心语义,补足省略的主语/宾语/动作对象,使人不看上下文也能理解这段做法;不是 rationale,也不要解释为什么匹配该节点。
-- 如果 body_excerpt 为空,body_excerpt_note 必须也为空;不允许只填写 body_excerpt_note。
+- body_excerpt_type 表示 body_excerpt 的内容类型,使用简短英文或中文标签,如 prompt、parameter、tool、image、workflow、setting、caption。
+- 如果 body_excerpt 为空,body_excerpt_note 和 body_excerpt_type 必须也为空;不允许只填写 note 或 type。
 
 # suggest_apply_to 规则
 
@@ -68,10 +69,10 @@ suggest_apply_to 用来指出:当前候选路径或已有内容树无法很好
 - 输入中的 body 只用于抽取 body_excerpt 证据,输出中不要回显完整 body。
 
 每个 apply_to 条目格式:
-`{ "category_id": 123, "category_path": "...", "element": null, "rationale": "...", "body_excerpt": "可为空;非空时逐字来自 body 的连续片段", "body_excerpt_note": "可为空;把原文片段改写成语义完整、能让人看明白的句子" }`
+`{ "category_id": 123, "category_path": "...", "element": null, "rationale": "...", "body_excerpt": "可为空;非空时逐字来自 body 的连续片段", "body_excerpt_note": "可为空;把原文片段改写成语义完整、能让人看明白的句子", "body_excerpt_type": "可为空;如 prompt" }`
 
 每个 suggest_apply_to 条目格式:
-`{ "source_type": "实质", "path": "...", "rationale": "...", "body_excerpt": "可为空;非空时逐字来自 body 的连续片段", "body_excerpt_note": "可为空;把原文片段改写成语义完整、能让人看明白的句子" }`
+`{ "source_type": "实质", "path": "...", "rationale": "...", "body_excerpt": "可为空;非空时逐字来自 body 的连续片段", "body_excerpt_note": "可为空;把原文片段改写成语义完整、能让人看明白的句子", "body_excerpt_type": "可为空;如 prompt" }`
 
 # 输出硬规则
 

+ 8 - 4
examples/process_pipeline/prompts/apply_to_grounding_capability.schema.json

@@ -12,7 +12,8 @@
         "category_path",
         "rationale",
         "body_excerpt",
-        "body_excerpt_note"
+        "body_excerpt_note",
+        "body_excerpt_type"
       ],
       "additionalProperties": false,
       "properties": {
@@ -21,7 +22,8 @@
         "element": { "type": ["string", "null"] },
         "rationale": { "type": "string", "minLength": 1 },
         "body_excerpt": { "type": "string" },
-        "body_excerpt_note": { "type": "string" }
+        "body_excerpt_note": { "type": "string" },
+        "body_excerpt_type": { "type": "string" }
       }
     },
     "suggest_apply_to_item": {
@@ -31,7 +33,8 @@
         "path",
         "rationale",
         "body_excerpt",
-        "body_excerpt_note"
+        "body_excerpt_note",
+        "body_excerpt_type"
       ],
       "additionalProperties": false,
       "properties": {
@@ -39,7 +42,8 @@
         "path": { "type": "string", "minLength": 1 },
         "rationale": { "type": "string", "minLength": 1 },
         "body_excerpt": { "type": "string" },
-        "body_excerpt_note": { "type": "string" }
+        "body_excerpt_note": { "type": "string" },
+        "body_excerpt_type": { "type": "string" }
       }
     }
   },

+ 1 - 1
examples/process_pipeline/prompts/extract_workflow.prompt

@@ -44,7 +44,7 @@
 - capability_id:字符串,见上方规则
 - action:{ description, reasoning },见下方 action 字段规则
 - inputs / outputs:结构化接口,见下方规则
-- body:该原子操作在原帖中的描述(可能是对应 step 内容里的子片段);未提及则为 null
+- body:该原子操作在原帖中的描述(可能是对应 step 内容里的子片段);该描述需尽可能细致,做到应有尽有,把每一个细节都记录下来,包括但不限于具体的prompt。未提及则为 null
 - effects:该原子操作产生的可观测效果,数组,每项为结构体(见下方 effects 字段规则)
 - control_target:该操作控制的对象,字符串数组,如 ["人物姿态", "背景风格"];未提及则为 []
 - artifact_type:该操作产出的工件类型,如 "正向提示词"、"蒙版"、"参考图";未提及则为 null

+ 112 - 28
examples/process_pipeline/prompts/extract_workflow.schema.json

@@ -2,12 +2,20 @@
   "$schema": "http://json-schema.org/draft-07/schema#",
   "title": "extract_workflow_output_v7",
   "type": "object",
-  "required": ["skip", "skip_reason", "workflow_groups"],
+  "required": [
+    "skip",
+    "skip_reason",
+    "workflow_groups"
+  ],
   "additionalProperties": false,
   "definitions": {
     "step": {
       "type": "object",
-      "required": ["step_id", "order", "phase"],
+      "required": [
+        "step_id",
+        "order",
+        "phase"
+      ],
       "additionalProperties": false,
       "properties": {
         "step_id": {
@@ -20,13 +28,21 @@
         },
         "phase": {
           "type": "string",
-          "enum": ["非制作", "预处理", "生成", "编辑"]
+          "enum": [
+            "非制作",
+            "预处理",
+            "生成",
+            "编辑"
+          ]
         }
       }
     },
     "workflow": {
       "type": "object",
-      "required": ["workflow_id", "steps"],
+      "required": [
+        "workflow_id",
+        "steps"
+      ],
       "additionalProperties": false,
       "properties": {
         "workflow_id": {
@@ -36,18 +52,33 @@
         "steps": {
           "type": "array",
           "minItems": 1,
-          "items": { "$ref": "#/definitions/step" }
+          "items": {
+            "$ref": "#/definitions/step"
+          }
         }
       }
     },
     "io_item": {
       "type": "object",
-      "required": ["modality", "description", "relation"],
+      "required": [
+        "modality",
+        "description",
+        "relation"
+      ],
       "additionalProperties": false,
       "properties": {
         "modality": {
           "type": "string",
-          "enum": ["文本", "图片", "视频", "音频", "特征点", "参数", "模型", "向量"]
+          "enum": [
+            "文本",
+            "图片",
+            "视频",
+            "音频",
+            "特征点",
+            "参数",
+            "模型",
+            "向量"
+          ]
         },
         "description": {
           "type": "string",
@@ -61,7 +92,12 @@
     },
     "effect": {
       "type": "object",
-      "required": ["statement", "criteria", "judge_method", "negative_examples"],
+      "required": [
+        "statement",
+        "criteria",
+        "judge_method",
+        "negative_examples"
+      ],
       "additionalProperties": false,
       "properties": {
         "statement": {
@@ -74,7 +110,12 @@
         },
         "judge_method": {
           "type": "string",
-          "enum": ["llm", "vlm", "rule", "human"]
+          "enum": [
+            "llm",
+            "vlm",
+            "rule",
+            "human"
+          ]
         },
         "negative_examples": {
           "type": "array",
@@ -88,25 +129,37 @@
     },
     "apply_to_draft": {
       "type": "object",
-      "required": ["实质", "形式"],
+      "required": [
+        "实质",
+        "形式"
+      ],
       "additionalProperties": false,
       "properties": {
         "实质": {
           "type": "array",
-          "items": { "type": "string" }
+          "items": {
+            "type": "string"
+          }
         },
         "形式": {
           "type": "array",
-          "items": { "type": "string" }
+          "items": {
+            "type": "string"
+          }
         }
       }
     },
     "workflow_step_ref": {
       "anyOf": [
-        { "type": "null" },
+        {
+          "type": "null"
+        },
         {
           "type": "object",
-          "required": ["workflow_id", "step_id"],
+          "required": [
+            "workflow_id",
+            "step_id"
+          ],
           "additionalProperties": false,
           "properties": {
             "workflow_id": {
@@ -145,7 +198,10 @@
         },
         "action": {
           "type": "object",
-          "required": ["description", "reasoning"],
+          "required": [
+            "description",
+            "reasoning"
+          ],
           "additionalProperties": false,
           "properties": {
             "description": {
@@ -160,19 +216,28 @@
         },
         "inputs": {
           "type": "array",
-          "items": { "$ref": "#/definitions/io_item" }
+          "items": {
+            "$ref": "#/definitions/io_item"
+          }
         },
         "outputs": {
           "type": "array",
-          "items": { "$ref": "#/definitions/io_item" }
+          "items": {
+            "$ref": "#/definitions/io_item"
+          }
         },
         "body": {
-          "type": ["string", "null"]
+          "type": [
+            "string",
+            "null"
+          ]
         },
         "effects": {
           "type": "array",
           "minItems": 1,
-          "items": { "$ref": "#/definitions/effect" }
+          "items": {
+            "$ref": "#/definitions/effect"
+          }
         },
         "control_target": {
           "type": "array",
@@ -182,14 +247,23 @@
           }
         },
         "artifact_type": {
-          "type": ["string", "null"]
+          "type": [
+            "string",
+            "null"
+          ]
         },
         "tools": {
           "type": "array",
-          "items": { "type": "string" }
+          "items": {
+            "type": "string"
+          }
+        },
+        "apply_to_draft": {
+          "$ref": "#/definitions/apply_to_draft"
+        },
+        "workflow_step_ref": {
+          "$ref": "#/definitions/workflow_step_ref"
         },
-        "apply_to_draft": { "$ref": "#/definitions/apply_to_draft" },
-        "workflow_step_ref": { "$ref": "#/definitions/workflow_step_ref" },
         "is_alternative_to": {
           "type": "array",
           "items": {
@@ -201,18 +275,26 @@
     },
     "workflow_group": {
       "type": "object",
-      "required": ["workflow_id", "workflow", "capability"],
+      "required": [
+        "workflow_id",
+        "workflow",
+        "capability"
+      ],
       "additionalProperties": false,
       "properties": {
         "workflow_id": {
           "type": "string",
           "pattern": "^w[0-9]+$"
         },
-        "workflow": { "$ref": "#/definitions/workflow" },
+        "workflow": {
+          "$ref": "#/definitions/workflow"
+        },
         "capability": {
           "type": "array",
           "minItems": 1,
-          "items": { "$ref": "#/definitions/capability" }
+          "items": {
+            "$ref": "#/definitions/capability"
+          }
         }
       }
     }
@@ -226,7 +308,9 @@
     },
     "workflow_groups": {
       "type": "array",
-      "items": { "$ref": "#/definitions/workflow_group" }
+      "items": {
+        "$ref": "#/definitions/workflow_group"
+      }
     }
   }
-}
+}

+ 3 - 2
examples/process_pipeline/script/apply_to_grounding.py

@@ -218,9 +218,10 @@ def body_excerpts_are_verbatim(apply_to: Any, suggest_apply_to: Any, body: str)
             return False
         excerpt = item.get("body_excerpt")
         note = item.get("body_excerpt_note")
-        if not isinstance(excerpt, str) or not isinstance(note, str):
+        excerpt_type = item.get("body_excerpt_type")
+        if not isinstance(excerpt, str) or not isinstance(note, str) or not isinstance(excerpt_type, str):
             return False
-        if not excerpt.strip() and note.strip():
+        if not excerpt.strip() and (note.strip() or excerpt_type.strip()):
             return False
         if excerpt.strip() and excerpt.strip() not in body:
             return False

+ 5 - 3
examples/process_pipeline/ui/app.js

@@ -2625,7 +2625,7 @@ window.renderStructuredData = function (items, type, parentItem = null) {
                 if (
                     typeof pathObj !== 'object'
                     || pathObj === null
-                    || !(pathObj.rationale || pathObj.body_excerpt || pathObj.body_excerpt_note || pathObj.category_id)
+                    || !(pathObj.rationale || pathObj.body_excerpt || pathObj.body_excerpt_note || pathObj.body_excerpt_type || pathObj.category_id)
                 ) {
                     return '';
                 }
@@ -2635,18 +2635,20 @@ window.renderStructuredData = function (items, type, parentItem = null) {
                         ${pathObj.rationale ? `<span class="tooltip-rationale">${escapeApplyToText(pathObj.rationale)}</span>` : ''}
                         ${pathObj.body_excerpt ? `<span class="tooltip-body-excerpt">${escapeApplyToText(pathObj.body_excerpt)}</span>` : ''}
                         ${pathObj.body_excerpt_note ? `<span class="tooltip-body-note">${escapeApplyToText(pathObj.body_excerpt_note)}</span>` : ''}
+                        ${pathObj.body_excerpt_type ? `<span class="tooltip-body-note">type: ${escapeApplyToText(pathObj.body_excerpt_type)}</span>` : ''}
                     </div>
                 `;
             };
             const renderEvidence = (pathObj) => {
                 if (typeof pathObj !== 'object' || pathObj === null) return '';
-                if (!('body_excerpt' in pathObj) && !('body_excerpt_note' in pathObj)) return '';
+                if (!('body_excerpt' in pathObj) && !('body_excerpt_note' in pathObj) && !('body_excerpt_type' in pathObj)) return '';
                 const excerpt = pathObj.body_excerpt || '';
                 const note = pathObj.body_excerpt_note || '';
+                const excerptType = pathObj.body_excerpt_type || '';
                 const excerptKey = excerpt ? makeExcerptKey(excerpt) : '';
                 return `<div class="apply-to-evidence">
                     <div class="apply-to-evidence-row">
-                        <span class="apply-to-evidence-label">关联做法</span>
+                        <span class="apply-to-evidence-label">关联做法 <span class="apply-to-evidence-type ${excerptType ? '' : 'empty'}">${excerptType ? escapeApplyToText(excerptType) : 'type: 空'}</span></span>
                         <span class="apply-to-evidence-value apply-to-evidence-note ${note ? '' : 'empty'}" ${excerptKey ? `data-excerpt-key="${excerptKey}"` : ''}>${note ? escapeApplyToText(note) : '空'}</span>
                     </div>
                 </div>`;

+ 2 - 2
examples/process_pipeline/ui/scratchpad.js

@@ -37,9 +37,9 @@ function renderStructuredData(items, type) {
                 const leaf = parts.pop();
                 const prefix = parts.length > 0 ? parts.join('/') + '/' : '';
                 const leafStyle = highlight ? 'background:#eff6ff; color:#2563eb; border:1px solid #bfdbfe;' : '';
-                const evidence = typeof path === 'object' && path !== null && ('body_excerpt' in path || 'body_excerpt_note' in path)
+                const evidence = typeof path === 'object' && path !== null && ('body_excerpt' in path || 'body_excerpt_note' in path || 'body_excerpt_type' in path)
                     ? `<div style="display:flex; flex-direction:column; gap:2px; font-size:0.78rem; color:#64748b; margin-top:4px;">
-                        <div style="display:flex; flex-direction:column; gap:2px;"><strong style="color:#94a3b8;">关联做法</strong><span>${path.body_excerpt_note ? String(path.body_excerpt_note).replace(/</g, '&lt;').replace(/>/g, '&gt;') : '<span style="color:#cbd5e1;font-style:italic;">空</span>'}</span></div>
+                        <div style="display:flex; flex-direction:column; gap:2px;"><strong style="color:#94a3b8;">关联做法 <span style="font-family:monospace; color:#64748b; border:1px solid #cbd5e1; border-radius:999px; padding:0 5px;">${path.body_excerpt_type ? String(path.body_excerpt_type).replace(/</g, '&lt;').replace(/>/g, '&gt;') : 'type: 空'}</span></strong><span>${path.body_excerpt_note ? String(path.body_excerpt_note).replace(/</g, '&lt;').replace(/>/g, '&gt;') : '<span style="color:#cbd5e1;font-style:italic;">空</span>'}</span></div>
                     </div>`
                     : '';
                 return `<span style="display:inline-flex; flex-direction:column; gap:4px;">

+ 17 - 0
examples/process_pipeline/ui/style.css

@@ -1205,6 +1205,23 @@ body {
     font-weight: 600;
 }
 
+.apply-to-evidence-type {
+    display: inline-block;
+    margin-left: 4px;
+    padding: 0 5px;
+    border: 1px solid #cbd5e1;
+    border-radius: 999px;
+    color: #475569;
+    background: #f8fafc;
+    font-weight: 500;
+    font-family: monospace;
+}
+
+.apply-to-evidence-type.empty {
+    color: #cbd5e1;
+    border-color: #e2e8f0;
+}
+
 .apply-to-evidence-value {
     color: #475569;
     word-break: break-word;