360 Secure SkillHub
360 安全技能中心

Kb Keyword Graph

只读式知识库关键词图谱读取 Skill:从 2brain 后端、本地语料目录或 Elasticsearch 取得(或计算)三级关键词树,提供知识结构、交互式环形图、主题分布、关键词关系四类解读。引擎用 python3 标准库实现,结果以文本叙述、HTML 图和 stdout JSON 呈现。

ywc668
ywc668
热度 12.88
最近更新 2026-07-18 12:54:29
分类:知识依赖:代码执行 / 读写文件 / 第三方 API应用场景:研究 / 笔记整理 / 报告撰写

安装技能

复制下面的话术发给你的 Agent,它会通过 secure-skills 检索并安装该技能。

执行命令安装此 skill: npx secure-skills-cli add kb-keyword-graph
Metadata
name
kb-keyword-graph
description
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 distribution / main themes / how do these materials relate", or explicitly says keyword graph / knowledge graph / word cloud / 关键词图谱 / 知识结构 / 主题分布. It pulls the KB's three-level keyword tree and interprets it four ways: ① structure (knowledge outline) ② graph (progressive interactive ring chart) ③ topics (topic distribution) ④ relate (how two keywords relate in the tree). Covers even when the user doesn't say "graph" (e.g. "what's in this library"). Current backend: 2brain (locate a library by base_id). Read-only — it never ingests, builds, edits, or Q&A-chats a KB, and does not route to Feishu/Lark Wiki or cloud docs.
user-invocable
true
license
MIT
metadata
{"requires":{"bins":["python3"]},"env":["TWOBRAIN_GRAPH_KEY","TWOBRAIN_BASE_ID","TWOBRAIN_API_BASE"]}

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 <TWOBRAIN_API_BASE>/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.

Backend How it gets the tree Config
twobrain (default) 2brain native keyword_api — a ready-made tree token + base_id (see First use)
local computes the tree from a folder of .txt/.md docs (stdlib keyword extraction + co-occurrence hierarchy) — for AI Digest or any self-hosted corpus --corpus <dir> or config corpus_dir
elasticsearch ES 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 signal Task Subcommand Execution doc
"what's in this library / knowledge structure / what areas / how is it structured" Structure structure references/workflows.md
"keyword graph / knowledge graph / word cloud / draw me a graph" Graph graph --html <path> references/workflows.md
"what topics / topic distribution / which area has the most / what's the focus" Topics topics references/workflows.md
"how do X and Y relate / how are these two connected" Relate relate --a X --b Y references/workflows.md
login / 401 / connection failure / empty graph Troubleshoot — 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/<base_id>.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

File Responsibility
scripts/kw_graph.py Engine: backend dispatch + credential resolution + cache + four subcommands (structure/topics/graph/relate) + ring-HTML renderer
scripts/backends.py Pluggable 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.