Memory

Kb Keyword Graph

Try it

Keyword-graph reader for a knowledge base. Trigger when the user wants to understand a KB — "what's in it / what does it cover / knowledge structure / topic...

What it does

中文版见 references/SKILL.zh.md (Chinese version).

The skill document

KB Keyword Graph

中文版见 references/SKILL.zh.md (Chinese version).

Wrap a knowledge base's "keyword graph" capability into a stably-triggerable, read-only workflow. All four tasks share one three-level keyword tree (keywords_tree) pulled from the backend; the four subcommands are just different readings of the same data. Engine: scripts/kw_graph.py (python3 standard library only, no third-party deps). Current backend: 2brain (keyword_api).

First use (install-and-go)

# Option A: private config file (recommended — token stays out of env & artifacts)
mkdir -p ~/.config/2brain-keyword-map
cat > ~/.config/2brain-keyword-map/config.json <<'JSON'
{ "token": "2B-your-graph-API-key", "base_id": 700 }
JSON
chmod 700 ~/.config/2brain-keyword-map && chmod 600 ~/.config/2brain-keyword-map/config.json

# Option B: environment variables (temporary / CI)
export TWOBRAIN_GRAPH_KEY="2B-..."      # 2brain "keyword graph" API key (Bearer)
export TWOBRAIN_BASE_ID=700             # integer base_id of the target library (--base-id overrides)
# Course/test env: export TWOBRAIN_API_BASE="https://test.2brain.ai/api"

# Self-check
python3 scripts/kw_graph.py fetch --base-id 700

The graph API key is generated on the 2brain platform and differs from the upload/chat keys. The host must be able to reach TWOBRAIN_API_BASE (default https://test.2brain.ai/api).

Privacy & Data Flow (read-only · no personal data · no autonomy)

This is a read-only KB-interpretation skill with a very narrow capability and data-flow surface:

① Capabilities: needs only python3 (stdlib, no third-party deps). Reads/writes only the cache dir ~/.local/state/2brain-keyword-map/ (stores the pulled keyword tree); the skill directory itself is read-only. No shell, no cron, no autonomous or scheduled behavior — it runs once, only when you ask.

② Data sent externally (minimal): it sends only one integer base_id to the fixed 2brain endpoint /kbase/keywords/keyword_api and receives that library's keyword tree. No personal data, document content, resume, or conversation is sent — base_id is just a library number. Beyond this single 2brain endpoint it contacts no third party (no scraper, no external LLM).

③ Credential discipline: the graph API key is read only from where you configure it — env var TWOBRAIN_GRAPH_KEY or the private file ~/.config/2brain-keyword-map/config.json (0600 recommended). It does not read host credentials outside the skill directory (never touches the OpenClaw auth store). The key is sent only as an Authorization: Bearer header to the fixed endpoint and is never written into HTML/JSON artifacts, logs, URLs, or the conversation (the engine guarantees zero-token artifacts — grep-verifiable).

④ Boundaries: no ingest, no KB creation, no edits/deletes, no Q&A; never acts on your behalf; the keywords/counts/percentages it reports come only from the API's real response — if empty it says "insufficient material", never fabricates.

Backends (pluggable)

"Getting the three-level keyword tree" is abstracted into a backend, selected by --backend / env KWGRAPH_BACKEND / config backend (default twobrain). The renderer and all four tasks operate on the normalized tree, so they behave identically across backends.

BackendHow it gets the treeConfig
twobrain (default)2brain native keyword_api — a ready-made treetoken + base_id (see First use)
localcomputes the tree from a folder of .txt/.md docs (stdlib keyword extraction + co-occurrence hierarchy) — for AI Digest or any self-hosted corpus--corpus or config corpus_dir
elasticsearchES significant_text aggregation over an index--es-url + --index or config es_url/index

Examples:

python3 scripts/kw_graph.py graph  --backend local --corpus ~/ai-digest/kb --html /tmp/g.html
python3 scripts/kw_graph.py topics --backend elasticsearch --es-url http://localhost:9200 --index market_news_rag

local / elasticsearch compute the tree themselves, so it reflects that corpus's own keyword co-occurrence — not identical to 2brain's engine, but the same four readings apply. Trees are cached by config fingerprint under ~/.local/state/2brain-keyword-map/graphs/.

Task routing (decide intent → read the matching execution doc → run the subcommand)

User intent signalTaskSubcommandExecution doc
"what's in this library / knowledge structure / what areas / how is it structured"Structurestructurereferences/workflows.md
"keyword graph / knowledge graph / word cloud / draw me a graph"Graphgraph --html references/workflows.md
"what topics / topic distribution / which area has the most / what's the focus"Topicstopicsreferences/workflows.md
"how do X and Y relate / how are these two connected"Relaterelate --a X --b Yreferences/workflows.md
login / 401 / connection failure / empty graphTroubleshoot—references/workflows.md

When intent is vague (e.g. just "take a look at this library"): default to structure, lay out the level-1 topics, then ask which area to go deeper on. Restate the task and target library to the user before executing.

Common constraints (all four tasks must follow)

Locating the KB — never hard-code base_id:

  1. User gave an integer base_id → use it (--base-id).
  2. User gave only a library name → the current backend works by base_id; if you don't know the id, ask the user for it (don't guess a number and probe).
  3. User gave nothing → use the default base_id from config, and note in the output which library was used.

