Files
nexus/Hermes/xingzhi/wiki-sync-setup-2026-04-16.md

7.1 KiB
Raw Blame History

Wiki Sync 系统搭建完整记录

日期2026-04-16 作者Hermes Agent 用途:记录 llm-wiki-agent 自动化同步系统的完整搭建过程


背景

用户希望将 Obsidian vault 中的 markdown 文件批量摄入到 LLM WikiKarpathy's LLM Wiki中。原有方案是手动逐篇执行效率低下。本次目标搭建自动化系统实现定时自动摄入。


系统架构

架构图

Wiki Sync Architecture

同步时序图

Wiki Sync Sequence Diagram

Ingest 9 步流程图

!IMG-20260418081458161.png

核心组件

组件 位置 职责
llm-wiki-sync skill ~/.hermes/skills/research/llm-wiki-sync/SKILL.md 执行模板和工作流定义
sync.py /Users/weishen/Git/llm-wiki-agent/tools/sync.py manifest 管理、CLI 工具
manifest.json /Users/weishen/Git/llm-wiki-agent/tools/manifest.json 文件状态追踪181篇
Hermes Cron Job 内部调度器 每 15 分钟触发一次摄入

一、初始探索(手动执行阶段)

1.1 发现 raw 文件

  • 路径:/Users/weishen/Workspace/nexus/raw/Obsidian vault
  • 通过 symlink 挂载到:/Users/weishen/Git/llm-wiki-agent/raw/
  • 文件数182 个 markdown 文件

1.2 创建 manifest.json

手动扫描 raw 目录,生成初始 manifest

# 扫描 raw 目录,提取 frontmatter
for md in Path("raw").glob("**/*.md"):
    # 提取 title, ingested, slug 等字段
    manifest.append({...})

1.3 测试 /wiki-ingest

Claude Code 的 /wiki-ingest 命令执行 9 步流程: 读取 source 文档 读取 wiki/index.md 和 overview.md 生成 wiki/sources/.md 更新 wiki/index.md 更新 wiki/overview.md 创建/更新 Entity 页面 创建/更新 Concept 页面 检测并记录冲突 追加 wiki/log.md

二、遇到的问题和解决方案

问题 1stdin 交互问题

现象claude --print 模式在非交互环境下无法正常工作stdin 被占用导致命令卡住。

解决方案:使用 TMUX 交互模式启动 Claude Code

# 启动 TMUX session
tmux new-session -d -s wiki-ingest "cd /Users/weishen/Git/llm-wiki-agent && claude --permission-mode bypassPermissions"

# 等待启动完成
sleep 8 && tmux send-keys -t wiki-ingest Enter

# 发送任务
tmux send-keys -t wiki-ingest "请执行任务..."

问题 2manifest slug 与实际文件不匹配

现象manifest 中记录的 slug 和 source_path 与 LLM 实际生成的文件名不一致。

原因LLM 根据内容自动生成 slug而不是简单从文件名转换。

解决方案:要求 LLM 在任务完成后输出 SLUG: xxx,然后 Hermes 解析并更新 manifest

def parse_slug_from_output(output: str) -> str:
    """从 LLM 输出中解析实际使用的 slug"""
    match = re.search(r'SLUG:\s*([^\s]+)', output)
    return match.group(1) if match else None

问题 3170 条 ingest 错误记录

现象manifest 中有 170 条记录标记为 ingested=true 但实际未成功。

原因:早期测试时使用 --print 模式失败但仍标记为成功。

解决方案:使用 sync.py --reset-failed 清理错误状态。


三、自建组件

3.1 sync.py CLI 工具

位置/Users/weishen/Git/llm-wiki-agent/tools/sync.py

功能

  • --pending:列出待摄取文件
  • --check:预览变化
  • --reset-failed:重置失败记录
  • --bootstrap:从现有 wiki sources 重建 manifest

核心函数

def get_pending_files() -> list:
    """返回所有未摄入的文件"""

def mark_ingested(file_path: str, slug: str):
    """标记文件为已摄入"""

def reset_failed():
    """重置所有失败状态"""

def parse_slug_from_output(output: str) -> str:
    """从 LLM 输出解析 SLUG"""

3.2 llm-wiki-sync skill

位置~/.hermes/skills/research/llm-wiki-sync/SKILL.md

版本1.4.0

核心内容

  • 角色分工Hermes 编排流程 → Claude Code 执行 ingest
  • 关键设计TMUX 交互模式、顺序执行、SLUG 输出要求
  • TMUX 执行流程:完整的启动、发送任务、监控、清理流程
  • Ingest Workflow 9 步:标准化执行步骤
  • Cron Job 自动化:使用 Hermes 原生 cron job

3.3 Hermes Cron Job

创建命令

cronjob create \
  --name wiki-sync-15min \
  --skill llm-wiki-sync \
  --schedule "*/15 * * * *" \
  --repeat 999999 \
  --deliver "telegram:5038825565" \
  --prompt "使用 llm-wiki-sync 技能执行一次 wiki 文章摄入..."

配置

  • Job ID98265b6998c5
  • Schedule*/15 * * * *(每 15 分钟)
  • 交付方式TelegramID: 5038825565
  • 技能llm-wiki-sync

四、执行流程(自动化阶段)

4.1 Cron Job 触发

  1. 每 15 分钟00, 15, 30, 45 分)触发
  2. 加载 llm-wiki-sync skill
  3. 执行 skill 中的 prompt

4.2 实际执行步骤

1. 加载 llm-wiki-sync 技能
2. 检查 manifestpython tools/sync.py --pending
3. 启动 TMUX session
4. 启动 Claude CodebypassPermissions
5. 发送任务指令(含 SLUG 输出要求)
6. 监控任务完成tmux capture-pane
7. 解析 SLUG 并更新 manifest.json
8. 清理 TMUX session
9. 输出结果(自动发往 Telegram

4.3 示例输出

## Wiki Sync 完成

| 项目 | 结果 |
|------|------|
| 摄入文件 | raw/Home Office/用Docker中安装Navidrome.md |
| Slug | 用docker中安装navidrome |
| 状态 | ✅ 已完成 |

新增页面:
- wiki/sources/用docker中安装navidrome.md
- wiki/entities/Navidrome.md
- wiki/concepts/Docker-Compose.md

manifest 已更新ingested: true
剩余待摄入165 篇

五、当前状态

指标
总文件数 181 篇
已摄入 16 篇
待摄入 165 篇
Cron Job 状态 运行中
下次运行 18:15:00

六、关键命令速查

# 检查待摄取文件
cd /Users/weishen/Git/llm-wiki-agent && python tools/sync.py --pending

# 预览变化
python tools/sync.py --check

# 重置失败记录
python tools/sync.py --reset-failed

# 查看 cron job 状态
cronjob --list

# 手动触发 cron job
cronjob --run <job_id>

七、注意事项

  1. 必须使用 TMUX:不能用 subprocess 或 --print 模式
  2. 必须顺序执行:并发会触发 529 rate limit
  3. 必须解析 SLUGLLM 输出的实际 slug 用于更新 manifest
  4. 交付方式:使用 telegram:5038825565 发给用户
  5. 保留 orphan:不删除任何原始数据

八、扩展方向

  • 添加错误重试机制529 时等待后重试)
  • 支持批量摄入(改为每次 3-5 篇)
  • 添加 webhook 通知(不只是 Telegram
  • 统计摄入速率和成功率

End of Note