7.1 KiB
Wiki Sync 系统搭建完整记录
日期:2026-04-16 作者:Hermes Agent 用途:记录 llm-wiki-agent 自动化同步系统的完整搭建过程
背景
用户希望将 Obsidian vault 中的 markdown 文件批量摄入到 LLM Wiki(Karpathy's LLM Wiki)中。原有方案是手动逐篇执行,效率低下。本次目标:搭建自动化系统,实现定时自动摄入。
系统架构
架构图
同步时序图
Ingest 9 步流程图
核心组件
| 组件 | 位置 | 职责 |
|---|---|---|
| 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
二、遇到的问题和解决方案
问题 1:stdin 交互问题
现象: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 "请执行任务..."
问题 2:manifest 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
问题 3:170 条 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 ID:
98265b6998c5 - Schedule:
*/15 * * * *(每 15 分钟) - 交付方式:Telegram(ID: 5038825565)
- 技能:llm-wiki-sync
四、执行流程(自动化阶段)
4.1 Cron Job 触发
- 每 15 分钟(00, 15, 30, 45 分)触发
- 加载 llm-wiki-sync skill
- 执行 skill 中的 prompt
4.2 实际执行步骤
1. 加载 llm-wiki-sync 技能
2. 检查 manifest(python tools/sync.py --pending)
3. 启动 TMUX session
4. 启动 Claude Code(bypassPermissions)
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>
七、注意事项
- 必须使用 TMUX:不能用 subprocess 或 --print 模式
- 必须顺序执行:并发会触发 529 rate limit
- 必须解析 SLUG:LLM 输出的实际 slug 用于更新 manifest
- 交付方式:使用
telegram:5038825565发给用户 - 保留 orphan:不删除任何原始数据
八、扩展方向
- 添加错误重试机制(529 时等待后重试)
- 支持批量摄入(改为每次 3-5 篇)
- 添加 webhook 通知(不只是 Telegram)
- 统计摄入速率和成功率
End of Note


