Kaynağa Gözat

实质作用域原子化:拆到"有意义概念" + 连接词拆分守卫

- phase2-scope.md §3.2:拆到"独立有意义的概念"为止(修饰叠加拆、空壳词不单独成值、张力用单词命名,附正反例)
- decompose.py:_split_scope_items 对含 和/与/、/,// 的作用域值确定性拆分,接进 apply_scopes,兜底 LLM 漏拆

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
SamLee 3 hafta önce
ebeveyn
işleme
84f6bc174e

+ 18 - 1
scripts/decompose.py

@@ -12,6 +12,7 @@ from __future__ import annotations
 
 import json
 import os
+import re
 from pathlib import Path
 
 from creation_knowledge.config import Settings
@@ -327,6 +328,22 @@ def link_scope(linker: ScopeLinker, scope_type: str, value: str) -> dict:
             "top": [{"name": h["name"], "score": h["score"], "path": h.get("path", "")} for h in hits]}
 
 
+_SCOPE_CONN = re.compile(r"\s*[和与、,,//&]\s*")  # 作用域值确定性拆分:含连接词必拆成多原子
+
+
+def _split_scope_items(items: list) -> list:
+    """连接词拆分守卫:把"社会共识与个体真实矛盾"这种拆成多原子,平铺。LLM 漏拆时兜底。"""
+    out = []
+    for it in (items or []):
+        st, v = it.get("scope_type"), it.get("value")
+        if not (st and v):
+            continue
+        parts = [p.strip() for p in _SCOPE_CONN.split(v) if p.strip()]
+        for p in (parts if len(parts) > 1 else [v]):
+            out.append({"scope_type": st, "value": p})
+    return out
+
+
 def apply_scopes(knowledges: list[dict], scopes: list, linker: ScopeLinker) -> None:
     by_k = {k.get("id"): k for k in knowledges}
     for sc in scopes:
@@ -334,7 +351,7 @@ def apply_scopes(knowledges: list[dict], scopes: list, linker: ScopeLinker) -> N
         if not k:
             continue
         linked = [link_scope(linker, it["scope_type"], it["value"])
-                  for it in (sc.get("items") or []) if it.get("scope_type") and it.get("value")]
+                  for it in _split_scope_items(sc.get("items"))]
         if k.get("type") == "how" and sc.get("step_id"):
             for s in k.get("steps", []):
                 if s.get("id") == sc["step_id"]:

+ 5 - 1
创作知识提取-skill/extraction/phase2-scope.md

@@ -75,7 +75,11 @@
 ## 3. 值的格式与多值约束
 
 1. **词性按类**:实质/形式/感受 = 名词/形容词短语;**作用 = 动名词**(营造/设置/引导后缀保留,只砍前置裸动词);**意图 = 动词**。多为 2-4 字、上限约 6 字(专有名可略长,别写成长句否则定位不上)。
-2. **原子**:不许用"和/与/、/,"拼接多义。复合 → 拆成多个值。
+2. **原子化(拆到"独立有意义的概念"为止,平铺多值)**:
+   - **含连接词(和/与/、/,)必拆**(代码也会兜底拆)。例:`主使人物与对立人物`→`主使人物`+`对立人物`;`社会共识与个体真实矛盾`→`社会共识`+`个体真实`。
+   - **把捆在一起的几个独立概念拆开,但拆到"概念"为止、别再往下碎**。例:`爆款选题逻辑`→`爆款`+`选题逻辑`("选题逻辑"是个完整方法概念,**别再削成`选题`、也别丢掉`逻辑`**);`短视频创意策略`→`短视频`+`创意策略`。
+   - **底线·空壳词不单独成值**:`逻辑 / 信号 / 模型 / 策略 / 方式`这类单独拎出来是放之四海的空壳,**不单独成一个值**;但它们和题材组成的完整概念(`选题逻辑`、`爆款信号`)**是合法原子**——别为了去壳反而把概念拆没了。
+   - **张力/对照若本身就是要表达的实质**:用**单个不含连接词的词**命名(如 `虚实对照`、`知行落差`),别写成"虚拟与现实"这种连接式(会被拆开、丢掉那层关系)。
 3. **平铺多值、摊正交**(见核心原则):同一类的多个值必须是不同视角、同一视角内同一上位语义类型;近义/子面收敛回一个。
 4. **不跨类重复**:一个值只进它该进的那列。
 5. **去重**:同一组同一类不重复同义值。