distill-textbook
一门课往往散落在:精装教材、PPT、B 站录播、官方 PDF、自己的旧笔记。直接丢给大模型,得到的是另一份流畅但不可信的转述——漏掉限定条件、编造法条编号、把口误写成定论。
distill-textbook 是给 Agent 用的工作流 skill:按节精炼,用脚本卡住预算与格式,用你本人的批准当硬门,再按你点头过的标准目录把多源材料合成一份私人教材。
目标函数只有一个:完整度。精炼只删减、只整理,不生成原文里没有的句子。
适合知识密度高、有标准答案的材料(公务员考试公共基础知识是典型场景)。不适合靠推导本身当内容的数学,也不适合观点即正文的人文学科。
为什么不是丢进对话框
| 常见做法 | 实际会发生什么 | 这里怎么挡 |
|---|---|---|
| 整章 / 整节课塞进上下文 | 注意力后半段塌掉,数字和例外先丢 | 脚本强制切到节,超预算直接失败 |
| 「帮我总结这本书」 | 流畅、完整、原文没有的结论也写进去了 | 提示词禁止补全;校验失败进隔离区 |
| 模型自己说「试跑通过」 | 自评永远偏乐观 | pilot.md 必须你填 approved,脚本不认「文件在」 |
| 教材永远压过讲义 | 口诀、解题技巧被当成冗余删掉 | 权威分层;讲义独有的技巧一律保留 |
| 无字幕就上 Whisper | 贵、慢、口误更多 | 有字幕用字幕(含自动字幕);没有再 ASR |
六问抽样(你来填,模型不准代填):漏了什么、多了什么、改了原意没有、数字/例外还在不在、存疑有没有被写死、结论能否回到页码或时间戳。
它做什么
flowchart LR
S["视频 / PDF / 网页 / Office"] --> I[ingest]
I --> C["按节切开<br/>3000–6000 字"]
C --> W["精炼笔记<br/>只删不写"]
W --> P{"你批准试跑?"}
P -->|否| C
P -->|是| M["跨源合并<br/>权威裁决"]
M --> T["05-textbook/<br/>私人教材"]
| 输入 | 处理 |
|---|---|
| YouTube / B 站 / 本地音视频 | 字幕优先;没有字幕再 faster-whisper |
| PDF / Word / PPT / Excel / EPUB | MarkItDown;PDF 优先 pdftotext -layout |
| 网页 URL / HTML | 正文 + 配图走你自己的视觉 API(只转录图上的字) |
| 旧笔记、讲义、习题解析 | 标明 content_type 与 authority,合并时按规则裁决 |
Agent 读的是 SKILL.md。字段与冲突规则在 schema.md,提示词种子在 prompts.md。
安装
丢给正在用的 Agent 这一句:
把 distill-textbook 装上:npx skills add NorthAdb/distill-textbook -g
或自己执行:
npx skills add NorthAdb/distill-textbook -g
装到用户级目录后,用名字唤起:/distill-textbook(或你那套 Agent 的等价写法)。
兼容 Cursor、Claude Code、Codex(agents/openai.yaml,默认不隐式触发),以及任何会加载 SKILL.md 的环境。
手动安装:把本仓库放到 ~/.agents/skills/distill-textbook,需要的话再 junction 到 ~/.claude/skills / ~/.cursor/skills。
运行依赖
pip install -r requirements.txt
| 依赖 | 用途 |
|---|---|
Python 3.10+、本仓库 requirements.txt |
脚本;含 faster-whisper、MarkItDown |
| ffmpeg | 无字幕时的 ASR |
| Agent Reach | YouTube / B 站字幕与音频(yt-dlp、bili-cli;B 站 CC 还要 OpenCLI + 桌面 Chrome) |
Poppler 的 pdftotext(可选) |
保留版式的 PDF 抽字 |
B 站不要用 yt-dlp。付费课、网盘、必须登录的页面,请先自己下到本地再 ingest。
十分钟试跑
对 Agent 说:
/distill-textbook
工作目录:D:\my-corpus
视频:https://www.bilibili.com/video/BVxxxxxxxxxx
教材:D:\books\xx.pdf
先做最小验证,不要全量。
或自己跑:
python scripts/init_corpus.py D:\my-corpus
python scripts/ingest_video.py "https://www.bilibili.com/video/BVxxxxxxxxxx" \
--transcript D:\my-corpus\01-transcripts\v01.md \
--audio D:\my-corpus\00-sources\v01.m4a \
--source "第一讲" \
--clip 0,600
python scripts/ingest_source.py D:\books\xx.pdf \
-o D:\my-corpus\00-text\book.md \
--content-type 教材 --source "《XX》"
python scripts/check_gate.py D:\my-corpus --stage 3
试跑没过,禁止全量。 pilot.md 初始就是 pending;只有你把 status 改成 approved 并填写 approved_by / approved_at,门才会开。每种实际用到的 media_type 各抽一节——不要只用 10 分钟视频代表全部材料。
全量流水线
阶段 0 素材归集 本地 path;文档进 00-text/
阶段 1 文稿 字幕优先,没有再 ASR → 01-transcripts/
阶段 2+3 单源精炼 切分 → wash → 校验;失败进 03-notes/_quarantine/
阶段 4 跨源整合 你先批 curriculum.yaml + crosswalk.yaml
阶段 5 产出 05-textbook/ + 按标准目录的索引
python scripts/check_gate.py <corpus> --stage 3 # 全量精炼前
python scripts/check_gate.py <corpus> --stage 4 # 跨源合并前
工作区:
<corpus>/
manifest.yaml # 来源:media_type / content_type / authority
plan.yaml # 节级计划(hash / model / status)
curriculum.yaml # 标准目录(须你批准)
crosswalk.yaml # 来源节 → 标准节(须你批准)
coverage.md
pilot.md # pending | approved | rejected
00-sources/ # 原始文件
00-text/ # ingest 后的可切分文本
01-transcripts/ # 字幕 / ASR(派生产物,不是来源类型)
02-sections/
03-notes/
03-notes/_quarantine/
04-merged/
05-textbook/
冲突裁决:authority(primary > official > textbook > lecture > personal)→ 较新的 published → priority。仍分不出就两说并存并标出处。讲义里的口诀、技巧,更高权威没写的全部留下。
节笔记固定四块:核心概念 / 要点 / 例子与数据 / 存疑。存疑空则写「无」,不能省略。
配置 API
精炼(wash.py)和网页配图识别共用一套 OpenAI 兼容接口。视觉模型自己配,不必装 Tesseract。
$env:DISTILL_API_KEY = "sk-..."
$env:DISTILL_API_BASE = "https://api.openai.com/v1" # 按服务商改,通常要带 /v1
$env:DISTILL_MODEL = "gpt-4o-mini" # 精炼;带视觉也可兼配图
$env:DISTILL_VISION_MODEL = "gpt-4o-mini" # 可选;不设则复用 DISTILL_MODEL
精炼用便宜文本模型、配图用视觉模型时,把两个变量分开。也可不设环境变量,在命令行传 --api-key --api-base --vision-model。
.env.example 可复制为 .env 当备忘;脚本不会自动加载,需要 export / 自行注入。
配图只转录图上已有的文字,不描述画面。未配 API 时仍保留 alt。动态空壳页抽不出字:用 Agent Reach 的 r.jina.ai 另存 Markdown,或把完整 HTML 存下来再 ingest。
脚本一览
在仓库根目录执行,scripts/ 与 SKILL.md 同级。
| 脚本 | 作用 |
|---|---|
init_corpus.py |
建工作区与模板 |
check_gate.py |
批准门 |
ingest_video.py |
字幕优先摄入视频 |
fetch_media.py |
无字幕时拉音频 |
transcribe.py |
faster-whisper 兜底 |
ingest_source.py |
文档 / 网页 → 00-text/ |
ocr_images.py |
抽图并走视觉 API |
api_env.py |
DISTILL_* 配置 |
split_budget.py |
强制字数切分 |
validate_note.py |
节笔记契约 |
wash.py |
精炼;失败隔离 |
常见问题
会不会把整本教材上传到网上?
不会。本仓库是工作流,不含教材。音视频、PDF 留在你指定的 corpus 目录。API 只在你调用 wash.py / 配图识别时,把已经切开的那一节或图片发给你配置的服务商。
产物能直接拿去考试吗?
不能当权威文本。法条、真题、执业要点必须回原书或官文核对。skill 里把这一点写成硬约束。
数学 / 文学为什么不适用?
推导步骤和论证脉络本身就是内容。当成「口语冗余」删掉之后,知识结构会一起消失。
模型能自己把 pilot 标成通过吗?
不能。check_gate.py 读的是 YAML 里的 status。模型代填属于违规,门不会开。
skills.sh 上搜得到吗?
安装命令立刻可用。目录收录靠安装量,可能要过一段时间。
许可
MIT。这是流程,不是教材。不要把受版权保护的课程视频、PDF、题库提交进 git。蒸馏笔记是二手材料。
Issue 与想法请开 GitHub Issues。
No comments yet
Be the first to share your take.