Auto-sync: 2026-04-16 20:05

This commit is contained in:
2026-04-16 20:05:13 +08:00
parent db72ecb4f6
commit ee6406f30c
43 changed files with 1786 additions and 12 deletions

View File

@@ -0,0 +1,273 @@
# Wiki Sync 系统搭建完整记录
> 日期2026-04-16
> 作者Hermes Agent
> 用途:记录 llm-wiki-agent 自动化同步系统的完整搭建过程
---
## 背景
用户希望将 Obsidian vault 中的 markdown 文件批量摄入到 LLM WikiKarpathy's LLM Wiki中。原有方案是手动逐篇执行效率低下。本次目标搭建自动化系统实现定时自动摄入。
---
## 系统架构
```
┌─────────────────────────────────────────────────────────────────┐
│ Hermes Agent (我) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ Cron Job │ → │ TMUX Session │ → │ Claude Code Agent │ │
│ │ 每15分钟 │ │ wiki-ingest │ │ /wiki-ingest │ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
│ ↓ ↓ │
│ manifest.json ←───────────────────────────────── 实际生成文件 │
│ 更新 wiki/ │
└─────────────────────────────────────────────────────────────────┘
```
### 核心组件
| 组件 | 位置 | 职责 |
|------|------|------|
| **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*