Files
nexus/Hermes/xingzhi/wiki-sync-setup-2026-04-16.md
2026-04-18 08:15:20 +08:00

272 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Wiki Sync 系统搭建完整记录
> 日期2026-04-16
> 作者Hermes Agent
> 用途:记录 llm-wiki-agent 自动化同步系统的完整搭建过程
---
## 背景
用户希望将 Obsidian vault 中的 markdown 文件批量摄入到 LLM WikiKarpathy's LLM Wiki中。原有方案是手动逐篇执行效率低下。本次目标搭建自动化系统实现定时自动摄入。
---
## 系统架构
### 架构图
![Wiki Sync Architecture](IMG-20260418081458052.png)
### 同步时序图
![Wiki Sync Sequence Diagram](IMG-20260418081458100.png)
### 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/<slug>.md
更新 wiki/index.md
更新 wiki/overview.md
创建/更新 Entity 页面
创建/更新 Concept 页面
检测并记录冲突
追加 wiki/log.md
## 二、遇到的问题和解决方案
### 问题 1stdin 交互问题
**现象**`claude --print` 模式在非交互环境下无法正常工作stdin 被占用导致命令卡住。
**解决方案**:使用 TMUX 交互模式启动 Claude Code
```bash
# 启动 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
```python
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
**核心函数**
```python
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
**创建命令**
```bash
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 分钟)
- 交付方式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 |
---
## 六、关键命令速查
```bash
# 检查待摄取文件
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. **必须解析 SLUG**LLM 输出的实际 slug 用于更新 manifest
4. **交付方式**:使用 `telegram:5038825565` 发给用户
5. **保留 orphan**:不删除任何原始数据
---
## 八、扩展方向
- [ ] 添加错误重试机制529 时等待后重试)
- [ ] 支持批量摄入(改为每次 3-5 篇)
- [ ] 添加 webhook 通知(不只是 Telegram
- [ ] 统计摄入速率和成功率
---
*End of Note*