Obsidian 知识库摄入(Ingest)
把任意资料(PDF / EPUB电子书 / 文章 / 网页 / 公众号 / 截图识别文本 / 会议记录)按 Obsidian 知识库根目录的「知识库规则.md」定义的 LLM 知识库模式,转化为互相链接的中文结构化知识页,让知识复利而非每次重头学。本技能源于卡帕西(Karpathy)《LLM Wiki》思路并融合评论区实践,全程中文命名与中文展示。
触发(人怎么说都行)
以下说法都代表「按知识库规则把这份资料摄入」:
- 「把这个文档 / 文章 / 链接按咱们的规则存起来」
- 「放进 Obsidian / 存进知识库 / 收进原始资料」
- 「按知识库规则处理这个」「按今天的方式操作」
- 「摄入这篇 / 整理进 wiki / 加到知识库里」
- 「把这本书存进知识库 / 导入 epub / 摄入这本电子书」
- 或直接丢文件并说「像上次那样存」
收到即执行下方流程,无需再确认意图。
Vault 定位(首次使用自动初始化)
按顺序确定用户知识库根目录 {VAULT}:
1. 环境变量 OBSIDIAN_VAULT
2. 默认值 D:\Obsidian
若 {VAULT} 根不存在「知识库规则.md」,视为未初始化,先运行初始化脚本帮用户建好中文骨架(对已有知识库无感,可安全重跑):
python "{SKILL}/scripts/init_vault.py" --vault "{VAULT}"
其中 {SKILL} 为本技能目录(~/.workbuddy/skills/obsidian-wiki-ingest)。脚本会创建目录骨架、部署「知识库规则.md」与 4 个页面模板、生成空索引/日志。
目录结构(全中文,由 init_vault.py 生成)
{VAULT}/
├── 知识库规则.md ← 规则源(本技能的操作手册,来自 references/)
├── 原始资料\ ← 不可变原始资料(只读不改)
│ ├── 素材\ 文章\ 论文\ 笔记\ 书籍\
├── 知识库\ ← 维护者生成的 markdown(全权拥有)
│ ├── 索引.md 日志.md
│ ├── 实体\ 概念\ 来源\ 综合\ 仪表盘\
└── 模板\ ← 页面模板(来源/实体/概念/综合)
流程(Ingest)
- 取原文
- PDF:Git Bash 自带pdftotext,pdftotext -enc UTF-8 -layout <源> <出.txt>(中文必须-enc UTF-8)。通读全文后再提炼,严禁臆造文中没有的内容。
- EPUB 电子书:用本技能自带脚本提取为 Markdown——"{PY}" "{SKILL}/scripts/epub_to_markdown.py" <源.epub> <出.md>({PY} 为 default venv 的 python.exe,即C:/Users/YANGLIN/.workbuddy/binaries/python/envs/default/Scripts/python.exe)。脚本按阅读顺序逐章提取、保留标题层级与段落、自动跳过导航/目录页、去重章节标题。依赖 ebooklib+beautifulsoup4+lxml(已装于 default venv)。提取后通读全文再提炼。- 跨章链接已自动净化(v1.2 起):epub 内 TOC/引用常形如
part0007.html#6LJU0,提取成单文件后该目标失效。脚本首遍扫描收集全部标题文本与id→标题映射,第二遍把这类链接解析为 Obsidian 书内锚点[[#标题]](链接文字本身即标题时同样处理);脚注链接([1]形)转为纯文本[1];其余跨章引用剥离失效目标、保留文字。导入后不再产生part*.html断链节点——无需再手动清理(详见下方"失败模式"第 7 条)。 - 网页/文章:优先
unset HTTP_PROXY HTTPS_PROXY后直连curl -sL --compressed;按页面 meta charset 解码,回退gb18030(防编码误判成乱码)。 - 链接疑似打不开的标准程序(重要):当用户给出的 URL 首次抓取返回 404 / 空壳 / 网络错时,不得仅凭这一次探针就判定"链接失效 / 用户链接有误",更不得据此在回复中声称"你给的链接 404 / 缺了某段 / 格式不对"。必须用用户给出的完整 URL 原样直接复测:① 确认代理已
unset、换 UA、加--compressed后重 curl;② 换WebFetch取;③ 用搜索引擎按内容标题或文章 ID(如content_xxxxxx)反查真实 URL。至少用 2 种不同方式一致失败,才可结论"链接当前不可达",并向用户说明已尝试的复测方式与结果、请其核对原始链接。严禁对链接结构妄下判断(如"缺了某目录段"),除非亲自用该完整 URL 复测证实。 - SPA 站点(如 xuexi.cn / 学习强国):
curl只返回<title>...</title>外壳,详情 API 需前端签名无法直接拿;直接改用 WebFetch 提取正文(提示词要求"提取标题/作者/日期/正文全文",若返回空壳说明需登录/JS)。xuexi.cn 文章 WebFetch 可正常拿到全文。 - 图片采集(固定伴随取原文):网页/文章/公众号来源除正文外,一律额外收集图片 URL——普通站点抓 HTML 后用正则在
data-src/src提取(见步骤 3.5);SPA 站点改用 WebFetch 时 prompt 追加"请另起一段列出文中所有图片的完整 URL",把 URL 存盘供后续下载。纯文本/PDF/EPUB 无内联图则跳过。 - 图片/截图:先按用户 OCR 规则(rapidocr 本地 venv)转文本再读。
- 跨章链接已自动净化(v1.2 起):epub 内 TOC/引用常形如
- 读规则:读
{VAULT}/知识库规则.md,严格遵循其目录结构、属性区约定、模板、索引/日志规范、颗粒度决策、失败模式。 - 落原始资料(不可变):把原始文件/提取文本放进
{VAULT}/原始资料/对应子目录。文件名用有意义的中文,避免英文与缩写;复制用 Pythonshutil.copy2最稳(避免中文路径 locale 问题)。
3.5 下载并嵌入图片(固定步骤,网页/文章/公众号等带图来源必做)
- 调用本技能脚本把图下载到{VAULT}/原始资料/素材/:- 普通网页/公众号(
curl能拿到 HTML):"{PY}" "{SKILL}/scripts/fetch_article_images.py" --url "<文章URL>" --out "{VAULT}/原始资料/素材" --prefix "<文章名前缀>" --referer "https://mp.weixin.qq.com/"(微信须带--referer否则 403;其他站点可不带或换成对应域名)。 - SPA/JS 壳站点(
curl失败,如 xuexi.cn):先按步骤 1 用 WebFetch 取出图片 URL 清单存为urls.txt,再python fetch_article_images.py --urls-file urls.txt --out "{VAULT}/原始资料/素材" --prefix "<文章名前缀>"下载。 - 脚本逐张输出
OK|../素材/文件名|原URL|字节数;在原始资料 md 对应图片出现的段落下方,用相对路径![[../素材/文件名.jpg]]嵌入(原始资料 md 位于原始资料/文章/,素材在原始资料/素材/,故用../素材/)。 - OCR 预描述(推荐,图含文字/数据时必做):对下载到
原始资料/素材/的图跑本地 rapidocr(C:/Users/YANGLIN/.workbuddy/binaries/python/envs/ocr),提取图中文字/数字,写入原始资料页对应图下方作为图注,或补强来源页「关键要点」。纯装饰图可跳过标注。 - 降级:若沙箱网络受限导致全部下载失败(极少,已实测微信图可下),则不本地化,改为在原始资料 md 对应位置以外部链接
录入,并在页面顶部加has_images: true+ 注释"配图以外部链接形式录入(抓取于 YYYY-MM-DD),链接可能失效,建议联网时手动下载到素材目录"。日志同注。 - 不臆造:拿不到真实图片 URL 就不写
![]();不要凭空编造图中内容。
- 普通网页/公众号(
- 写知识库页(维护者全权拥有,遵循属性区约定与模板):
-知识库/来源/1 份单源摘要页(一句话 / 关键要点 / 与现有知识的关系 / 抽取实体)。
-知识库/实体/实体页(人 / 组织 / 工具 / 项目)。
-知识库/概念/概念页(方法 / 框架 / 术语)。按颗粒度决策:被 ≥2 主题引用、有演进状态、可命名 → 独立页;单纯服务父概念的子知识点 → 并入父概念页作子节。拿不准先建status: 待核桩页。
- 页面间用[[中文维基链接]]互链(Obsidian 原生双链),这是知识库价值来源。
- 新信息推翻旧结论 → 标status: 矛盾+ 写矛盾行,不静默覆盖。
- 一篇源通常触动 9–15 个页面。 - 末步统一更新导航(防索引/日志不同步):
- 重写/追加知识库/索引.md:按 实体/概念/来源/综合 四类各加一行[链接] 一行摘要 | 来源数 | 更新日。
- 追加知识库/日志.md:统一前缀## [YYYY-MM-DD] 摄入 | <标题>,列出源路径、产出页、备注(含图片是否已本地化/降级标注)。
铁律
原始资料\永不被维护者修改;只新增,不删改用户原稿。- 知识库页不夹带密钥;敏感稿用
.gitignore排除。 - 每次摄入末步必更新 索引 + 日志,否则查不到刚摄入的页。
- 命名全中文:目录、文件名、属性区
type(实体/概念/来源/综合)、维基链接目标,尽量不用英文与缩写(专有名词如 τ 缩放可保留符号)。 - 带图来源必做图片步骤(3.5):下载本地化优先,降级为外链时务必标注
has_images与抓取日期,绝不留下无来源的![]()。 - 链接不可达先复测:用户给的 URL 首次抓取失败时,必须用完整 URL 原样换方式复测(≥2 种:换 UA/curl → WebFetch → 搜索反查),确认一致失败才可下"链接失效"结论;严禁凭单次探针即声称"你给的链接 404 / 缺某段 / 有误"。
环境注意
- 沙箱默认代理 127.0.0.1:7890 常未运行,外网抓取需
unset HTTP_PROXY HTTPS_PROXY后直连。 - 中文 PDF 必须
-enc UTF-8;Git Bash 中文路径用 Python 复制最稳。 - 编码坑:解码误用
utf-8+ignore会把非法字节静默丢弃、替换符计数为 0,从而误判「已是 UTF-8」;须优先读 meta charset 或 strict 解码。curl 须加--compressed防 gzip 字节被当文本解码成乱码。 - 文件名乱码排查:如「t韬定律」实为 τ(tau)缩放——遇到看不懂的文件名先读正文确认真实主题再命名。
- 维基链接目标用文件名(不含扩展名);重命名文件后必须同步更新所有
[[链接]],避免断链。 - ⚠️ Windows 文件名禁含
/\:*?"<>|:[[华为三大业务流程(LTC/IPD/ITR)]]这类含/的链接,Windows 会把/当路径分隔符,Write 工具会把文件建到嵌套错位目录(概念\华为三大业务流程(LTC)\IPD\ITR).md),且[[...]]因/无法匹配文件名而断链。修复法:层级分隔改用中圆点·(U+00B7,Windows 合法),如华为三大业务流程(LTC·IPD·ITR),并全局替换所有 md 里的旧串(用 Pythonglob+str.replace批量改最稳)。命名含层级时优先用·或、。 - ⚠️ 索引/日志被 Obsidian Linter 实时重排:对
索引.md等高频被 Linter 触碰的文件,Edit 工具并行多改同一文件会报「modified since read」而失败(Linter 在每次保存后重排)。批量更新索引改用 Python 单进程read→改→写(用io.open全程 utf-8),逐行startswith锚定标题前缀再追加新行/替换| n |来源计数,避免并行 Edit 竞态。日志用 Edit 在顶部追加通常无碍(Linter 一般不动日志)。 - ⚠️ 图片下载:沙箱已实测可直连
mp.weixin.qq.com并下载mmbiz.qpic.cn配图(须带--referer https://mp.weixin.qq.com/绕过防盗链)。正则用data-src="(https?://[^"]+)"优先(微信配图在data-src,src常为占位 1x1 图)。SPA 站点(xuexi.cn 等)curl拿不到 HTML,图片 URL 须由 WebFetch 取,再走--urls-file模式下载。图片文件名用<文章前缀>_图NN.<ext>,避开 Windows 非法字符。