Lathe 帮助程序员用 LLM 系统学习新领域而非浅尝,提升学习效率。实用开源项目,直接改善开发者学习流程。
这是一个用 LLM 教你而不是代替你思考的实验。
Lathe 按需生成实践性的、多部分的技术教程,通过调整技能使内容更易于理解。然后你在一个从零开始专为愉快学习体验设计的本地 UI 中自己手动完成这些教程。(就像我们在石器时代做的那样 😎)
Lathe 是 LLM 技能和 Golang CLI 的组合,用于存储、管理和查看生成的教程。安装后(见下文),你可以在任何编码智能体内部生成教程(支持 Claude Code、Cursor、Codex、Gemini CLI、opencode、Cline 和 Windsurf),通过提示如:
/lathe build a 3D Slicer in Erlang
然后从任何终端打开 lathe:
lathe serve # starts the web server, opens the browser
别担心,我们还有深色模式:
点击你想阅读的教程并开始学习!
CLI 有很多其他命令,但坦白说,这些命令是为了给 LLM 一个确定的方式来管理教程。我预期以上对你日常所需来说已经足够(这是我经常使用的全部)。如果你想就教程提问、让 LLM 验证它或通过额外部分扩展它,UI 为每一个都提供了相应的功能。
这些按钮有两种工作方式:
实时模式(无需复制粘贴):在 lathe serve 运行时在你的编码智能体中运行一次 /lathe-work。这会启动一个小的工作循环,Ask 抽屉显示"● agent connected",Ask / Verify this tutorial / Add a part 按钮在那个会话中直接驱动工作——答案直接在阅读器中呈现,验证和扩展就地更新。在任何支持的智能体中工作。随时停止循环;按钮只是恢复为复制粘贴。
复制粘贴回退(无工作器连接):每个按钮会提供给你确切的 /lathe-* 命令以粘贴到你的 LLM 中以触发操作。
无论哪种方式,模型工作都在你的交互式智能体会话中运行——二进制文件从不自己驱动模型。
Lathe 是一个单一的自包含二进制文件。你只需要在 $PATH 中有 lathe;技能在交互式编码智能体会话中运行(Claude Code、Cursor、Codex、Gemini CLI、opencode、Cline 或 Windsurf)。
Homebrew(macOS,推荐):
brew install devenjarvis/tap/lathe
作为 cask(预构建的二进制文件)分发,所以仅限 macOS——在 Linux 上使用下面的安装脚本或 go install。
安装脚本(curl | sh):
curl -sSf https://raw.githubusercontent.com/devenjarvis/lathe/main/install.sh | sh
go install github.com/devenjarvis/lathe@latest
git clone https://github.com/devenjarvis/lathe
cd lathe
go build -o lathe
技能被捆绑到二进制文件中。安装 lathe 后,将它们放入项目中,以便你的编码智能体可以发现它们:
lathe skills install # ./.claude/skills/<name>/SKILL.md (this project)
lathe skills install --user # ~/.claude/skills/<name>/SKILL.md (all projects)
lathe skills install --agent cursor # ./.cursor/commands/<slug>.md (Cursor slash commands)
lathe skills install --agent codex # ./.agents/skills/<name>/SKILL.md (Codex Agent Skills)
lathe skills install --agent gemini # ./.gemini/skills/<name>/SKILL.md (Gemini CLI)
lathe skills install --agent opencode # ./.opencode/skills/<name>/SKILL.md (opencode)
lathe skills install --agent cline # ./.cline/skills/<name>/SKILL.md (Cline)
lathe skills install --agent windsurf # ./.windsurf/skills/<name>/SKILL.md (Windsurf)
lathe skills install --agent antigravity # ./.antigravity/skills/<name>/SKILL.md (Antigravity)
lathe skills install --agent all # every target above
lathe skills list # show the bundled skills
SKILL.md(名称 + 描述 frontmatter)现在是跨工具标准,所以除了 Cursor 之外的每个目标都逐字交付原始技能——Claude Code、Codex、Gemini CLI、opencode、Cline 和 Windsurf 都按原样读取,而 --user 安装到该智能体的主目录(Cursor 和 Windsurf 仅限项目,会警告并回退)。Cursor 是唯一的翻译情况:其命令作为 /<slug>(例如 /lathe)被斜杠调用。交互式交接模型对照 Claude Code 记录,所以在其他智能体上有一些运行时细节差异。
Lathe 本身不与任何模型通信,所以本地 LLM 不需要特定的 Lathe 设置:将你的编码智能体指向本地 OpenAI 兼容的端点(例如 Ollama 的 http://localhost:11434/v1)并完全按照上面运行 /lathe 技能。你能运行的本地"思考"模型越大,教程就越好——这些是研究和解释繁重的任务,而不是机械编辑。
我在 2000 年代作为青少年学习编程,通过为 PSP(PlayStation Portable)构建自制游戏,用 Lua,然后用 C++。我当时学到的很多东西都是通过我参与其中的小型 PSP 自制社区学到的,我为此感到无比感激,但我也欠了很多重要的学习资源给互联网上可用的免费在线资源和教程(向 2007 年的 cplusplus.com 致敬——天哪,那个网站现在比以前有更多广告了😅)。最终我成为了一名专业软件工程师,在接下来的十年中,我通过寻找和消费大量技术博客来"提升技能"(尽管通常是为了学习比需要更有趣的主题),更重要的是对我的学习风格而言——实践教程。像 build-your-own-x 仓库、Crafting Interpreters 以及 1000 多个其他一次性教程这样的资源教会了我从构建光线追踪器到时间序列数据库再到线性代数矩阵库的各种知识,以及所有其他的东西(说真的,我甚至无法开始列出所有影响我的惊人实践教程)。
实践学习一直是我最好的学习方式。这些教程为我提供了从零到一进入全新领域所需的学习曲线,但更重要的是,它们给了我从一到十自己继续的基础和信心。
快进到 2026 年,现在我们有了 LLM。我不想离题讨论我与 LLM 的复杂关系,但对于编写软件来说,它们很有趣,在很多情况下它们可以真正提高生产力!但是它们为你做了大部分工作,随着这些工作消失,它们也带走了帮助我学习新概念或领域的部分。在某些情况下,这没有关系——我们有产品要发布,LLM 帮助我们更快地发布——但对于我和我对这个领域和爱好的热情,我仍然渴望那些"顿悟!"的时刻,当某些东西最终点击,我有了开始将其塑造成我自己的东西所需的信心。
所以 lathe 是一个用 LLM 教我而不是代替我思考的实验。重新创造那些教会我热爱这项工作的实践学习的时刻,并将其与一个广泛的"专家" LLM 的潜力相结合,这个 LLM 在理论上可以教我任何东西。我使用 lathe 作为催化剂来启动我不知道如何开始的项目,并且找不到任何现有的人工编写的资源来教学。例如,我最初想出 lathe 是因为我想从头开始编写 3D 切片软件(仅仅找到 g-code 的文档就很痛苦,向 reprap 致敬)。在撰写本文时,我正在深入研究 Zig 的嵌入式软件开发世界。在这两种情况下,lathe 都是一个有效的工具,帮助我在人工编写的资源还不存在的模糊或极其年轻的领域中从零到一(我想知道如果只有 LLM 读取,人类还会麻烦编写教程多久...)。
Lathe 教程与人工编写的教程一样好吗?根本不是。但是它们在真挚、个性和架构合理性方面的不足,通过让教程编写者随时准备回答你所有的问题、总是愿意修复或更新他们的教程直到它正是你想要的样子、他们实际上完成了他们在 2018 年开始的那个系列的全部 6 部分(我们都经历过😁)来弥补。Lathe 是一个 LLM,虽然我已经构建并调整了它以尽我所知对这个特定任务尽可能好,但它仍然会以 LLM 失败的方式失败。我建议使用你有权访问的最大"思考"模型(Opus、GPT-5 Codex 等),因为这些任务不太涉及你在编程时可能会优化的迭代机械执行,而更多是关于研究、设计和从头到尾解释一个有形的概念。
此外,在这种情况下,幻觉的风险在我看来要低得多。Lathe 的设计目标是帮助你进行思考,而不是替你思考,它建立在你自己敲代码的预期基础上。通过阅读指南并自己敲出代码,你在主动参与工作中,当遇到奇怪的地方时,应该能自然地问自己「等等,这说得通吗?」。到那时你可以用 /lathe-ask(有时 AI 智能体会给出我没想到的好理由,因为这是陌生领域,我学到了新东西),或者直接告诉你的 AI 智能体更新教程。虽然我没有教育学证书来支撑这个说法,但我认为通过发现并推敲 AI 智能体的感知失误,我可能会更好地内化概念。具体效果因人而异。
也就是说,如果你能找到人工撰写的教程,我总是会优先选择那个。我希望大多数情况下你也这样做。但如果你和我学习方式相同,并且想深入一个教学资料稀缺的领域,Lathe 是个相当不错的工具。只是要记住它是 AI 智能体,不是人。为了帮助你意识到这一点,我始终努力清楚地表明你能获得什么和不能获得什么。Lathe 编写教程的技能会告诉你它什么时候对自己写的东西没把握,而我虽然尝试了更「个人化」的语气,但我默认选择了一个不会冒充真人的声音。
说实话,你是凭感觉编程来做这个的吗?这不是和你的论点自相矛盾吗?
没错,Lathe 本身是「凭感觉编程」出来的。在这种情况下,Lathe 的范围和风险都很低。它是一个活的论文,用于个人学习。也就是说,最近我每天都在用它,它已被证明是我工具箱中有用且稳定的工具。我通过使用它学到了很多东西,到目前为止我认为它足够好,让其他人也能从中受益。我期望接下来的几个小版本会进行一些有意的代码/架构清理,以确保它对其他人保持稳定,当然还要吸收我收到的任何反馈。
也就是说,为了透明起见,目前我在 macOS 上用 Claude Code 测试 Lathe 的我的用例。Lathe 的设计与特定 AI 智能体无关(技能是跨工具标准,CLI 本身从不调用模型),所以其他 AI 智能体和平台应该也能工作,但我只验证过自己的设置。如果你愿意在不同的 AI 智能体或操作系统上试试,结果是可以工作或遇到了困难,我很乐意通过 issue 了解任何一种情况!
好吧,它到底怎样工作的?
LLM 技能 — 在你的交互式编码 AI 智能体会话中生成和处理教程,所有操作都在你的会话内运行:/lathe 编写 part-01.md,/lathe-extend 添加下一部分,/lathe-verify 逐步完成教程以确认其编译和运行,/lathe-ask 回答你阅读某部分时的问题,/lathe-tag 为现有教程添加搜索标签,/lathe-work 运行一个工作循环,让网页按钮直接驱动 Ask/Verify/Extend(见上面的实时模式)。Go 二进制文件从不驱动任何模型 — 所有模型工作都在你的交互式 AI 智能体会话中运行,所以它使用的是该 AI 智能体的订阅或端点。(具体来说,这也让 Lathe 远离了 Claude Code 的 claude -p 等计量无头运行,计划从 2026-06-15 起作为计量的一部分。)/lathe-work 也遵守这一点:它是你交互式会话中的长轮询循环,永远不是无头 -p 运行。
lathe CLI(Go) — 将教程复制到 ~/.lathe/tutorials/,在 http://localhost:4242 提供呈现的输出,拥有所有持久状态。它本身从不调用 AI 智能体。当有 /lathe-work 工作进程连接时,网页按钮会为该会话排队一个任务供其接取;否则它们会给你要粘贴的技能命令。无论哪种方式,技能都会完成模型工作并回调到 CLI(lathe store、lathe verify-result、lathe extend-start/extend-commit、lathe voice add 以及 /lathe-work next/answer/done 用于工作循环)来记录结果和关闭任务。
UI 怎么样?
我很高兴你问了!Lathe 技能和 CLI 是同时开发的,目的是提供(我认为是)很好的阅读和学习体验。一些关键特性让使用 Lathe 比直接提示 Claude 更有价值(对我来说):
在右侧栏悬停时有完整的目录导航
内容全程伴有旁注,促使我更深入地思考
每个教程末尾都有留给读者的练习
每个教程都有一个声音。声音控制散文的风格,但不会改变准确性、研究、引文、验证或结构,这些是固定的。Lathe 附带两个声音:
plainspoken(默认)— 诚实而精确,没有虚构的人设或编造的第一人称战争故事。它的写法是为了避免把生成它的 AI 智能体拟人化。
companion — 温暖、讽刺的「键盘旁的朋友」的第一人称尝试。
通过在你的 /lathe 调用中命名它来为每次运行选择一个(「...in the companion voice」),或更改全局默认值:
lathe voice list # 查看可用选项;* 标记默认值
lathe voice show companion # 打印某个声音的完整规格
lathe voice set-default companion # 为新教程更改默认值
自定义声音。如果你不喜欢 Lathe 自带的声音,没问题,你随意。你可以在 AI 智能体会话中用 /lathe-voice 编写自己的声音,它会向你提问关于寄存器、人称和幽默的问题,草拟一个规格,经你同意后通过 lathe voice add <name> --file - 保存到 ~/.lathe/voices/。
自定义声音被指示不得冒充真实的具名人物、编造资历或否认 AI 智能体作者身份。/lathe-voice 拒绝这些,每个声音都被包裹在一个固定的前言中,在生成时强制执行相同规则。教程编写所用的声音被记录下来(所以 /lathe-extend 会用它继续),并在每个教程顶部的作者署名中披露:Generated by <Model> · voice <name>,其中模型是用于生成教程的具体 AI 智能体(例如「Claude Opus 4.8」),声音名称会展开显示完整规格。
我充分认识到这是一场猫鼠游戏,任何这里的安全尝试都可能被规避。不幸的是,无论我是否发布 Lathe,想要用 AI 生成的垃圾教程淹没世界的坏人已经全力以赴了。但我想尽自己的一份力,让人清楚 Lathe 不是 为了在你的个人使用范围之外写内容,而是为了你个人学习。
随着你的库增长,网页列表页面(lathe serve)有一个搜索框和过滤器来缩小范围 — 全部客户端运行,所以速度快且离线可用:
搜索匹配教程的标题、主题、标签、仓库和工具版本。
按最新、最旧或标题排序(A–Z)。
按状态、类型(单独或系列)、标签和版本过滤。
默认端口是 4242;用 --port 覆盖。
教程全局存放在 ~/.lathe/tutorials/ 中,每个 slug 一个目录:
~/.lathe/tutorials/
digital-synth-zig/
metadata.json
part-01.md
part-02.md
part-03.md
database-from-scratch-go/
metadata.json
index.md
{
"slug": "digital-synth-zig",
"title": "Build a Digital Synth in Zig",
"topic": "build a digital synth in Zig",
"created": "2026-05-03T19:00:00Z",
"status": "unverified",
"tags": ["zig", "audio", "dsp"],
"parts": ["part-01.md", "part-02.md", "part-03.md"],
"tools": [{ "name": "zig", "version": "0.13.0" }],
"sources": ["https://ziglang.org/documentation/0.13.0/"],
"voice": "plainspoken",
"model": "Claude Opus 4.8"
}
除了核心字段(slug/title/topic/created/status)外的所有内容都是可选的,为空时省略:tools(教程针对的语言/工具链,显示为版本芯片和版本过滤器)、sources(研究线索 — 见下文)、voice 和 model(阅读页面上的署名),以及当教程针对特定 git 仓库编写时的 repo/repo_branch。
Status 是下列之一:unverified(lathe store 后的默认值;不呈现徽章)、verifying、verified、failed、skipped 或 extending(在 /lathe-extend 编写新部分时设置)。失败时,verify-result.json 被写入到教程旁,记录失败的部分、步骤号和错误输出;网页 UI 在教程页面上呈现为一个面板。
每个教程都保留了其背后的研究轨迹——生成技能在编写时实际查阅的网址。这与部分 markdown 中内联的 ## Sources 引用不同:它是一条持久的、教程级的记录,存储在 metadata.json 的 sources 字段中,并在 UI 中展示为来源出处,这样你可以理性地检查材料来自何处,而不是盲目相信文章内容。
/lathe 通过 lathe store --source <url>(可重复)来捕获它们,/lathe-extend 会将任何新查阅的网址折叠到同一轨迹中(lathe extend-commit --source),并根据已有内容进行去重。
在列表页面上,每张卡片在其元数据行中显示 · N sources 计数。
在阅读页面上,"Researched against N sources"(基于 N 个来源研究)面板展开显示完整的链接列表。
验证是可选的,在你的交互式 LLM 会话中运行。存储教程时会保持未验证状态,在你主动请求前不会运行任何内容。如果连接了 /lathe-work worker,"Verify this tutorial"(验证此教程)按钮会直接在该会话中启动它。否则——通过 lathe verify <slug> 命令或 lathe store 上的 --verify 标志——你会得到相同的命令粘贴到你的会话中:
/lathe-verify <slug>
/lathe-verify 技能遍历教程中的每一步,在新的 mktemp -d 暂存目录中创建文件(从不在你的仓库中),运行命令,执行每个 ## Checkpoint 块,然后调用 lathe verify-result 将结果记录在教程的 metadata.json 中。它在开始时标记运行为验证中,在完成时标记为已验证 / 失败 / 已跳过。
验证仅在安装了教程工具链的地方才有意义。如果缺少所需工具(例如没有 zig 二进制文件),运行被报告为已跳过 (⚠️) 而非失败——"无法在此验证"与"已损坏"不同。
由于验证现在在你自己的交互式会话中运行,它在你的常规 LLM 权限模型下执行,所以你可以看到并批准工具调用。暂存目录约定可以将构建工件保持在仓库外,但最多将其视为软隔离,而不是安全边界。