📦 Narrative TopologyExtract — 叙事拓扑提取

v1.0.0

擅长从长篇叙事、架构或复杂讨论中抽取语义关系,并以RDF三元组形式建模,随后生成邻接矩阵重构信息结构。

0· 8·0 当前·0 累计
by @turinfohlen (TurinFohlen)
下载技能包
最后更新
2026/4/20
0
安全扫描
VirusTotal
无害
查看报告
OpenClaw
安全
high confidence
该技能的代码和说明与其声明目的(提取单行 RDF 风格三元组并生成邻接矩阵)一致;无网络调用、秘密访问或异常安装,但实现存在几个可解释的小限制,需留意。
评估建议
该技能如其所述:一个轻量级 Python 扫描器,查找单行 ‘<<{Subject, Predicate, Object}.’ 条目,并输出 subject→object 邻接矩阵。不访问网络,不读取机密。运行前:1)在专用目录(或文档副本)中执行脚本,因为它会递归读取当前工作目录下的文件并处理所有匹配扩展名。2)注意代码忽略 predicate——若需感知 predicate 的图,需自行修改脚本。3)扫描器仅匹配以 ‘}.’ 结尾的单行三元组,多行或格式不同的三元组会被遗漏。若能接受这些限制,该技能逻辑清晰、风险低;否则请向作者请求 predicate 处理、多行支持或更严格的文件通配。...
详细分析 ▾
用途与能力
名称/描述(提取 RDF 风格三元组并生成邻接矩阵)与附带的 scanner.py 和 SKILL.md 保持一致。唯一实质性差异:scanner 明确忽略谓词字段(注释:“p is ignored (predicate)”)——该工具仅将三元组转换为主题→客体边。这对邻接矩阵是合理的,但意味着谓词语义被丢弃。
指令范围
SKILL.md 要求用户将 scanner.py 放入一个 markdown 目录并运行;该脚本递归读取当前工作目录下所有扩展名为 .txt、.def、.erl、.ex、.md 的文件,仅匹配以 '&lt;&lt;{' 开头、以 '}.' 结尾的单行三元组,多行三元组不会被提取。用例预期扫描整个 cwd,但可能误处理非目标文件(如源码文件)——如有需要请在专用文件夹中运行。
安装机制
无安装规范,无外部下载;这是一个仅含指令的技能,附带一个小型 Python 脚本。不安装任何包,除标准脚本执行外不向磁盘写入任何内容。
凭证需求
不请求或使用任何环境变量、凭据或外部配置文件路径。脚本仅执行本地文件系统读取和标准输出写入。
持久化与权限
技能不会请求持久/系统级常驻(always:false),也不会修改其他技能或系统设置。它不会持久化 token,也不会更改配置。
安全有层次,运行前请审查代码。

运行时依赖

无特殊依赖

版本

latestv1.0.02026/4/20

narrative-topology 技能初始发布。 - 引入 RDF 风格三元组表示,用于从叙事中提取语义。 - 提供 Python 扫描器,提取并扩展三元组,生成邻接矩阵。 - 支持并行主语/宾语,使用笛卡尔积表示。 - 输出压缩邻接矩阵及基础叙事图统计。 - 支持下游图分析(度、路径、环)以处理复杂讨论。 - 包含扩展输出至加权边及生成 Mermaid 图的说明。

无害

安装命令

点击复制
官方npx clawhub@latest install narrative-topology
镜像加速npx clawhub@latest install narrative-topology --registry https://cn.longxiaskill.com

技能文档

核心概念

问题: 长讨论(100+ 消息、架构辩论、叙事分析)失去结构,容易遗漏关键依赖、因果链或瓶颈。 解决方案: 在 markdown 中嵌入 RDF 风格三元组,用 Python 扫描,提取语义邻接矩阵,一眼看清结构。

---

三元组语法

格式

`` <<{Subject, Predicate, Object}. `

示例

简单关系:
` <<{Claude, outputs, analysis}. <<{analysis, informs, decision}. `

并行主语(笛卡尔积): ` <<{[A, B, C], implements, feature}. ` 展开为: ` {A, implements, feature} {B, implements, feature} {C, implements, feature} `

并行宾语: ` <<{payment_system, affects, [latency, cost, security]}. `

两者并行: ` <<{[Claude, User], collaborated_on, [design, implementation]}. ` 全笛卡尔积:2×2 = 4 条边。

语法规则

  • <<{ 开始三元组
  • }.(点号)结束
  • 逗号分隔主语、谓语、宾语
  • 自动去除空白
  • [...] 表示列表;裸词为单例
  • 置于 markdown 行内,易 grep

为何选此格式

  • 类 RDF——语义网标准,易懂
  • 易 grep——grep '<<{' file.md 找出全部三元组
  • 无歧义——起止清晰,无嵌套
  • 原生 Markdown——不破坏渲染
  • 紧凑——一行一关系

---

示例:哈姆雷特

输入 markdown(节选): `markdown

Act I

<<{Claudius, murders, old_king}. <<{Claudius, usurps, Denmark_throne}. <<{Claudius, marries, Gertrude}.

Act II

<<{ghost, reveals, Hamlet}. <<{ghost, demands, revenge}. <<{Hamlet, feigns, madness}. <<{Hamlet, kills, Polonius}.

Consequences

<<{Polonius_death, causes, Ophelia_madness}. <<{Ophelia, drowns, river}.

Climax

<<{[Hamlet, Laertes], duel, each_other}. <<{[poison_sword, poison_wine], kills, [Hamlet, Laertes, Claudius, Gertrude]}. <<{Fortinbras, takes_over, Denmark}.
` 输出:邻接矩阵,展示 14 个节点及其因果/叙事依赖。

---

Python 扫描器 把 scanner.py 放入 markdown 目录,运行: `bash python scanner.py `

代码 `python #!/usr/bin/env python3 """ Narrative Topology Scanner Usage: python scanner.py 输出 x::n 压缩格式的邻接矩阵 """ import os import sys

def list_files_recursive(directory, extensions=('.txt', '.def', '.erl', '.ex', '.md')): for root, _, files in os.walk(directory): for f in files: if f.endswith(extensions): yield os.path.join(root, f)

def parse_list(s): s = s.strip() if s.startswith('[') and s.endswith(']'): inner = s[1:-1].strip() if not inner: return [] return [item.strip() for item in inner.split(',')] return [s]

def smart_split(content): parts, current, depth = [], [], 0 for ch in content: if ch == ',' and depth == 0: parts.append(''.join(current).strip()) current = [] else: if ch == '[': depth += 1 elif ch == ']': depth -= 1 current.append(ch) if current: parts.append(''.join(current).strip()) return parts if len(parts) == 3 else None

def process_line(line): line = line.strip() if not line.startswith('<<{'): return [] if not line.endswith('}.'): return [] content = line[3:-2] parts = smart_split(content) if not parts: return [] s, p, o = parts subjects = parse_list(s) objects = parse_list(o) edges = [] for subj in subjects: for obj in objects: edges.append((subj, obj)) return edges

def process_file(filepath): edges = [] try: with open(filepath, 'r', encoding='utf-8') as f: for line in f: edges.extend(process_line(line)) except Exception: pass ``

数据来源ClawHub ↗ · 中文优化:龙虾技能库