llm-wiki — Personal knowledge base construction system
Turn fragmented information into a continuously accumulating, interlinked knowledge base. You only need to provide the materials; AI does all the organizing work.
What this skill does
llm-wiki helps you build a continuously growing personal knowledge base. It is not traditional note-taking software, but a wiki system for AI to maintain on your behalf:
- You provide materials (links, files, text), and AI extracts the core knowledge and organizes it into interlinked wiki pages
- The knowledge base becomes richer with each use, instead of starting over every time
- All content is local markdown files, viewable in Obsidian or any editor
Core philosophy
The problem with traditional approaches (RAG/chat logs): every time you ask a question, AI has to read the original files from scratch, with no accumulation. The value of a knowledge base lies in knowledge being compiled once and then continuously maintained, rather than re-derived every time.
Quick start
Telling the user these two steps is enough:
- Initialize: say "help me initialize a knowledge base"
- Add materials: give a link or file and say "help me digest this"
Script Directory
Scripts located in scripts/ subdirectory.
Path Resolution:
SKILL_DIR= this SKILL.md's directory- Script path =
${SKILL_DIR}/scripts/<script-name>
Dependency check
The core mainline (local files, plain text, operations on an existing knowledge base) does not require these extraction dependencies by default.
Only when the user provides a URL-type source and explicitly wants to automatically extract web page / X / WeChat Official Account / YouTube / Zhihu content should you check the following optional dependencies.
If missing, prompt the user to run:
bash ${SKILL_DIR}/install.sh --platform <当前平台> --with-optional-adapters
Optional dependency skills / tools:
baoyu-url-to-markdown— general web pages, X/Twitter, some Zhihu extractionwechat-article-to-markdown— WeChat Official Account extractionyoutube-transcript— YouTube subtitle extraction
Even if these dependencies are missing, the skill can still work (the user can directly provide local files, paste text, or switch to the manual entry point).
External tool status model
External tool failures are uniformly divided into not_installed / env_unavailable / runtime_failed / unsupported / empty_result five categories.
Everywhere that requires enumerating sources or reading source_label、raw_dir、adapter_name、fallback_hint , first read the source master table:
bash ${SKILL_DIR}/scripts/source-registry.sh list
When you need the definition of a single source, use:
bash ${SKILL_DIR}/scripts/source-registry.sh get <source_id>
For URL-type sources, first run:
bash ${SKILL_DIR}/scripts/adapter-state.sh check <source_id>
adapter-state.sh check returns 8 columns:
source_id source_label state state_label detail recovery_action install_hint fallback_hint
not_installed: prompt the user that it can be installed additionally, while allowing a switch to the manual entry pointenv_unavailable: explain the missing environmental conditions, while allowing a switch to the manual entry pointruntime_failed: explain that this extraction attempt failed, allow one retry, then switch to the manual entry pointunsupported: directly provide the manual entry point, do not attempt automatic extractionempty_result: explain that automatic extraction did not obtain valid content, ask the user to manually complete the text
After automatic extraction has actually been executed, then run:
bash ${SKILL_DIR}/scripts/adapter-state.sh classify-run <source_id> <exit_code> <output_path>
Use the returned detail、recovery_action、install_hint、fallback_hint Generate prompts. The core mainline does not get interrupted by skill failures.
Workflow Routing
Based on the user's intent, route to the corresponding workflow:
| User intent keywords | Workflow |
|---|---|
| "initialize knowledge base", "create new wiki", "create knowledge base" | → init |
| URL / file path / "add material", "ingest", "organize" / directly giving a link | → ingest |
| "batch ingest", "organize all of these" / given a folder path | → batch-ingest |
| "about XX", "query", "what is XX", "summarize" | → query |
| "tell me about XX", "deep analysis of XX", "review XX", "digest XX" | → digest |
| "compare X and Y", "compare X and Y", "organize the timeline", "arrange by time" | → digest (specified format) |
| "check knowledge base", "health check", "lint" | → lint |
| "knowledge base status", "what is there now", "how much material is there" | → status |
| "draw a knowledge graph", "look at the relationship graph", "graph", "knowledge base map" | → graph |
| "delete material", "remove", "delete source", "remove" | → delete |
| "crystallize", "crystallize", "record this into the knowledge base", "summarize this conversation" | → crystallize |
Important: If the user directly gives a URL or file but does not clearly say what to do, default to the ingest workflow. If the knowledge base does not yet exist, first automatically run init and then ingest.
General Pre-check
Except for init , other workflows by default first run this check:
- First check whether the current working directory contains
.wiki-schema.md- If it contains it → use the current directory as the knowledge base root path
- If it does not contain it → fall back to reading
~/.llm-wiki-path
- If neither exists:
ingest/batch-ingest→ first runinitquery/lint/status/digest/graph/delete→ prompt the user to initialize the knowledge base first
- Read the
.wiki-schema.mdunder the knowledge base root directory - Determine
.wiki-schema.mdfrom the "language" field ofWIKI_LANG语言:中文→WIKI_LANG=zh语言:English→WIKI_LANG=en- Field missing → default
WIKI_LANG=zh
Output Language Rules
All user-facing output and newly written wiki content are generated according to WIKI_LANG :
WIKI_LANG=zh→ use the Chinese examples belowWIKI_LANG=en→ keep the same structure, information density, and order as the Chinese examples, changing only to natural English wording- File paths, wiki links, and directory names keep the existing conventions and are not changed because of a language switch
Terminology mapping:
- 素材 → Source
- 实体 → Entity
- 主题 → Topic
- 摘要 → Summary
- 综合 → Synthesis
- 消化 → Ingest
- 对比 → Comparison
- 深度报告 → Deep Dive Report
- 知识图谱 → Knowledge Graph
Workflow 1: init (initialize knowledge base)
Pre-check (including multi-knowledge-base CWD check)
- First check whether the current working directory contains
.wiki-schema.md- If it contains it → the current directory is already a knowledge base; prompt the user that it already exists and ask whether to reinitialize
- If the current directory does not have it → read
~/.llm-wiki-pathfile- If it exists → inform the user that a knowledge base already exists (show the path), and ask whether they want to create a new one or switch to that one
- Neither exists → enter the initialization flow
Steps
-
Ask about the knowledge base topic (ask the user first):
- "What topic should your knowledge base be centered around? For example, 'AI Study Notes', 'Product Competitive Analysis', 'Reading Notes'"
- If the user has no idea, default to "My Knowledge Base"
-
Ask about the knowledge base language (ask the user first):
- "What language should the knowledge base content use? Chinese / English (default Chinese)"
- Options:
zh(Chinese) oren(English) - If the user does not specify, default to
zh - Record the choice as
WIKI_LANG(zhoren)
-
Ask about the save location (ask the user first):
- Default:
~/Documents/我的知识库/(zh) or~/Documents/my-wiki/(en) - The user can customize the path
- Default:
-
Run the initialization script:
bash ${SKILL_DIR}/scripts/init-wiki.sh "<路径>" "<主题>" -
Supplement the initialization result explanation:
init-wiki.shwill simultaneously generatepurpose.mdand.wiki-cache.jsonpurpose.mdand.wiki-schema.mdare stored at the same level, used to record research goals, key questions, and research scope- Remind the user to fill in the core goals and key questions first; this content is written in
purpose.md, and subsequent ingest will prioritize referring to the direction here
-
Write the language configuration and localize the seed files:
- Replace
.wiki-schema.mdin语言:{{LANGUAGE}}with:zh→语言:中文(seed files remain in Chinese, no additional processing needed)en→语言:English, and at the same time overwrite the following seed files with the English version:
- If
WIKI_LANG=en, read${SKILL_DIR}/templates/index-en-template.md、${SKILL_DIR}/templates/overview-en-template.md、${SKILL_DIR}/templates/log-en-template.md, replace{{DATE}}and{{TOPIC}}with actual values, and write them respectively toindex.md、wiki/overview.md、log.md
- Replace
-
Record the path to
~/.llm-wiki-path:echo "<路径>" > ~/.llm-wiki-path -
Output guidance (switch language according to
WIKI_LANG):Chinese (zh):
知识库已创建!路径:<路径> 接下来你可以: - 给我一个链接,我会自动提取并整理(网页、X/Twitter、公众号、知乎等) - 小红书内容请直接粘贴文本给我(暂不支持自动提取) - 给我一个本地文件路径(PDF、Markdown 等) - 直接粘贴文本内容 - 批量消化:给我一个文件夹路径 推荐:用 Obsidian 打开这个文件夹,可以实时看到知识库的构建效果。(The English version is generated according to the "Output Language Rules", with the same structure.)
Workflow 2: ingest (digest material)
This is the most core workflow. The user provides a piece of material, and the AI does all the organizing work.
Pre-check
Execute the General Pre-check (see definition above).
Privacy self-check prompt (must be executed the first time entering ingest)
Before starting to extract or analyze any content, the AI must first say the following sentence to the user, then wait for confirmation:
Before starting to analyze this material, please quickly confirm that it does not contain these sensitive contents:
- Mobile phone numbers (e.g., 138xxxxxxxx)
- ID card numbers (18 digits)
- API keys (
sk-...、AIzaSy...、OPENAI_API_KEY=、ANTHROPIC_API_KEY=、Bearer ...)- Plaintext passwords (
password=、passwd=)- Other personal information you do not want to enter the knowledge base
If the material contains any of the above, please first delete or desensitize it with a text editor before continuing. llm-wiki will not automatically filter these contents, and the processed content will enter your knowledge base.
If you confirm there is no such content, please reply
y, and to abort please replyn.
Process rules:
- User replies
y(or "OK", "continue", "none", etc. with clear affirmation) → continue executing subsequent steps - User replies
n(or "stop", "cancel", or another clear negation) → terminate this ingest, prompt the user to clean up and come back - Other unclear replies → ask again, at most twice; if neither is a clear y/n, terminate
- Bypass rule: if the user has already clearly said in the current conversation "there's no sensitive information in the material, just start",
or the user is in the
batch-ingestflow (has already confirmed once at the top level), the AI may skip this step
Why a self-check list instead of a script:
- Regexes have a high false-positive rate in unstructured text (chat logs, notes), missing real sensitive words and flagging harmless ordinary words
- Returning the judgment to the user is more reliable than letting a script decide
- More beginner-friendly, no inscrutable script errors
Material extraction routing
Automatically route to the best extraction method based on the material type:
External adapter pre-check:
- For URLs, first call
bash ${SKILL_DIR}/scripts/source-registry.sh match-url "<url>" - For local files, first call
bash ${SKILL_DIR}/scripts/source-registry.sh match-file "<path>" - For plain text pastes, directly call
bash ${SKILL_DIR}/scripts/source-registry.sh get plain_text source-registry.shreturns 10 columns:source_id、source_label、source_category、input_mode、match_rule、raw_dir、adapter_name、dependency_name、dependency_type、fallback_hint- Call
bash ${SKILL_DIR}/scripts/adapter-state.sh check <source_id> - From the 8-column result of
adapter-state.sh check, readstate、detail、recovery_action、install_hint、fallback_hint - If
state=not_installed/env_unavailable/unsupported→ do not call the external adapter, directly followdetail、recovery_action、install_hint、fallback_hintto tell the user the next step - Only when it returns
availabledo you continue with automatic extraction
URL-type material (always go through the source master table; do not hand-write a domain table):
Chrome note (only when
adapter_name=baoyu-url-to-markdown): adapter-state.sh check expresses "extractor available" and "whether a reusable 9222 session exists" separately. If check returnsavailable, call the external adapter normally; even if the detail says no 9222 was detected, continue executing. baoyu-url-to-markdown will handle Chrome startup itself, continue executing, do not wait for user confirmation. Only when you want to reuse the currently logged-in Chrome session do you need to manually enable 9222. If extraction still fails (usually because the page requires login state, such as X/Twitter, Zhihu, etc.), you may prompt the user to enable the debug port to reuse the logged-in session:open -na "Google Chrome" --args --remote-debugging-port=9222
- If
source_category=manual_only→ do not call the external adapter, directly usefallback_hint - If
adapter_name=wechat-article-to-markdown→ executewechat-article-to-markdown "<URL>" - If
adapter_name=youtube-transcript→ callyoutube-transcript - If
adapter_name=baoyu-url-to-markdown→ callbaoyu-url-to-markdown
Local files:
- Always go through
bash ${SKILL_DIR}/scripts/source-registry.sh match-file "<path>" - Read directly once matched, do not call the external adapter
Plain text paste:
- Always treat as
plain_text - Directly use the text provided by the user
Unified fallback rules:
- For automatic extraction results, always run
bash ${SKILL_DIR}/scripts/adapter-state.sh classify-run <source_id> <exit_code> <output_path> - From the 8-column result returned by
classify-run, readstate、detail、recovery_action、fallback_hint - If it returns
runtime_failed→ followdetail、recovery_action、fallback_hintto tell the user "this automatic extraction failed; you can retry once first; if it still fails, switch to the manual entry point" - If it returns
empty_result→ followdetail、recovery_action、fallback_hintTell the user: "Automatic extraction did not obtain valid body text. Please manually complete the text before continuing." - Other statuses also use the same returned result; do not hand-write a second set of fallback copy.
Content tiered processing
Automatically choose the processing level based on material length and information density:
Criteria:
- Material content > 1000 characters → Full processing
- Material content <= 1000 characters (short tweets, Xiaohongshu notes, etc.) → Simplified processing
Full processing workflow (long material > 1000 characters)
-
Extract material content: Obtain the material text according to the routing above.
-
Save the original material to
raw/the corresponding directory:- Save to the corresponding directory based on the material type (articles/, tweets/, wechat/, xiaohongshu/, zhihu/, etc.)
- File name format:
{日期}-{短标题}.md - If it is URL-type material, record the original URL in the file header.
Image detection and tracking: After saving the material, scan the content for image references (
![or<imgor.png/.jpg/.gif/.svgURL). If images are detected:- Tell the user: "The material contains {N} image references. Image links may become invalid. It is recommended to manually download them to
raw/assets/(Obsidian users can bind a shortcut in settings to download attachments with one click)." - In the frontmatter of the subsequent source page:
images: Record the number of detected image referencesimage_paths: If the user has already downloaded the images toraw/assets/, record the paths using the YAML block list format; if not yet downloaded, keep it as an empty array[]. Example:image_paths: - raw/assets/2026-01-15-fig1.png - raw/assets/2026-01-15-fig2.jpg
- Do not block the ingest workflow; only provide a reminder.
- After the user downloads the images later, they can manually update the source page's
image_paths, or have AI assist in completing it during the next lint.
-
Read context:
- Priority order:
purpose.md>.wiki-schema.md>index.md - If
purpose.mdexists, first read the core goals, key questions, and research scope in it. - Use
purpose.mdto guide the selection and weighting of subsequent entities, topics, and associations.
- Priority order:
-
Cache check:
- Before entering LLM processing, first run:
bash ${SKILL_DIR}/scripts/cache.sh check “<raw 文件路径>” - If it returns
HITorHIT(repaired)→ skip this LLM call, directly read the existing wiki page, and tell the user this is "no changes, directly reuse the existing result."HIT(repaired)indicates cache self-healing repair succeeded (the last update was skipped but the source page exists and source_path matches)
- If it returns
MISS:<reason>→ continue with the two-step workflow belowMISS:no_entry— First time processing this material (normal case)MISS:hash_changed— Material content has changed and needs reprocessingMISS:no_source— A cache record exists but the source page has been deletedMISS:repaired_needs_verify— A source page with the same name was found but source_path does not match; reprocessing is needed to confirm the association is correct
- Before entering LLM processing, first run:
-
Step 1: Structured analysis:
- Input: raw content +
purpose.md+ existing wiki structure (at least readindex.mdsummary) - Output: analysis result in JSON format, not persisted, only temporarily passed within the current ingest workflow
- The JSON must at least contain
entities、topics、connections confidenceis a required field; if missing, treat it as a format anomaly and trigger single-step fallback
{ "source_summary": "一句话概括", "entities": [{"name": "xxx", "type": "concept", "relevance": "high", "confidence": "EXTRACTED", "evidence": "原文摘录或推理依据"}], "topics": [{"name": "xxx", "importance": "high"}], "connections": [{"from": "A", "to": "B", "type": "因果", "confidence": "INFERRED", "evidence": "推理依据"}], "contradictions": [{"claim_a": "...", "claim_b": "...", "context": "..."}], "new_vs_existing": {"new_entities": [], "updates": []} }Confidence assignment rules (Claude must follow):
- EXTRACTED: The information appears directly in the original text and can be found literally. An excerpt from the original text should be provided in the
evidencefield (preferably ≤50 characters); if missing, the script will issue a WARN but will not block - INFERRED: The information is inferred from multiple places in the original text, and the original text does not directly state it. The basis for the inference should be explained in the
evidencefield; if missing, the script will issue a WARN but will not block - AMBIGUOUS: The wording in the original text is unclear, or there is ambiguity.
evidenceOptional - UNVERIFIED: The information comes from Claude's background knowledge, and there is no evidence in the original text.
evidenceOptional
After Step 1 is completed, validation must be performed:
- mkdir -p {wiki_root}/.wiki-tmp
- Write the Step 1 JSON to {wiki_root}/.wiki-tmp/step1-latest.json
- Call bash ${SKILL_DIR}/scripts/validate-step1.sh {wiki_root}/.wiki-tmp/step1-latest.json
- After validation is complete, delete {wiki_root}/.wiki-tmp/step1-latest.json
If the script returns non-0, automatically fall back to single-step ingest (do not perform Step 2).
- Input: raw content +
-
Step 2: Page generation:
- Input: original content +
purpose.md+ Step 1 analysis results + existing related wiki pages - Context loading rules: only read the existing pages listed in Step 1 under
new_vs_existing.updates; if a page exceeds 2000 characters, only read the frontmatter + the sections that need updating - Output: the content of all wiki pages that need to be created or updated
- Step 2 is responsible for completing the material summary, entity pages, topic pages, index, and log updates in the original process
- Input: original content +
-
Fault-tolerant fallback:
- If Step 1 is not valid JSON, or is missing required fields such as
entities、topics、confidence, automatically fall back to the original single-step process - When falling back, uniformly add the following to all content newly generated this time:
<!-- confidence: UNVERIFIED --> - At the same time, add a comment at the top of the page explaining that this processing was downgraded due to a formatting issue, to avoid a state where "some parts are annotated and some are not"
- If Step 1 is not valid JSON, or is missing required fields such as
-
Generate material summary page (
wiki/sources/{日期}-{短标题}.md):- Refer to the format of
templates/source-template.md- Keep thesources: []field in the frontmatter; if this ingest has a clear source, fill it in according to the actual raw/source reference - Include: basic information, core viewpoints, key concepts, associations with other materials, and excellent excerpts from the original text
- For relationships marked in Step 1 as
INFERREDorAMBIGUOUS, preserve the confidence level with HTML comments:<!-- confidence: INFERRED --> <!-- confidence: AMBIGUOUS --> - When writing to the source page, you must use
create-source-page.sh(automatically update the cache):# 先把页面内容写到临时文件 echo "<页面内容>" > /tmp/source-content.tmp # 调用脚本原子写入 + 缓存更新 bash ${SKILL_DIR}/scripts/create-source-page.sh "<raw 文件路径>" "wiki/sources/{日期}-{短标题}.md" /tmp/source-content.tmp - If the script returns
SUCCESS→ both the write and the cache have been updated - If the script returns
ERROR→ the write or cache failed; check the error message and retry
- Refer to the format of
-
Update or create entity pages (
wiki/entities/):- For each key concept, check whether a corresponding page already exists under
wiki/entities/- If it already exists → append the new information and update the "Viewpoints in Different Materials" section - If it does not exist → create a new entity page, refer to
templates/entity-template.md - Use
[[实体名]]syntax for bidirectional links
- For each key concept, check whether a corresponding page already exists under
-
Update or create topic pages (
wiki/topics/):
- Identify the main research topics involved in the material
- If a corresponding topic page already exists → update the material summary table and core viewpoints
- If it does not exist → create a new topic page, refer to
templates/topic-template.md
- Update index.md:
- Add a new entry under the corresponding category
- Update the overview statistics numbers
- Update log.md:
- log.md append format:
## {日期} ingest | {素材标题} - Record the list of newly added and updated pages
- Note: cache updates have already been automatically completed in Step 8 via
create-source-page.sh, so there is no need to callcache.sh update
again here.
- Show the results to the user (switch language according to
WIKI_LANG):
Chinese (zh):
已消化:{素材标题}
新增页面:
- {素材摘要页}
- {新实体页1}
- {新主题页1}
更新页面:
- {已有实体页2}(追加了新信息)
发现关联:
- 这篇素材和 [[已有素材]] 在 {某概念} 上有联系
别名建议:(仅当发现新的同义词关系时显示)
- 建议添加到别名词表:{术语A} = {术语B}
(The English version is generated according to the "Output Language Rules", with the same structure.)
Simplified Processing Flow (short material <= 1000 characters)
Applicable to short tweets, Xiaohongshu notes, brief comments, etc.
-
Save the raw material to the corresponding
raw/directory- Image detection and tracking: same as the full processing flow, scan image references and remind the user; record the count and paths in the source page
imagesand theimage_pathsfrontmatter field
- Image detection and tracking: same as the full processing flow, scan image references and remind the user; record the count and paths in the source page
-
Read context and check cache:
- Still prioritize reading
purpose.md - Still run
bash ${SKILL_DIR}/scripts/cache.sh check "<raw 文件路径>"first - If there is a cache hit (
HITorHIT(repaired)), directly reuse the existing result
- Still prioritize reading
-
Generate a simplified summary page (
wiki/sources/):- Write
sources: []into the frontmatter - Include only basic information and core viewpoints
- Do not write the "Original Highlights" section
- Also use
create-source-page.shwhen writing the source page (automatically updates the cache)
- Write
-
Extract 1-3 key concepts:
- If the corresponding entity page already exists -> append a one-sentence explanation
- If it does not exist -> mark it in the summary page with
[待创建: [[概念名]]]5. Update index.md and log.md (the cache has already been automatically updated bycreate-source-page.sh)
-
Skip: topic page creation/update, overview update
-
Show the simplified results to the user (switch language according to
WIKI_LANG):Chinese (zh):
已消化:{素材标题}(短内容,简化处理) 新增: - 素材摘要页 待完善: - [待创建: [[概念名]]](积累更多素材后整理)(The English version is generated according to the "Output Language Rules", with the same structure.)
Workflow 3: batch-ingest (batch digestion)
When the user gives a folder path, or says "organize all of these".
Steps
-
Confirm the knowledge base path:
- Execute the general pre-check (see the definition above), obtain the knowledge base root path and
WIKI_LANG
- Execute the general pre-check (see the definition above), obtain the knowledge base root path and
-
List all processable files:
- Supported formats:
.md,.txt,.pdf,.html - Ignore: hidden files,
.gitdirectories,node_modules, etc.
- Supported formats:
-
Show the file list and confirm the processing scope (switch language according to
WIKI_LANG):zh:
发现 {N} 个文件待处理: 1. file1.pdf 2. file2.md 3. file3.txt 预计需要 {N} 轮处理。是否开始?(The English version is generated according to the "Output Language Rules", with the same structure.)
-
Process one by one: execute the ingest workflow for each file
- For each file, first
cache check - Files with a cache hit are skipped directly and no longer enter LLM processing
- Only files with
MISScontinue to execute full or simplified processing
- For each file, first
-
Pause after every 5 files, show progress and ask whether to continue (switch language according to
WIKI_LANG):zh:
进度:5/{N} 已完成 本批处理结果: - 新增素材摘要:5 - 新增实体页:3 - 更新已有页面:7 继续处理剩余 {M} 个文件?(The English version is generated according to the "Output Language Rules", with the same structure.)
-
After everything is completed:
- Run a full update of index.md
- Output a summary report (switch language according to
WIKI_LANGSwitch language):
zh:
批量消化完成! 处理了 {N} 个文件: - 已跳过 N 个(无变化),处理 M 个(新增/更新) - 成功:{S} - 跳过(内容为空/格式不支持):{K} - 失败:{F} 新增页面:{total_new} 更新页面:{total_updated}(The English version is generated according to the "Output Language Rules," with the same structure.)
Workflow 4: query (query the knowledge base)
Steps
-
Confirm the knowledge base path:
- Execute the general pre-check (see the definition above) to obtain the knowledge base root path and
WIKI_LANG - If no knowledge base is available, prompt the user to initialize one first
- Execute the general pre-check (see the definition above) to obtain the knowledge base root path and
-
Read index.md to understand the overall knowledge base
-
Search related pages:
- Alias expansion: First read the "alias glossary" in
.wiki-schema.md; if the user's query keywords hit a certain alias group, include all synonyms in that group in the search (for example, when searching for "LLM," also search for "large language model" and "large model")- Expansion rule: expand only within the hit group, with no cross-group propagation (when A=B and B=C are two groups, searching A expands only the first group and does not merge the second group)
- Deduplication: the expanded keyword list is automatically deduplicated, ignoring empty items and whitespace-only items
- Locate related categories and entries in index.md (using all expanded keywords)
- Then use Grep in the
wiki/directory to search all keywords (original + alias expansions) - Sort by relevance: exact filename hit > index.md entry hit > number of keyword hits in the body text (when multiple words from the same alias group hit the same page, count it only once, to avoid artificially high scores for pages with dense aliases)
- Paragraph limit: after expansion, take at most 3 hit paragraphs per keyword, with a total of no more than 15 paragraphs
- Read the 3-5 most relevant pages
- Single-page length limit: if a page exceeds 2000 characters, read only the frontmatter + the first 500 characters + the Grep hit paragraphs (3 lines before and after each), to avoid long pages consuming too much context
- Alias expansion: First read the "alias glossary" in
-
Comprehensive answer:
- Answer the user's question in the corresponding language according to
WIKI_LANG- Indicate the information sources (cite wiki pages, using the[[页面名]]format) - If multiple materials have different viewpoints, list them separately and indicate their sources
- Answer the user's question in the corresponding language according to
-
Determine whether it is worth persisting:
- If the answer cites a comprehensive analysis of 3 or more sources, prompt the user: "Save this answer to the knowledge base?"
- When there are fewer than 3 sources, by default provide only an immediate answer and do not proactively suggest persistence
-
Duplicate detection:
- Before persisting, first search for pages on the same topic under
wiki/queries/- Match via frontmatter tags and title to determine whether a query page on the same topic already exists - If one already exists, prompt the user to choose "update the existing page" or "create a new page"
- If the user chooses to update the old page, add a
superseded-bymarker to the old page version
- Before persisting, first search for pages on the same topic under
-
Save the query page:
- Use
templates/query-template.mdto generate the page - Use
wiki/queries/{date}-{short-hash}.mdfor the save path, to avoid naming conflicts on the same topic - The frontmatter must include
type: queryandderived: true derived: trueto indicate that this is derivative content, not first-hand material
- Use
-
Self-reference protection:
- Query pages are treated as secondary sources in subsequent ingest analysis and are not used as the main knowledge source
- If subsequent pages reference information in a query page, handle the related relationships uniformly as
INFERRED- Ingest does not proactively scanwiki/queries/; only read the query page as supplementary material when the current question truly requires it
-
Update the index and log:
- After saving successfully, add a query entry to index.md
- Also append a query save record to log.md
Workflow 5: lint (health check)
Trigger timing
- The user proactively says "check the knowledge base"
- After each ingest, if the total number of materials is a multiple of 10, proactively suggest running lint
Pre-check
Perform the general pre-check (see definition above). If there is no available knowledge base, prompt the user to initialize first.
-
Determine the check scope:
- The 10 most recently updated pages (sorted by file modification time)
- 10 randomly sampled pages (to avoid missing problems in old pages)
- If the total number of pages <= 20, check all of them
-
Step 0: Call a script to do mechanical checks (must be done first, do not skip):
bash ${SKILL_DIR}/scripts/lint-runner.sh <wiki_root>The script reads once and then uniformly checks orphan pages, index, images, source information, and all wikilinks. Explicit paths and unique bare names are resolved according to the actual page path; pages with the same name will not be merged. Ambiguous links do not guess a target and are not counted in relationships, and all candidates are listed; "to be created" and true broken links are reported separately, and code examples will not be treated as links.
Ordinary checks only read and fully report data problems, with exit code
0; path, parameter, parsing, or read failures return1. When you need CI to block due to ambiguity, true broken links, or path conflicts, explicitly run:bash ${SKILL_DIR}/scripts/lint-runner.sh <wiki_root> --strictAfter strict mode completes the report, if there is
errorreturn2, and if there are only prompts such as "to be created" it still returns0. You can add at the end--jsonto get the same structured complete report. None of these checks will modify the knowledge base Markdown. -
Item-by-item checks (AI judgment type, which the script cannot do):
Contradictory information (read related pages and check whether there are statements that contradict each other):
- List the contradictions found
- Mark the source page of each contradiction
Missing cross-references (check whether pages on related topics should link to each other but do not):
- Suggested cross-references to add
Confidence report (count
EXTRACTED/INFERRED/AMBIGUOUS/UNVERIFIED):- Highlight
AMBIGUOUSentries, and remind the user to verify them first - Spot-check entries marked as EXTRACTED, and check whether the corresponding original text can be found in the source material
- If an EXTRACTED item is found that cannot be traced back to the original text, prompt the user to downgrade it to a lower confidence level or reorganize it
Supplementary suggestions: Based on the orphan page/broken link output of the Step 0 script, give repair suggestions (the script only lists problems, it does not give solutions)
- Orphan pages -> suggest from which related pages to add
[[链接]] - Broken links -> suggest for which concepts to create new pages, or rewrite the references to existing pages
-
Output report (switch language according to
WIKI_LANG, integrating the Step 0 script output + the Step 3 AI judgment results):zh:
知识库健康检查报告 检查范围:最近更新 10 页 + 随机抽查 10 页(共 {N} 页) 孤立页面(没有其他页面链接到它): - [[某页面]] → 建议从 [[相关页面]] 添加链接 断链(被链接但不存在): - [[某概念]] → 建议创建新页面 矛盾信息: - 关于"XX",[[页面A]] 说是 Y,但 [[页面B]] 说是 Z 缺失索引: - {文件名} 存在但未记录在 index.md 中 置信度报告: - EXTRACTED:{N} - INFERRED:{N} - AMBIGUOUS:{N} - UNVERIFIED:{N}(The English version is generated according to the "Output Language Rules", with the same structure.)
-
Ask the user: Which problems should be automatically fixed? (Ask in the corresponding language according to
WIKI_LANG)
Workflow 6: status (view status)
Pre-check
Perform the general pre-check (see definition above). If there is no available knowledge base, prompt the user to initialize first.
Steps
-
First run
bash ${SKILL_DIR}/scripts/source-registry.sh listRead the source master table -
Get the knowledge base path (according to the CWD check logic above)
-
Count:
- By the
source_labelandraw_dirin the source master table, count item by item the number ofraw/files - The number of pages under
wiki/entities/- The number of pages underwiki/topics/- The number of pages underwiki/sources/- The number of pages underwiki/comparisons/andwiki/synthesis/-purpose.md 是否存在
- By the
-
Read the last 5 records of
log.md5. Readindex.mdto get the topic overview -
Run
bash ${SKILL_DIR}/scripts/adapter-state.sh summary-humanto get the plugin status -
Run
node ${SKILL_DIR}/scripts/source-signal-coverage.js <wiki_root>to get the source signal coverage data, and read from thesummaryof the returned JSON:ok(already participating),missing_sources(missing sources),empty_sources(sources empty),invalid_sources(invalid format),not_applicable(currently not participating)
-
Output report (switch language according to
WIKI_LANG):zh:
知识库状态:{主题} 素材分布(按来源总表): - {source_label}:{N} - {source_label}:{N} ... Wiki 页面:{总数} 页 - 实体页:{N} - 主题页:{N} - 素材摘要:{N} - 对比分析:{N} - 综合分析:{N} 图谱来源信号覆盖: - 已参与:{ok} - 缺少 sources:{missing_sources} - sources 为空:{empty_sources} - 格式无效:{invalid_sources} - 当前不参与:{not_applicable} 研究方向: - purpose.md 是否存在:{是/否} 最近活动: - {日期} ingest | {素材标题} - {日期} ingest | {素材标题} ... 外挂状态: {summary-human 原文} 建议: - 你可能想深入了解 {某主题},已有 {N} 篇相关素材 - {某实体} 被 {N} 篇素材提到,值得整理成独立页面(The English version is generated according to the "Output Language Rules", with the same structure.)
For the plugin status, directly use the output of
bash ${SKILL_DIR}/scripts/adapter-state.sh summary-human; do not rewrite another source list yourself.
Workflow 7: digest (in-depth synthesis report)
Different from query: query is quick Q&A and does not generate new pages; digest is cross-material in-depth synthesis and generates a persistent report.
Trigger keywords
- Default in-depth report format:
"给我讲讲 XX"、"深度分析 XX"、"综述 XX"、"digest XX"、"全面总结一下 XX" - Comparison table format:
"对比一下 X 和 Y"、"比较 X 和 Y"、"X 和 Y 有什么区别" - Timeline format:
"整理一下时间线"、"按时间排列"、"时间顺序"
Pre-check
Execute the general pre-check (see the definition above). If there is no available knowledge base, prompt the user to initialize first.
-
Search related pages:
- Alias expansion: same as the query workflow, first read the "alias glossary" in
.wiki-schema.mdto expand synonyms (not passed across groups, automatically deduplicated) - Use Grep to search for all keywords (original + alias expansion) under
wiki/; if the same alias group hits the same page, count it only once - List the pages to be synthesized (so the user understands the report coverage)
- Alias expansion: same as the query workflow, first read the "alias glossary" in
-
Deeply read all related pages + choose the output format:
- Read all related wiki pages found (sources/, entities/, topics/)
- Single-page length limit: if a page exceeds 3000 characters, prioritize reading the frontmatter + core viewpoint section + paragraphs directly related to the topic, and skip lengthy quotation sections such as "original text highlights"
- Summarize the core viewpoints and source information of each page
- Decide the output format according to the trigger keywords:
- If the user says "comparison"/"compare" type → use the comparison table format (see template B below)
- If the user says "timeline"/"by time" type → use the timeline format (see template C below)
- Otherwise by default → use the in-depth report format (see template A below)
-
Generate a structured in-depth report, save it to
wiki/synthesis/{主题}-{格式}.md(switch language according toWIKI_LANG):File name rules: use
{主题}-深度报告.mdfor the default format,{主题}-对比.mdfor the comparison table, and{主题}-时间线.mdfor the timeline
Template A: In-depth report format (default)
zh:
# {主题} 深度报告 > 综合自 {N} 篇素材 | 生成日期:{日期} ## 背景概述 (简要说明这个主题的背景和重要性) ## 核心观点 (按重要性排列,每个观点标注来源) - 观点一(来源:[[素材A]]、[[素材B]]) - 观点二(来源:[[素材C]]) ## 不同视角对比 (如有多个素材观点不同,在此对比) | 维度 | 来源A的观点 | 来源B的观点 | |------|------------|------------| ## 知识脉络 (按时间或逻辑顺序梳理该主题的发展) ## 尚待解决的问题 (现有素材中尚未回答的问题,可作为下次搜集素材的方向) ## 相关页面 (列出所有综合来源的链接)(The English version is generated according to the "Output Language Rules", with the same structure.)
Template B: Comparison Table Format (trigger words: compare / comparison)
# {对比主题} 对比分析 > 对比 {N} 个对象 | 生成日期:{日期} ## 对比对象 - [[对象 A]] - [[对象 B]] - [[对象 C]](如有) ## 对比表 | 维度 | [[对象 A]] | [[对象 B]] | [[对象 C]] | |-----------|-----------|-----------|-----------| | 核心观点 | ... | ... | ... | | 适用场景 | ... | ... | ... | | 优点 | ... | ... | ... | | 缺点 / 限制 | ... | ... | ... | | 来源素材 | [[素材1]] | [[素材2]] | [[素材3]] | ## 关键差异 (用 1-2 句话说清最重要的差异点) ## 相关页面Template C: Timeline Format (trigger words: timeline / by time)
# {主题} 时间线 > 时间跨度:{起始年} ~ {结束年} | 生成日期:{日期} ```mermaid gantt title {Topic} Timeline dateFormat YYYY-MM-DD section Main Events Event A : 2023-01-01, 1d Event B : 2024-03-15, 1d Event C : 2025-06-20, 1d事件说明
- 2023-01-01 — 事件 A:简要说明(来源:[[素材A]])
- 2024-03-15 — 事件 B:简要说明(来源:[[素材B]])
- 2025-06-20 — 事件 C:简要说明(来源:[[素材C]])
相关页面
> **Notes on the timeline format**: > - `gantt` requires `YYYY-MM-DD` precision > - If the material only has a year (such as "2023"), fill the date in as the first day of that year (`2023-01-01`) > - If even the year is uncertain, switch to a **plain-text timeline** (an unordered list sorted by time) instead of Mermaid gantt > - If there are more than 15 events, it is recommended to group them by section to avoid making the diagram too long -
Update index.md and log.md:
- Add the new report entry under the "Comprehensive Analysis" category in index.md
- Append to log.md:
## {日期} digest | {主题}
-
Show the result to the user (switch language according to
WIKI_LANG):zh:
已生成深度报告:{主题} 综合了 {N} 篇素材: - [[素材1]]、[[素材2]]... 报告已保存:wiki/synthesis/{主题}-深度报告.md 发现这些待解决问题,可以继续搜集素材: - {问题1} - {问题2}(The English version is generated according to the "Output Language Rules", with the same structure.)
Workflow 8: graph (knowledge graph · Mermaid + interactive HTML)
Trigger keywords
"draw a knowledge graph", "look at the relationship diagram", "graph", "knowledge base map", "show knowledge relationships"
Pre-check
Execute the general pre-check (see the definition above). If there is no available knowledge base, prompt the user to initialize one first.
-
Scan bidirectional links:
- Traverse all
wiki/under.mdfiles - Extract the
[[链接]]syntax in each file to build a relationship list:页面A → 页面B
- Traverse all
-
Generate the Mermaid diagram file
wiki/knowledge-graph.md:# 知识图谱 > 自动生成 | {日期} | 共 {N} 个节点,{M} 条关联 ```mermaid graph LR A[Concept 1] --> B[Concept 2] A --> C[Material 1] D[Topic 1] --> A D --> E[Concept 3] ``` 查看方式:用 Typora、VS Code(Markdown Preview Enhanced)、或直接在 GitHub 上查看。Generation rules:
- Use square brackets for node names
[名称], and if the name is too long, truncate it to 10 characters - Only show nodes with bidirectional link relationships (isolated nodes are not included in the graph)
- If there are more than 50 relationships, keep only the 30 most-referenced nodes to avoid making the graph too dense
- By default, use only
A --> Bunlabeled arrows and do not automatically determine relationship types
Optional: manually beautify the graph (done by the user after generation; AI does not handle it automatically):
The generated
wiki/knowledge-graph.mdhas only-->arrows by default. If the user wants the graph to express relationship types more clearly, they can:- Open
wiki/knowledge-graph.mdin an editor - Refer to the "relationship type vocabulary" in
.wiki-schema.md(implements / depends on / compares / contradicts / derives) - Rewrite the 3-5 most important arrows into annotated forms such as
A -->|实现| Band similar - After saving, re-render with Obsidian / VS Code / Typora
In the graph workflow, AI does not automatically label — because automatically determining relationship types requires additionally reading the entire context, which is costly and hard to guarantee in accuracy. Human judgment about "which relationships are most worth labeling" is more reliable. If the user explicitly asks AI to label certain edges, they can separately say "label the relationship between A and B as 'implements'", and AI will then manually modify
wiki/knowledge-graph.mdthe corresponding row. - Use square brackets for node names
2b. Generate interactive graph data (wiki/graph-data.json):
bash scripts/build-graph-data.sh "$WIKI_ROOT"
The script recursively scans wiki/{entities,topics,sources,comparisons,synthesis,queries}/**/*.md,
parses wikilinks and <!-- confidence: EXTRACTED|INFERRED|AMBIGUOUS --> comments,
calls a local Node helper to compute 3-signal edge weights (co-citation strength / source overlap / type affinity), Louvain communities, and rule-based insights,
and writes wiki/graph-data.json paired with the unique wiki/graph-warnings.json in the same directory (content >2MB is automatically downgraded, only 500 lines are kept per node; insights are automatically downgraded when the graph scale exceeds the budget). Node identity uses the actual knowledge base relative path, so pages with the same name in the six formal directories are all retained. Explicit paths and unique bare names are linked normally; ambiguous links are not linked and candidates are reported; "to be created" and truly broken links are reported separately.
A normal build returns 0even if data issues are found; only tool, input, or write failures return 1, and Markdown is never modified. To have CI block on data errors, additionally run node scripts/wiki-link-cli.js check "$WIKI_ROOT" --strict; a strict check returns error for 2. Custom output must still be inside the knowledge base, filenames must remain graph-data.json, and it must use its own directory; the graph-warnings.json in that directory is its only paired detail file, and two custom outputs must be placed in two different directories.
Depends on jq + node(if missing, you can run brew install jq node).
2c. Graph runtime notes:
- Basic graph construction now depends on
jq+node - No additional
npm install nodeis needed; it is only used to run the local prebuilt helper distributed with the repository
2d. Generate interactive graph HTML (Eastern Editorial Department × Digital Landscape style):
bash scripts/build-graph-html.sh "$WIKI_ROOT"
Generate wiki/knowledge-graph.html. The script first validates the paired warnings, then safely embeds the graph and up to 2 MiB (gzip level 9) of warning details, so it can be opened offline by double-clicking. When the details exceed the limit, it is stably trimmed while preserving all totals; when the details are missing or are not from the same generation as the graph, the graph is still displayed and a rebuild is suggested.
The page keeps a three-column Chinese-style layout: document index on the left, digital landscape graph in the middle, and persistent node details on the right.
Includes search, community filtering, node visual layering, first-screen recommendation preview, summary, body text, adjacent nodes, insights, minimap, and relationship confidence legend.
The offline page is only responsible for explaining warnings and does not provide renaming, resolution, or other write operations.
-
Read insights and present results to the user (switch language according to
WIKI_LANG):First read insights:
jq '.insights' "$WIKI_ROOT/wiki/graph-data.json"zh:
知识图谱已生成! 共 {N} 个节点,{M} 条关联 图谱洞察: - 惊人连接:{from} ↔ {to}(跨社区,权重 {weight}){如有} - 桥节点:{node}(连接 {count} 个社区){如有} - 知识缺口:{node}(度数 {degree},建议补充素材){如有} - 稀疏社区:{community}(密度 {density}){如有} 查看方式: - 交互式(推荐):双击 wiki/knowledge-graph.html (建议 Chrome / Firefox;Safari 若提示"已阻止脚本", 可在 wiki/ 下跑 `python3 -m http.server 8000` 再访问) - Mermaid 静态图:wiki/knowledge-graph.md (Obsidian / VS Code Markdown Preview Enhanced / GitHub / Typora 均可渲染) 孤立页面(未纳入图谱): - [[某页面]](建议添加到相关实体页或主题页)(The English version is generated according to the "Output Language Rules" and has the same structure. When an insight category is empty, omit that line.)
Workflow 9: delete (delete material)
Trigger keywords
"delete material", "remove", "delete source", "remove"
Pre-check
Perform the general pre-check (see the definition above). If no knowledge base is available, prompt the user to initialize first.
Steps
-
Identify the target material:
- Search for the material name mentioned by the user under
raw/- If multiple candidates match, list the candidate files first and ask the user to confirm
- Search for the material name mentioned by the user under
-
Scan the impact scope:
- First run:
bash ${SKILL_DIR}/scripts/delete-helper.sh scan-refs "<wiki 根目录>" "<素材文件名>" - Use the page list returned by the script as the reference scan result
- Determine page by page whether to "delete the entire page" or "keep the page but remove that material reference"
- First run:
-
Safety confirmation:
- If more than 5 pages are affected, first list all affected pages in full to the user, then ask for a second confirmation
- If an entity or topic is referenced only by this material, ask the user whether to delete it together with the page
-
Perform cascading cleanup:
- Delete
raw/the corresponding original file - Delete
wiki/sources/the corresponding material summary page - For
wiki/entities/、wiki/topics/、wiki/comparisons/、wiki/synthesis/pages that still need to be kept, remove only the reference paragraphs related to that material - Update
index.md - In
log.mdappend the deletion record - Mark
wiki/overview.mdfor regeneration
- Delete
-
Clear cache:
- After deletion is complete, run the following for the corresponding raw file:
bash ${SKILL_DIR}/scripts/cache.sh invalidate "<raw 文件路径>"
- After deletion is complete, run the following for the corresponding raw file:
-
Broken-link check:
- Use grep or
delete-helper.shto scan again for links pointing to deleted pages - Clean up broken links that can be clearly determined; if ownership is unclear, keep the original text and prompt the user for later manual confirmation
- Use grep or
-
Report the result to the user:
zh:
已删除: - raw/articles/2024-01-15-ai-article.md - wiki/sources/2024-01-15-ai-article.md 已更新(移除引用): - wiki/entities/AI-Agent.md - wiki/topics/大语言模型.md 需要重新生成: - wiki/overview.md(The English version is generated according to the "Output Language Rules," with the same structure.)
Workflow 10: crystallize
Trigger conditions: The user says "crystallize", "crystallize", "record this in the knowledge base", "this conversation is valuable"
Input: Content actively provided by the user (text pasted into the conversation, or an explicit reference to a certain context). The user must actively provide the content; Claude does not automatically extract the current session.
Processing steps (MVP):
- The user provides content (text pasted into the conversation)
- Claude extracts from the content:
- Core insights (3-5 items)
- Key decisions and reasons
- Conclusions worth recording
- Generate
wiki/synthesis/sessions/{主题}-{日期}.md, format referencetemplates/synthesis-template.md- This round does not require crystallize pages to supplement
sources, and by default they do not participate in graph source overlap
- This round does not require crystallize pages to supplement
- Update
log.md(record this crystallization operation)
The MVP version does not automatically create entity pages and does not automatically update index.md.
confidence rules:
Content from crystallization sources is marked by default as INFERRED(from inference/conversation, not original documents).
Output example: Created wiki/synthesis/sessions/AI-agent-设计决策-20260413.md Updated log.md