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_typeauthority,合并时按规则裁决

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-dlpbili-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)→ 较新的 publishedpriority。仍分不出就两说并存并标出处。讲义里的口诀、技巧,更高权威没写的全部留下。

节笔记固定四块:核心概念 / 要点 / 例子与数据 / 存疑。存疑空则写「无」,不能省略。


配置 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