Credential discipline (hard rule):

  • The token is sent only as an Authorization: Bearer header to the fixed 2brain endpoint;
  • never print the token to the conversation, write it into HTML/JSON artifacts, logs, or URL query;
  • the engine guarantees artifacts contain no token; don't repeat the key when relaying results.

Output discipline:

  • Every number (node counts, count, percentage, weight) must come from kw_graph.py stdout — never from memory or imagination.
  • The graph shows sibling-share percentages only (a node's count share among its direct siblings), not raw count; each sibling group sums to 100%. This is not a whole-KB absolute share.
  • Empty or near-empty graph/structure → say "this library has too little material to graph", don't improvise content.
  • relate is based only on co-occurrence at tree levels; state explicitly it does not imply causation, semantic equivalence, or document-level provenance.

Read-only boundaries (this skill does NOT):

  • ingest, scrape, create, delete, or edit a KB;
  • do 2brain Q&A (chat) — that's a separate capability;
  • route to Feishu/Lark Wiki / cloud docs / local files — "knowledge base" here means a 2brain platform library.

Cache & idempotency: a fetched tree is cached to ~/.local/state/2brain-keyword-map/graphs/.json. If the user asks about the same library again shortly after, the cache serves it; use --fresh to re-pull the latest (e.g. after new material was ingested).

Input/output example (graph)

Input (user says to the agent):

Show me the keyword graph of my job library (base 700)

Run:

python3 scripts/kw_graph.py graph --base-id 700 --html /tmp/kw-700.html

Engine stdout (relay from this; don't paste raw JSON at the user):

{"ok": true, "task": "graph", "base_id": 700, "file_count": 256,
 "levels": {"l1": 10, "l2": 21, "l3": 45},
 "metric": "sibling_count_percentage", "html": "/tmp/kw-700.html"}

What you tell the user (template):

The keyword graph of library 700 (256 documents) is ready: 10 level-1 topics, 21 level-2, 45 level-3. The heaviest level-1 topics are Research and Technical. The chart is at /tmp/kw-700.html; click a level-1 topic to expand level-2/3 in the same view. Percentages are sibling-share, not whole-KB share.

Script inventory

FileResponsibility
scripts/kw_graph.pyEngine: backend dispatch + credential resolution + cache + four subcommands (structure/topics/graph/relate) + ring-HTML renderer
scripts/backends.pyPluggable KB backends: local (compute tree from a doc folder) + elasticsearch (significant_text); the twobrain path lives in kw_graph.py

Boundaries (restated)

  • Read-only 2brain keyword graph; no writes, no Q&A, no KB creation.
  • Numbers come only from engine output; never fabricate keywords or relations.
  • The token never appears in any artifact or conversation.

Related skills

Generate and edit Draw.io, Mermaid, and Excalidraw diagrams from natural language using a structured JSON spec.

by nssa.io1.0k installs47 stars

Stores durable facts in a categorized, plain-markdown vault on disk, alongside your agent's built-in memory.

by Iván559 installs18 stars

Find why your productivity system keeps failing, then apply the smallest fix — capacity math, bottleneck routing, durable local notes.

by Iván855 installs69 stars

Join a video meeting as an AI bot with voice, avatar, and screenshare across four operating modes.

by johnpatternai22 installs8 stars

Fetch raw ad creative, app, ranking, and revenue data from AdMapix as structured JSON.

by fly0pants4.3k installs296 stars

More from ywc668

Browse all skills

Autonomous job-market watcher for OpenClaw. On a cron schedule it monitors the career pages of companies the user has EXPLICITLY configured, judges each posting against the user's own job profile (visa / seniority / red lines) with an LLM, pushes strong matches, digests the rest daily, and archives postings into a knowledge base; it also tracks the user's application status and answers questions about their own watched jobs. PRIVACY & CAPABILITIES (see the Privacy & Data Flow section): this skill collects and stores a personal job-seeking profile (resume text, visa needs, seniority, red lines); sends watched URLs and job-description text to third-party services (Firecrawl / Jina scrapers, an OpenAI-compatible LLM endpoint, and a 2brain knowledge base); reads host OpenClaw / Telegram credentials only when the user opts in (JOBWATCH_ALLOW_HOST_CREDS=1); and registers a recurring cron job — every autonomous action happens only after an explicit onboarding consent step. Use ONLY when the u

by ywc6681 installs