with one click
llm-wiki-book-workflow
// 内容摄入 Wiki 全流程:书籍 / GitHub仓库 / 论文 / 微信公众号文章 → wiki实体页 + 概念页 + 道法术器分析。触发:书籍入库、repo归档、wiki摄入、内容归档、知识库构建。自动处理下载/提取/wiki写入/索引更新/跨页链接验证。
// 内容摄入 Wiki 全流程:书籍 / GitHub仓库 / 论文 / 微信公众号文章 → wiki实体页 + 概念页 + 道法术器分析。触发:书籍入库、repo归档、wiki摄入、内容归档、知识库构建。自动处理下载/提取/wiki写入/索引更新/跨页链接验证。
| name | llm-wiki-book-workflow |
| description | 内容摄入 Wiki 全流程:书籍 / GitHub仓库 / 论文 / 微信公众号文章 → wiki实体页 + 概念页 + 道法术器分析。触发:书籍入库、repo归档、wiki摄入、内容归档、知识库构建。自动处理下载/提取/wiki写入/索引更新/跨页链接验证。 |
关键词(任一):
前置动作:无条件读取 ~/wiki/SCHEMA.md
决策顺序:PDF 书 → 先试 archive.org;EPUB → Anna's Archive
⚠️ 2026-05 变更:Archive.org 对版权书强制登录认证,直接 curl 下载返回 HTTP 401。公共领域/老书(Thinking Fast and Slow、7 Habits、正义之心等)仍可直接下载;新版商业书需登录或换源。
curl -s "https://openlibrary.org/search.json?q=<书名>&limit=3"
# 返回的 doc[].ia 字段即为 Archive.org identifier
curl -s "https://archive.org/metadata/<ia_id>" | python3 -c "
import sys,json; d=json.load(sys.stdin)
for f in d['files']:
if '.pdf' in f['name'].lower():
print(f['name'], int(f.get('size',0))/1024/1024, 'MB')
"
curl -L -o ~/books/<书名>.pdf \
"https://archive.org/download/<identifier>/<identifier>.pdf"
IA 直链返回 401 时,不要立即放弃。按以下顺序尝试:
fast_download URL,curl 下载详见 references/book-sources.md
决策规则:
https://annas-archive.gl/search?q=<书名+作者>Array.from(document.querySelectorAll('a[href*="fast_download"]')).map(a=>a.href)[0] 获取第一个下载链接curl -s --max-time 60 -L -A "Mozilla/5.0" "<url>" -o ~/books/<书名>_<作者>.epub~/books/curl 直接下载 Anna's Archive 的限制:
fast_download/<md5>/0/0 返回 JS 挑战页(curl 拿到 HTML 而非文件)验证(通用):
# Step 1: magic bytes 检查(必须)
file ~/books/<书名>.pdf
# ✓ 有效:PDF document, version 1.x
# ✗ 无效:HTML document text(curl 拿到的是 HTML 错误页)
# Step 2: 大小检查(配合 file 一起判断)
ls -lh ~/books/<书名>.pdf
# > 100KB + PDF magic bytes → 高可信度有效
# < 100KB → 大概率无效,即使 magic bytes 碰巧是 PDF
# 某些 HTML 错误页可达 150KB(如 怪诞行为学 128KB 是 HTML)
# 纯文本本书(无图片)通常 1~5MB;扫描版 10~30MB
多书并行搜索:一次 web_search 最多搜 4 本书,避免触发频率限制
参考:references/book-sources.md(含各源连通性状态和失败模式)
GitHub Repo 摄入:references/github-repo-ingestion.md(克隆+raw提取+wiki写入+index更新的完整流程模式)
微信公众号摄入:references/article-ingestion-notes.md(微信文章抓取+wiki写入流程)
工具:execute_code(Python)
依赖:pip install ebooklib beautifulsoup4 lxml -q
核心逻辑:
from ebooklib import epub
from bs4 import BeautifulSoup
book = epub.read_epub(epub_path)
chapters = []
for item in book.get_items():
if item.get_type() == 9: # HTML
soup = BeautifulSoup(item.get_content(), 'lxml')
text = soup.get_text(separator='\n', strip=True)
if len(text) > 200:
chapters.append(text)
输出路径:~/wiki/raw/books/<书名>_<作者>.md
格式要求:
# <书名>_<作者>.epub> Extracted from EPUB | {char_count} characters | {para_count} paragraphs验证:文件行数 > 50 行
工具:Python pypdf(系统已安装,无需额外 pip)
实操流程(在 terminal 中用 heredoc 执行):
python3 << 'EOF'
import pypdf, os
books = [
("书名.pdf", "输出.md"),
]
for pdf_name, md_name in books:
path = f"/Users/fuzhuo/books/{pdf_name}"
out_path = f"/Users/fuzhuo/wiki/raw/books/{md_name}"
r = pypdf.PdfReader(path)
total = len(r.pages)
text = ""
for p in r.pages[:30]:
t = p.extract_text()
if t: text += t + "\n"
with open(out_path, 'w') as f:
f.write(f"# {md_name.replace('_', ' ')}\n\n")
f.write(f"*来源: {pdf_name} | 总页数: {total} | 已提取前30页*\n\n")
f.write(text[:80000])
print(f"OK {md_name}: {total}p, {os.path.getsize(out_path)/1024:.0f}KB")
EOF
提取范围:前30页(覆盖目录、前言、第1-2章,足以提取核心概念和框架)
⚠️ 扫描版 PDF 检测(必须):
下载 PDF 后立即检查:
r = pypdf.PdfReader(path)
total = len(r.pages)
sample = r.pages[0].extract_text()
print(f"总页数: {total}, 第1页字数: {len(sample)}")
判断标准:
| 总页数 | 第1页字数 | 结论 | 处理 |
|---|---|---|---|
| >50页 | >100字 | ✅ 文本版 | 正常提取 |
| 1-30页 | 0字 | ❌ 扫描图片版 | 跳过文字提取,记录元数据 |
| >50页 | 0字 | ⚠️ 混合/损坏 | 尝试其他页面,全空则跳过 |
已知节选/样本版:08正义之心(8页)、14终身成长(10页)、16象与骑象人章节(29页) — 总页数<30的都是节选,跳过文字提取
工具:delegate_task(并行,batch=4 限制)
前置:读取 ~/wiki/SCHEMA.md
流程:
raw/articles/,对 book 填 raw/books/)[[wikilinks]]~/wiki/index.md(entity 区先于 concept 区)~/wiki/log.mdLog 格式(通用):
## [日期] — [来源类型] | [来源标识]
- [实体页] 创建
- [概念页] 创建
- Key insight 1
来源类型:book / github / arxiv / website。不要硬编码"ingest"。
Page 类型判断:
并行策略:每次 delegate_task 最多 4 个子任务,超出则分批
⚠️ Subagent 超时保护(2026-05-15 强制规则):
工具:read_file(读取所有新创建的 concept pages)+ LLM 推理
框架:
| 层级 | 含义 | 产出 |
|---|---|---|
| 道 | 信念 / Why | 一句话核心信念 |
| 法 | 核心原则 / What | 3~5 条不变原则 |
| 术 | 方法论 / How | 具体操作步骤 |
| 器 | 工具 / Tools | 可用工具清单 |
输出格式:
## <书名>
### 道
> 核心信念(一句话)
### 法
- 原则1
- 原则2
- ...
### 术
1. 方法A
2. 方法B
...
### 器
- 工具X
- 工具Y
Meta-Skill 对齐(可选标签):
~/books/ # 原始 epub/pdf
~/wiki/raw/books/ # 提取的 markdown(书籍)
~/wiki/raw/articles/ # 提取的 markdown(文章)
~/wiki/raw/github/ # 提取的 markdown(repo)
~/wiki/entities/ # 实体页面
~/wiki/concepts/ # 概念页面
~/wiki/index.md # 索引
~/wiki/log.md # 操作日志(append-only)
web_extract 对 >5000 字符的文章截断,恢复方法见 references/article-ingestion-notes.md Step 1 三步法创建批量页面后,新页面之间的 wikilinks 引用必须逐个验证:
问题现象:新创建的 entity 页 A 链接 [[Entity-B]],但 Entity-B 的文件名是 entity-b.md,link 无法解析。
验证命令:
# 检查所有新建页面中的 [[wikilinks]] 是否都有对应文件
cd ~/wiki
# 提取所有 wikilink 目标
grep -rho '\[\[[^]]\+\]\]' entities/ concepts/ | sort -u | sed 's/\[\[\([^\]]*\)\]\]/\1/g' > /tmp/wiki_links_needed.txt
# 提取所有已创建的文件名(无后缀)
find entities/ concepts/ -name "*.md" | xargs -I{} basename {} .md | sort -u > /tmp/wiki_files_exist.txt
# 对比
diff /tmp/wiki_links_needed.txt /tmp/wiki_files_exist.txt
快速人工检查:创建后扫一眼新页面的 Related Concepts / Related Entities 段,确认链接名称与实际文件名完全一致。
常见错误模式:
[[Claude-Opus-4-7]] 但文件是 claude-opus-4-7.md[[claude-code]] 但文件是 claude-code-system-prompt.md修复方式:直接 patch 错误的 wikilink 为正确的文件名(不含 .md 后缀)。
file 命令显示为 PDF,总页数少(<30)。处理:跳过文字提取,不写入 raw/books/file 命令验证 magic bytes{"error": "content too short"} 或空 content → 使用已有上下文(skill 内容、session memory)补全,不重试 web_extract