Token导航 LogoToken导航

Agent Skill · 研究检索

narrative-topology(叙事拓扑)

narrative-topology 用于查找、检索和筛选相关信息,适合在 OpenClaw 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

narrative-topology 是研究检索类 Agent Skill,可用宿主为 OpenClaw,通过ClawHub获取,权限为只读;许可证为 MIT-0,第三方扫描已通过,按安装量在研究检索类的 73,675 个 Skill 里排第 26,016。

总安装 3,648周安装 149GitHub Stars 1下载 1,168核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
MIT-0
版本
1.0.0

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:narrative-topology(叙事拓扑)
来源仓库:https://github.com/turinfohlen/narrative-topology
安装命令:
openclaw skills install narrative-topology
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 OpenClaw 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

ClawHubOpenClaw
openclaw skills install narrative-topology

这个 Skill 是做什么的

研究检索类 Skill 主要解决「找资料、核对事实、把来源整理清楚」的问题,通常会让助手先检索再总结。

narrative-topology 从长篇叙述中提取语义关系,生成 RDF 三元组与邻接矩阵。适用于复杂架构讨论、知识图谱构建或文本结构分析场景。通过 clawhub 安装后可辅助 Agent 进行信息组织与可视化呈现。使用时需注意输入文本长度与语义密度,避免低效提取。

适用宿主包括 OpenClaw,接入前应确认版本、权限和运行环境要求。

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 OpenClaw;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 openclaw skills install narrative-topology;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它标注为只读,先用只读任务试一次,确认行为符合预期再扩大使用范围。

常见问题

6 条

narrative-topology 怎么安装?

在终端执行 openclaw skills install narrative-topology。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

narrative-topology 支持哪些 AI 工具?

公开资料标注支持 OpenClaw。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

narrative-topology 需要什么权限?

权限级别是只读。该 Skill 主要提供规则、说明或参考内容,本身偏只读;真正读写文件、联网或执行命令仍取决于宿主 Agent 的任务。

narrative-topology 是免费的吗?

来源标注的许可证是 MIT-0。本站不代收任何费用,也不托管安装包;能否商用、要不要署名,以许可证原文为准。

narrative-topology 用的人多吗?

公开数据是累计安装 3,648 次,近一周安装 149 次,下载 1,168 次,GitHub 1 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

narrative-topology 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 专注 OpenClaw 一种宿主,触发方式和使用习惯不用来回切换。
  • 许可证明确为 MIT-0,商用和分发边界好判断。
  • 第三方扫描已通过,常见的高风险行为没有命中。
  • 标注为只读权限,试用阶段不容易误改本地文件。

先想清楚的地方

  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 OpenClaw,想直接扩展它能力的人。
  • 需要处理研究检索类任务、又不想每次都手写提示词的人。
  • 需要许可证清楚、并且有第三方扫描结果的团队项目。

不太适合

  • 需要厂商级技术支持和 SLA 的生产系统。

研究检索类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
find-skills

寻找技能 · Codex、Claude

31,199,81316,486操作浏览器MIT有提醒
self-improving-agent

自我改进 Agent · OpenClaw

16,464,0023,396接触敏感数据MIT-0通过
soultrace

灵魂追踪 · Codex、Claude

7,588,94412需要联网未明确有提醒
self-improving

自我完善 · OpenClaw

6,829,2841,046需要联网MIT-0通过
microsoft-foundry

微软代工厂 · Codex、Claude

6,614,144764调用外部服务未明确有提醒
narrative-topology

叙事拓扑 · 本页

3,6481只读MIT-0通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

name
narrative-topology
description
>

Narrative Topology

Core Concept

Problem: Long discussions (100+ messages, architectural debates, narrative analysis) lose structure. Easy to miss critical dependencies, causality chains, or bottlenecks.

Solution: Embed RDF-style triples in markdown. Scan with Python. Extract semantic adjacency matrix. See structure.


Triple Notation

Format


<<{Subject, Predicate, Object}.

Examples

Simple relations:


<<{Claude, outputs, analysis}.
<<{analysis, informs, decision}.

Parallel subjects (cartesian product):


<<{[A, B, C], implements, feature}.

Expands to:


{A, implements, feature}
{B, implements, feature}
{C, implements, feature}

Parallel objects:


<<{payment_system, affects, [latency, cost, security]}.

Expands to:


{payment_system, affects, latency}
{payment_system, affects, cost}
{payment_system, affects, security}

Both parallel:


<<{[Claude, User], collaborated_on, [design, implementation]}.

Full cartesian product: 2×2 = 4 edges.

Syntax Rules

  • <<{ starts the triple
  • }. (period-dot) terminates
  • Commas separate subject, predicate, object
  • Whitespace trimmed automatically
  • [...] denotes list; bare tokens are singletons
  • Lines in markdown, easily greppable

Why This Format

  1. RDF-like — Semantic web standard, well-understood
  2. Grep-friendly — grep '<<{' file.md finds all triples
  3. Unambiguous — Clear start/end, no nesting
  4. Markdown-native — Doesn't break rendering
  5. Compact — One line per relation

Example: Hamlet

Input markdown (partial):

## 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}.

Output: Adjacency matrix showing all 14 nodes and their causal/narrative dependencies.


Python Scanner

Place scanner.py in your markdown directory. Run:

python scanner.py

Code

#!/usr/bin/env python3
"""
Narrative Topology Scanner
Usage: python scanner.py
Outputs adjacency matrix compressed with x::n notation
"""

import os
import sys

def list_files_recursive(directory, extensions=('.txt', '.def', '.erl', '.ex', '.md')):
    """Yield all files with given extensions under directory."""
    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):
    """Parse a token that may be a singleton or a bracketed list."""
    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):
    """
    Split content by commas while respecting nested brackets.
    Returns list of three parts: subject, predicate, object.
    """
    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):
    """Extract triples from a single line."""
    line = line.strip()
    if not line.startswith('<<{'):
        return []
    if not line.endswith('}.'):
        return []
    # Extract content between <<{ and }.
    content = line[3:-2]
    parts = smart_split(content)
    if not parts:
        return []
    s, p, o = parts  # p is ignored (predicate)
    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):
    """Process a single file, returning list of (source, target) edges."""
    edges = []
    try:
        with open(filepath, 'r', encoding='utf-8') as f:
            for line in f:
                edges.extend(process_line(line))
    except Exception:
        pass
    return edges

def compress_row(row):
    """Convert list of ints to x::n compressed string."""
    if not row:
        return ''
    compressed = []
    current_val = row[0]
    count = 1
    for val in row[1:]:
        if val == current_val:
            count += 1
        else:
            compressed.append(f"{current_val}::{count}")
            current_val = val
            count = 1
    compressed.append(f"{current_val}::{count}")
    return ','.join(compressed)

def main():
    cwd = os.getcwd()
    edges = []
    for filepath in list_files_recursive(cwd):
        edges.extend(process_file(filepath))

    # Gather unique nodes
    nodes = set()
    for s, o in edges:
        nodes.add(s)
        nodes.add(o)
    nodes = sorted(nodes)
    n = len(nodes)

    # Build index map
    idx = {node: i for i, node in enumerate(nodes)}

    # Build adjacency matrix (list of lists)
    matrix = [[0] * n for _ in range(n)]
    for s, o in edges:
        i, j = idx[s], idx[o]
        matrix[i][j] = 1

    # Output
    print("Nodes: " + ", ".join(nodes))
    print()
    print("Adjacency Matrix (compressed x::n):")
    print("# x::n = n copies of value x")
    for row in matrix:
        print(compress_row(row))

    print()
    print("Stats:")
    print(f"Nodes: {n}")
    print(f"Edges: {len(edges)}")
    if n > 0:
        density = len(edges) / (n * n)
        print(f"Density: {density:.4f}")

if __name__ == "__main__":
    main()

Output

The scanner outputs an adjacency matrix compressed with x::n notation (n copies of value x):

Nodes: Claudius, Denmark_throne, Fortinbras, Gertrude, Hamlet, Laertes, Ophelia, Polonius, Polonius_death, ...

Adjacency Matrix (compressed x::n):
# x::n = n copies of value x
0::14
0::3,1::1,0::10
0::4,1::2,0::8
1::14
...

Stats:
Nodes: 14
Edges: 12
Density: 0.0612

Format rule: x::n means n consecutive occurrences of value x. Example: 0::2,1::3,0::1 expands to [0,0,1,1,1,0].

For AI analysis: The matrix rows = sources (in node list order), columns = targets. 1 = edge exists.


Interpreting the Matrix

Rows = Sources, Columns = Targets

Matrix M where M[i,j] = 1 means: Node_i → Node_j

Key Analyses

· In-degree (column sum): How many things cause this node? (Count 1s in each column) · Out-degree (row sum): How many things does this node cause? (Count 1s in each row) · Strongly connected components: Cycles (feedback loops, mutual causality) · Topological sort: Order events by causal dependency · Critical path: Chain with maximum bottleneck nodes


Extending the Scanner

Add Weighted Edges

Replace binary (0/1) with strength values:

# Instead of setting to 1, count occurrences
weight_matrix = [[0] * n for _ in range(n)]
for s, o in edges:
    i, j = idx[s], idx[o]
    weight_matrix[i][j] += 1

Output matrix has counts, not just binary.

Generate Mermaid Graph

Add to scanner:

print("graph LR")
for s, o in edges:
    print(f"  {s} --> {o}")

Pipe output to a .mmd file, render in claude.ai.

Generate GraphViz DOT

print("digraph {")
for s, o in edges:
    print(f'  "{s}" -> "{o}";')
print("}")

Render with dot, convert to PNG/SVG.


Use Cases

  1. Narrative Analysis

Extract plot dependency from novel/screenplay. · Identify critical turning points (high in-degree) · Find orphaned subplots (isolated nodes) · Spot circular dependencies (tragedy, irony)

  1. Architectural Discussions

Embed triples in design doc markdown:

   <<{microservice_A, calls, microservice_B}.
   <<{microservice_B, depends_on, database}.
   <<{database, shared_by, [service_C, service_D]}.

Scan → see service coupling graph → identify decoupling opportunities.

  1. Project Workflows

Task dependencies:

   <<{design_doc, blocks, implementation}.
   <<{implementation, requires, code_review}.
   <<{code_review, unblocks, deployment}.

Scan → topological sort → critical path analysis.

  1. Technical Debt Mapping
   <<{legacy_code, causes, technical_debt}.
   <<{technical_debt, blocks, new_feature}.
   <<{new_feature, required_by, [OKR_1, OKR_2]}.

Prioritize refactor based on downstream impact.


Integration with all-dialogue-to-markdown

Optional pairing:

  1. Claude writes analysis in markdown (using all-dialogue skill)
  2. You embed triples in the markdown as you read
  3. Run scanner on the output file → see structure
  4. Use matrix to:

· Ask follow-up questions · Spot gaps · Verify causality chains

Example workflow:

User: "Analyze scheduler design. Save as scheduler-analysis.md"
Claude: [saves full analysis to scheduler-analysis.md]

User: [reads md, embeds triples]
<<{async_dispatch, reduces, latency}.
<<{latency, affects, throughput}.

User: "Run scanner on scheduler-analysis.md"
Scanner: [adjacency matrix]

User: [examines matrix] "What about error propagation?"

No requirement to use all-dialogue — works standalone on any markdown.


Workflow

Standalone Use

  1. Write markdown with embedded triples
  2. Place scanner.py in same directory
  3. Run: python scanner.py
  4. Get compressed adjacency matrix
  5. Use for analysis or feed back to AI

With all-dialogue Pairing

  1. Ask Claude to save analysis to markdown (all-dialogue skill)
  2. Read markdown, mark critical relations with triples
  3. Run scanner
  4. Iterate: use matrix to ask more precise questions

Philosophy

· Why separate from all-dialogue? All-dialogue manages token flow (thinking + response → file). Narrative-topology manages semantic extraction (relations → matrix). Independent concerns. Both can upgrade separately. Narrative-topology applies to any markdown, not just Claude output. · Why triples instead of prose summaries? Prose is lossy. Easy to miss connections. Triples are canonical, computable, greppable. Matrix enables quantitative analysis (paths, cycles, centrality). Scales: 50 triples → clear structure. 500 triples → still manageable. · Why Python? Ubiquitous, no extra dependencies. Single file, runs anywhere. Clear, readable, and easily extensible.


Summary

Narrative Topology extracts relational structure from dense text.

· Input: Markdown with <<{S, P, O}. triples · Processing: Python scanner parses + expands cartesian products · Output: Adjacency matrix compressed with x::n notation (low token cost, AI‑friendly) · Power: See causal chains, bottlenecks, cycles in long discussions · Scope: Works standalone. Pairs naturally with all-dialogue.

Use it to maintain signal in long, complex narratives.

平台分布

OpenClaw

77.22%
按下载量换算902

安全审计

VirusTotal

通过

ClawScan

通过

Static analysis

通过

权限和风险

只读

该 Skill 主要提供规则、说明或参考内容,本身偏只读;真正读写文件、联网或执行命令仍取决于宿主 Agent 的任务。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills