Skip to content

Feat/llm wiki poc - #10

Open
Ujikintoki wants to merge 6 commits into
HKUST-KnowComp:mainfrom
Ujikintoki:feat/llm-wiki-poc
Open

Feat/llm wiki poc#10
Ujikintoki wants to merge 6 commits into
HKUST-KnowComp:mainfrom
Ujikintoki:feat/llm-wiki-poc

Conversation

@Ujikintoki

Copy link
Copy Markdown
Contributor

Summary

POC 验证将 DeepRefine-Skill 从 code-centric KG 扩展到 general LLM-Wiki(Obsidian [[双括号链接]] markdown)。框架 95% 可复用,目前是 POC 阶段,需要进一步讨论和决策后继续开发。

Architecture

Obsidian wiki → wiki_importer → graph.json → deeprefine refine → obsidian_refresh → wiki

PR #8 做了 Graphify Wiki格式的 export,我做了 Obsidian 格式的 import + export 回写,本质上是验证我们的仓库可不可以向通用的,non-code的markdown wiki复用和扩展。

Changes

Module What
🆕 wiki_importer.py [[links]] → graph.json
🆕 wiki_retrieval.py Full-text search + BFS subgraph
🆕 obsidian_refresh.py Incremental .md write-back
✏️ agent_loop.py Wiki retrieval method whitelist
✏️ action_review.py Wiki evidence + ambiguous labels

Known Limitations

  • CLI integration 待下个 PR
  • create_node 待后续
  • General wiki 的格式和形式是什么?其所对应的功能范围是什么?还需进一步讨论和决策

Ujikintoki and others added 5 commits July 14, 2026 15:19
POC Step 2: Scan .md files, extract Obsidian-style [[wikilinks]] via regex,
build graph.json + page_contents.json compatible with existing refine pipeline.

- Two-pass algorithm: nodes + label→id lookup, then link resolution
- Wiki nodes use page_path (absolute path) to distinguish from code source_file
- Handles [[Page]], [[Page|alias]], [[Page#heading]], [[Page#heading|alias]]
- Dangling links (no matching page) use slug-ified target ID
- Zero external dependencies (stdlib only)

Co-Authored-By: Claude <noreply@anthropic.com>
POC Step 3: Two-step retrieval pipeline for wiki subgraphs:
1. Substring search across page contents → top-K entry pages
2. BFS k-hop expansion along links_to edges → subgraph triples

Output format matches existing graphify query output ({subject, relation, object}),
requiring no downstream changes to the refinement loop.

- Cycle-safe BFS with visited-node tracking
- Human-readable labels in output triples (what the LLM sees)
- Zero external dependencies (stdlib only)

Co-Authored-By: Claude <noreply@anthropic.com>
POC Step 4: Replace hardcoded retrieval method tuples with named constants
and add 6 wiki-native retrieval methods:

Step 1 (initial hop): wiki_search, wiki_search+k_hop_expansion
Hop 2+ (expansion): wiki_search, wiki_search+k_hop_expansion, link_traversal

Existing code-path methods (graphify_query, k_hop_expansion) unchanged.
Backward compatible — all existing traces continue to validate.

Co-Authored-By: Claude <noreply@anthropic.com>
POC Step 5: Three additive changes for wiki-mode evidence review:

1. AMBIGUOUS_LABELS: Add 9 wiki-specific ambiguous page names
   (untitled, draft, index, home, introduction, overview, notes, todo, new_page)
   while preserving all existing code-specific labels.

2. _has_wiki_evidence(): New function that verifies [[obj]] wikilinks
   exist in markdown source files. Supports Obsidian variants including
   |alias and #heading fragments. Used to confirm delete_edge targets.

3. review_action() wiki evidence branch: After code evidence check,
   if source_files is empty (wiki nodes use page_path, not source_file),
   checks for wikilinks in the page's .md file. Wiki evidence only fires
   for delete_edge (MEDIUM→HIGH upgrade when [[link]] confirmed in source).

Confidence logic updated to recognize 'Direct wiki evidence' as HIGH.

Backward compatible: code evidence path runs first; wiki path only
activates for nodes with page_path and no source_file.

Co-Authored-By: Claude <noreply@anthropic.com>
Incremental write-back for Obsidian-style wikis after deeprefine
refinement. Unlike PR HKUST-KnowComp#8's wiki_refresh which regenerates the entire
wiki via graphify, this module preserves human-written content and
only touches the specific wikilinks or titles that changed.

Action → edit mapping:
  insert_edge → append [[target]] to source page
  delete_edge → remove [[target]] from source page
  replace_node → update # Title in the page

Transaction safety: all target files are backed up before editing;
any failure triggers full rollback. Idempotent — re-applying the
same refinement produces no duplicate edits.

Follows the same Result dataclass pattern as wiki_refresh.py for
transparent CLI dispatch.

Co-Authored-By: Claude <noreply@anthropic.com>
@Ujikintoki

Copy link
Copy Markdown
Contributor Author

feasibility_report_zh.md

@hhy-huang

Copy link
Copy Markdown
Collaborator

llmwiki格式比较flexible,我理解general llmwiki的格式应该一般是一堆 file system中的markdown文件?
我们做的这个wiki_importer不能把wiki格式or schema定死,但是generally应该一些带有hyperlink的markdown file,这种style的文件应该都能ingest才行

@hhy-huang

Copy link
Copy Markdown
Collaborator

llmwiki格式比较flexible,我理解general llmwiki的格式应该一般是一堆 file system中的markdown文件? 我们做的这个wiki_importer不能把wiki格式or schema定死,但是generally应该一些带有hyperlink的markdown file,这种style的文件应该都能ingest才行

比如这个interface应该可以ingest any wiki-style files adaptively,不能说这个markdown文件不是.md是.txt就没法处理了。

@hhy-huang

Copy link
Copy Markdown
Collaborator

refresh同理,当然originally是obsidian的format的话refresh也要这样做。本质上是要follow original format,不能说refresh完了之后人家本身的文件格式也给改了,用户体验就不太好。

另外这个最好rename成update,refresh感觉大部分情况下指content不发生改变。

@Ujikintoki

Copy link
Copy Markdown
Contributor Author

明白了,现在的主要问题是llm-wiki的输入格式问题。我们需要允许不同类型的输入文件(markdown, txt等),和不同格式的文件(obsidian,传统wiki,notion等)

可能采取的方法:

importer 在 ingest 时检测每个文件的 convention → 存到 node metadata → write-back 时读取这个 metadata → 用同一个 convention 写回。

ingest:  scan 所有文件 → 检测格式惯例 → 提取 link + title → graph.json (带 format tag)
           ↓
refine:   LLM 精化(不改)
           ↓
update:  读 node 的 format tag → 用对应的 link/title 语法 → 写回原文件

ingestion中根据不同格式wiki设计不同的正则解析部件(可能有优化空间)

下面还有一些待确定的问题:

  1. 首节点(step1)的检索(在原始的设计中,step1是识别边)
  2. BFS扫描和扩展(这里我目前没有用embedding,目前是纯线形扫描)
  3. ‼️action_review的的置信度设计(这个问题可能比较重要,因为对于code, review时有非常清晰的置信度判断可以将refine动作分类为:HIGH, MEDIUM, LOW。但是对于general wiki, 如何确定置信度是一个问题,可能需要单独设计)
  4. ‼️原始文本选择(也就是从文本中推断精确关系)在code refine中也比较清晰,因为一个源文件(.py)与其包含的实体(其中定义的函数/类)精确相关,但是对于general wiki,纯自然语言的文本进行关系推断的query可能比较复杂。我打算尝试用滑动窗口识别[[]]等wiki link的前后固定长度字符的方式进行llm推断(这个方法比较笨,可能也有优化空间)

解决学长 review 的 4 个问题:

1. wiki_importer 支持多种 link schema — 新增 MDLINK_RE 和
   detect_link_format(),按比例判断 [[wikilinks]] vs [text](url),
   过滤外部 URL、锚点、非页面资产(图片/PDF/音视频)

2. 解除文件扩展名限制 — glob('*.md') → _find_wiki_files(),
   白名单扩展名 + 内容嗅探支持 .txt/.markdown/无扩展名等

3. 写回 follow 原文件格式 — wiki_update 按 node.link_format
   派发 _append_wikilink() 或 _append_mdlink(),互不污染

4. 重命名 obsidian_refresh → wiki_update — 类/函数全部重命名,
   旧文件保留为向后兼容的 re-export shim

cli.py 新增 --update-wiki flag,--refresh-wiki 保持不变

Co-Authored-By: Claude <noreply@anthropic.com>
@Ujikintoki

Copy link
Copy Markdown
Contributor Author

修改:

  1. wiki_importer 支持多种 link schema — 新增 MDLINK_RE 和 detect_link_format(),按比例判断 [[wikilinks]] vs text,过滤外部 URL、锚点、非页面资产(图片/PDF/音视频)

  2. 解除文件扩展名限制 — glob('*.md') → _find_wiki_files(),白名单扩展名 + 内容嗅探支持 .txt/.markdown/无扩展名等

  3. 写回 follow 原文件格式 — wiki_update 按 node.link_format 派发 _append_wikilink() 或 _append_mdlink(),互不污染

  4. 重命名 obsidian_refresh → wiki_update — 类/函数全部重命名,旧文件保留为向后兼容的 re-export shim

cli.py 新增 --update-wiki flag,--refresh-wiki 保持不变

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants