<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Claude Code on Hypho - AI Agent 技术博客</title><link>https://blog.hypho.cn/tags/claude-code/</link><description>Recent content in Claude Code on Hypho - AI Agent 技术博客</description><image><title>Hypho - AI Agent 技术博客</title><url>https://blog.hypho.cn/papermod-cover.png</url><link>https://blog.hypho.cn/papermod-cover.png</link></image><generator>Hugo -- 0.148.2</generator><language>zh-cn</language><lastBuildDate>Mon, 08 Jun 2026 10:06:01 +0800</lastBuildDate><atom:link href="https://blog.hypho.cn/tags/claude-code/index.xml" rel="self" type="application/rss+xml"/><item><title>Vibe Coding 让你跳过学习，这个开源项目偏要让你亲手写代码</title><link>https://blog.hypho.cn/posts/lathe-llm-learn-by-doing-not-vibecoding/</link><pubDate>Mon, 08 Jun 2026 10:06:01 +0800</pubDate><guid>https://blog.hypho.cn/posts/lathe-llm-learn-by-doing-not-vibecoding/</guid><description>当 AI 编程助手让开发者习惯&amp;#34;跳过思考直接出代码&amp;#34;时，开源项目 Lathe 反其道而行——用 LLM 生成手把手教程，要求你亲手敲每一行代码。这种&amp;#34;反 Vibe Coding&amp;#34;的学习方式，可能才是 LLM 时代真正需要的开发者工具。</description><content:encoded><![CDATA[<p>最近 HN 上有篇帖子引起了我的注意：一个叫 Lathe 的开源项目，247 points，标题是&quot;Use LLMs to learn a new domain, not skip past it&quot;。</p>
<p>说实话，看到这个标题的第一反应是：又一个 LLM 教学工具？市面上这类东西已经太多了——NotebookLM、各种 AI tutor、ChatGPT 自己就能教你任何东西。但仔细看完 README 和 HN 评论区之后，我觉得这个项目抓住了一个很多人没说出口的痛点。</p>
<h2 id="问题出在哪">问题出在哪？</h2>
<p>过去一年，&ldquo;Vibe Coding&quot;这个概念从 Andrej Karpathy 的一条推文变成了整个行业的主流工作方式。打开 Claude Code、Cursor 或者 Copilot，描述你想要什么，AI 帮你生成代码，你负责 Review 和微调。效率确实高，但这里有一个很少被正面讨论的问题：<strong>你到底学到了什么？</strong></p>
<p>HN 上另一篇今天 807 points 的帖子——&ldquo;LLMs are eroding my software engineering career&rdquo;——把这个焦虑写得很直白。一位资深工程师说，LLM 正在侵蚀他的软件工程职业，他不知道该怎么办。评论区里各种声音都有，但核心矛盾其实就一个：当 AI 代劳了思考过程，工程师的价值在哪里？</p>
<p>这不是杞人忧天。看看现在的 AI 编程成本追踪工具（比如 <a href="/posts/budi-ai-coding-cost-tracker/">Budi</a>）就知道，很多团队每个月在 AI 编程上的开销已经不小了。但如果你问这些开发者&quot;你从 AI 生成的代码里学到了什么&rdquo;，大部分人会沉默。</p>
<h2 id="lathe-的反直觉设计">Lathe 的反直觉设计</h2>
<p>Lathe 的作者 Deven Jarvis 在 README 里写了一段很长的个人经历，我读完觉得挺真诚的。他在 2000 年代通过 PSP 自制游戏社区学会了编程，后来通过各种 hands-on 教程（build-your-own-x、Crafting Interpreters 这类）不断精进。他说这些教程给他的不只是知识，更是&quot;从零到一&quot;的信心和继续深入的底气。</p>
<p>然后他发现 LLM 把这个过程跳过了。</p>
<p>Lathe 的设计哲学很明确：<strong>LLM 应该是你的老师，不是你的代笔。</strong> 具体来说，它做的是：</p>
<ol>
<li><strong>生成手把手教程</strong>：你给一个主题（比如&quot;用 Zig 写一个 3D 切片器&quot;），Lathe 会生成多部分的详细教程，每一步都有代码和解释</li>
<li><strong>你必须亲手敲代码</strong>：教程在本地 UI 里展示，但代码不会自动复制到你的编辑器——你得自己打</li>
<li><strong>带验证机制</strong>：教程可以被 LLM 自己验证，跑一遍看能不能编译通过</li>
<li><strong>记录信源</strong>：每个教程都记录它参考了哪些资料，方便你溯源</li>
</ol>
<p>技术实现上，Lathe 是一个 Go CLI + LLM Skills 的组合。CLI 负责存储和管理教程（存在 <code>~/.lathe/tutorials/</code>），本地 Web 服务（端口 4242）负责展示，而生成、验证、提问这些操作都通过 LLM Skills 完成。目前支持 Claude Code、Cursor 和 Codex。</p>
<h2 id="skills-架构比想象中更精巧">Skills 架构：比想象中更精巧</h2>
<p>Lathe 的 Skills 设计值得单独说一下。它不是简单地让 LLM &ldquo;写一篇教程&rdquo;，而是拆分成了多个专门的 Skills：</p>
<table>
  <thead>
      <tr>
          <th>Skill</th>
          <th>功能</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>/lathe</code></td>
          <td>生成教程（单篇或系列）</td>
      </tr>
      <tr>
          <td><code>/lathe-extend</code></td>
          <td>在现有教程基础上追加新部分</td>
      </tr>
      <tr>
          <td><code>/lathe-verify</code></td>
          <td>在临时目录里跑一遍教程，验证能不能正常工作</td>
      </tr>
      <tr>
          <td><code>/lathe-ask</code></td>
          <td>针对教程内容提问</td>
      </tr>
      <tr>
          <td><code>/lathe-tag</code></td>
          <td>给教程添加搜索标签</td>
      </tr>
      <tr>
          <td><code>/lathe-voice</code></td>
          <td>自定义写作风格</td>
      </tr>
  </tbody>
</table>
<p>这个设计的好处是：每个 Skill 都有明确的输入输出和行为约束，不会出现&quot;LLM 突然开始帮你写代码而不是教你&quot;的情况。尤其是 <code>/lathe-verify</code>，它在 <code>mktemp -d</code> 临时目录里执行，不会碰你的项目代码，但能验证教程的可执行性。</p>
<p>自定义 Voice 功能也很有意思。默认有两种风格：&ldquo;plainspoken&rdquo;（平实直接）和&quot;companion&quot;（温暖的第一人称）。你还可以用 <code>/lathe-voice</code> 让 LLM 采访你的写作偏好，生成自定义风格。不过有一点值得注意：所有 Voice 都被要求不能冒充真人、不能伪造资质、不能否认 LLM 作者身份。这种透明性设计在现在的 AI 写作工具里其实不多见。</p>
<h2 id="与-notebooklm-和传统-ai-教学的区别">与 NotebookLM 和传统 AI 教学的区别</h2>
<p>HN 评论区有人问&quot;这和 Google NotebookLM 有什么区别&quot;。我觉得核心区别在于：</p>
<p><strong>NotebookLM 是被动学习</strong>：你上传资料，它帮你总结和回答问题。学习的主体还是你，但交互模式是问答式的。</p>
<p><strong>Lathe 是主动学习</strong>：它生成结构化的动手教程，要求你实际操作。学习过程中你会遇到真实的编译错误、运行时问题，这些&quot;挫折&quot;本身就是学习的一部分。</p>
<p>还有一个关键区别：Lathe 的教程会记录信源（sources），在 UI 里展示&quot;Researched against N sources&quot;。这意味着你可以追溯 LLM 的知识来源，而不是像 ChatGPT 那样凭空给你一段看起来很专业的解释。</p>
<h2 id="坦白说这个方案也有局限">坦白说，这个方案也有局限</h2>
<p>Lathe 不是万能的。作者自己也很坦诚地承认了几个问题：</p>
<ol>
<li><strong>幻觉风险依然存在</strong>：虽然教程要求你亲手写代码（这意味着你会自然地发现不合理的地方），但 LLM 生成的教程本身可能有错误</li>
<li><strong>学习效果取决于你的投入</strong>：如果你只是机械地抄代码而不思考，效果和直接让 AI 写没区别</li>
<li><strong>依赖 Claude Code 等付费工具</strong>：作者提到 Claude Code 的 headless 模式即将收费（2026-06-15），这可能影响成本</li>
<li><strong>目前主要在 macOS + Claude Code 上测试</strong>：其他平台的兼容性还需要验证</li>
</ol>
<p>但我觉得，这些问题恰恰说明了 Lathe 的定位很清醒——它不是要取代人类写的教程（作者明确说&quot;能找到人类写的教程就先看那个&quot;），而是填补那些&quot;没有现成教程的冷门领域&quot;的空白。</p>
<h2 id="对开发者工具的启示">对开发者工具的启示</h2>
<p>Lathe 给我最大的启发不是它本身，而是它代表的一种设计模式：<strong>用 LLM 的能力来增强人的学习，而不是替代人的思考。</strong></p>
<p>在 <a href="/posts/claude-code-routines/">Claude Code 的 Routines</a> 这类工具里，我们已经看到 LLM 可以被约束成&quot;按规则办事&quot;的执行者。Lathe 更进一步，把 LLM 约束成&quot;按规则教学&quot;的老师。这种思路可能比单纯追求&quot;AI 帮你写更多代码&quot;更有长期价值。</p>
<p>想想看，如果每个 AI 编程工具都有一个&quot;学习模式&quot;——在帮你写完代码之后，用教程的形式解释为什么这样写、背后的原理是什么、有哪些替代方案——那&quot;LLM 侵蚀工程师职业&quot;的焦虑可能会小很多。</p>
<h2 id="怎么用">怎么用？</h2>
<p>如果你感兴趣，安装很简单：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># macOS（推荐）</span>
</span></span><span class="line"><span class="cl">brew install devenjarvis/tap/lathe
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Linux</span>
</span></span><span class="line"><span class="cl">curl -sSf https://raw.githubusercontent.com/devenjarvis/lathe/main/install.sh <span class="p">|</span> sh
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 或者 Go 安装</span>
</span></span><span class="line"><span class="cl">go install github.com/devenjarvis/lathe@latest
</span></span></code></pre></div><p>然后在 Claude Code（或 Cursor/Codex）里：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># 安装 Skills</span>
</span></span><span class="line"><span class="cl">lathe skills install
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 生成教程</span>
</span></span><span class="line"><span class="cl">/lathe build a raytracer in Rust
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 启动本地 UI</span>
</span></span><span class="line"><span class="cl">lathe serve
</span></span></code></pre></div><p>项目地址：<a href="https://github.com/devenjarvis/lathe">github.com/devenjarvis/lathe</a></p>
<p>目前 550 stars，MIT 协议，4 个 release，作者（和 Claude）123 commits，非常活跃。如果你和我一样，觉得&quot;Vibe Coding 虽然爽但总有点心虚&quot;，可以试试这个。</p>
<hr>
<p><strong>参考资料：</strong></p>
<ul>
<li><a href="https://github.com/devenjarvis/lathe">Lathe GitHub README</a></li>
<li><a href="https://news.ycombinator.com/item?id=48433756">HN: Show HN: Lathe</a></li>
<li><a href="https://human-in-the-loop.bearblog.dev/llms-are-eroding-my-software-engineering-career-and-i-dont-know-what-to-do/">HN: LLMs are eroding my software engineering career</a></li>
</ul>
]]></content:encoded></item><item><title>Open Design 能替代 Claude Design 吗？把编码 Agent 变成设计引擎的工程边界</title><link>https://blog.hypho.cn/posts/open-design-coding-agent-design-engine/</link><pubDate>Mon, 04 May 2026 10:02:22 +0800</pubDate><guid>https://blog.hypho.cn/posts/open-design-coding-agent-design-engine/</guid><description>Open Design 把 Claude Code、Codex、Cursor 等编码 Agent 变成设计引擎，试图替代封闭的 Claude Design 工作流。本文从本地优先、技能系统、沙盒预览、导出链路、Agent 安全和设计系统约束出发，分析它是否适合真实团队用于原型、演示与生产设计流程。</description><content:encoded><![CDATA[<p>如果你已经习惯让 Claude Code 或 Codex 写业务代码，那么下一个很自然的问题是：能不能让同一个 Agent 顺手把产品原型、落地页、PPT、甚至一段演示视频也做出来？</p>
<p>我以前对这类“AI 做设计”的项目比较警惕。原因很简单：很多工具只是把 prompt 包了一层漂亮 UI，最后产物看起来像模板站，改两轮就塌。但最近 Hacker News 上的 <a href="https://hnrss.org/item?id=47985750">Open Design</a> 让我多看了几眼。它不是另一个单点生成器，而是把 Claude Code、Codex、Cursor Agent、Gemini CLI、Qwen、Copilot CLI 等命令行编码 Agent 当成“设计引擎”，再叠一层本地优先的技能、设计系统、沙盒预览和导出链路。项目 README 直接把自己定位成 <a href="https://github.com/nexu-io/open-design">Claude Design 的开源替代</a>。</p>
<p>这句话听起来很大，但工程上真正有意思的不是“替代 Claude Design”，而是它暴露了一个更具体的搜索问题：<strong>设计工作流到底应该由专门的设计模型驱动，还是由已经会读文件、改代码、跑命令的 Coding Agent 驱动？</strong></p>
<p>我的判断是：Open Design 不一定会马上成为生产级设计平台，但它代表了一条很值得关注的路线——把设计从“生成一张图”拉回到“生成一个可运行、可审查、可导出的工程项目”。</p>
<h2 id="它不是文生图工具而是把设计任务工程化">它不是文生图工具，而是把设计任务工程化</h2>
<p>Open Design 的 README 里有几个关键词很关键：local-first、BYOK、agent CLI auto-detect、Skills、Design Systems、sandboxed preview、HTML/PDF/PPTX/MP4 export。翻成人话就是：它不试图自己训练一个万能设计模型，而是把你机器上已有的 Agent CLI 调起来，让 Agent 在一个受控项目里生成和修改设计资产。</p>
<p>这和很多 AI 设计产品的差别很大。后者通常是“输入一句话，得到一个不可解释的视觉结果”；Open Design 更像是“给 Agent 一个设计系统、任务说明和预览环境，让它持续修改文件，直到产物可运行”。</p>
<p>说白了，它把设计任务变成了一种软件工程任务。</p>
<p>这件事的价值在于可迭代性。一个登录页、一份销售 deck、一个移动端交互原型，本质上不只是图片，而是一组结构、样式、文案、资源和导出规则。Coding Agent 已经擅长处理这些东西：读项目、改组件、运行构建、根据错误日志修复。Open Design 做的是把这些能力迁移到设计场景。</p>
<p>这里我会联想到之前写过的 <a href="https://blog.hypho.cn/posts/claude-code-routines/">Claude Code Routines</a>：真正稳定的 Agent 工作流，很少靠一次神奇 prompt，而是靠可复用步骤、上下文约束和反馈循环。Open Design 的 Skills 和 Design Systems，本质上也是在给 Agent 建立可复用的“套路”。</p>
<h2 id="为什么本地优先比看起来重要">为什么“本地优先”比看起来重要</h2>
<p>Open Design 强调 local-first 和 BYOK。这个卖点有点老生常谈，但放在设计工作流里反而很实际。</p>
<p>设计原型里经常包含还没发布的产品信息、客户名单、商业计划、品牌资产。把这些内容直接丢到一个黑盒 SaaS 里，很多团队嘴上说能接受，法务和安全团队未必接受。Open Design 的思路是：前端、预览、导出尽量在本地或自托管环境完成，模型调用用你自己的 key，Agent CLI 也优先复用本机环境。</p>
<p>当然，这不等于“绝对安全”。只要调用外部模型，prompt 和上下文仍然可能离开本机；只要让 Agent 执行命令，就要考虑权限边界。项目的沙盒预览能降低一部分风险，但不能替代企业里的密钥隔离、网络出站控制和审计。</p>
<p>换句话说，本地优先不是免死金牌，只是把控制权从平台手里拿回来一部分。</p>
<p>如果你关心 Agent 安全边界，可以顺手看我之前写的 <a href="https://blog.hypho.cn/posts/agentarmor-8-layer-security-framework/">AgentArmor 八层安全框架</a>。Open Design 这种“让 Agent 生成并运行设计项目”的模式，和代码 Agent 一样，需要最小权限、文件系统边界、命令执行白名单，以及对外部资源的审查。设计资产看起来不像生产代码危险，但它一样可能带上外链、脚本、埋点和泄露信息。</p>
<h2 id="它的核心工程假设设计系统可以被-agent-消费">它的核心工程假设：设计系统可以被 Agent 消费</h2>
<p>Open Design 最激进的地方，不是支持多少个 Agent CLI，而是它把设计系统作为一等公民。README 里提到多套 brand-grade Design Systems 和 composable Skills。这个方向我比较认可，因为“好看”这个目标太抽象，Agent 如果没有约束，很容易生成一堆平均化的 Tailwind 卡片。</p>
<p>设计系统的作用，是把审美问题的一部分转成约束问题：颜色、间距、字体、组件层级、动效节奏、品牌语气。Agent 不一定真的懂设计，但它能遵守规则。</p>
<p>人话翻译一下：不要让模型凭空发挥，要让它在护栏里发挥。</p>
<p>这也是为什么我觉得 Open Design 比单纯的文生图工具更有工程价值。图片生成模型可以给你灵感，但很难稳定接住“把这个 hero section 改成更企业级，同时保持品牌色、导出 PPT、再生成一个移动端版本”这种连续任务。Coding Agent 虽然审美上不一定更强，但它有文件级记忆和可执行反馈，适合做多轮修改。</p>
<p>不过这里也有一个坑：设计系统本身要足够清晰。很多团队的“设计系统”其实只是一份 Figma 文件和几句口头约定。如果把这种松散规范交给 Agent，最后还是会失控。Open Design 能不能落地，很大程度取决于团队是否愿意把品牌规则、组件规则、导出规则文档化。</p>
<h2 id="生产环境最大的风险不是生成失败而是审查成本">生产环境最大的风险不是生成失败，而是审查成本</h2>
<p>我不太担心 Open Design 生成一次失败。失败了再跑、再改就行。真正的问题是：它生成出来的东西谁来审？怎么审？审哪些层面？</p>
<p>设计产物至少有三层需要检查。</p>
<p>第一层是视觉和品牌一致性。这个还可以靠人工设计师或产品经理看。</p>
<p>第二层是工程质量。HTML 是否可维护？组件是否乱堆？导出的 PDF/PPT 是否在不同环境下稳定？如果里面有脚本，是否引入未知第三方资源？这已经不是传统设计评审能完全覆盖的范围。</p>
<p>第三层是版权和合规。Agent 生成的图片、图标、文案和模板风格，是否借鉴了不该借鉴的东西？Open Design 是开源工具，不代表它生成的一切天然可商用。尤其是团队把外部模型接进来后，模型服务商的条款也要算进来。</p>
<p>所以我的建议是：Open Design 更适合作为“设计工程加速器”，而不是无人值守的设计外包。</p>
<p>比较稳妥的用法，是让它处理中间态产物：早期原型、内部评审材料、销售 demo、文档配图、概念验证页面。等到要进入正式品牌投放或客户交付，再由设计师和工程师做一次收口。</p>
<h2 id="和-claude-design-的差异开源不是唯一重点">和 Claude Design 的差异：开源不是唯一重点</h2>
<p>Open Design 把自己称为 Claude Design 的开源替代，这个定位很容易让人只盯着“免费”和“可自托管”。但我觉得更关键的差异是工作流所有权。</p>
<p>封闭产品的优势是体验完整：打开即用、模型和界面高度整合、少折腾。缺点也明显：你很难控制底层 prompt、很难插入自己的 Agent、很难把内部设计系统变成可执行约束，也很难把产物链路嵌进现有 CI、文档或营销系统。</p>
<p>Open Design 的路线更工程师友好。它假设你愿意折腾，也愿意把设计流程当成代码流程来管理。比如用 Git 管理设计资产，用 PR 审查 Agent 修改，用脚本批量导出多种格式，用不同模型后端做成本和质量权衡。</p>
<p>这和 <a href="https://blog.hypho.cn/posts/chrome-prompt-api-browser-local-llm/">Chrome Prompt API</a> 那篇里讨论的浏览器内置 AI 有点相似：真正影响落地的，往往不是模型能力单点，而是运行位置、权限模型、成本结构和可集成性。Open Design 也是这样。它的卖点不只是“能生成设计”，而是“能嵌进工程师已经熟悉的工具链”。</p>
<h2 id="我会怎么选型">我会怎么选型</h2>
<p>如果你是个人开发者、独立产品团队，或者需要频繁做 landing page、demo、deck，Open Design 值得试。项目在 GitHub 上已经有较高关注度，最近提交也很活跃；从 GitHub API 看，仓库 stars 超过 1.9 万，最后更新时间在 2026 年 5 月，至少不是一个只有 README 的概念仓库。</p>
<p>如果你是中大型企业，我会更保守：先用它做内部原型，不要直接接生产品牌资产；先把模型 key、文件系统权限、导出目录、外链策略管住；再考虑把它接入正式流程。</p>
<p>如果你是专业设计团队，也别急着把它当威胁。短期内它更像一个会写代码的设计助理，而不是能替代资深设计师的创意总监。它能把“从想法到可运行原型”的距离缩短，但对品牌判断、叙事节奏、用户研究和商业取舍仍然很粗糙。</p>
<p>我真正看好的，是“设计工程师”这个角色会被放大。未来很多团队可能不再区分那么清楚：这个人只写前端，那个人只做 Figma。会用 Agent 组织设计系统、生成原型、审查代码、导出交付物的人，会非常吃香。</p>
<p>Open Design 还不完美，我也不确定它的长期维护质量能不能跟上热度。但它提出的方向是清楚的：AI 设计工具不应该只追求一次性惊艳截图，而应该追求可复用、可审查、可集成的工程链路。</p>
<p>这才是它值得写的原因。</p>
<h2 id="参考资料">参考资料</h2>
<ul>
<li><a href="https://github.com/nexu-io/open-design">Open Design GitHub 仓库</a></li>
<li><a href="https://hnrss.org/item?id=47985750">Open Design 在 Hacker News 的讨论</a></li>
<li><a href="https://raw.githubusercontent.com/nexu-io/open-design/main/README.md">Open Design README 原文</a></li>
<li><a href="https://api.github.com/repos/nexu-io/open-design">GitHub API：nexu-io/open-design 仓库元数据</a></li>
<li><a href="https://docs.claude.com/en/docs/claude-code/overview">Claude Code 官方文档</a></li>
</ul>
]]></content:encoded></item><item><title>Claude Code Routines 实战：把 AI 编程助手变成准时的自动化同事</title><link>https://blog.hypho.cn/posts/claude-code-routines/</link><pubDate>Thu, 16 Apr 2026 10:00:00 +0800</pubDate><guid>https://blog.hypho.cn/posts/claude-code-routines/</guid><description>Claude Code Routines 是 Anthropic 为 Claude Code 推出的自动化执行框架，让开发者通过 YAML 配置定义定时任务、GitHub 事件触发和 API 调用，在云端基础设施上自动运行重复性工作。Stars 114k 的明星项目实战深度解析。</description><content:encoded><![CDATA[<h2 id="真实案例引入深夜-11-点的-pr-终于有人-review-了">真实案例引入：深夜 11 点的 PR 终于有人 review 了</h2>
<p>王海（化名）是一家中型 SaaS 公司的后端工程师。团队采用 monorepo 结构，每到周五晚上，积压的 PR 少则七八个，多则十几个。手动 review 耗时耗力，完全丢给 AI review 工具又担心质量。</p>
<p>他尝试的解法：用 Claude Code Routines 配置了一个每周五 20:00 自动运行的代码审查 routine。Claude 会主动拉取本周所有未合并的 PR，按模块分类，生成结构化 review 报告推送到 Slack。第二天早上，他只需要花 20 分钟过一遍 AI 的报告，重点关注高风险变更。</p>
<p>这不是科幻场景——这是 Claude Code Routines 已经支持的真实能力。</p>
<hr>
<h2 id="背景claude-code-不只是交互式工具">背景：Claude Code 不只是交互式工具</h2>
<p>Claude Code 最早以&quot;终端里的 AI 搭档&quot;定位——你提需求，它在本地仓库里翻代码、写文件、跑测试。但这套模式的本质还是<strong>被动响应</strong>：你在，它才动。</p>
<p>2026 年 4 月 14 日，Anthropic 正式发布 <strong>Routines</strong> 功能（<a href="https://code.claude.com/docs/en/routines">官方文档</a>，HN 热度 700+），将 Claude Code 的能力边界从&quot;交互式&quot;扩展到&quot;自动化&quot;。你可以定义一组任务，让它按时间表、按 GitHub 事件、或按 API 调用触发，在 Anthropic 托管的云端基础设施上自动执行——不需要保持终端打开。</p>
<hr>
<h2 id="框架核心拆解">框架核心拆解</h2>
<h3 id="触发模型三种自动化路径">触发模型：三种自动化路径</h3>
<p>Routines 支持三种触发机制，覆盖了开发者日常中最常见的自动化场景：</p>
<p><strong>① 定时触发（Cron）</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">triggers</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l">schedule</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">cron</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;0 9 * * 1-5&#34;</span><span class="w">   </span><span class="c"># 每周一至周五 9:00 AM UTC</span><span class="w">
</span></span></span></code></pre></div><p>适用于：每日 standup 报告生成、代码质量巡检、定时数据拉取。</p>
<p><strong>② GitHub 事件触发</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">triggers</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l">github</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">events</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">pull_request.opened</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">pull_request.merged</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">issue.comment</span><span class="w">
</span></span></span></code></pre></div><p>适用于：PR 自动 review、issue 分类、release note 生成。</p>
<p><strong>③ API 调用触发</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">triggers</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l">api</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">auth</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l">bearer_token</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">secret</span><span class="p">:</span><span class="w"> </span><span class="l">$ROUTINES_API_SECRET</span><span class="w">
</span></span></span></code></pre></div><p>适用于：与内部平台集成、webhook 驱动的工作流、CI/CD pipeline 串联。</p>
<h3 id="routine-执行单元task--tool">Routine 执行单元：Task + Tool</h3>
<p>每个 Routine 由一个或多个 <strong>Task</strong> 组成，Task 定义&quot;做什么&quot;，Tool 定义&quot;用什么工具做&quot;。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">routines</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">daily-code-review</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">trigger</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l">schedule</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">cron</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;0 20 * * 5&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">tasks</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">fetch-open-prs</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">tool</span><span class="p">:</span><span class="w"> </span><span class="l">github</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">action</span><span class="p">:</span><span class="w"> </span><span class="l">list_prs</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">params</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">state</span><span class="p">:</span><span class="w"> </span><span class="l">open</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">base</span><span class="p">:</span><span class="w"> </span><span class="l">main</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">review-each-pr</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">tool</span><span class="p">:</span><span class="w"> </span><span class="l">claude_code</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">action</span><span class="p">:</span><span class="w"> </span><span class="l">review_code</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">context</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">pr_data</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;${fetch-open-prs.output}&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">config</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">model</span><span class="p">:</span><span class="w"> </span><span class="l">claude-sonnet-4-20250514</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">max_tokens</span><span class="p">:</span><span class="w"> </span><span class="m">8000</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">post-to-slack</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">tool</span><span class="p">:</span><span class="w"> </span><span class="l">slack</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">action</span><span class="p">:</span><span class="w"> </span><span class="l">send_message</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">params</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">channel</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;#engineering&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">message</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;${review-each-pr.output}&#34;</span><span class="w">
</span></span></span></code></pre></div><h3 id="云端执行架构">云端执行架构</h3>
<p>Routines 运行在 <strong>Anthropic 托管的基础设施</strong>上，不依赖本地终端：</p>
<pre tabindex="0"><code class="language-mermaid" data-lang="mermaid">%%{init: {&#39;theme&#39;: &#39;neutral&#39;}}%%
flowchart TB
    subgraph Triggers
        Cron[&#34;Cron Scheduler&#34;]
        GH[&#34;GitHub Webhooks&#34;]
        API[&#34;API / Webhook Endpoint&#34;]
    end

    subgraph RoutineEngine
        Parser[&#34;YAML Parser&#34;]
        Executor[&#34;Task Executor&#34;]
        ContextMgr[&#34;Context Manager&#34;]
    end

    subgraph Tools
        GitHub[&#34;GitHub API Tool&#34;]
        ClaudeCode[&#34;Claude Code Tool&#34;]
        Slack[&#34;Slack API Tool&#34;]
        Custom[&#34;Custom API Tool&#34;]
    end

    Cron --&gt; Parser
    GH --&gt; Parser
    API --&gt; Parser
    Parser --&gt; Executor
    Executor --&gt; ContextMgr
    Executor --&gt; GitHub
    Executor --&gt; ClaudeCode
    Executor --&gt; Slack
    Executor --&gt; Custom

    ContextMgr --&gt; Output[&#34;Structured Output&lt;br/&gt;/ Slack / File&#34;]
</code></pre><p>关键优势：<strong>上下文持久化</strong>——同一 Routine 的多次执行可以访问历史状态，实现增量分析而非每次从零开始。</p>
<h3 id="与传统-cicd-的区别">与传统 CI/CD 的区别</h3>
<table>
  <thead>
      <tr>
          <th>维度</th>
          <th>传统 CI/CD (GitHub Actions)</th>
          <th>Claude Code Routines</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>定义方式</strong></td>
          <td>YAML + Shell 脚本</td>
          <td>YAML + 自然语言 prompt</td>
      </tr>
      <tr>
          <td><strong>上下文理解</strong></td>
          <td>无代码理解能力</td>
          <td>全代码库语义理解</td>
      </tr>
      <tr>
          <td><strong>触发条件</strong></td>
          <td>事件驱动</td>
          <td>事件 + 定时 + API</td>
      </tr>
      <tr>
          <td><strong>执行位置</strong></td>
          <td>云端 ephemeral</td>
          <td>Anthropic 托管云端</td>
      </tr>
      <tr>
          <td><strong>适用场景</strong></td>
          <td>构建/测试/部署</td>
          <td>分析/审查/生成/监控</td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="关键洞察工程化落地的三个建议">关键洞察：工程化落地的三个建议</h2>
<h3 id="1-routine-不等于-script设计好上下文边界">1. Routine 不等于 Script——设计好上下文边界</h3>
<p>Routines 的强大之处在于 Claude 对代码库的语义理解，但这也意味着每次执行都在消耗 token。<strong>不要让一个 Routine 试图做所有事情</strong>。</p>
<p>推荐做法：按职责拆分多个小 Routine，通过 Slack 消息或文件作为它们之间的数据传递媒介。比如 <code>daily-pr-fetcher</code> 只负责拉取数据写入 <code>pr-summary.json</code>，<code>pr-reviewer</code> 读取该文件做 review。</p>
<h3 id="2-api-触发模式下的安全性配置">2. API 触发模式下的安全性配置</h3>
<p>Routines 的 API 触发支持 Bearer Token 认证，但这意味着你的 <code>$ROUTINES_API_SECRET</code> 需要安全存储。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># 推荐：通过环境变量注入，不写在 YAML 里</span>
</span></span><span class="line"><span class="cl">claude routines create --name my-routine --env ROUTINES_API_SECRET
</span></span></code></pre></div><p>如果与 GitHub Actions 集成，推荐使用 <strong>GitHub Apps</strong> 而非 Personal Access Token，避免 token 泄露导致仓库权限被滥用。</p>
<h3 id="3-定时任务的时区陷阱">3. 定时任务的时区陷阱</h3>
<p><code>cron: &quot;0 9 * * *&quot;</code> 默认是 <strong>UTC</strong>，而大多数团队的作息是 UTC+8（北京时间）。如果希望&quot;每天早上 9 点&quot;运行，需要写成 <code>cron: &quot;0 1 * * *&quot;</code>（UTC 1:00 = 北京时间 9:00）。Anthropic 文档明确建议在 cron 表达式旁加上注释说明对应的本地时间。</p>
<hr>
<h2 id="信源引用">信源引用</h2>
<ul>
<li><a href="https://code.claude.com/docs/en/routines">Claude Code Routines 官方文档</a>（HN 热度 700+，本文核心信源）</li>
<li><a href="https://github.com/anthropics/claude-code">GitHub: anthropics/claude-code</a>（Stars 114k+，最新提交 2026-04-16）</li>
<li><a href="https://news.ycombinator.com/item?id=47768133">HN Discussion: Claude Code Routines</a></li>
</ul>
<hr>
<h2 id="总结">总结</h2>
<p>Claude Code Routines 代表了 AI 编程助手从&quot;被动工具&quot;向&quot;主动自动化同事&quot;的进化。对于工程团队而言，它的最大价值不是替代人类，而是<strong>接管那些结构清晰、重复性强、但需要代码语义理解的工作</strong>——定时 code review、release note 生成、依赖安全巡检……</p>
<p>关键落地原则：保持 Routine 职责单一、善用 API 触发时的安全配置、注意时区换算。如果你在团队中承担着大量&quot;每天都要做但不需要深度思考&quot;的工作，Routines 值得投入 1-2 小时认真配置。</p>
]]></content:encoded></item></channel></rss>