<?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/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>Anthropic | Feisky</title><link>https://feisky.xyz/tags/anthropic/</link><description>极客时间专栏作者，专注于 Kubernetes、AI Infra、AI Agent 领域的深度技术分享，让 AI 成为你的第二大脑</description><generator>Hugo 0.165.0</generator><language>zh-CN</language><managingEditor>Pengfei Ni</managingEditor><webMaster>Pengfei Ni</webMaster><lastBuildDate>Fri, 14 Aug 2026 12:39:05 +0000</lastBuildDate><atom:link href="https://feisky.xyz/tags/anthropic/index.xml" rel="self" type="application/rss+xml"/><item><title>Claude Code 作者说：用好 Fable 5 的关键是管理你的未知</title><link>https://feisky.xyz/posts/2026-07-06-fable-field-guide-unknowns/</link><pubDate>Mon, 06 Jul 2026 10:00:00 +0800</pubDate><dc:creator>Pengfei Ni</dc:creator><category>Claude</category><category>Fable 5</category><category>Prompt Engineering</category><category>AI Agent</category><category>Anthropic</category><guid>https://feisky.xyz/posts/2026-07-06-fable-field-guide-unknowns/</guid><description>&lt;blockquote&gt;
&lt;p&gt;题记：本文编译自 Claude Code 团队 Thariq 的文章，原文链接：&lt;a href="https://x.com/trq212/status/2073100352921215386"&gt;https://x.com/trq212/status/2073100352921215386&lt;/a&gt;。本文在翻译基础上做了整理和补充。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Fable 5 恢复访问之后，我拿它跑了一些之前用 Opus 做的任务。明显感觉它的一次性完成率高了很多，以前需要三四轮迭代才能收敛的事，现在经常一轮就做对了。不过反过来也有一个新问题：一旦中间跑偏了，那结果也比以前歪的更厉害了，回头看才发现是我自己没想清楚就让它动手了。&lt;/p&gt;</description><content:encoded>&lt;![CDATA[<blockquote><p>题记：本文编译自 Claude Code 团队 Thariq 的文章，原文链接：<a href="https://x.com/trq212/status/2073100352921215386">https://x.com/trq212/status/2073100352921215386</a>。本文在翻译基础上做了整理和补充。</p></blockquote><p>Fable 5 恢复访问之后，我拿它跑了一些之前用 Opus 做的任务。明显感觉它的一次性完成率高了很多，以前需要三四轮迭代才能收敛的事，现在经常一轮就做对了。不过反过来也有一个新问题：一旦中间跑偏了，那结果也比以前歪的更厉害了，回头看才发现是我自己没想清楚就让它动手了。</p><p>以前用 Opus 还能靠反复重试和人工 review 来兜底，现在 Fable 不太给你这个机会，具体的结果取决于你喂进去的上下文质量。</p><p>刚好看到 Claude Code 团队的 Thariq 发了一篇文章讲这个问题。他的核心观点是：Fable 5 是第一个瓶颈不在模型能力的模型，瓶颈在你能不能把自己不确定的东西讲清楚。他用了一个比喻叫“地图不是疆域”，你给 Claude Code 的 prompt、skill、上下文是地图，代码库和真实世界的约束是疆域，两者之间的差距就是未知的地方。管理好这些未知，才是用好 Fable 5 的核心。</p><p>社交媒体上这几天的实践也印证了这一点。有人用 Fable 做了 60 多个 Three.js 3D 场景 demo（Karpathy 评价 &ldquo;top tier fablemaxxing&rdquo;），有人复刻了 70% 的 Notion，还有人让它在终端自己渲染起了视频。这些人出活效率高，并不是因为他们 prompt 写得更长，而是他们在动手前把自己不清楚的东西消化掉了。</p><p>Thariq 这篇文章给了一套非常实用的操作框架，从实现前、实现中到实现后，每个阶段都有对应的方法来消除未知。我觉得参考价值很高，整理出来分享给大家，同时补充了 Anthropic 官方提示词指南和社区实践中的一些经验。</p><h2 id="四种未知">四种未知</h2><p><img src="/images/2026-07-06-fable-field-guide-unknowns-map-territory-diagram.jpg" alt="地图与疆域的关系" loading="lazy" decoding="async"/></p><p>跟人类似，Claude Code 碰到未知的时候只能靠瞎猜。做的工作越多，碰到的未知就越多，猜错的概率也越大，结果当然也会越离谱。Thariq 用了 Donald Rumsfeld 的经典分类框架，把未知拆成四种：</p><table><thead><tr><th>类型</th><th>含义</th><th>例子</th></tr></thead><tbody><tr><td>Known Knowns</td><td>你知道自己知道的，写在 prompt 里</td><td>“把首页改成暗色模式”</td></tr><tr><td>Known Unknowns</td><td>你知道自己还没想清楚</td><td>“数据模型还没定，但我知道要先定下来”</td></tr><tr><td>Unknown Knowns</td><td>你不会主动写出来，但看到就知道对不对</td><td>“这个按钮放在这里就是觉得不对”</td></tr><tr><td>Unknown Unknowns</td><td>你根本不知道你不知道</td><td>“这个代码库里竟然有三套认证中间件”</td></tr></tbody></table><p><img src="/images/2026-07-06-fable-field-guide-unknowns-four-unknowns.jpg" alt="四种未知分类" loading="lazy" decoding="async"/></p><p>Thariq 观察到一个事情：最强的 agentic coder 并不是 prompt 写得最长，而是未知最少。他看 Boris 和 Jarred 用 Claude Code 的时候，明显能感觉到他们非常清楚自己要什么，对代码库和模型行为都有深度同步。</p><p>不过就算是高手，也会假设自己有很多未知的地方。管理和减少这些未知本身就是 agentic coding 的核心技能。</p><h2 id="怎么跟-fable-5-配合">怎么跟 Fable 5 配合</h2><p><img src="/images/2026-07-06-fable-field-guide-unknowns-help-claude-help-you.jpg" alt="帮 Claude 帮你" loading="lazy" decoding="async"/></p><p>指导 Claude Code 是一个微妙的平衡。说得太具体，它会死板执行，该转弯的时候不知道转弯。而说得太模糊，它又会按行业最佳实践自己做选择，但未必适合你的场景。</p><p>Anthropic 官方的 Fable 5 提示词指南里提到一个关键点：Fable 5 的指令跟随好到一句简短的指令就能调整大多数行为。以前你可能要列十条不要做 X，现在一句简洁回答就够了。不过这也意味着它偶尔会做未被要求的事（比如自动起草邮件、建防御性 git 分支备份），所以需要明确告诉它边界在哪里。</p><p>另一个实用的参数是 effort。<code>high</code> 做默认就好，<code>xhigh</code> 留给最难的任务，日常用<code>medium</code> 甚至<code>low</code>。低 effort 的 Fable 5 往往比之前模型的<code>xhigh</code> 还强，这个也侧面说明 Fable 5 模型的提升的确是很大的。</p><p>不过 Claude Code 能帮你更快发现未知。它搜代码库和互联网极快，对大多数话题知道得比你多，从失败中迭代的速度也比你快。Thariq 说最重要的一点是：告诉 Claude Code 你现在处于思考过程的哪个阶段。主动告诉它你对这个问题和代码库的理解，让它像伙伴一样跟你一起工作，而不是一个单纯的执行者。</p><h2 id="动手之前把不清楚的找出来">动手之前：把不清楚的找出来</h2><p><img src="/images/2026-07-06-fable-field-guide-unknowns-pre-implementation.jpg" alt="实现前的方法概览" loading="lazy" decoding="async"/></p><h3 id="盲点扫描">盲点扫描</h3><p>当你在一个不熟悉的代码库开始工作，或者用 Claude Code 帮你做设计这种你不太擅长的事情时，大概率有很多 Unknown Unknowns。</p><p>这时候直接问 Claude Code：“帮我做一次盲点扫描，找出我在这个问题上的 Unknown Unknowns”。</p><p>示例提示词：</p><blockquote><p>我要在这个代码库里加一个新的 auth provider，但我对 auth 模块一无所知。帮我做一次盲点扫描，找出我的相关 Unknown Unknowns，帮我更好地给你写 prompt。</p></blockquote><h3 id="头脑风暴--原型">头脑风暴 + 原型</h3><p>当你有很多 Unknown Knowns 的时候（就是那种“我说不出来但看到就知道对不对”的标准），最好让 Claude Code 做几个方向给你挑。</p><p>比如你想加一个按钮到界面上，但不确定放哪里好看，也说不清什么算好看。这时候让 Claude Code 做四个完全不同的设计方向，用 HTML 原型展示出来，你看到了自然就能做选择。</p><blockquote><p>我想做一个数据 dashboard，但我没有视觉品味，也不知道有什么可能性。做一个 HTML 页面展示 4 个完全不同的设计方向，让我能看看效果，然后跟你反馈。</p></blockquote><p>其实 Thariq 几乎每次 coding session 都会以探索或头脑风暴阶段开始。Claude Code 经常能找到他自己会错过的高价值路径。</p><h3 id="面试">面试</h3><p>做完头脑风暴后大概率还有很多未知点。这时候让 Claude Code 来采访你：</p><blockquote><p>对任何模糊的地方一个一个问我，优先问那些答案会改变架构的问题。</p></blockquote><p>这个方法特别有用。Claude Code 会逼你想清楚那些你以为已经想清楚、但其实并没有的东西。</p><h2 id="动手的时候记下每次偏离">动手的时候：记下每次偏离</h2><p>不管规划做得多充分，动手之后总会遇到意料之外的情况。Thariq 的做法是让 Claude 维护一个临时的<code>implementation-notes.md</code> 文件：</p><blockquote><p>维护一个 implementation-notes.md。如果碰到 edge case 需要偏离计划，选保守方案，记录到 Deviations 下面，然后继续。</p></blockquote><p>这样下一次做类似任务的时候就有据可查。这里补充一个 Anthropic 官方指南里提到的坑：长时间运行的任务中，Fable 5 可能编造进度报告。官方建议是让它对照实际工具结果审计每一条进度声明，只报告你能指向证据的工作。不要让它复述自己的推理过程（会触发安全分类器导致 refusal），需要看推理过程就读 thinking block。</p><h2 id="做完之后让别人看懂你做了什么">做完之后：让别人看懂你做了什么</h2><p><img src="/images/2026-07-06-fable-field-guide-unknowns-post-implementation.jpg" alt="实现后的交付" loading="lazy" decoding="async"/></p><p>做完之后，Thariq 会让 Claude Code 把原型、规格文档和实现笔记打包成一个可以扔到 Slack 里让人快速理解的文档。</p><p>还有一个我觉得挺妙的做法：让 Claude Code 给你出一份关于这次改动的测试题。</p><blockquote><p>我想确保我理解了这次改动的所有内容。给我一份 HTML 报告，包含改动的上下文、直觉、做了什么，底部附一个 quiz，我必须答对才 merge。</p></blockquote><h2 id="fable-5-的实战验证视频剪辑">Fable 5 的实战验证：视频剪辑</h2><p>Thariq 在文章最后举了一个自己的例子：Fable 5 的发布视频是他完全用 Claude Code 剪辑的。</p><p>他的流程完美体现了管理未知的方法：</p><ol><li>他知道 Claude Code 能用代码剪视频和做转录，但不确定精度够不够。于是先问 Claude Code 解释 Whisper 的工作原理，确认是否能精确切掉”嗯啊”和停顿</li><li>他想做一个和语音同步的字幕 UI，但不确定能不能做到。让 Claude Code 做一个 Remotion 原型验证可行性</li><li>视频色彩偏灰，他知道需要调色但不知道什么是好的调色。让 Claude Code 教他调色的基础知识，帮他发现自己的未知</li></ol><p>每一步都是先暴露未知，再决定怎么做。</p><h2 id="社区在怎么用-fable-5">社区在怎么用 Fable 5</h2><p>Thariq 这篇文章是方法论层面的。社区这几天的实践则展示了 Fable 5 的具体能力边界。</p><p>我觉得最有意思的一个玩法是知识蒸馏。有人让 Fable 5 扮演即将退休的首席工程师，审计整个代码库，写出 10-16 个 Skill 文件（调试手册、变更规则、曾经踩过的坑等等）。之后 Opus 和 Sonnet 按这套 playbook 跑更便宜的 session，效果接近 Fable 标准。代价是一次跑下来能吃掉 30% 的周额度。这个玩法和 Anthropic 官方建议的构建记忆系统不谋而合：给 Fable 一个地方记录教训，哪怕只是一个 Markdown 文件，它在有历史参考的时候表现显著更好。</p><p>另一个社区逐渐形成共识的模式是 Fable 做大脑、Codex 做四肢。Fable 5 最强的不是写代码，而是理解复杂需求、拆解任务、制定策略。具体执行交给 GPT-5.5 或者 Opus，相当于 Tech Lead 配高执行力工程师。</p><p>Peter Gostev 在 3D 场景生成方向做了一个 45 分钟的视频，60 多个 Three.js 环境 demo。Karpathy 看完评价”top tier fablemaxxing”，Fable 在 3D 这块确实跨了一个台阶。</p><p>还有一个方向是网站复刻。给 Fable 5 一个链接，它能读底层代码（不只是截图），理解视觉和技术细节，然后复刻出带动效和 3D 交互的落地页。</p><h2 id="写在最后">写在最后</h2><p>说实话，Fable 5 让我对“怎么写 prompt”这件事的理解变了。以前的难点是怎么让模型理解我的意思，现在的难点是我自己到底想要什么。这完全是两码事。</p><p>推荐你在下次动手前试试 Thariq 的方法：先花两分钟问问自己“我这里有什么不确定的”，然后让 Claude Code 帮你先把它们挖出来之后再去干活。</p><hr><p>相关资源：</p><ul><li>Thariq 原文：<a href="https://x.com/trq212/status/2073100352921215386">https://x.com/trq212/status/2073100352921215386</a></li><li>Anthropic 官方 Fable 5 提示词指南：<a href="https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/prompting-claude-fable-5">https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/prompting-claude-fable-5</a></li><li>Fable 5 知识蒸馏到 Skill 的完整 prompt（@PrajwalTomar_）：<a href="https://x.com/PrajwalTomar_/status/2073768365873885396">https://x.com/PrajwalTomar_/status/2073768365873885396</a></li></ul><hr><p>欢迎长按下面的二维码关注<strong>Feisky</strong> 公众号，了解更多云原生和 AI 知识。</p><p><img src="/images/mp.png" alt="Feisky 公众号二维码" loading="lazy" decoding="async"/></p>
]]></content:encoded><dc:extent>8 min read</dc:extent></item><item><title>Claude Code 官方教你用 Loop：你可能一直卡在最基础那层</title><link>https://feisky.xyz/posts/2026-07-01-claude-code-loops/</link><pubDate>Wed, 01 Jul 2026 10:00:00 +0800</pubDate><dc:creator>Pengfei Ni</dc:creator><category>Claude Code</category><category>Loop Engineering</category><category>AI Agent</category><category>Anthropic</category><category>长时任务</category><guid>https://feisky.xyz/posts/2026-07-01-claude-code-loops/</guid><description>&lt;blockquote&gt;
&lt;p&gt;题记：本文编译自 Claude Code 官方博客《Getting started with loops》，原文链接：&lt;a href="https://claude.com/blog/getting-started-with-loops"&gt;https://claude.com/blog/getting-started-with-loops&lt;/a&gt;。本文在翻译基础上做了整理和补充。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;上个月写完&lt;a href="https://mp.weixin.qq.com/s/QR40uuNa1oxtV5ds3i3Ukw"&gt;《Loop Engineering》这篇文章&lt;/a&gt;之后，我一直在用 /goal 跑各种任务。当时的结论是 loop 好不好用取决于你能不能把”做完了”写清楚。这话没错，但其实并不完整。后来我碰到很多任务，并不是把停止条件写清楚就能完事的，还有验证步骤和触发时机也很关键。&lt;/p&gt;</description><content:encoded>&lt;![CDATA[<blockquote><p>题记：本文编译自 Claude Code 官方博客《Getting started with loops》，原文链接：<a href="https://claude.com/blog/getting-started-with-loops">https://claude.com/blog/getting-started-with-loops</a>。本文在翻译基础上做了整理和补充。</p></blockquote><p>上个月写完<a href="https://mp.weixin.qq.com/s/QR40uuNa1oxtV5ds3i3Ukw">《Loop Engineering》这篇文章</a>之后，我一直在用 /goal 跑各种任务。当时的结论是 loop 好不好用取决于你能不能把”做完了”写清楚。这话没错，但其实并不完整。后来我碰到很多任务，并不是把停止条件写清楚就能完事的，还有验证步骤和触发时机也很关键。</p><p>刚看到 Claude Code 团队发了一篇官方博客，把他们内部怎么想 loop 这件事系统梳理了一遍。读完觉得挺有价值的，它给了一个我之前缺的判断框架：loop 分四种，区分标准是你愿意交出去什么。验证步骤、停止条件、触发时机、整个决策流程，这四样东西对应四种 loop，具体怎么选择取决于你愿意放手多少。</p><p>Claude Code 团队把 loop 定义为 Agent 重复执行工作、循环直到满足停止条件，然后按触发方式、停止机制和适用场景分成了四种。这个分法比社区里各种五花八门的说法清楚得多，因为它有明确的递进关系：你交出去的东西越多，Claude Code 帮你自动完成的任务也就越多，当然对应的成本也会越高。</p><h2 id="第一层交出验证步骤">第一层：交出验证步骤</h2><p><img src="/images/2026-07-01-claude-code-loops-turn-based-loop.png" alt="Turn-based Loop 流程" loading="lazy" decoding="async"/></p><p>这是最基础的一种。你发一条 prompt，Claude Code 读代码、改代码、跑测试、返回结果，然后等你的下一条指令。</p><p>这就是我们每天都在用的标准交互模式。你还在循环里，每一轮都需要你判断"做完了没"。</p><p>怎么让这种模式更高效？Claude Code 团队的建议是把你的验证步骤写成 Skill。比如前端改了一个按钮，应该启动 dev server、打开页面、点一下、截图、检查 console。把这些写进 SKILL.md，Claude Code 就能自己跑完验证，不用你每次手动检查。</p><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-markdown" data-lang="markdown"><span style="display:flex;"><span>---</span></span><span style="display:flex;"><span><span style="color:#f92672">name</span>:<span style="color:#ae81ff">verify-frontend-change</span></span></span><span style="display:flex;"><span><span style="color:#f92672">description</span>:<span style="color:#ae81ff">任何 UI 改动在宣布完成前必须端到端验证。</span></span></span><span style="display:flex;"><span>---</span></span><span style="display:flex;"><span/></span><span style="display:flex;"><span># 前端改动验证流程</span></span><span style="display:flex;"><span><span style="color:#66d9ef">1.</span> 启动 dev server，在浏览器中打开改动页面。</span></span><span style="display:flex;"><span><span style="color:#66d9ef">2.</span> 直接与改动交互（点按钮、填表单），确认预期行为。</span></span><span style="display:flex;"><span><span style="color:#66d9ef">3.</span> 检查浏览器 console：不能有新的 error 或 warning。</span></span><span style="display:flex;"><span><span style="color:#66d9ef">4.</span> 用 Chrome Devtools MCP 跑一次性能追踪。</span></span></code></pre></div><p>你可以看到，这一层交出去的是"怎么确认做对了"。Claude Code 替你检查，但做什么、做到什么程度，还是你说了算。</p><h2 id="第二层交出停止条件">第二层：交出停止条件</h2><p><img src="/images/2026-07-01-claude-code-loops-goal-based-loop.png" alt="Goal-based Loop 流程" loading="lazy" decoding="async"/></p><p>Turn-based 的问题是复杂任务一轮搞不定，Claude Code 会频繁停下来问你要决策。/goal 解决的正是这个问题：你定义好成功标准，Claude Code 自己迭代到满足为止。</p><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-markdown" data-lang="markdown"><span style="display:flex;"><span>/goal 把首页 Lighthouse 分数提到 90 以上，最多试 5 次。</span></span></code></pre></div><p>这一层你交出去的是"什么时候算做完"。/goal 的关键在于停止条件必须是确定性的。数字、测试通过数、分数阈值这种最好用。为什么？因为描述性结果要大模型自己给自己打分，这种打分很不靠谱，而跑个 Lighthouse 拿到 92 分这种确定性结果它才能判断得准。</p><p>每次 Claude Code 尝试停下来，会有一个独立的评估模型检查你的条件是否满足。没满足就打回去继续干，直到达标或者到了你设的次数上限。</p><p>这跟 Codex 的 /goal 机制本质上是一样的。我之前在<a href="https://mp.weixin.qq.com/s/qwjxsGpMacLNy93g6dz4Aw">《Codex /goal 》</a>文章中提过的"完成契约"概念在这里同样适用：你把"做完"从主观判断变成可验证的合约，agent 才能真正闭环。</p><h2 id="第三层交出触发时机">第三层：交出触发时机</h2><p>前两种都是你手动触发的。但有些工作是周期性的，比如每天早上总结 Slack 消息，或者持续盯着一个 PR 等 review 评论进来。</p><p>/loop 做的就是这件事：按时间间隔重复执行同一条 prompt。</p><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-markdown" data-lang="markdown"><span style="display:flex;"><span>/loop 5m 检查我的 PR，处理 review 评论，修复挂掉的 CI</span></span></code></pre></div><p>这一层你交出去的是"什么时候该跑"。每 5 分钟检查一次 PR，有新 review 就处理，CI 挂了就修。你不需要一直盯着，它自己按节奏跑。</p><p>有一点需要注意的是，/loop 跑在你本地，机器关掉它就停止了。如果想让它不间断，需要用 /schedule 把它变成一个云端任务。</p><p>我觉得这一层最有意思的地方是它把 Claude Code 变成了一个值班机器人。以前你盯 CI、盯 review、盯 deploy，现在这些事可以交给一个定时轮询的 agent。当然它是以 token 消耗为代价的，这个后面会说。</p><h2 id="第四层交出整个决策流程">第四层：交出整个决策流程</h2><p><img src="/images/2026-07-01-claude-code-loops-proactive-loop.png" alt="Proactive Loop 流程" loading="lazy" decoding="async"/></p><p>最后一种是把前面所有原语组合起来，做成一个无人值守的长期任务流水线。</p><p>比如处理用户反馈：用 /schedule 每小时检查一次 #project-feedback 频道，用 /goal 定义每个 bug report 必须被分类、修复、回复，用动态工作流让多个 agent 并行探索不同修复方案，用 auto mode 跳过权限确认。</p><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-markdown" data-lang="markdown"><span style="display:flex;"><span>/schedule 每小时检查 #project-feedback 里的 bug 报告。</span></span><span style="display:flex;"><span>/goal 这一轮发现的每个报告都必须被分类、修复、回复后才能停。</span></span><span style="display:flex;"><span>修 bug 时用动态工作流在并行 worktree 里探索三种方案，</span></span><span style="display:flex;"><span>再让一个独立 agent 做对抗性审查。</span></span></code></pre></div><p>这一层你交出去的是整个决策流程：做什么、怎么做、什么时候做、做到什么程度，全部由 agent 自己决定。</p><p>说实话这一层出问题的概率是最高的。动态工作流加上 /schedule 加上 auto mode，组合起来确实是一个完整的 agent 流水线。这对大模型本身的性能和你提供给它的上下文信息有极高的要求，也是最烧 token 的模式，动态工作流一次能起几十 agent，没有做好成本控制的话，很容易账单就爆了。前阵子不少公司砍掉了员工的 Claude 订阅，我觉得这种跑法肯定是原因之一。</p><h2 id="怎么控制-token-消耗">怎么控制 token 消耗</h2><p>从前面可以看出，交给 Claude Code 的越多，token 消耗也就越大。Claude Code 团队给了几条实操建议：</p><table><thead><tr><th>策略</th><th>做法</th><th>原理</th></tr></thead><tbody><tr><td>选对原语和模型</td><td>简单任务不需要套 loop，能用便宜模型就别用贵的</td><td>90% 的任务 turn-based 就够了</td></tr><tr><td>确定性工作写脚本</td><td>比如填 PDF 表单，写一次脚本以后每次调用就行</td><td>跑脚本比让模型推理便宜得多</td></tr><tr><td>先小规模试跑</td><td>动态工作流别上来就给 100 个 issue，先跑 5 个验证一下</td><td>先看消耗和质量再放量</td></tr><tr><td>间隔匹配变化频率</td><td>PR 一小时才有一条 review，别用 5 分钟轮询</td><td>轮询频率超过变化频率就是 token 浪费</td></tr><tr><td>看消耗明细</td><td>/usage 看总量，/goal 不带参数看当前 loop 消耗，/workflows 看每个 agent</td><td>知道钱花在哪才能省</td></tr></tbody></table><h2 id="速查表">速查表</h2><table><thead><tr><th>Loop 类型</th><th>你交出去的</th><th>适合场景</th><th>用什么</th></tr></thead><tbody><tr><td>Turn-based</td><td>验证步骤</td><td>探索性任务、一次性修改</td><td>Skill</td></tr><tr><td>Goal-based</td><td>停止条件</td><td>有明确完成标准的任务</td><td>/goal</td></tr><tr><td>Time-based</td><td>触发时机</td><td>周期性工作、监控外部系统</td><td>/loop、/schedule</td></tr><tr><td>Proactive</td><td>整个决策流程</td><td>长期运行的定型工作流</td><td>以上全部 + 动态工作流</td></tr></tbody></table><h2 id="写在最后">写在最后</h2><p>回到开头说的那个问题：loop 用不好，往往不是模型不行，是你选错了层级。</p><p>我自己的经验是，先从 /goal 开始。找一个你每天重复做的事，问自己能不能把"做完了"写成一句可验证的话。能写出来，你就可以从 turn-based 升级到 goal-based 了。这一步收益最大，门槛最低，最能节省人力。至于 /loop 和 proactive，等你把 /goal 用顺了再说也不迟。</p><p>如果你想了解更多，推荐阅读：</p><ul><li>Claude Code 官方 Loop 博客：<a href="https://claude.com/blog/getting-started-with-loops">https://claude.com/blog/getting-started-with-loops</a></li><li>Loop Engineering 很好，但先想清楚一个问题：<a href="https://mp.weixin.qq.com/s/QR40uuNa1oxtV5ds3i3Ukw">https://mp.weixin.qq.com/s/QR40uuNa1oxtV5ds3i3Ukw</a></li><li>Codex /goal 上线后，我把 Ralph loop 卸了：<a href="https://mp.weixin.qq.com/s/qwjxsGpMacLNy93g6dz4Aw">https://mp.weixin.qq.com/s/qwjxsGpMacLNy93g6dz4Aw</a></li></ul><hr><p>欢迎长按下面的二维码关注<strong>Feisky</strong> 公众号，了解更多云原生和 AI 知识。</p><p><img src="/images/mp.png" alt="Feisky 公众号二维码" loading="lazy" decoding="async"/></p>
]]></content:encoded><dc:extent>6 min read</dc:extent></item><item><title>终于搞明白 Claude Code 为什么会忽略我的指令了</title><link>https://feisky.xyz/posts/2026-06-23-claude-code-steering/</link><pubDate>Tue, 23 Jun 2026 10:00:00 +0800</pubDate><dc:creator>Pengfei Ni</dc:creator><category>Claude Code</category><category>Anthropic</category><category>AI 编程</category><category>Harness</category><category>Skills</category><category>Hooks</category><guid>https://feisky.xyz/posts/2026-06-23-claude-code-steering/</guid><description>&lt;blockquote&gt;
&lt;p&gt;题记：本文编译自 Anthropic 工程博客《Steering Claude Code: skills, hooks, subagents and more》，原文链接：&lt;a href="https://www.anthropic.com/engineering/claude-code-best-practices"&gt;https://www.anthropic.com/engineering/claude-code-best-practices&lt;/a&gt;。本文在翻译基础上做了整理和补充。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在使用 Claude Code 时，我的 CLAUDE.md 曾经写到几千行。项目规范、参考约定、编码风格、部署流程，还有日常开发中碰到的各种坑，全往里面塞。CLAUDE.md 的内容越来越丰富，Claude Code 也越来越好用。直到有一天我发现 Claude Code 开始选择性忽略某些指令，才反应过来，它的上下文太长了，它已经不能很好地遵循 CLAUDE.md 定义的各种规则了。&lt;/p&gt;</description><content:encoded>&lt;![CDATA[<blockquote><p>题记：本文编译自 Anthropic 工程博客《Steering Claude Code: skills, hooks, subagents and more》，原文链接：<a href="https://www.anthropic.com/engineering/claude-code-best-practices">https://www.anthropic.com/engineering/claude-code-best-practices</a>。本文在翻译基础上做了整理和补充。</p></blockquote><p>在使用 Claude Code 时，我的 CLAUDE.md 曾经写到几千行。项目规范、参考约定、编码风格、部署流程，还有日常开发中碰到的各种坑，全往里面塞。CLAUDE.md 的内容越来越丰富，Claude Code 也越来越好用。直到有一天我发现 Claude Code 开始选择性忽略某些指令，才反应过来，它的上下文太长了，它已经不能很好地遵循 CLAUDE.md 定义的各种规则了。</p><p>你是不是也碰到过类似的情况？明明写了“所有修改必须跑完整 e2e 测试”，结果只跑了一个单元测试就停了，需要你反复提示才执行。</p><p>我在这个问题上卡了很久，一度怀疑是 Claude 模型又降智了，后来才发现根本原因是上下文膨胀。把所有东西都塞进了 CLAUDE.md，这本身就是用错了 AI 工具。</p><p>Anthropic 最近发了一篇官方指南，系统梳理了提示 Claude Code 的 7 种方法和它们的实现原理。我之前踩过的很多坑，根因都是没搞清楚每种方法的加载时机和上下文成本。</p><p>下面是我对这篇指南的编译和解读，每一节加了自己的使用经验。</p><h2 id="claudemd写得越多质量越差">CLAUDE.md：写得越多，质量越差</h2><p>CLAUDE.md 是使用 Claude Code 所必需的第一步，所以也就成了大家最先接触、也是最容易写过头的配置方法。它在 Claude Code 会话启动时就加载，全程驻留在上下文空间中。</p><p>不过这里有个容易忽略的设计：CLAUDE.md 的写法其实分两种。</p><p>第一种，放在项目根目录的 CLAUDE.md 每次会话都加载，压缩后会被重新读取。适合放构建命令、目录结构、团队硬性约定这些 Claude 需要始终知道的信息。</p><p>第二种，子目录的 CLAUDE.md（比如<code>app/api/CLAUDE.md</code>）只在 Claude 读到该目录下的文件时才加载。离开这个目录，这些指令就不在上下文里了。</p><p><img src="/images/2026-06-23-claude-code-steering-claude-md-hierarchy.jpg" alt="CLAUDE.md 层级加载示意" loading="lazy" decoding="async"/></p><p>Anthropic 给的建议是：根 CLAUDE.md 控制在 200 行以内，给它一个 owner，像审查代码一样审查对它的修改。</p><p>这件事在团队协作的大仓库里尤其明显。CLAUDE.md 很容易变成一个没人维护的公共配置文件，每个组都往里加自己的规范，没人删旧的。</p><p>最终每个工程师的每次会话都要加载所有团队的规范，不管跟当前任务有没有关系。</p><p>要解决也很简单，在 monorepo 里给每个团队目录配置单独的 CLAUDE.md，让团队只加载自己的规范。还可以用<code>claudeMdExcludes</code> 跳过不相关团队的文件。</p><p>总结起来一句话，不要把 CLAUDE.md 当成垃圾桶，而是寸土寸金的黄金地段。能不放的，就别放。</p><h2 id="rules按路径触发不白占上下文">Rules：按路径触发，不白占上下文</h2><p>Rules 是<code>.claude/rules/</code> 目录下的 Markdown 文件。</p><p>不带路径限定的 Rule 跟根 CLAUDE.md 行为一样：每次会话都会加载、会话压缩后也会重新注入。其实本质上就是换了个目录放的 CLAUDE.md 内容。</p><p>真正有意思的是带路径限定的 Rule。给 Rule 加一个<code>paths</code> 字段，它就只在 Claude 碰到匹配路径的文件时才加载：</p><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span>---</span></span><span style="display:flex;"><span><span style="color:#f92672">paths</span>:</span></span><span style="display:flex;"><span> -<span style="color:#e6db74">"src/api/**"</span></span></span><span style="display:flex;"><span> -<span style="color:#e6db74">"**/*.handler.ts"</span></span></span><span style="display:flex;"><span>---</span></span><span style="display:flex;"><span><span style="color:#ae81ff">所有 API handler 必须用 Zod 校验输入参数.</span></span></span></code></pre></div><p>这条规则在你改文档的时候完全不占上下文，只有碰到 API 相关代码才会出现。</p><p>所以，凡是只对特定目录或文件类型生效的约束，都应该用 path-scoped Rule，而不是写在 CLAUDE.md 里。这是控制上下文膨胀最直接的手段。</p><p>什么时候用 Rule 而不是子目录 CLAUDE.md？当一个约束是跨目录的。比如“所有<code>.handler.ts</code> 文件都要校验输入”，它可能散布在多个目录下，放某一个目录的 CLAUDE.md 里不合适。</p><h2 id="skills按需加载用完即走">Skills：按需加载，用完即走</h2><p>Skills 住在<code>.claude/skills/</code> 目录里，每个 Skill 是一个文件夹，核心是一个<code>SKILL.md</code> 文件，里面包含了名称、描述和正文。</p><p>Skills 最关键的一个设计时只有名称和描述在会话启动时加载，正文只有在被调用时才进入上下文。</p><p><img src="/images/2026-06-23-claude-code-steering-skills-trigger.jpg" alt="Skills 触发机制" loading="lazy" decoding="async"/></p><p>它的调用方式有两种：通过斜杠命令（比如<code>/code-review</code>），或者 Claude 根据任务自动匹配。</p><p>在使用 Skills 的时候，也需要注意会话压缩的行为：压缩时，已调用的 Skills 会被重新注入，但所有 Skills 共享一个总 token 预算。一次会话里调用太多 Skills，最早调用的会被丢掉。</p><p>Anthropic 给的原则是：流程性的东西放 Skill，不要放 CLAUDE.md。部署流程、发布检查清单、代码审查规范，这些都应该是 Skill。CLAUDE.md 只放 Claude 需要始终知道的事实。</p><p>我自己的经历可也是如此。之前 CLAUDE.md 里写了一大段“发布+验证流程”，后来拆成 Skill，不发布的时候这些指令就不占空间了。省下来的上下文让 Claude 能记住更多真正相关的事情。</p><h2 id="subagents不是多一个帮手是多一块白板">Subagents：不是多一个帮手，是多一块白板</h2><p>Subagents 是<code>.claude/agents/</code> 目录下的 Markdown 文件，用 YAML frontmatter 定义名称、描述和工具权限，正文是这个子 Agent 的系统提示词。</p><p>名称、描述和工具列表在会话启动时加载。但正文永远不会进入主会话的上下文，它在子 Agent 自己的独立上下文窗口里运行，只有最终的摘要消息回到主会话。</p><p><img src="/images/2026-06-23-claude-code-steering-context-window.jpg" alt="Claude Code 上下文窗口结构" loading="lazy" decoding="async"/></p><p>这个设计对上下文管理的意义挺大的。Subagent 可以嵌套最多 5 层，动态工作流可以编排几十甚至上百个后台 Agent。中间结果全在脚本变量里，不污染主上下文。</p><p>那 Skill 和 Subagent 怎么选？Anthropic 给的判断标准是这样的：</p><ul><li>用 Skill：当你希望流程在主线程里执行，你能看到每一步、随时干预。</li><li>用 Subagent：当侧任务的中间结果你不需要再看（深度搜索、日志分析、依赖审计），只需要一个最终摘要。</li></ul><p>说白了，Subagent 的核心价值不是“多一个 Agent”，而是上下文隔离。让主会话保持干净，不被旁支任务的中间过程淹没。</p><p>我自己用 Subagent 最多的场景有两个：一个是让它先 explore 整个代码库，写一份结构报告回来，主 Agent 拿着报告再动手改代码；另一个是设计和实现分离，设计时需要进行大量的调研工作，但实现的时候只需要设计文档就足够了。</p><h2 id="hooks让-claude-code-100-执行">Hooks：让 Claude Code 100% 执行</h2><p>Hooks 是在 Claude Code 生命周期事件上触发的用户定义命令。注册在<code>settings.json</code> 里，在文件编辑、工具调用、会话启动等事件上自动触发。</p><p><img src="/images/2026-06-23-claude-code-steering-hooks-lifecycle.jpg" alt="Hooks 生命周期事件图" loading="lazy" decoding="async"/></p><p>Hook 有五种类型：command、HTTP、mcp_tool、prompt 和 agent。前三种确定性执行（跑脚本、发请求、调工具），后两种用模型判断来决定输出。</p><p>Hooks 的上下文成本极低，配置在主上下文窗口外面，harness 直接执行。只有少数 Hook 的输出会回到主上下文（比如阻断型 Hook 的错误信息，让 Claude Code 知道为什么被拒绝）。</p><p>Hooks 在整套 Claude Code 体系里最容易被忽略但最重要的一点是：</p><p>“每次 X 都必须做 Y” 如果放在 CLAUDE.md 里，本质上是在靠模型的遵从性来保证执行。模型大多数时候会遵守，但在长会话、上下文压力大、或者遇到 prompt injection 的时候，它可以不遵守。</p><p>想要确定性执行，必须用 Hook。比如“每次编辑后跑 prettier”，这不该是一条指令让 Claude Code 选择执行，而应该是一个<code>PostToolUse</code> Hook 在每次文件写入后自动触发。</p><p>同理，“绝对不能做 X” 这种约束也不该靠 CLAUDE.md。用<code>PreToolUse</code> Hook 检查调用，exit code 2 直接阻断。对企业来说，更严格的配置可以用 Managed Settings，管理员部署、用户不可覆盖。</p><p>所以，你要注意，凡是在 CLAUDE.md 里写了“必须”或“绝对不能”的规则，都别忘了问自己一句：这条规则失败了会怎样？如果后果严重，就赶紧改成 Hook。</p><h2 id="output-styles-和-append-system-prompt慎用杀伤力大">Output Styles 和 append-system-prompt：慎用，杀伤力大</h2><p>最后两种方法放在一起说，它们都作用在系统提示词层面，威力大但副作用也大。</p><p>Output Styles 是<code>.claude/output-styles/</code> 目录下的文件，注入系统提示词，永不压缩。注意一个关键细节：自定义 Output Style 默认会替换 Claude Code 的默认系统提示词，除非在 frontmatter 里设置<code>keep-coding-instructions: true</code>。</p><p>换句话说，一旦用了自定义 Output Style，Claude Code 默认的那些行为指导（怎么控制变更范围、什么时候加注释、安全关注点、跑测试再报完工）全部会被覆盖。Claude Code 就从一个软件工程助手变成一个通用助手了。</p><p>所以 Anthropic 的建议是：先看看内置的 Proactive、Explanatory、Learning 三个样式够不够用，再考虑自定义。</p><p>append-system-prompt 是另一种用法，它是 CLI 启动时传入的 flag，只对当前会话生效，不会持久化。它是纯追加的，不会替换默认行为，一般适合临时加一些格式偏好或领域知识。</p><p>我觉得大多数人不需要碰 Output Styles。内置样式加上 CLAUDE.md 已经够用了，除非你真的要把 Claude Code 改造成一个完全不同的角色。</p><h2 id="别踩这些坑">别踩这些坑</h2><p>最后整理一下 Anthropic 给的“反模式”清单，基本都是我自己踩过或见过别人踩的：</p><p>第一个是把“每次 X 都必须做 Y” 这种强制性约束写在 CLAUDE.md 里。模型的指令遵循和代码自动执行是两回事。如果这个行为必须可靠发生，一定要用 Hook。同理，“绝对不能做 X” 也不该靠 CLAUDE.md，禁止性约束在 prompt injection 面前毫无抵抗力，要用 Hook 或 Managed Settings 做墙纸约束。</p><p>第二个是把流程放在 CLAUDE.md 里面。CLAUDE.md 应该只放 Claude Code 需要始终知道的事实以及它最常犯的一些错误的经验教训，而流程则放到 Skills 里面。</p><p>第三个是 Rule 不加 paths。一条只对<code>src/api/</code> 生效的规则如果不加路径限定，效果等同于在 CLAUDE.md 里多了一行，每次都加载，每次都耗 token。个人偏好也是同样的道理，所有的配置方法都分为项目级和用户级，“永远用 semantic commit message” 这种个人习惯应该只放在本地，项目级只放团队共识。</p><hr><h2 id="速查表7-种方法一览">速查表：7 种方法一览</h2><table><thead><tr><th>方法</th><th>何时加载</th><th>压缩行为</th><th>上下文成本</th><th>适用场景</th></tr></thead><tbody><tr><td>CLAUDE.md（根目录）</td><td>会话启动，全程驻留</td><td>缓存式：读一次缓存，压缩后重读</td><td>高</td><td>构建命令、目录结构、编码规范、团队约定</td></tr><tr><td>CLAUDE.md（子目录）</td><td>按需加载，读到该目录下文件时触发</td><td>触发后才有，离开即丢</td><td>低</td><td>特定目录的局部规范</td></tr><tr><td>Rules</td><td>会话启动（无路径限定）或文件触发（有路径限定）</td><td>压缩后重新注入</td><td>中</td><td>具体约束（如“所有 API handler 必须用 Zod 校验”）</td></tr><tr><td>Skills</td><td>名称和描述在会话启动时加载，正文在调用时加载</td><td>已调用的 skill 按预算重新注入，超出则最旧的先丢</td><td>低</td><td>流程性工作（部署清单、发布检查、代码审查）</td></tr><tr><td>Subagents</td><td>名称、描述和工具列表在会话启动时加载，正文在被调用时加载</td><td>只有最终摘要回到主会话</td><td>低</td><td>并行任务或需要隔离的侧任务（深度搜索、日志分析、依赖审计）</td></tr><tr><td>Hooks</td><td>生命周期事件触发</td><td>完全绕过压缩</td><td>低</td><td>确定性自动化（跑 linter、发 Slack、拦截命令）</td></tr><tr><td>Output Styles</td><td>会话启动，注入系统提示词</td><td>永不压缩</td><td>高</td><td>大幅改变 Claude 的角色定位</td></tr></tbody></table><p>这张表最有价值的一列是“上下文成本”。搞清楚哪些指令需要全程驻留、哪些只在触发时加载，是用好这套系统的关键。</p><hr><h2 id="写在最后">写在最后</h2><p>说实话，这篇官方指南没介绍什么新功能，这 7 种方法早就存在了。但它的价值在于第一次把每种方法的加载时机、压缩行为和上下文成本都讲清楚了。</p><p>这 7 种方法按 harness 设计的思路大致可以整理成为四层：</p><ul><li>全局层（CLAUDE.md、unscoped Rules、Output Styles）：高成本、高权威，克制使用</li><li>触发层（path-scoped Rules、子目录 CLAUDE.md、Skills）：按需加载，中低成本</li><li>隔离层（Subagents）：零主上下文成本，只关注结果</li><li>确定性层（Hooks）：绕过模型，代码级保证</li></ul><p>搞清楚这四层，大部分“Claude 为什么忽略我的指令”的问题就有了答案。不是模型不听话，是你把指令放在了错误的层级，或者上下文爆满之后它被忽略掉了。</p><p>我推荐的实践顺序是这样的：所有项目第一步先给根 CLAUDE.md 瘦身，拆出去的流程丢进 Skills，跨目录的约束用 path-scoped Rules，必须 100% 执行的规则用 Hooks 做约束。然后在日常使用中持续观察、持续迭代修改，如果发现有的指令被忽略了，那大概率是相关的指令放错了层级。</p><p>上下文窗口就那么大，每一行指令都有成本。把对的指令放在对的层级，比写更多指令管用得多。</p><hr><p>原文：Steering Claude Code: skills, hooks, subagents and more<a href="https://www.anthropic.com/engineering/claude-code-best-practices">https://www.anthropic.com/engineering/claude-code-best-practices</a></p><hr><p>欢迎长按下面的二维码关注<strong>Feisky</strong> 公众号，了解更多云原生和 AI 知识。</p><p><img src="/images/mp.png" alt="Feisky 公众号二维码" loading="lazy" decoding="async"/></p>
]]></content:encoded><dc:extent>9 min read</dc:extent></item><item><title>Claude Code 动态工作流：让 AI 自己写 Harness，这事靠谱吗</title><link>https://feisky.xyz/posts/2026-06-03-dynamic-workflows/</link><pubDate>Wed, 03 Jun 2026 10:00:00 +0800</pubDate><dc:creator>Pengfei Ni</dc:creator><category>Claude Code</category><category>AI Agent</category><category>工作流</category><category>多Agent架构</category><category>Anthropic</category><guid>https://feisky.xyz/posts/2026-06-03-dynamic-workflows/</guid><description>&lt;blockquote&gt;
&lt;p&gt;题记：本文编译自 Anthropic 官方博客《&lt;a href="https://claude.com/blog/a-harness-for-every-task-dynamic-workflows-in-claude-code"&gt;A harness for every task: dynamic workflows in Claude Code&lt;/a&gt;》，由 Anthropic 工程师 Thariq Shihipar 和 Sid Bidasaria 撰写。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Claude Code 的默认模式是单 Agent，一个上下文窗口搞定规划和执行。大多数编程任务这就足够好用了。&lt;/p&gt;</description><content:encoded>&lt;![CDATA[<blockquote><p>题记：本文编译自 Anthropic 官方博客《<a href="https://claude.com/blog/a-harness-for-every-task-dynamic-workflows-in-claude-code">A harness for every task: dynamic workflows in Claude Code</a>》，由 Anthropic 工程师 Thariq Shihipar 和 Sid Bidasaria 撰写。</p></blockquote><p>Claude Code 的默认模式是单 Agent，一个上下文窗口搞定规划和执行。大多数编程任务这就足够好用了。</p><p>但是也有很多场景你怎么优化都跑不好。单 Agent 在长时间运行、大规模并行、需要对抗性验证的任务上，有三个已知的退化模式：</p><p>第一个是偷懒。让它做一轮安全审查，50 个检查项查到 20 个就宣布完成了。这不是幻觉，是 Agent 在长上下文里的行为退化。第二个是自我偏爱。让它评判自己的产出，它天然倾向于给好评，需要严格验证的场景里这是致命的。第三个是目标漂移。上下文压缩是有损的，每压缩一次，原始需求里的边缘条件、约束细节就丢一点。时间长了之后，Agent 在优化的目标可能已经偏离了你最初给它的任务。</p><p>这三个问题不是模型能力问题，是单上下文窗口同时承担规划和执行带来的架构局限。Anthropic 显然也清楚这一点，所以之前陆续搞了 Research、安全审计、Agent Teams、Code Review 这些定制 Harness，每个都是针对特定任务类型写死的调度逻辑。</p><p>上周他们把这个能力泛化了：Claude Code 现在可以自己写调度逻辑，针对当前任务实时生成编排脚本，也就是 Dynamic Workflows。</p><h2 id="工作原理">工作原理</h2><p>动态工作流的核心思路是：用独立的子 Agent 各自占一个干净的上下文窗口，每个子 Agent 只干一件事，由一个确定性的 JavaScript 脚本来调度它们的执行顺序和依赖关系。</p><p><img src="/images/2026-06-03-dynamic-workflows-image1.jpg" alt="动态工作流架构" loading="lazy" decoding="async"/></p><h2 id="动态-vs-静态区别在哪">动态 vs 静态：区别在哪</h2><p>之前用 Claude Agent SDK 或者<code>claude -p</code> 来编排多个 Claude Code 实例，本质上是静态工作流。你得提前写好脚本，考虑各种边界情况，写出来的东西往往比较通用。</p><p>动态工作流不一样。Claude Code 自己看任务，自己写调度脚本，针对当前这一个具体任务量身定制。Opus 4.8 的能力已经足够让它自己写出高质量的 Harness。</p><p><img src="/images/2026-06-03-dynamic-workflows-image9.jpg" alt="动态工作流与静态工作流对比" loading="lazy" decoding="async"/></p><p>我自己试了一下，感受是：对于那些你本来就知道怎么拆分的任务，静态工作流更可控。但对于"我大概知道要做什么，但不确定最优的拆分方式"的场景，让 Claude Code 自己决定怎么调度确实省事。</p><h2 id="六种调度模式">六种调度模式</h2><p>Claude Code 在构建动态工作流时会组合使用几种基本模式：</p><p><img src="/images/2026-06-03-dynamic-workflows-image10.jpg" alt="工作流模式" loading="lazy" decoding="async"/></p><p>最基础的是分类路由，一个分类 Agent 判断任务类型，分发给不同的处理 Agent。也可以反过来，在最后加一个分类器决定输出格式。</p><p>用得最多的是扇出合并。把任务拆成很多小步，每个小步一个独立 Agent，最后一个合并 Agent 汇总结果。好处是每个子 Agent 有干净的上下文，互不污染。</p><p>对抗验证是直接针对自我偏爱问题的解法：每个生成 Agent 配一个独立的验证 Agent，专门挑毛病。生成过滤类似，先大量生成，再按标准筛选去重，只留通过验证的。</p><p>然后是锦标赛模式。N 个 Agent 用不同策略做同一件事，两两比较淘汰，留下赢家。最后是循环到完成，不设固定轮次，一直跑到满足停止条件为止。</p><p>这些模式可以组合。比如先扇出，每个分支内部做对抗验证，合并时再跑一轮锦标赛选最优方案。</p><h2 id="实际能干什么">实际能干什么</h2><p>那这些模式实际能用在哪？原文列了不少场景，我挑几个觉得实用的说。</p><h3 id="大规模迁移和重构">大规模迁移和重构</h3><p>Bun 从 Zig 重写成 Rust 就用了工作流。核心思路是：把需要改的地方拆成独立单元（调用点、失败的测试、模块），每个单元派一个子 Agent 在独立的 worktree 里修，另一个 Agent 做对抗性 Review，通过了再合并。</p><p>这个场景我觉得价值最大。平时做大规模重构最头疼的就是改着改着上下文丢了，或者改了 A 忘了 B 也要跟着改。每个修改点一个独立 Agent，天然避免了交叉污染。</p><h3 id="深度验证">深度验证</h3><p><img src="/images/2026-06-03-dynamic-workflows-image2.jpg" alt="深度验证工作流" loading="lazy" decoding="async"/></p><p>如果你写了一篇技术文章，里面有大量事实性声明，可以用工作流让一个 Agent 先把所有事实性声明提取出来，然后每个声明派一个子 Agent 去核实。还可以再加一层，验证核实 Agent 引用的信息源本身是否可靠。</p><h3 id="排序">排序</h3><p><img src="/images/2026-06-03-dynamic-workflows-image3.jpg" alt="排序工作流" loading="lazy" decoding="async"/></p><p>对定性内容排序（比如按 Bug 严重程度排 1000 条工单），单次 Prompt 的质量会随数量急剧下降。工作流的做法是用锦标赛模式，两两比较。比较判断比绝对评分可靠得多，而且每次比较是一个独立 Agent，确定性的循环逻辑只负责维护对阵表。</p><h3 id="规则遵守">规则遵守</h3><p><img src="/images/2026-06-03-dynamic-workflows-image8.jpg" alt="规则遵守工作流" loading="lazy" decoding="async"/></p><p>有时候明明在 CLAUDE.md 里写了规则，但 Claude Code 跑着跑着就忘了。这时候，就可以用工作流做一个验证层：一条规则一个验证 Agent，每个验证 Agent 用怀疑论者的视角去检查是否违规。</p><p>反过来也行：扫最近的 session 日志和 Code Review 评论，找反复出现的纠正，聚类、验证（这条规则真的能防住之前的错误吗？），然后把确认有效的提炼成新的 CLAUDE.md 规则。</p><h3 id="根因分析">根因分析</h3><p>调试最怕的是认定了一个假设就一路追到底。单 Agent 在一个上下文窗口里特别容易犯这个错误。工作流可以结构性地避免：分别从日志、文件变更、数据状态生成独立假设，每个假设面对一组验证者和反驳者。</p><p>这个模式不只适用于代码。销售数据下降、数据管道故障、任何需要事后复盘的场景都能用。</p><h3 id="大规模分流">大规模分流</h3><p><img src="/images/2026-06-03-dynamic-workflows-image6.jpg" alt="分流工作流" loading="lazy" decoding="async"/></p><p>每个团队都有处理不完的支持队列。工作流可以对每条工单做分类、去重（跟已有的 ticket 对比）、尝试自动修复或升级给人。</p><p>这里有个有意思的设计模式叫隔离区：读不可信外部内容的 Agent 不允许执行高权限操作，高权限操作由另一个 Agent 负责。读和写分离，避免 prompt injection 导致的越权。</p><h2 id="什么时候不需要工作流">什么时候不需要工作流</h2><p>动态工作流消耗的 token 显著更多，适合复杂、高价值的任务。</p><p>日常写代码，问自己一个问题：这件事真的需要 5 个 Reviewer 组成的评审团吗？大多数常规编程任务可能并不需要。</p><p>我的判断标准是：如果你能在 Prompt 里一句话描述清楚要做什么，而且做完之后你自己能快速验证结果，那就不需要工作流。需要工作流的场景通常有两个特征：任务可以被拆成独立的并行单元，或者验证成本高到你不想自己一个个检查。</p><h2 id="用法和技巧">用法和技巧</h2><p>开启动态工作流的方法有两种：直接在 Prompt 里要求 Claude 创建工作流，或者用触发词<code>ultracode</code>。</p><p>描述调度模式的时候要具体。不是”用工作流做这件事”就完了，而是告诉 Claude Code 你想要什么样的验证方式、什么样的并行策略。上面那六种模式的名字可以直接用在 Prompt 里。</p><p>对于可重复的工作流（分流、监控、验证），搭配<code>/loop</code> 设置定期执行，<code>/goal</code> 设置硬性完成条件。工作流很容易跑飞，在 Prompt 里加一句“用 10k token”（大概一两轮对话的量）就能限制消耗。</p><p>工作流运行时按<code>s</code> 可以保存脚本，存到<code>~/.claude/workflows</code> 或者通过 Skill 分发给团队。</p><p><img src="/images/2026-06-03-dynamic-workflows-image4.jpg" alt="保存工作流" loading="lazy" decoding="async"/></p><p><img src="/images/2026-06-03-dynamic-workflows-image7.jpg" alt="通过 Skill 分享工作流" loading="lazy" decoding="async"/></p><h2 id="几个实际的-prompt-示例">几个实际的 Prompt 示例</h2><p>原文给了一组示例 Prompt，我觉得比理论解释更直观：</p><ul><li>这个测试大概 50 次跑挂一次。用工作流复现它，形成竞争性假设，不找到经得起验证的根因不许停。</li><li>用工作流扫我最近 50 个 session，找到我反复在纠正的模式，把重复出现的提炼成 CLAUDE.md 规则。</li><li>拿我的商业计划，用工作流让不同 Agent 分别从投资人、客户、竞争对手的视角撕它。</li><li>这个文件夹有 80 份简历，用工作流按后端岗位排名，前 10 名交叉验证一遍。先用 AskUserQuestion 问我评分标准。</li><li>用工作流把我们的 User 模型全局重命名成 Account。</li></ul><p>共同点很明显：都是可以拆分成独立并行单元的任务，并且都需要某种形式的验证或对抗。</p><h2 id="写在最后">写在最后</h2><p>三个月前的《<a href="https://mp.weixin.qq.com/s/6AexM5_VngU1KDcYCU7gaA">为什么单 Agent 搞不定复杂应用？Anthropic 的 Harness 设计给出了答案</a>》，当时聊的是 Anthropic 用 Generator-Evaluator 模式做长时间全栈开发。那套架构需要人手动搭建，三个 Agent 跑 6 小时花 200 美元。</p><p>动态工作流的思路是把"搭建 Harness"这件事也交给 Claude Code 自己。不再需要你预先想好怎么拆分、怎么验证、怎么合并，Claude 看了任务之后自己决定。</p><p>这是不是靠谱？说实话，我的体感是：对于你已经有经验的任务类型，自己写静态工作流更可控；对于探索性的任务，让 Claude Code 自己决定调度方式确实能发现一些你没想到的拆法。两者不矛盾，动态工作流可以保存下来变成静态的。</p><p>不过话说回来，Harness 可能也像 prompt engineering 一样，是大模型发展过程中的一个中间状态。模型不够强的时候需要人写精巧的调度逻辑，需要多个 Agent 互相制衡才能把一件事做好；模型足够强了，这些逻辑就会被内化。今天你还在想怎么编排子 Agent，也许下一代模型根本不需要外部编排，自己就能在内部完成任务分解和对抗验证。当然，这个"也许"到底要多久，没人知道。</p><hr><p>相关资源：</p><ul><li>原文链接：<a href="https://claude.com/blog/a-harness-for-every-task-dynamic-workflows-in-claude-code">https://claude.com/blog/a-harness-for-every-task-dynamic-workflows-in-claude-code</a></li><li>动态工作流文档：<a href="https://code.claude.com/docs/en/workflows">https://code.claude.com/docs/en/workflows</a></li><li>前作：Bun 重写（Jarred Sumner）：<a href="https://x.com/jarredsumner/status/2060050578026189172">https://x.com/jarredsumner/status/2060050578026189172</a></li></ul><hr><p>欢迎长按下面的二维码关注<strong>Feisky</strong> 公众号，了解更多云原生和 AI 知识。</p><p><img src="/images/mp.png" alt="Feisky 公众号二维码" loading="lazy" decoding="async"/></p>
]]></content:encoded><dc:extent>7 min read</dc:extent></item><item><title>Claude Code 在大型代码库里到底怎么用？Anthropic 给出了官方答案</title><link>https://feisky.xyz/posts/2026-05-16-claude-code-large-codebase/</link><pubDate>Sat, 16 May 2026 10:00:00 +0800</pubDate><dc:creator>Pengfei Ni</dc:creator><category>Claude Code</category><category>Anthropic</category><category>大型代码库</category><category>Harness</category><category>AI 编程</category><guid>https://feisky.xyz/posts/2026-05-16-claude-code-large-codebase/</guid><description>&lt;blockquote&gt;
&lt;p&gt;题记：本文编译自 Anthropic 工程团队官方博客《How Claude Code Works in Large Codebases: Best Practices and Where to Start》，原文链接：&lt;a href="https://claude.com/blog/how-claude-code-works-in-large-codebases-best-practices-and-where-to-start"&gt;https://claude.com/blog/how-claude-code-works-in-large-codebases-best-practices-and-where-to-start&lt;/a&gt;。本文在翻译基础上做了整理和补充。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Claude Code 在小项目里用着真挺丝滑的，基本上你碰到的问题它都能帮你解决。&lt;/p&gt;</description><content:encoded>&lt;![CDATA[<blockquote><p>题记：本文编译自 Anthropic 工程团队官方博客《How Claude Code Works in Large Codebases: Best Practices and Where to Start》，原文链接：<a href="https://claude.com/blog/how-claude-code-works-in-large-codebases-best-practices-and-where-to-start">https://claude.com/blog/how-claude-code-works-in-large-codebases-best-practices-and-where-to-start</a>。本文在翻译基础上做了整理和补充。</p></blockquote><p>Claude Code 在小项目里用着真挺丝滑的，基本上你碰到的问题它都能帮你解决。</p><p>不过一旦搬到大代码库，体验就开始打折扣。让它查找一个函数，grep 出来上千条匹配，你的上下文空间直接就被淹没了；改一个子服务，它非要跑全项目的测试用例，跑就跑吧还动不动超时偷懒，有时甚至自作聪明顺手改了一堆不该改的代码。</p><p>你在大型代码库里使用 Claude Code 是不是也碰到过这些问题？反正我是经常碰到。</p><p>前两天 Anthropic 工程团队发了一篇官方博客 How Claude Code Works in Large Codebases: Best Practices and Where to Start），系统讲解了大型代码仓库中用好 Claude Code 的方法论，推荐所有 Claude Code 用户都读一读。</p><p>下面是逐节的翻译，每一节我加上了自己的注解。</p><h2 id="一claude-code-是怎么浏览代码的">一、Claude Code 是怎么浏览代码的</h2><p>Anthropic 博客一开头就讲了一个容易被忽略的事实：Claude Code 在大代码库里搜代码的方式，跟我们一直理解的 RAG 方式是完全不同的思路。</p><p>RAG 的做法是把整个代码库做 embedding，查询时检索相关片段。听起来挺合理的，但在大代码库里有个死结：embedding 流程追不上工程团队的提交速度。等你查询的时候，索引反映的是几天甚至几周前的代码，搜出来的可能是已经被重命名的函数，或者已经被删掉的模块。</p><p>Claude Code 走的是另一条路，叫 agentic search。它就像一个工程师那样找代码：遍历文件系统、读文件、grep 关键字、跟着 reference 跳转。所有动作都是实时的，不依赖任何索引。</p><p>这个差异不是技术孰优孰劣，而是适用场景不同。小到中型、变化没那么频繁的代码库，RAG 可能更快。但大代码库、活跃项目、频繁重构这些场景，agentic 是唯一靠谱的方式。</p><p>要用好 agentic search 也有它的前提：你的代码库得让 Claude Code 快速定位到具体的位置。如果目录命名混乱、没有 README、没有任何线索告诉它从哪开始看，再聪明的模型也得绕远路遍历大量无关文件，导致上下文空间被白白浪费。后面 Anthropic 讲的所有最佳实践，本质都是在解决这个问题。</p><h2 id="二harness-比模型更重要">二、harness 比模型更重要</h2><p>Anthropic 在原文里给了一个清单，列出了塑造 Claude Code 能力的 harness 七件套：</p><ul><li>CLAUDE.md</li><li>Hooks</li><li>Skills</li><li>Plugins</li><li>LSP</li><li>MCP servers</li><li>Subagents</li></ul><p>这七件套加起来，决定了同样的模型在你手里跑出来是什么效果。</p><p>我自己的体验跟这个清单完全一致。同样是 Claude Opus 4.6 模型，裸装 Claude Code 写代码，跟调好 CLAUDE.md 、装备 subagent 、配上 skills 之后相比，效果不是一个量级的。</p><p>这跟之前 Anthropic 在 Harness 设计那篇文章（《<a href="https://mp.weixin.qq.com/s/6AexM5_VngU1KDcYCU7gaA">为什么单 Agent 搞不定复杂应用</a>》）里讲的逻辑是一致的：模型能力决定了天花板，harness 决定了你能走到天花板的多少。差的 harness 把模型能力浪费一大半都不夸张。</p><p>下面把这七件套一个一个聊聊。</p><h2 id="三claudemd分层是最大的杠杆">三、CLAUDE.md：分层是最大的杠杆</h2><p>CLAUDE.md 是每个会话启动时自动加载的上下文文件。Claude Code 会从当前目录往上一直走到根目录，把每一层的 CLAUDE.md 都读进来。</p><p>这个加载机制是叠加的，所以分层非常关键。Anthropic 给的原则是：根 CLAUDE.md 只放指针和关键注意事项。</p><p>Anthropic 还给了几条特实用的具体建议：</p><p>第一，给子目录创建 CLAUDE.md，而不是只是在根目录里。Claude 自动会往上走，所以你启动它的时候 cd 到任务相关的子目录，加载到的上下文最聚焦。</p><p>第二，lint 和 test 命令按子目录配置。改一个子服务却跑全项目的 test，是大代码库里最常见的浪费。耗时耗力不说，跑出来的输出信息还容易把 context 全淹了。子目录的 CLAUDE.md 应该写清楚“在这个目录下，跑测试用 X，跑 lint 用 Y”。</p><p>第三，用<code>.ignore</code> 文件（ripgrep 的标准 ignore 格式）排除生成目录、build 产物、第三方代码这些噪音，同时把<code>permissions.deny</code> 规则写到<code>.claude/settings.json</code> 里。后者会跟着 git 一起 commit 出去，团队每个人都自动生效，不用各自配。如果某些开发者就是要碰生成目录，可以在自己的本地 settings 里覆盖项目级规则，不影响其他人。</p><p>第四，如果你的代码库就是没有传统目录结构，那写一个 codebase map：根目录放一个简短的 markdown 文件，列出顶层目录每个是干嘛的，一句话描述，给 Claude Code 一个目录索引。</p><p>这一节是整篇文章里最值得反复读的。CLAUDE.md 调好，其他六件套的价值才能放出来。</p><h2 id="四hooks让你的-setup-自我进化">四、Hooks：让你的 setup 自我进化</h2><p>Hooks 是绑定在事件上的脚本。Stop hook 在 session 结束时跑，Start hook 在开始时跑，另外还有 PreToolUse、PostToolUse 这些。</p><p>Anthropic 给了三个典型用法：</p><p>第一个是 Stop hook 可以让 Claude 自己回顾这个 session，分析有什么经验值得沉淀，然后主动提议更新 CLAUDE.md。这其实是把 self-improvement 自动化了，让其越用越聪明。</p><p>第二个是 Start hook 可以根据当前路径或者当前用户动态加载团队特定的上下文。比如你今天在前端目录，自动加载 UI 团队的约定；明天切到后端目录，自动换成后端的那一套。每个开发者就不用手动维护自己模块的 setup 了。</p><p>第三个是强制规则用 hook 而不是 prompt。比如自动跑 lint、提交前必须过 typecheck、危险命令拦截，这些都很适合。Prompt 是建议，hook 是约束，能用 hook 就别只写在 prompt 里。这点跟我自己的体感完全一样：让模型自觉其实远不如代码里拦住它来得靠谱。</p><p>在我看来，Hooks 是 Claude Code 里最被低估的扩展点，配置门槛比 skill 低，杀伤力却大。建议先把基础 hook 配上，再去考虑其他扩展。</p><h2 id="五skills-和-plugins把好东西散播开">五、Skills 和 Plugins：把好东西散播开</h2><p>Skills 解决的是“专业能力按需出现”的问题。</p><p>大代码库里任务类型几十上百种，每个 session 都把所有能力塞进上下文是不现实的。Skills 用的是 progressive disclosure 的思路：能力描述常驻 context，具体内容只有用到才加载。这次 Anthropic 还提了一个进阶用法，skill 可以按路径 scope，只在特定子目录激活，避免无关 skill 互相打架。</p><p>说实话，写好一个 skill 门槛其实不低。Anthropic 之前专门写过一篇（《<a href="https://mp.weixin.qq.com/s/k_BmfjCByVE2HJz7nqtXRw">写好一个 Skill 有多难</a>》），踩了几百个坑才总结出来一套规则。这次大代码库文档里强调的“按路径 scope”算是新增的进阶建议。</p><p>Plugins 解决的是“好配置散播开”的问题。</p><p>大代码库里最常见的一个现象是：少数几个老员工把 skill、hook、MCP 配置摸透了用得很爽，新人入职完全不知道有这些东西。这种 tribal knowledge 进不了生产力分布，对组织来说是很可惜的。</p><p>Plugin 把 skill、hook、MCP server 打包成一个安装包，新人一条命令装完就跟老员工同样的能力。我自己开源过两个仓库（<a href="https://github.com/feiskyer/claude-code-settings">claude-code-settings</a> 和<a href="https://github.com/feiskyer/codex-settings">codex-settings</a>），初衷就是这个：把自己折腾出来的配置整理出来，让别人不用再走一遍弯路。</p><p>升级路径也是 plugin 的优势。所有人都装同一个 plugin，你修了一个 skill 的 bug，下一次更新所有人都拿到。靠口口相传根本做不到这种分发。</p><h2 id="六lsp从-grep-到-symbol">六、LSP：从 grep 到 symbol</h2><p>这一段可能是文档里最技术、但也最实用的一节。</p><p>Claude Code 默认搜代码靠 grep。grep 在小代码库还行，到了大代码库就是个灾难：你搜一个<code>getUser</code>，可能返回上千个匹配，分布在几百个文件里。Claude 为了搞清楚到底是哪个，得一个个打开看，context 瞬间被烧光。</p><p>LSP（Language Server Protocol）是编程 IDE 早就已经在用的东西。它知道你这个<code>getUser</code> 是哪个 class 的方法、有哪些 reference、定义在哪、被谁调用。把 LSP 的能力转给 Claude Code，搜索就从字符串变成了符号。</p><p>实际效果差距可能是几十倍。同一个查询，grep 返回的是上千条文本匹配，LSP 返回的可能只有几条，并且每一条都是真正引用这个符号的位置。Claude 不用再去打开一堆无关文件，context 也省下来了。</p><p>这个适用前提是你的语言有靠谱的 LSP，对 Go、TypeScript、Java、Python、Rust 这些主流语言都没问题。脚本类语言可能稍微弱一些。</p><h2 id="七mcp-和-subagent扩展和隔离">七、MCP 和 Subagent：扩展和隔离</h2><p>MCP server 主要是让 Claude 接入它本来够不到的那些东西：内部工具、私有 API、文档系统等等。我之前在《<a href="https://mp.weixin.qq.com/s/rLwm5v3IFRP7UcOarfqEZg">MCP 不只是开发工具</a>》里聊过生产级 MCP 怎么搭，这里就不展开了。</p><p>这次有个新的角度挺值得提：专门写一个 MCP server，把代码库的结构化搜索包装成 Claude 可以直接调用的工具。比如“查找所有 implements 这个 interface 的 class”、“查找所有调用这个 deprecated API 的地方”。这类查询用 grep 做不到，用 LSP 部分能做，但用专用 MCP 是最干净的。</p><p>Subagent 这个我想专门聊一下，因为是我用得最多的一个。</p><p>简单来说，Subagent 就是一个独立的 Claude Code 实例，有自己的 context window，接到任务、做完工作、只把最终结果返回给主 agent。</p><p>我用 Subagent 用得最多的场景就是 explore/edit 拆分。让一个 read-only 的 Explore subagent 先去摸目录、读文件、画出系统结构，写到一个文件里。主 agent 拿到这份报告，再带着完整图景去改代码。</p><p>为什么不让主 agent 自己 explore 自己 edit？因为 explore 阶段会读几十个文件，每个文件成百上千行，主 context 很快就被这些读取结果污染了。等到要写代码的时候，模型注意力已经分散在大量无关的细节上。</p><p>把 explore 隔离到 subagent 里，主 agent 只拿到一份精炼的总结，相当于拿到一张地图开始施工，而不是边挖边迷路。这跟之前讲上下文管理那篇文章（《<a href="https://mp.weixin.qq.com/s/ihzAIlFQZCe7AlvjLQfeCw">Claude Code 作者亲授：百万 token 上下文的正确用法</a>》）里“Subagent 本质上是上下文管理工具”的说法完全一致。</p><h2 id="八配置随模型升级要瘦身">八、配置随模型升级要瘦身</h2><p>这是整篇文档里我觉得最容易被忽视的一节。</p><blockquote><p>为旧模型写的指令，可能反过来限制新模型。</p></blockquote><p>模型在不停升级。你为 Sonnet 4.5 写的 CLAUDE.md 提示、为修补当时模型缺陷加的 hook、为绕过当时上下文管理 bug 写的 skill，到了 Opus 4.7 可能不仅没用，反而成了限制。</p><p>我自己有个真实例子。早期我在根 CLAUDE.md 里加了一段“请先列出所有计划再执行”，那是因为当时模型容易跳步。等模型升级后，规划能力本来就有了，这条提示反而让 Claude 每次都先输出一段冗长的计划，效率反而降了。</p><p>Anthropic 的建议是每 3 到 6 个月，或者每次大版本发布后，专门 review 一次 harness 配置：哪些规则还有意义、哪些已经过时、哪些 hook 可以删、哪些 skill 可以合并。</p><p>这个习惯在传统工程里叫技术债清理，放到 harness 上同样适用。CLAUDE.md 跟代码注释一样会腐烂，你不主动清，它就慢慢变成噪音。</p><h2 id="九组织准备driagent-manager跨职能工作组">九、组织准备：DRI、agent manager、跨职能工作组</h2><p>最后一节是组织层面的，大公司读者可能更关心。</p><p>Anthropic 观察到一个规律：Claude Code 推广最顺利的组织，都是在大规模铺开之前先做了一波基础设施建设。少数几个早期采用者负责把 plugin 库搭起来、把 MCP 接好、把 CLAUDE.md 模板写出来，然后才让全员上手。</p><p>新出现的一个角色叫 agent manager，是 PM + 工程师的混合角色，专门管理 Claude Code 生态。如果团队没这么奢侈，最起码也要有一个 DRI（Directly Responsible Individual），管 plugin marketplace、管 CLAUDE.md 约定、管 settings 决策。</p><p>问题是，光靠工程师自下而上的热情其实不够。热情会催生很多个人配置，但散乱、重复、互相冲突。这种时候需要有人来收口。</p><p>大公司还有一层是治理。安全、合规、代码审查流程要早立工作组。原文这点是比较国际化的语境，搬到中国团队还要再加上数据出境、审查留痕，以及敏感行业（金融、政务）的额外要求。这些事情早做比晚做要少很多痛苦。</p><p>哪怕你是个人开发者或者小团队，把配置维护这件事当成一个明确的责任分配下来，也比“大家都用一下吧”要有效得多。</p><h2 id="写在最后">写在最后</h2><p>正如 Claude Code 一直在持续不停迭代一样，要用好 Claude Code 的 harness 配置也不是一次配好就一劳永逸的，也需要随着模型迭代一起进化。CLAUDE.md、Hooks、Skills、MCP、LSP、Subagent，每个配置存在的理由都要定期审视，不能因为它已经在那就让它一直在那。</p><p>我自己的实践顺序是这样的：所有项目第一步先创建 CLAUDE.md（包括核心子目录中的 CLAUDE.md），然后再根据需要在项目的 .claude 里面配置所需要的 Hook、MCP 和 Skills，然后就可以用 Claude Code 玩起来了。之后在根据实际需要调整优化，并提醒 Claude Code 把经常出错的地方存入它的 Memory。</p><hr><p>相关资源：</p><ul><li>原文：<a href="https://claude.com/blog/how-claude-code-works-in-large-codebases-best-practices-and-where-to-start">https://claude.com/blog/how-claude-code-works-in-large-codebases-best-practices-and-where-to-start</a></li><li>Harness 设计前作：<a href="https://mp.weixin.qq.com/s/6AexM5_VngU1KDcYCU7gaA">为什么单 Agent 搞不定复杂应用</a></li><li>上下文管理：<a href="https://mp.weixin.qq.com/s/ihzAIlFQZCe7AlvjLQfeCw">Claude Code 作者亲授：百万 token 上下文的正确用法</a></li><li>Skill 写作经验：<a href="https://mp.weixin.qq.com/s/k_BmfjCByVE2HJz7nqtXRw">写好一个 Skill 有多难</a></li><li>我的 Claude Code 配置：<a href="https://github.com/feiskyer/claude-code-settings">feiskyer/claude-code-settings</a></li></ul><hr><p>欢迎长按下面的二维码关注<strong>Feisky</strong> 公众号，了解更多云原生和 AI 知识。</p><p><img src="/images/mp.png" alt="Feisky 公众号二维码" loading="lazy" decoding="async"/></p>
]]></content:encoded><dc:extent>10 min read</dc:extent></item><item><title>MCP 不只是开发工具：生产级 Agent 集成的三条路</title><link>https://feisky.xyz/posts/2026-04-23-mcp%E4%B8%8D%E5%8F%AA%E6%98%AF%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7%E7%94%9F%E4%BA%A7%E7%BA%A7agent%E9%9B%86%E6%88%90%E7%9A%84%E4%B8%89%E6%9D%A1%E8%B7%AF/</link><pubDate>Thu, 23 Apr 2026 10:00:00 +0800</pubDate><dc:creator>Pengfei Ni</dc:creator><category>AI Agent</category><category>MCP</category><category>Anthropic</category><category>Claude Code</category><category>Skills</category><category>架构设计</category><guid>https://feisky.xyz/posts/2026-04-23-mcp%E4%B8%8D%E5%8F%AA%E6%98%AF%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7%E7%94%9F%E4%BA%A7%E7%BA%A7agent%E9%9B%86%E6%88%90%E7%9A%84%E4%B8%89%E6%9D%A1%E8%B7%AF/</guid><description>&lt;blockquote&gt;
&lt;p&gt;题记：本文编译自 Anthropic 博客《&lt;a href="https://claude.com/blog/building-agents-that-reach-production-systems-with-mcp"&gt;Building agents that reach production systems with MCP&lt;/a&gt;》。文章从 Agent 连接外部系统的三条路讲起，重点梳理了 MCP 服务器的设计模式、认证标准化、上下文优化，以及 Skills 的互补定位。不算长，但信息密度不低，尤其是 Cloudflare 的代码编排模式和 Vault 的凭证管理思路，值得做 MCP 服务器的人细看和参考。&lt;/p&gt;</description><content:encoded>&lt;![CDATA[<blockquote><p>题记：本文编译自 Anthropic 博客《<a href="https://claude.com/blog/building-agents-that-reach-production-systems-with-mcp">Building agents that reach production systems with MCP</a>》。文章从 Agent 连接外部系统的三条路讲起，重点梳理了 MCP 服务器的设计模式、认证标准化、上下文优化，以及 Skills 的互补定位。不算长，但信息密度不低，尤其是 Cloudflare 的代码编排模式和 Vault 的凭证管理思路，值得做 MCP 服务器的人细看和参考。</p></blockquote><p>我之前给 Claude Code 配 MCP 服务器的时候，最头疼的是上下文占用的问题，后来《Claude Code 终于解决了 MCP 最大的痛点》那篇写过 Tool Search 怎么解决这个事。但用得越多越发现，上下文只是冰山一角。</p><p>本地开发时，Agent 调个 API、跑个命令行工具，一切都很丝滑。但等你想把它放到云上跑，问题就来了：CLI 工具没有 shell 可用，API 调用的认证凭证要自己管，每对接一个新服务就要从头写一套集成代码。</p><p>刚刚看到 Anthropic 发了一篇博客，系统梳理了 Agent 连接外部系统的三条路，以及为什么生产环境下 MCP 可能是最务实的选择，分享一下，供大家参考。</p><h2 id="把-agent-接入外部系统">把 Agent 接入外部系统</h2><p>Anthropic 把 Agent 接入外部系统的方式分成三种：直接调 API、用 CLI，以及走 MCP 协议。</p><p>直接调 API 是最多人的起点，也是最简单的。Agent 在沙箱里发 HTTP 请求，或者通过 function calling 调用外部服务。一个 Agent 对一个服务没什么问题。但接的服务一多，每个 Agent 和服务的配对都要单独处理认证、工具描述和异常情况。做过微服务的人应该很熟悉，这就是经典的 M×N 集成问题。</p><p>CLI 也能用，快、轻量，复用现有工具链。但在移动端、Web 端和云托管平台这些没有 shell 的地方往往会到处碰壁，认证也只能靠磁盘上的凭证文件。说白了，CLI 是本地开发的好帮手，离生产还差一截。</p><p>MCP 走的是协议层。Agent 连上一个 MCP 服务器，服务器把你系统的能力暴露出来，认证、发现、语义描述都标准化了。一个远程服务器可以同时服务 Claude、ChatGPT、Cursor、VS Code 这些客户端，部署在哪都行。MCP 的前期投入确实比前两种大一些，但换来的是可移植性，以及协议本身能描述的东西也更多。</p><p>我自己的感受是，本地开发阶段 CLI 和 MCP 都够用，但一旦 Agent 要上云、要服务多个客户端，MCP 基本是唯一的选择。那为什么 Anthropic 现在特别强调生产环境？</p><h2 id="生产-agent-跑在云上">生产 Agent 跑在云上</h2><p>因为生产级 Agent 越来越多地跑在云上，它们需要连接的系统也在云上：数据存在那里，工单跟踪在那里，基础设施也在那里。这些系统通常是远程的、带认证的，正好是 MCP 擅长处理的场景。</p><p>从 Anthropic 自己的产品线也能看出这个趋势。前段时间发布的 Managed Agents，底层就是靠 MCP 连接外部工具和数据源，之前那篇《Managed Agents 架构拆解》分析过它的脑手分离设计。Claude Cowork、Claude Code Channels 也是类似的思路，MCP 在里面扮演的就是连接层的角色。MCP SDK 的月下载量从年初的 1 亿涨到了 3 亿，增速确实有点猛。</p><p>不过 Anthropic 也没说 MCP 就应该替代其他方式。API 是基础，CLI 服务本地开发，MCP 覆盖云端。三条路最终都会并存。</p><p>那问题就变成了：决定用 MCP 之后，服务器怎么设计才好用？</p><h2 id="mcp-服务器怎么设计才好用">MCP 服务器怎么设计才好用</h2><p>Anthropic 目前 MCP 目录里有 200 多个服务器。从这些实践中他们提炼了几个设计模式，结合我自己写 MCP 服务器的经验，聊聊几个我觉得最有价值的。</p><h3 id="远程服务器优先">远程服务器优先</h3><p>只有远程服务器才能同时覆盖 Web、移动端和云端 Agent，这是分发的前提。本地服务器在开发阶段够用，但想让 Agent 在任何环境下都能调用你的服务，必须上远程。</p><h3 id="按意图分组工具不要一比一镜像-api">按意图分组工具，不要一比一镜像 API</h3><p>这个我之前在《Claude Code 终于解决了 MCP 最大的痛点》提过，工具越少、描述越好，Agent 用起来越准。一个<code>create_issue_from_thread</code> 工具，比让 Agent 自己拼<code>get_thread</code> +<code>parse_messages</code> +<code>create_issue</code> +<code>link_attachment</code> 靠谱得多。</p><p>做过 Agent 开发的你应该都体会过，把底层 API 原封不动暴露给模型，基本就是在赌它能自己编排出正确的调用序列。赌赢的概率不高。我之前做 Kubernetes MCP 服务器的时候，最开始也是把 Kubernetes API 一比一映射成工具，结果模型光是选对工具就要好几轮，后来按运维场景重新分组，调用准确率提升了很多。</p><h3 id="大量-api-场景用代码编排">大量 API 场景用代码编排</h3><p>如果你的服务有几百个接口，按意图分组也覆盖不完。这时候 Cloudflare 的做法挺妙的：只暴露两个工具（搜索和执行），覆盖了大约 2500 个 API 端点，整个工具定义只占 1K token。思路是让 Agent 写一小段脚本，服务器在沙箱里跑，只返回结果。</p><h3 id="用-mcp-apps-做交互">用 MCP Apps 做交互</h3><p>MCP Apps 是 MCP 协议的第一个官方扩展，允许工具返回交互式界面，图表、表单、仪表盘，直接嵌在对话里渲染。你让 Agent 查一下数据库的慢查询，返回的不是一堆文本，而是一个可排序的交互式表格。这体验一下子就提升上去了，Anthropic 说支持 MCP Apps 的服务器在用户留存上表现好很多，这个不难理解。</p><p>还有一个叫 Elicitation 的能力也值得关注。它让 MCP 服务器在工具调用中途暂停，向用户请求输入。比如你让 Agent 删一个资源，服务器可以弹一个确认表单，而不是直接执行。更敏感的操作比如 OAuth 登录，可以把用户引到浏览器里完成，凭证不经过 MCP 客户端。这个设计思路和之前聊过的 Managed Agents 的安全隔离一脉相承，敏感信息能不过手就不过手。</p><h2 id="认证这块终于不用自己造轮子了">认证这块终于不用自己造轮子了</h2><p>说实话，认证一直是 MCP 从开发到生产最让人头疼的部分。本地开发时 MCP 服务器大多不需要认证，或者直接用 API Key 凑合。但到了生产环境，用户授权、token 存储、过期刷新、多租户隔离，每个环节都是坑。之前每个 MCP 服务器都得自己处理 OAuth 流程，各种边角情况踩不完。</p><p>最新的 MCP 规范在这块改进了不少。CIMD（Client ID Metadata Documents）简化了客户端注册的 OAuth 流程，用户首次授权更快，反复弹授权框的情况也少了。MCP SDK、Claude.ai 和 Claude Code 都已经支持这个规范。</p><p>对云端 Agent 来说，令牌的存储和刷新是另一个痛点。Managed Agents 的 Vault 机制处理了这个问题：注册一次用户的 OAuth 令牌，创建 session 时引用 Vault ID，平台自动把凭证注入每个 MCP 连接，过期了自己刷新。不用自己搭密钥管理服务，不用每次调用传 token。这个思路和 Kubernetes 里 ServiceAccount 自动挂载 token 的逻辑挺像的，让凭证管理变成基础设施的一部分，应用层不用操心。</p><h2 id="上下文效率tool-search-和程序化调用">上下文效率：Tool Search 和程序化调用</h2><p>MCP 服务器越多，上下文占用越大，这个问题前面提到过。Anthropic 现在有两个客户端侧的优化模式。</p><p>Tool Search 是按需加载工具定义，不一次性全塞进上下文。Agent 运行时搜索工具目录，只拉取当前任务需要的工具。根据 Anthropic 的测试，工具定义相关的 token 占用能降低 85% 以上，选择准确率基本不受影响。</p><p><img src="/images/2026-04-23-MCPAgent-context-usage.jpg" alt="Tool Search 上下文优化效果" loading="lazy" decoding="async"/></p><p>程序化工具调用是在代码执行沙箱里处理工具返回结果，而不是原样扔回给模型。Agent 可以在代码里循环、过滤、聚合多次调用的结果，只把最终输出放进上下文。复杂的多步工作流能省掉大约 37% 的 token。</p><p>两个模式叠加使用的效果更好：上下文更精简，往返次数更少，响应也更快。</p><h2 id="skills-和-mcp-是互补的">Skills 和 MCP 是互补的</h2><p>这个话题之前也聊过。简单说，MCP 给 Agent 能力（能调什么工具、能访问什么数据），Skills 给 Agent 知识（怎么用这些工具完成具体任务），两者最好结合着一起使用。</p><p><img src="/images/2026-04-23-MCPAgent-skills-mcp.png" alt="Skills 和 MCP 的协作方式" loading="lazy" decoding="async"/></p><p>具体有两种组合模式。</p><p>第一种是把 Skills 和 MCP 服务器打包成 Plugin。Claude 的 Plugin 可以捆绑 Skills、MCP 服务器、Hooks、子 Agent 这些组件，一键分发。比如 Cowork 的数据 Plugin，里面有 10 个 Skills 和 8 个 MCP 服务器，覆盖 Snowflake、Databricks、BigQuery 这些数据工具。这种模式让 Claude 从通用助手变成领域专家。</p><p>第二种是让 MCP 服务器自带 Skill。Canva、Notion、Sentry 这些厂商已经在做了，在 Claude 的目录里把 Skill 和 Connector 放在一起。MCP 社区也在做一个扩展，让服务器直接分发 Skills，客户端自动继承，版本跟着 API 走。</p><p>我的体会是：MCP 服务器只提供工具的话，Agent 每次都得自己摸索调用顺序和参数搭配，效率不高。Skill 把最佳实践编码进去，等于给 Agent 附了一份操作手册，开箱就能按套路来。</p><h2 id="写在最后">写在最后</h2><p>回头看生产环境 Agent 集成外部系统这件事，由于 Agent 跑在云上，需要连接的服务也在云上，中间就需要一个标准化的协议层。</p><p>相比直接 API 调用和命令行 CLI，MCP 目前是这个位置上最合适的协议，特别是远程 MCP 服务器。MCP 的优势在于它是开放协议，不绑定任何一家模型厂商，一个服务器建好了，Claude、ChatGPT 之类的任意 AI Agent 都能用。</p><hr><p>相关资源：</p><ul><li>原文链接：<a href="https://claude.com/blog/building-agents-that-reach-production-systems-with-mcp">https://claude.com/blog/building-agents-that-reach-production-systems-with-mcp</a></li><li>MCP SDK 文档：<a href="https://modelcontextprotocol.io/docs/sdk">https://modelcontextprotocol.io/docs/sdk</a></li><li>MCP Apps 扩展：<a href="https://modelcontextprotocol.io/extensions/apps/overview">https://modelcontextprotocol.io/extensions/apps/overview</a></li><li>高级工具使用指南：<a href="https://www.anthropic.com/engineering/advanced-tool-use">https://www.anthropic.com/engineering/advanced-tool-use</a></li><li>写好 Agent 工具：<a href="https://www.anthropic.com/engineering/writing-tools-for-agents">https://www.anthropic.com/engineering/writing-tools-for-agents</a></li><li>MCP 规范（含 CIMD 和 Elicitation）：<a href="https://modelcontextprotocol.io/specification/2025-11-25">https://modelcontextprotocol.io/specification/2025-11-25</a></li></ul><hr><p>欢迎长按下面的二维码关注<strong>Feisky</strong> 公众号，了解更多云原生和 AI 知识。</p><p><img src="/images/mp.png" alt="Feisky 公众号二维码" loading="lazy" decoding="async"/></p>
]]></content:encoded><dc:extent>8 min read</dc:extent></item><item><title>Harness 不只是脚手架：从 Claude Code、Hermes 和 OpenClaw 看 Agent 架构的三条路</title><link>https://feisky.xyz/posts/2026-04-21-%E4%B8%89%E7%A7%8Dagent%E5%93%B2%E5%AD%A6/</link><pubDate>Tue, 21 Apr 2026 10:00:00 +0800</pubDate><dc:creator>Pengfei Ni</dc:creator><category>AI Agent</category><category>架构设计</category><category>OpenClaw</category><category>Hermes Agent</category><category>Claude Code</category><category>Anthropic</category><guid>https://feisky.xyz/posts/2026-04-21-%E4%B8%89%E7%A7%8Dagent%E5%93%B2%E5%AD%A6/</guid><description>&lt;p&gt;提到 Harness，大部分人第一反应是 Anthropic 说的那个概念：模型外面包的一层编排代码，负责调用模型、路由工具、管理上下文。我之前写过一篇《为什么单 Agent 搞不定复杂应用？Anthropic 的 Harness 设计给出了答案》，里面详细拆了 Anthropic 的 Generator-Evaluator 模式。Anthropic 的核心观点是 Harness 编码的是对模型能力边界的假设，模型变强了，Harness 就该做减法。&lt;/p&gt;</description><content:encoded>&lt;![CDATA[<p>提到 Harness，大部分人第一反应是 Anthropic 说的那个概念：模型外面包的一层编排代码，负责调用模型、路由工具、管理上下文。我之前写过一篇《为什么单 Agent 搞不定复杂应用？Anthropic 的 Harness 设计给出了答案》，里面详细拆了 Anthropic 的 Generator-Evaluator 模式。Anthropic 的核心观点是 Harness 编码的是对模型能力边界的假设，模型变强了，Harness 就该做减法。</p><p>这个理解没错，但只是三种理解中的一种。</p><p>最近我把 Claude Code、Hermes Agent 和 OpenClaw 的源码和架构文档都翻了一遍，发现一个挺有意思的事：这三个项目嘴上都在说 Harness，但做出来的东西完全不一样。Claude Code 把 Harness 当脚手架，越轻越好，模型能搞定的事就别替它做。Hermes 把 harness 当学习系统，每次任务都在积累经验，越用越聪明。OpenClaw 把 Harness 当基础设施，Gateway、路由、设备节点、任务调度，跟模型强不强没什么关系。</p><p>对 Harness 的理解不同，造出来的产品就完全不同。下面我就带你一起拆开看看它们都是如何设计 Harness 的。</p><h2 id="harness-核心设计">Harness 核心设计</h2><p>从这三个项目的代码结构和设计文档上，很容易发现它们的架构设计具有明显的不同。</p><p>OpenClaw 的核心是 Gateway。官方架构文档第一句也写明了他是一个 long-lived Gateway 拥有所有 messaging surfaces。CLI、macOS app、Web UI、自动化任务，全部通过 WebSocket 连接 Gateway。</p><p>手机、Mac、远程设备也通过同一个协议接入，只不过声明自己是 node，暴露摄像头、屏幕、Canvas 等能力。Gateway 默认监听<code>127.0.0.1:18789</code>，连 Canvas 和 A2UI 都由同一个 HTTP server 托管。</p><p><img src="/images/2026-04-21-Agent-openclaw-arch.png" alt="OpenClaw 架构全景" loading="lazy" decoding="async"/></p><p>也就是说，OpenClaw 把多入口收束成了单控制平面。你从 Telegram 发消息，从 Web UI 操作，从手机节点触发，最终都进入同一套协议、同一套会话管理、同一套工具策略、同一套事件流。也就是说，OpenClaw 先做了神经系统，而不是大脑。</p><p>Hermes Agent 的核心是<code>AIAgent</code>。它通过一个 1 万多行的代码，整合了 prompt 装配、provider 选择、工具执行、重试、fallback、上下文压缩、会话持久化等所有的核心功能。CLI、Gateway、ACP、Batch Runner、API Server 这些入口最终都收敛到一起，后来才逐渐补充了 Gateway 和 messaging 平台的适配。</p><p><img src="/images/2026-04-21-Agent-hermes-arch.png" alt="Hermes Agent 架构全景" loading="lazy" decoding="async"/></p><p>Hermes 的优先级是先把 Agent Loop 做到足够强，让它支持并发工具调用、子代理委派、多 provider fallback、上下文压缩保护，然后再考虑怎么把这个大脑连上外面的世界。</p><p>Claude Code 的核心既不是 Gateway 也不是 Agent Loop，而是权限系统和上下文管理。正如《Managed Agents 架构拆解：Anthropic 给 Agent 造了一套 K8s》里提到的，Anthropic 把 Agent 的组件拆成了 session、harness、sandbox 三个独立接口，每个可以独立替换。Claude Code 的源码也是这个思路的体现。</p><p><img src="/images/2026-04-21-Agent-claude-code-arch.png" alt="Claude Code 架构全景" loading="lazy" decoding="async"/></p><p>翻它之前泄漏的源码，最庞大的模块是权限相关的代码，处理了六种权限模式、八个权限来源、分类器自动审批、hook 扩展等等。而主循环本身反而很薄，只是负责把每轮完整消息历史交给模型，工具执行完立刻流式返回，没有复杂的调度算法。</p><p>Claude Code 的设计哲学可以总结为信任模型+管好边界。模型自己决定调用什么工具、按什么顺序执行、什么时候停下来。Harness 不替模型做决策，只在两个地方卡住：你有没有权限做这件事，上下文是不是快溢出了。</p><p>三个项目对 Harness 的理解，在这一层就分道了。OpenClaw 把重心放在多入口收束和协议统一，Hermes 把重心放在 Agent Loop 的能力密度，Claude Code 把重心放在权限管控和上下文保护。</p><h2 id="记忆系统设计">记忆系统设计</h2><p>记忆是 Agent 从临时工变成长期搭档的关键一步。三个项目在这件事上的做法差异也很大。</p><p>Claude Code 的方案最简单，简单到有点反直觉。CLAUDE.md 文件前缀加载，每次会话开始时注入 system prompt。Auto Memory 让模型自己往<code>~/.claude/</code> 目录下写 Markdown 文件，MEMORY.md 作为索引（最多 200 行、25KB）。没有向量检索，没有 embedding，没有外部数据库。记忆不是主动召回的，而是作为上下文的一部分被模型看到。</p><p>上下文压缩也是反应式的：上下文窗口用到快满了才触发压缩。压缩方式是 fork 一个新的 Claude 实例来做摘要，压缩算法会保护工具调用和结果的完整性，不会把一个 tool call 和它的 result 切开。如果压缩连续失败三次，circuit breaker 会停掉，避免死循环。</p><p><img src="/images/2026-04-21-Agent-claude-code-memory.png" alt="Claude Code 怎么处理记忆" loading="lazy" decoding="async"/></p><p>这个方案的好处是简单、可预测、不依赖外部服务。代价是记忆容量有限，跨会话的信息密度完全取决于 CLAUDE.md 写得好不好。</p><p>Hermes Agent 把记忆做成了分层系统。第一层是<code>MEMORY.md</code> 和<code>USER.md</code>，类似 Claude Code 的方案，保存在<code>~/.hermes/memories/</code>，会话开始时注入 prompt。第二层是 SQLite + FTS5 全文搜索，所有历史会话都能被检索和摘要。第三层是 8 个外部 memory provider 插件，包括 Honcho、Mem0、Hindsight 等。</p><p>Honcho 的设计值得单独说一下。它不只做向量检索，而是把用户和 AI 都建模为 peer，做跨会话的辩证推理，维护用户表征和 session summary。启用后，Hermes 每轮前会预取相关记忆，每轮后同步对话，会话结束时抽取长期记忆。</p><p>Hermes 的记忆哲学是：模型的短期记忆不够用，需要系统帮它在多个时间尺度上积累和召回信息。这和 Claude Code 模型自己能搞定的思路差别挺大的。</p><p><img src="/images/2026-04-21-Agent-hermes-memory.png" alt="Hermes Agent 怎么处理记忆" loading="lazy" decoding="async"/></p><p>OpenClaw 则走了另一条路：把 Context Engine 做成可替换的运行时插件，控制如何构建模型上下文，决定包含哪些消息、如何摘要旧历史、如何跨 subagent 管理上下文。内置的是<code>legacy</code> engine，但插件可以注册完全不同的 engine。</p><p>每次模型运行时，engine 有四个生命周期点：ingest(消息进来时)、assemble(构建上下文时)、compact(压缩时)、after turn(一轮结束后)。插件 engine 甚至可以返回<code>systemPromptAddition</code>，动态注入召回指导或检索提示。</p><p>OpenClaw 的会话管理也很讲究：DM 默认共享 session，群聊按 group 隔离，rooms 按 room 隔离，cron 每次新 session。多 Agent 场景下，每个 Agent 有独立的 workspace、auth profile、session store。</p><p>OpenClaw 的记忆哲学不是记更多，而是让记忆管理本身成为一个可插拔的系统服务。长期 Agent 的记忆需求会不断变化，与其内置一套固定方案，不如把接口留好，让生态去填充。</p><p><img src="/images/2026-04-21-Agent-openclaw-memory.png" alt="OpenClaw 怎么处理记忆" loading="lazy" decoding="async"/></p><p>三种方案，背后是三种对 Agent 该记什么的不同理解。Claude Code 觉得模型够聪明，给它看到就行。Hermes 觉得光看到不够，得帮它在多个时间尺度上积累。OpenClaw 觉得记忆本身的需求会变，不如把接口留好。</p><h2 id="扩展性设计">扩展性设计</h2><p>接下来再来看看扩展性的设计，这是让 Agent 能搜索、浏览网页、生成图片、读写文件等各种外置能力的关键。</p><p>OpenClaw 把能力扩展拆成了三层：内置 Tools 是 Agent 可以随时调用的预装能力，Skills 是教 Agent 什么时候用、怎么用外部工具的扩展能力，而 Plugins 则是打包了工具、技能、消息通道、模型等各种扩展的能力包。</p><p>这个三层模型把三个容易混淆的东西拆开了：工具是默认能做什么，技能是什么时候/怎么样去调用外部工具，插件是怎么打包、发现、分发这些能力。ClawHub 上架了 58000 多个社区 Skill，一条命令安装，这对于带火 OpenClaw 功不可没。</p><p><img src="/images/2026-04-21-Agent-openclaw-capability.png" alt="OpenClaw 怎么扩展能力" loading="lazy" decoding="async"/></p><p>Hermes Agent 的工具系统用了 registry 自注册模式。<code>tools/registry.py</code> 是中心注册表，每个工具文件在模块级调用<code>registry.register()</code> 声明 schema、handler、toolset 归属和可用性检查。<code>model_tools.py</code> 是 registry 之上的薄编排层，负责导出工具定义、处理函数调用、维护工具到 toolset 的映射。</p><p>有个很细的设计：<code>model_tools.py</code> 会根据当前真正可用的工具重建<code>execute_code</code> 的 schema。比如 web API key 没配置，模型就不会在 sandbox 里看到<code>web_search</code> 这个工具。这能减少模型“以为自己能做但其实做不了”的幻觉式调用。</p><p><img src="/images/2026-04-21-Agent-hermes-capability.png" alt="Hermes Agent 怎么扩展能力" loading="lazy" decoding="async"/></p><p>Hermes 的技能系统用了 progressive disclosure：Level 0 只加载 name 和 description，Level 1 加载完整技能内容，Level 2 加载技能引用的附件。模型先扫描技能列表，匹配到了再深入加载。更关键的是，Agent 可以通过<code>skill_manage</code> 自己创建、更新、删除技能。解决了一个非平凡任务后，它可以把方法保存为技能文件，下次遇到类似问题直接复用。</p><p>这就是 Hermes 说的“程序性记忆”。普通 Agent 完成任务后只留下结果，Hermes 完成任务后还试图留下方法。当你积累 20 个以上自创技能后，同领域任务完成速度能提升 40% 。</p><p>Claude Code 的扩展体系跟前两者的思路都不一样，它不是围绕工具注册或技能发现来组织的，而是围绕权限边界层层展开的。</p><p>最底层是 28 个内置工具，覆盖文件读写、搜索、Shell 执行、Web 访问、子代理调度等基础能力。这些工具分两类：Read、Glob、Grep 这类只读工具不需要权限，Bash、Edit、Write 这类有副作用的工具每次执行都要过权限检查。权限不在工具注册时声明，而是在执行时由 harness 拦截，模型不需要考虑“我能不能做这件事”，该拦的时候自然会拦。</p><p>往上一层是 MCP 协议。Claude Code 通过 MCP 接入外部工具服务器，支持 stdio、HTTP、SSE 三种传输方式。MCP 工具默认是延迟加载的：会话开始时只把工具名称放进上下文，模型需要用的时候通过<code>ToolSearch</code> 工具按需拉取完整 schema。这个设计跟 Hermes 的 progressive disclosure 异曲同工，只是实现路径不同，一个在技能层做分级加载，一个在工具层做延迟发现。</p><p>再往上是 Hooks、Skills 和 Plugins 三层扩展。Hooks 提供了 25 个生命周期事件，可以挂 shell 命令、HTTP 请求、甚至 LLM 评估。Skills 遵循开放的 Agent Skills 标准，用 Markdown + YAML frontmatter 定义可复用的工作流，，持参数替换和条件触发。Plugins 则是把 Skills、Hooks、MCP 配置、子代理定义打包成一个可分发的单元。</p><p>子代理是 Claude Code 处理复杂任务的核心机制。每个子代理运行在独立的上下文窗口里，有自己的系统提示和会话历史。内置了 Explore（快速搜索，用 Haiku 模型）、Plan（规划研究）、general-purpose（全功能）等预设类型，也支持通过<code>.claude/agents/</code> 目录自定义。自定义子代理可以精细控制工具白名单、权限规则、模型选择，甚至预加载特定 Skills。</p><p><img src="/images/2026-04-21-Agent-claude-code-capability.png" alt="Claude Code 怎么扩展能力" loading="lazy" decoding="async"/></p><p>能力管理的复杂性往哪放？OpenClaw 交给社区生态，Hermes 交给 Agent 自身的积累，Claude Code 交给分层的权限边界。</p><h2 id="怎么面对模型进步">怎么面对模型进步</h2><p>这个维度最值得琢磨。</p><p>Anthropic 有一个很有意思的观察：harness 编码的是对模型能力边界的假设，但模型在进步，假设会过期。Sonnet 4.5 的时候模型有上下文焦虑，随着上下文窗口接近极限会提前收工，harness 里加了重置机制来应对。结果换到 Opus 4.5，这个行为自己消失了，重置机制变成了死代码。</p><p>Claude Code 对这一点的应对是大量的功能开关，从它泄露的源码能看到大量 HISTORY_SNIP、REACTIVE_COMPACT、TRANSCRIPT_CLASSIFIER 等等这样的开关。比如，到了 Opus 4.6，之前在 harness 里加的 Sprint 机制（把长任务拆成小块、每块结束后评估）就被整个拿掉了，因为模型已经可以连续写代码不跑偏。Evaluator 也从每个 Sprint 后评分改成了全部开发完再做一轮 QA。</p><p>Anthropic 认为 harness 应该为减法而设计。每个组件都应该能被安全移除，而不是越堆越厚。权限分类器也是同一思路，模型能力到了之后，很多需要人类确认的操作可以自动放行（所以后来新增了 Auto 权限模式）。</p><p><img src="/images/2026-04-21-Agent-claude-code-model-progress.png" alt="Claude Code 怎么面对模型进步" loading="lazy" decoding="async"/></p><p>Hermes Agent 的思路不太一样。它认为有些东西不会因为模型变强而过期：五层记忆系统、技能文件沉淀、跨会话搜索、用户建模。模型再强，也需要知道“上次这个用户让我做过什么”和“这类任务我之前是怎么解决的”。</p><p>Hermes 甚至有一个单独的<code>hermes-agent-self-evolution</code> 仓库，用 DSPy 和 GEPA 来做自动化的技能优化。具体做法是：跑一组评估任务，比较优化前后的技能文件在完成效率和准确率上的差异，自动选择更好的版本。目前实现了 Phase 1 的技能文件优化，Phase 2 计划覆盖工具描述和系统提示词。说实话，这个想法挺有意思的，相当于给 Agent 加了一个慢速但持续的自然选择过程。虽然模型会趋同，但谁能把每次任务变成下一次的能力，谁就有了复利。</p><p><img src="/images/2026-04-21-Agent-hermes-model-progress.png" alt="Hermes Agent 怎么面对模型进步" loading="lazy" decoding="async"/></p><p>OpenClaw 的基础设施层几乎不受模型进步的影响。Gateway 不会因为 Claude 变强就不需要了。多入口路由不会过期，设备节点不会过期，会话隔离不会过期，权限分层不会过期。</p><p>模型会越来越强，但连接现实世界的管道不会自动出现。你还是需要一个东西来管理“谁能在什么时候通过什么入口让 Agent 做什么事”，模型再强也替代不了这一层。</p><p><img src="/images/2026-04-21-Agent-openclaw-model-progress.png" alt="OpenClaw 怎么面对模型进步" loading="lazy" decoding="async"/></p><p>三种方向，对应三种对“模型进步会淘汰什么”的判断。OpenClaw 认为基础设施不会过期，所以建管道。Hermes 认为经验积累不会过期，所以做加法。Claude Code 认为大部分脚手架会过期，所以做减法。</p><h2 id="写在最后">写在最后</h2><p>有意思的是，三条路正在往一个方向收敛。Claude Code 加了 auto memory 和 channels，Hermes 加了 Gateway 和多平台适配，OpenClaw 在做 Context Engine 可插拔化。起点不同，但目的地越来越像：一个有记忆、有技能、有入口、有权限、有持久状态的个人 AI 系统。</p><hr><p>欢迎长按下面的二维码关注<strong>Feisky</strong> 公众号，了解更多云原生和 AI 知识。</p><p><img src="/images/mp.png" alt="Feisky 公众号二维码" loading="lazy" decoding="async"/></p>
]]></content:encoded><dc:extent>11 min read</dc:extent></item><item><title>多 Agent 协调的五种模式：从最简单的开始，按需演进</title><link>https://feisky.xyz/posts/2026-04-14-%E5%A4%9Aagent%E5%8D%8F%E8%B0%83%E7%9A%84%E4%BA%94%E7%A7%8D%E6%A8%A1%E5%BC%8F%E4%BB%8E%E6%9C%80%E7%AE%80%E5%8D%95%E7%9A%84%E5%BC%80%E5%A7%8B%E6%8C%89%E9%9C%80%E6%BC%94%E8%BF%9B/</link><pubDate>Tue, 14 Apr 2026 10:00:00 +0800</pubDate><dc:creator>Pengfei Ni</dc:creator><category>AI Agent</category><category>Anthropic</category><category>多Agent架构</category><category>协调模式</category><category>Claude</category><guid>https://feisky.xyz/posts/2026-04-14-%E5%A4%9Aagent%E5%8D%8F%E8%B0%83%E7%9A%84%E4%BA%94%E7%A7%8D%E6%A8%A1%E5%BC%8F%E4%BB%8E%E6%9C%80%E7%AE%80%E5%8D%95%E7%9A%84%E5%BC%80%E5%A7%8B%E6%8C%89%E9%9C%80%E6%BC%94%E8%BF%9B/</guid><description>&lt;blockquote&gt;
&lt;p&gt;题记：本文编译自 Anthropic 博客《&lt;a href="https://claude.com/blog/multi-agent-coordination-patterns"&gt;Multi-agent coordination patterns: Five approaches and when to use them&lt;/a&gt;》，由 Cara Phillips 撰写。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;用一个 Agent 搞不定复杂任务？上多 Agent 吧。这个判断现在大家基本都认了。但上多 Agent 之后紧跟着一个更具体的问题：这些 Agent 之间怎么配合？&lt;/p&gt;</description><content:encoded>&lt;![CDATA[<blockquote><p>题记：本文编译自 Anthropic 博客《<a href="https://claude.com/blog/multi-agent-coordination-patterns">Multi-agent coordination patterns: Five approaches and when to use them</a>》，由 Cara Phillips 撰写。</p></blockquote><p>用一个 Agent 搞不定复杂任务？上多 Agent 吧。这个判断现在大家基本都认了。但上多 Agent 之后紧跟着一个更具体的问题：这些 Agent 之间怎么配合？</p><p>我之前写过 Anthropic 的 Harness 设计和 Managed Agents 架构，都涉及到多 Agent 的分工协作。但那两篇偏重怎么搭基础设施，没有系统聊过协调模式本身该怎么选。网上能找到的多 Agent 教程大多也停留在“拆任务 + 合结果”这个层面，对模式之间的取舍和演进路径讲得不多。Anthropic 刚发的这篇博客正好补了这个缺口，把多 Agent 协调归纳成五种模式，从最简单到最复杂，还给出了什么时候该从一种演进到另一种的判断标准。</p><p>读完最大的感受是：大部分团队的问题不是不知道多 Agent 的好处，而是上来就挑了一个听起来最酷的模式，结果被协调开销拖死了。Anthropic 的建议是，从最简单的能跑通的模式开始，看它哪里撑不住了，再往上演进。</p><h2 id="模式一生成-验证">模式一：生成-验证</h2><p>这是最简单的多 Agent 模式，也是部署最广的。</p><p><img src="/images/2026-04-14-Agent-pattern1-generator-verifier.jpg" alt="Generator-Verifier 模式" loading="lazy" decoding="async"/></p><p>逻辑很简单。一个 Agent 负责生成输出，另一个负责评估。评估通过就结束，不通过就把反馈打回给生成方，重新来一轮。循环下去直到通过或者达到最大迭代次数。</p><p>最典型的应用是代码生成：一个 Agent 写代码，另一个写测试、跑测试。客服场景也适用，生成方起草邮件回复，验证方检查是否准确引用了产品文档、是否回应了用户提到的每个问题。</p><p>这个模式看着简单，但踩坑的地方也很集中。</p><p>最常见的失败是验证标准太模糊。如果你只告诉验证方检查输出是否足够好，它大概率会糊弄人，放行所有东西。验证方的价值完全取决于你能不能把“好”拆成具体的、可检查的标准。</p><p>这一点在我之前写 Harness 设计那篇里也提过。Anthropic 的工程师 Prithvi 花了很多精力调教 Evaluator，反复看日志、找判断偏差、改 Prompt，来回迭代了好几轮才让它的评分标准达到合理水平。</p><p>另一个问题是迭代循环可能卡死。生成方解决不了验证方提的问题，两边来回震荡不收敛。所以必须设最大迭代次数，加一个兜底策略，比如升级给人处理，或者返回当前最好的版本并标注问题。</p><h2 id="模式二编排-子-agent">模式二：编排-子 Agent</h2><p>这是层级式的分工。一个 Agent 当 Team Lead，负责规划任务、分配工作、汇总结果。子 Agent 接到具体任务后执行完就汇报。</p><p><img src="/images/2026-04-14-Agent-pattern2-orchestrator-subagent.jpg" alt="Orchestrator-Subagent 模式" loading="lazy" decoding="async"/></p><p>Claude Code 用的就是这个模式。主 Agent 自己写代码、编辑文件、跑命令，需要搜索大型代码库或者调查独立问题时，就在后台派 subagent 去做，自己继续手头的活。每个 subagent 在自己的上下文窗口里工作，完成后把精炼过的结果返回给主 Agent。</p><p>这个模式适合任务拆分清晰、子任务之间依赖少的场景。比如自动化代码审查：一个 PR 进来，需要查安全漏洞、检查测试覆盖率、评估代码风格、验证架构一致性。每个检查维度独立、上下文不同、输出格式明确。编排 Agent 把每个检查派给专门的子 Agent，收集结果后合成一份统一的 Review。</p><p>问题出在信息瓶颈上。当子 Agent 发现了对其他子 Agent 有用的信息时，这条信息必须经过编排 Agent 中转。安全子 Agent 发现了一个认证漏洞，这个发现影响架构子 Agent 的分析。编排 Agent 需要识别这种依赖关系并正确路由信息。经过几轮中转之后，关键细节经常被丢失或者在摘要中被省略掉。</p><p>我在用 Claude Code 的 subagent 时也有类似体感。subagent 搜完代码库回来的结果有时候会把关键上下文压缩掉，主 Agent 拿到的是一个干净但不够完整的摘要。对于简单查询这不是问题，但对于需要子 Agent 之间共享发现的复杂任务，编排模式就开始吃力了。</p><h2 id="模式三agent-团队">模式三：Agent 团队</h2><p>编排模式里的子 Agent 是用完即弃的。接到任务，干完活，交结果，走人。但如果任务需要 worker 在多轮中积累经验呢？</p><p>Agent 团队模式的区别就在这里：worker 是持久的。</p><p><img src="/images/2026-04-14-Agent-pattern3-agent-teams.jpg" alt="Agent Teams 模式" loading="lazy" decoding="async"/></p><p>一个协调者启动多个 worker Agent 作为独立进程。领任务，干活，交结果。不重置，不遗忘。每个 worker 在多轮迭代中积累对自己负责领域的熟悉度。</p><p>最直观的例子是大规模代码迁移。每个 worker 分管一个服务，在反复处理这个服务的依赖、测试、部署配置的过程中，逐渐摸清它的脾气。一次性 subagent 每次接手都要重新理解服务的配置约定和依赖关系，持久 worker 第一次弄明白之后后续迭代直接复用，省掉重复的上下文加载。</p><p>但独立性是硬前提。</p><p>团队模式里的 worker 没有中间人帮忙传话。一个 worker 的改动影响了另一个，谁都不知道，产出可能冲突。多个 worker 操作同一个代码库时尤其明显，常见的应对方式是文件级别的分区或者合并前跑冲突检测，但这增加了协调者的复杂度。完成时间的参差也是个问题，一个 worker 两分钟搞定，另一个要二十分钟，协调者得有耐心等。</p><h2 id="模式四消息总线">模式四：消息总线</h2><p>前面三种模式都有明确的协调者在指挥交通。但如果 Agent 数量继续增加、交互模式变得不可预测呢？</p><p><img src="/images/2026-04-14-Agent-pattern4-message-bus.jpg" alt="Message Bus 模式" loading="lazy" decoding="async"/></p><p>消息总线引入了一个共享通信层。核心操作就两个：发布和订阅。Agent 订阅自己关心的 topic，路由器负责分发。新 Agent 上线不需要改已有的连接，订阅相关 topic 就能开始接收工作。搞过微服务事件驱动架构的应该不陌生，本质上就是 Kafka 那套思路，只不过参与者从服务变成了 Agent。</p><p>Anthropic 举的例子是安全运维自动化。告警从多个来源进来，分诊 Agent 分类后路由给对应的调查 Agent，调查结果再流向响应协调 Agent。事件一个阶段接一个阶段地流下去，新出了什么威胁类型就加个新 Agent，各个 Agent 还能独立开发部署。</p><p>代价是可追溯性变差了。一个告警触发五个 Agent 之间的事件级联，要搞清楚到底发生了什么，调试难度比编排模式那种顺序决策链高了不少。路由器分错类或者丢了事件更麻烦，系统会静默失败，什么都不处理但也不崩溃。</p><h2 id="模式五共享状态">模式五：共享状态</h2><p>前四种模式里都有一个中心角色在管理信息流。共享状态模式把这个中间人去掉了。</p><p><img src="/images/2026-04-14-Agent-pattern5-shared-state.jpg" alt="Shared State 模式" loading="lazy" decoding="async"/></p><p>没有中央协调者。Agent 自主运行，读写一个共享的数据库、文件系统或文档。工作一般从往存储里丢一个问题或数据集开始。停下来的条件有几种：时间到了、结果收敛了，或者有个专门的 Agent 判断存储里的东西已经够用了。</p><p>研究综合场景是这个模式的主场。多个 Agent 分头调查一个复杂问题的不同方面，学术 Agent 发现了一个关键研究者，这条信息对行业 Agent 调查这个研究者的公司立刻就有用。不用等协调者来路由，发现直接写进存储，其他 Agent 马上就能看到。附带好处是没有单点故障，任何一个 Agent 停了，其他 Agent 继续读写。</p><p>代价也很明显。Agent 可能重复工作或者走互相矛盾的方向。更棘手的是反应式循环：Agent A 写了一个发现，Agent B 读到后写了跟进，Agent A 看到跟进后又回应。系统持续烧 token 但不收敛。重复工作和并发写入有成熟的工程方案，加锁、版本控制、分区都行。但反应式循环是行为层面的问题，必须认真设计终止条件：时间预算、收敛阈值，或者专门的 Agent 来判断何时该停。</p><p>这个模式让我想到分布式系统里的最终一致性。没有强协调者的好处是吞吐量高、没有瓶颈，但你需要在应用层面处理冲突和收敛问题。Agent 领域也是同样的取舍。</p><h2 id="怎么选怎么演进">怎么选，怎么演进</h2><p>五种模式摆在面前，选哪个？Anthropic 给了几组对比的决策逻辑，我觉得最实用的是前两组。</p><h4 id="编排-子-agent-vs-agent-团队">编排-子 Agent vs Agent 团队</h4><p><img src="/images/2026-04-14-Agent-vs-orchestrator-teams.jpg" alt="编排-子Agent vs Agent 团队" loading="lazy" decoding="async"/></p><p>两者都有协调者分派工作，区别在于 worker 需要维持上下文多久。子任务短小、输出明确的，用编排模式。子任务需要多步骤持续工作、会从积累的上下文中受益的，用团队模式。判断标准是：当子 Agent 需要跨调用保留状态时，团队模式更合适。</p><p>我自己的经验也验证了这一点。Claude Code 日常的代码搜索、文件查阅用编排模式完全够用，subagent 干完就走。但之前写复杂 feature 的时候，需要多个 Agent 持续处理不同模块的开发和测试，编排模式的一次性 subagent 就不够用了，每次都要重新理解模块上下文。</p><h4 id="编排-子-agent-vs-消息总线">编排-子 Agent vs 消息总线</h4><p><img src="/images/2026-04-14-Agent-vs-orchestrator-messagebus.jpg" alt="编排-子Agent vs 消息总线" loading="lazy" decoding="async"/></p><p>两者都能处理多步骤工作流，区别在于工作流结构是否可预测。步骤顺序事先已知的，用编排模式。工作流由事件驱动、可能随发现变化的，用消息总线。有个经验法则：当编排 Agent 里的条件分支越来越多、需要处理越来越多的特殊情况时，就该考虑换消息总线了。</p><h4 id="agent-团队-vs-共享状态">Agent 团队 vs 共享状态</h4><p><img src="/images/2026-04-14-Agent-vs-teams-sharedstate.jpg" alt="Agent 团队 vs 共享状态" loading="lazy" decoding="async"/></p><p>各管各的互不交叉，用团队模式。发现需要实时流通，用共享状态。一旦 worker 之间需要互相沟通而不只是最后汇总结果，共享状态更自然。</p><h4 id="消息总线-vs-共享状态">消息总线 vs 共享状态</h4><p><img src="/images/2026-04-14-Agent-vs-messagebus-sharedstate.jpg" alt="消息总线 vs 共享状态" loading="lazy" decoding="async"/></p><p>事件从一个阶段触发到下一个阶段然后完成的，用消息总线。Agent 在持续积累的知识基础上反复迭代的，用共享状态。还有一个值得留意的信号：如果消息总线里的 Agent 发布事件是为了分享发现而不是触发动作，那你可能需要的是共享状态。</p><h2 id="写在最后">写在最后</h2><p>实际生产系统往往会混用多种模式。常见的组合是外层用编排-子 Agent 管整体工作流，内层某个协作密集的子任务用共享状态。或者外层用消息总线做事件路由，每种事件类型由一个 Agent 团队来处理。这五种模式是积木，不是互斥的选项。</p><p>Anthropic 的建议是从编排-子 Agent 开始。它能覆盖最广的问题范围，协调开销也最低。等它在特定场景下撑不住了，再根据具体瓶颈演进到其他模式。</p><p>Claude Code 就是编排-子 Agent 模式的典型实现，对大多数日常任务来说完全够用。只有当任务复杂到需要多个 Agent 持续协作、共享中间发现的时候，才值得引入更复杂的模式。</p><p>有意思的是，不同框架对协调模式的抽象思路差异很大。Anthropic 这套分类偏描述性，告诉你有哪些模式、怎么选。LangGraph 走的是 graph-based 的路子，用状态图来定义 Agent 之间的流转逻辑，更偏编程范式。CrewAI 则是角色分工优先，先定义 Agent 的角色和目标，协调模式隐含在角色关系里。三种抽象各有适用场景，但底层要解决的问题是一样的：谁跟谁通信、信息怎么流、什么时候该停。</p><hr><p>相关资源：</p><ul><li>原文链接：<a href="https://claude.com/blog/multi-agent-coordination-patterns">https://claude.com/blog/multi-agent-coordination-patterns</a></li><li>构建多 Agent 系统：<a href="https://claude.com/blog/building-multi-agent-systems-when-and-how-to-use-them">https://claude.com/blog/building-multi-agent-systems-when-and-how-to-use-them</a></li><li>Harness 设计：<a href="https://www.anthropic.com/engineering/harness-design-long-running-apps">https://www.anthropic.com/engineering/harness-design-long-running-apps</a></li><li>Managed Agents：<a href="https://www.anthropic.com/engineering/managed-agents">https://www.anthropic.com/engineering/managed-agents</a></li><li>构建有效 Agent：<a href="https://www.anthropic.com/engineering/building-effective-agents">https://www.anthropic.com/engineering/building-effective-agents</a></li></ul><hr><p>欢迎长按下面的二维码关注<strong>Feisky</strong> 公众号，了解更多云原生和 AI 知识。</p><p><img src="/images/mp.png" alt="Feisky 公众号二维码" loading="lazy" decoding="async"/></p>
]]></content:encoded><dc:extent>9 min read</dc:extent></item><item><title>Managed Agents 架构拆解：Anthropic 给 Agent 造了一套 K8s</title><link>https://feisky.xyz/posts/2026-04-09-anthropic%E7%BB%99ai-agent%E9%80%A0%E4%BA%86%E4%B8%80%E5%A5%97kubernetes/</link><pubDate>Thu, 09 Apr 2026 10:00:00 +0800</pubDate><dc:creator>Pengfei Ni</dc:creator><category>AI Agent</category><category>Anthropic</category><category>Managed Agents</category><category>架构设计</category><category>Kubernetes</category><guid>https://feisky.xyz/posts/2026-04-09-anthropic%E7%BB%99ai-agent%E9%80%A0%E4%BA%86%E4%B8%80%E5%A5%97kubernetes/</guid><description>&lt;blockquote&gt;
&lt;p&gt;题记：本文编译自 Anthropic 工程博客《&lt;a href="https://www.anthropic.com/engineering/managed-agents"&gt;Scaling Managed Agents: Decoupling the brain from the hands&lt;/a&gt;》，由 Lance Martin、Gabe Cemaj 和 Michael Cohen 撰写。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Kubernetes 早就是 AI 基础设施的事实标准了。不管是大模型训练还是推理服务，最后都跑在 K8s 上。AI Agent 也不例外，Harness、sandbox、工具调用这些组件，基本都可以容器化部署。&lt;/p&gt;</description><content:encoded>&lt;![CDATA[<blockquote><p>题记：本文编译自 Anthropic 工程博客《<a href="https://www.anthropic.com/engineering/managed-agents">Scaling Managed Agents: Decoupling the brain from the hands</a>》，由 Lance Martin、Gabe Cemaj 和 Michael Cohen 撰写。</p></blockquote><p>Kubernetes 早就是 AI 基础设施的事实标准了。不管是大模型训练还是推理服务，最后都跑在 K8s 上。AI Agent 也不例外，Harness、sandbox、工具调用这些组件，基本都可以容器化部署。</p><p>但跑过长时间 Agent 任务的人应该都碰过这种事：Agent 跑着跑着容器挂了，session 没了，只能从头来。session 卡死了想调试，Harness、sandbox、session 全在一个容器里，根本分不清问题出在哪。好不容易跑起来了，上下文窗口又满了，压缩还是丢弃，怎么选都可能踩坑。</p><p>做过 K8s 的人看这些问题应该很眼熟。十年前容器编排领域碰到的也是同一类：组件耦合、状态丢失、扩展困难。K8s 的解法是把硬件虚拟化成抽象层，Pod、Service、PersistentVolume 这些概念比底层硬件活得久得多。你换磁盘、换机器，上层应用完全不用管。</p><p>Anthropic 昨天开放公测的 Managed Agents，本质上在做同样的事，只不过虚拟化的对象从硬件换成了 Agent 的组件。</p><p>Anthropic 的工程博客一直在聊怎么给 Agent 搭 Harness：从<a href="https://www.anthropic.com/engineering/building-effective-agents">构建有效 Agent</a> 到<a href="https://www.anthropic.com/engineering/harness-design-long-running-apps">长时间任务的 Harness 设计</a>，再到<a href="https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents">上下文工程</a>。这些文章贯穿着一条线索：Harness 编码的是对 Claude 当前能力边界的假设，但模型在进步，假设会过期。</p><p>举个例子。之前在 Sonnet 4.5 上，他们发现模型会随着上下文窗口接近极限而提前收工（也称为上下文焦虑）。于是 Harness 里加了上下文重置机制。结果换到 Opus 4.5 上一跑，行为消失了。重置机制变成了死代码。</p><p>Harness 免不了一直改下去。所以 Anthropic 造了 Managed Agents：用一组尽可能通用的接口来运行长时间 Agent，让这些接口比任何一套具体的 Harness 实现活得更久。</p><p><img src="/images/2026-04-09-AnthropicAI-AgentKubernetes-image.jpg" alt="Managed Agents 架构概览" loading="lazy" decoding="async"/></p><p>它把 Agent 的核心组件虚拟化成了三个接口：session（发生了什么的完整事件日志）、harness（调用 Claude 和路由工具调用的循环）、sandbox（Claude 跑代码和编辑文件的执行环境）。每个组件可以独立替换，互不干扰。跟 K8s 对 Pod、Volume、Service 的抽象思路一致。</p><h2 id="别养宠物">别养宠物</h2><p>做过 K8s 的你对 Pets vs Cattle 这个比喻肯定不陌生。Pet 是你精心照料的单台服务器，挂了就得抢救；Cattle 是随时可以杀掉重建的无状态实例。云原生的核心理念之一就是把所有东西变成 Cattle。</p><p>Managed Agents 一开始没做到这一点。</p><p>最初的设计是把所有 Agent 组件塞进一个容器。好处是文件操作就是本地 syscall，不需要设计服务边界。但这就养了一只宠物。容器挂了，session 就没了。容器卡住了，得想办法把它救活。</p><p>救活容器意味着调试卡死的 session。唯一的观察窗口是 WebSocket 事件流，但它分不清故障发生在哪个环节。Harness 的 bug、事件流的丢包、容器下线，在外面看起来症状完全一样。要搞清楚怎么回事，工程师得开 shell 进到容器里，但容器里还有用户数据，这条路基本走不通。</p><p>还有一个更深的问题。Harness 默认 Claude 的工作内容就在同一个容器里。当客户说“我想让 Claude 连我自己的 VPC”时，要么做网络对等互联，要么让客户在自己的环境里跑 Anthropic 的 Harness。一个 Harness 里硬编码的假设，变成了基础设施层面的约束。</p><p>这跟早年单体应用跑在物理机上的困境太像了。</p><h2 id="把大脑从手上拆下来">把大脑从手上拆下来</h2><p>解法是把大脑（Claude 和 Harness）从手（sandbox 和工具）和记忆（session 日志）上拆开。每个组件变成一个接口，对其他组件的假设尽可能少，独立故障、独立替换。</p><p>K8s 里 Pod 是无状态的计算单元，PersistentVolume 是持久化存储，两者通过声明式绑定关联但互不依赖。Pod 挂了重建一个，数据还在。Managed Agents 的拆法思路一样。</p><p>Harness 不再住在容器里。它像调用其他工具一样调用容器：<code>execute(name, input) → string</code>。容器变成了 Cattle，挂了就挂了，Harness 把失败当作工具调用错误传回给 Claude，Claude 决定要不要重试。重试的话，<code>provision({resources})</code> 拉一个新的就行。</p><p>不用再抢救挂掉的容器了。</p><p>Harness 自己也是 Cattle。session 日志在外部，Harness 里没有任何需要在崩溃中存活的状态。挂了？<code>wake(sessionId)</code> 启动一个新的，<code>getSession(id)</code> 拿回事件日志，从最后一个事件继续。运行过程中用<code>emitEvent(id, event)</code> 往 session 写入持久化记录。</p><p><img src="/images/2026-04-09-AnthropicAI-AgentKubernetes-image2222.jpg" alt="脑手分离架构" loading="lazy" decoding="async"/></p><p>这里面还有一个安全维度值得单独说。</p><p>之前所有东西耦合在一个容器里的时候，Claude 生成的不可信代码和凭证跑在同一个环境中。一次成功的 prompt injection 只需要说服 Claude 读一下自己的环境变量。拿到 token 之后，攻击者可以开新 session 干什么都行。</p><p>收窄 token 权限？当然可以。但这本身又是一个假设：Claude 拿着受限 token 干不了什么。模型在变强，这个假设随时可能失效。</p><p>结构性的解法是让 token 在 sandbox 里根本不可达。Git 仓库的做法是在 sandbox 初始化时用 token 克隆仓库并写入本地 git remote，之后<code>push</code> 和<code>pull</code> 都走本地配置，Agent 从头到尾碰不到 token。自定义工具走 MCP，OAuth token 存在安全保险箱里，Claude 通过专用代理调用 MCP 工具，代理根据 session 拿到对应的凭证再调外部服务。整个链路里，Harness 不接触任何凭证。</p><p>Anthropic 这个思路挺值得参考的：不是所有安全问题都要靠权限收窄来解决，有时候换个架构就能把问题消除掉。</p><h2 id="session-不是上下文窗口">Session 不是上下文窗口</h2><p>脑手分离解决了组件耦合的问题，但 Agent 跑久了还有另一个挑战：上下文管理。</p><p>长时间任务经常超出 Claude 的上下文窗口。常见的应对方式都涉及不可逆的决策：compaction 把上下文压缩成摘要，memory 工具把信息写到文件，context trimming 选择性地删掉旧的工具结果或 thinking block。这些方法都能用，但有个共同的软肋，就是你很难预判未来哪些 token 会被用到。删错了就回不来了。</p><p>之前有<a href="https://arxiv.org/pdf/2512.24601">研究</a>探索过一个思路：把上下文存成一个对象放在 REPL 里，模型通过写代码来过滤和切片，而不是被动接受压缩后的结果。</p><p>Managed Agents 的 session 做了类似的事，但把上下文存在了 sandbox 外面。session 日志是持久化的，通过<code>getEvents()</code> 接口让大脑按位置切片查询事件流。可以从上次读到的地方继续往下读，也可以倒回某个时刻前几个事件看看当时的背景，或者在执行某个操作前重新读一遍相关上下文。</p><p><img src="/images/2026-04-09-AnthropicAI-AgentKubernetes-session-context.jpg" alt="Session 作为外部上下文对象" loading="lazy" decoding="async"/></p><p>拿到的事件在传给 Claude 之前还可以在 Harness 里做各种变换：重组结构以提高 prompt cache 命中率，或者做其他上下文工程。这里的设计考量是把“可恢复的上下文存储”和“任意的上下文管理”分成两个关注点。前者放在 session 里保证持久和可查询，后者放在 Harness 里，怎么折腾都行。因为未来的模型需要什么样的上下文工程，现在谁也说不准，但 session 的持久性是确定需要的。</p><p>用 K8s 类比的话，session 就是 PersistentVolume：数据在那里，不管哪个 Pod 来挂载都能用。上下文工程是 Pod 里的应用逻辑，随着业务需求随时可以换。</p><h2 id="多脑多手">多脑多手</h2><p>组件拆开之后，扩展变得自然了。</p><p>先说多脑。之前大脑和手都在一个容器里，每启动一个 session 就要起一个容器。不管这次 Claude 用不用 sandbox，容器都得先跑起来：克隆仓库、启动进程、拉取待处理事件。这些全卡在 TTFT（Time to First Token）上，用户最敏感的延迟指标。</p><p>拆开之后，容器只在需要时才通过工具调用启动。不需要 sandbox 的 session 直接跳过容器初始化，推理在编排层拉到 session 事件后就开始。</p><p>p50 TTFT 下降约 60% ，p95 下降超过 90% 。</p><p>这个优化思路在 K8s 社区一点都不陌生。这些年围绕 Pod 冷启动的优化从没停过：镜像预拉取、lazy snapshot、WASM 轻量运行时。核心逻辑都是一样的，不需要的东西别提前准备。</p><p>再说多手。之前一个大脑只能操作一个容器，容器挂了就全完了。现在每只手就是一个工具调用：<code>execute(name, input) → string</code>，名字和输入进去，字符串出来。这个接口能接任何自定义工具、任何 MCP 服务器、Anthropic 自己的内置工具。Harness 不知道也不关心 sandbox 到底是一个容器、一部手机，还是一个宝可梦模拟器。</p><p><img src="/images/2026-04-09-AnthropicAI-AgentKubernetes-image23433.jpg" alt="多手架构" loading="lazy" decoding="async"/></p><p>因为手不绑定任何特定的脑，多个 Agent 之间可以互相传递工具。产品公告里提到 Managed Agents 已经在研究预览中支持多 Agent 协调，一个 Agent 可以生成和指挥其他 Agent。多脑多手的架构落地之后，这种能力是水到渠成的。</p><p>Anthropic 内测的数据也挺有意思。在结构化文件生成这类任务上，比如根据 API schema 自动生成 SDK 代码和文档，相比标准的 prompting 循环，任务成功率最高提升了 10 个百分点，难题上增益最大。加上 Console 里内置的执行追踪和分析工具，每个工具调用、每次决策、每个失败点都能看到，对于把 Agent 推上生产环境的团队来说实用性不错。</p><h2 id="写在最后">写在最后</h2><p>读完这篇工程博客，我脑子里一直跑着一个想法：这就是 Agent 领域的 Kubernetes。</p><p>K8s 当年解决的也是同一类问题。应用越来越复杂，单机跑不动了，需要一个编排层来管理容器的生命周期、网络和存储。K8s 没有规定你的应用该怎么写，它定义了一组接口，让任何应用都能跑在上面。十年过去了，底层的容器运行时从 Docker 换到了 containerd，节点从 CPU 服务器换到了 GPU 集群，但 Pod 的定义还是那个 Pod。</p><p>Managed Agents 在做同样的事。它不规定 Harness 怎么写，而是把 Agent 的核心组件虚拟化成接口。Claude Code 是一个很好的 Harness，任务专用的 Agent Harness 在特定领域可能表现更好，Managed Agents 都能承载。接口固定，实现自由替换。</p><p>不过有一个差异。K8s 是开源的，CNCF 社区驱动，任何云厂商都能跑。Managed Agents 是 Anthropic 的托管服务，目前只服务 Claude 生态，或许这也是为什么他们会不停封禁诸如 OpenClaw 这样的第三方平台。当然，这篇博客公开了设计理念和接口抽象的思路，即使不用 Managed Agents，这套脑手分离的架构模式也能自己实现。</p><p>AI Agent 的基础设施层还在快速成型。Anthropic 在做 Managed Agents，OpenAI 有 Codex 的云端 Agent，Google 有 Vertex AI Agent Engine，最终谁成为 Agent 编排的事实标准还不好说。但有一点是确定的：Agent 的组件解耦、状态持久化、安全隔离这些需求不会消失，只会随着 Agent 能力的增长变得更重要。</p><hr><p>相关资源：</p><ul><li>原文链接：<a href="https://www.anthropic.com/engineering/managed-agents">https://www.anthropic.com/engineering/managed-agents</a></li><li>产品公告：<a href="https://claude.com/blog/claude-managed-agents">https://claude.com/blog/claude-managed-agents</a></li><li>Managed Agents 文档：<a href="https://platform.claude.com/docs/en/managed-agents/overview">https://platform.claude.com/docs/en/managed-agents/overview</a></li><li>构建有效 Agent：<a href="https://www.anthropic.com/engineering/building-effective-agents">https://www.anthropic.com/engineering/building-effective-agents</a></li><li>长时间 Agent Harness 设计：<a href="https://www.anthropic.com/engineering/harness-design-long-running-apps">https://www.anthropic.com/engineering/harness-design-long-running-apps</a></li><li>上下文工程：<a href="https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents">https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents</a></li></ul><hr><p>欢迎长按下面的二维码关注<strong>Feisky</strong> 公众号，了解更多云原生和 AI 知识。</p><p><img src="/images/mp.png" alt="Feisky 公众号二维码" loading="lazy" decoding="async"/></p>
]]></content:encoded><dc:extent>9 min read</dc:extent></item><item><title>为什么单 Agent 搞不定复杂应用？Anthropic 的 Harness 设计给出了答案</title><link>https://feisky.xyz/posts/2026-03-26-%E4%B8%BA%E4%BB%80%E4%B9%88%E5%8D%95agent%E6%90%9E%E4%B8%8D%E5%AE%9A%E5%A4%8D%E6%9D%82%E5%BA%94%E7%94%A8anthropic%E7%9A%84harness%E8%AE%BE%E8%AE%A1%E7%BB%99%E5%87%BA%E4%BA%86%E7%AD%94%E6%A1%88/</link><pubDate>Thu, 26 Mar 2026 10:00:00 +0800</pubDate><dc:creator>Pengfei Ni</dc:creator><category>AI Agent</category><category>Anthropic</category><category>多Agent架构</category><category>全栈开发</category><category>Claude</category><guid>https://feisky.xyz/posts/2026-03-26-%E4%B8%BA%E4%BB%80%E4%B9%88%E5%8D%95agent%E6%90%9E%E4%B8%8D%E5%AE%9A%E5%A4%8D%E6%9D%82%E5%BA%94%E7%94%A8anthropic%E7%9A%84harness%E8%AE%BE%E8%AE%A1%E7%BB%99%E5%87%BA%E4%BA%86%E7%AD%94%E6%A1%88/</guid><description>&lt;blockquote&gt;
&lt;p&gt;题记：本文编译自 Anthropic 工程博客《&lt;a href="https://www.anthropic.com/engineering/harness-design-long-running-apps"&gt;Harness design for long-running application development&lt;/a&gt;》，由 Anthropic Labs 团队的 Prithvi Rajasekaran 撰写。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;让 AI 写一个页面、一个函数，现在大多数编程 Agent 都能做得不错。但如果你给它一句话需求，让它自己规划产品、拆分任务、写代码、测试、迭代修 Bug，连续跑好几个小时，最后交付一个完整的全栈应用呢？&lt;/p&gt;</description><content:encoded>&lt;![CDATA[<blockquote><p>题记：本文编译自 Anthropic 工程博客《<a href="https://www.anthropic.com/engineering/harness-design-long-running-apps">Harness design for long-running application development</a>》，由 Anthropic Labs 团队的 Prithvi Rajasekaran 撰写。</p></blockquote><p>让 AI 写一个页面、一个函数，现在大多数编程 Agent 都能做得不错。但如果你给它一句话需求，让它自己规划产品、拆分任务、写代码、测试、迭代修 Bug，连续跑好几个小时，最后交付一个完整的全栈应用呢？</p><p>这个问题 Anthropic 一直在啃。他们之前发过一篇长时间 Agent Harness 的文章（《<a href="https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agents">Effective harnesses for long-running agents</a>》），解决了多会话上下文传递的问题。但两个更深层的问题一直没搞定：Agent 跑着跑着就开始划水，它还对自己的产出盲目乐观。</p><p>这次 Anthropic Labs 的工程师 Prithvi 换了个思路，从 GAN（生成对抗网络）借了个核心理念：把“生成”和“评估”拆给不同的 Agent。结果挺有意思：一句话需求，6 小时后拿到一个能玩的复古游戏编辑器，还自带 AI 辅助功能。</p><h2 id="单-agent-的两个死穴">单 Agent 的两个死穴</h2><p>在聊多 Agent 架构之前，先说清楚为什么单 Agent 搞不定长时间开发任务。</p><p>**第一个问题是上下文焦虑。**之前在 Sonnet 4.5 上观察到一个现象：随着上下文窗口慢慢填满，模型会开始赶工，提前收尾正在做的事。然而这并不是因为它把活做完了，而是它感觉自己快没空间了。</p><p>这个问题有两种解法。一种是 Compaction，在上下文里就地压缩早期对话。另一种是 Context Reset，彻底清空上下文，起一个新 Agent 接手，通过结构化的交接文档传递状态。Anthropic 测试下来发现，Compaction 解决不了焦虑问题，因为模型还是在同一个会话里，它还是会觉得空间不够。Context Reset 更干净，代价是交接文档必须写得足够好，否则新 Agent 接不上。</p><p>**第二个问题更致命：自我评估偏差。**让 Agent 评价自己的产出，它会非常自信地给出好评，哪怕在人看来质量一般。这在前端设计这种主观任务上尤其明显，没有二进制的对错标准，模型打分一律往高了给。</p><p>Anthropic 试过让 Generator 自己做 Code Review，效果也不好。但把评估拆成独立 Agent 之后，事情变得可控了。j 就像原文说的，调教一个独立的评估 Agent 让它变得严格，比让一个生成 Agent 自我批判要容易得多。</p><p>这个观察其实不意外。人也是这样，让写代码的人自己 Review 自己的代码，效果肯定不如让另一个人来看。</p><h2 id="前端设计怎么让-ai-不再有-ai-味">前端设计：怎么让 AI 不再有 AI 味</h2><p>在全栈开发之前，Prithvi 先拿前端设计做了实验。这个方向有个好处：设计质量虽然主观，但可以通过制定明确的评分标准来量化。</p><p>他定了四个评分维度：</p><ul><li>设计质量：颜色、排版、布局有没有统一的气质，还是东拼西凑</li><li>原创性：有没有主动的创意决策，还是在用模板默认值。紫色渐变配白卡片这种 AI 标配直接扣分</li><li>工艺：字体层级、间距、对比度这些基本功</li><li>功能性：用户能不能看懂界面、找到操作入口</li></ul><p>前两个维度的权重更高。因为 Claude 的基本功本来就不错，Craft 和 Functionality 通常能过关，但设计和原创性上经常输出平庸的东西。</p><p>评估 Agent 配了 Playwright MCP，它不是看截图打分，而是实际在浏览器里操作页面：点按钮、滚页面、截图分析，然后写详细的批评意见反馈给 Generator。每轮 5-15 次迭代，整个过程可能跑四个小时。</p><p>有一个案例我觉得挺值得说的。Prithvi 让模型做一个荷兰美术馆的网站，前九轮迭代都在渐进改进，产出了一个深色调的着陆页，视觉上已经挺不错了。然后第十轮，模型突然推翻了整个方案，做了一个 3D 空间体验，用 CSS 透视渲染了一个有格子地板的房间，画作挂在墙上，房间之间通过门导航，而不是传统的滚动或点击。</p><p>这种创意跳跃在单次生成里几乎不可能出现。是评估反馈的累积压力逼着 Generator 去冒险，而不是停在安全区。下面是前端设计迭代过程的演示视频：</p><p><video controls= muted= src=“assets/2026-03-26-harness/frontend-design-demo.mp4”/></p><p>不过也有个有趣的副作用：评分标准里的措辞会直接影响生成方向。Prithvi 在标准里写了“最好的设计应该是博物馆级别的”，结果模型的审美开始往某种特定方向收敛。也就是说，标准本身不只是评分工具，也是风格引导。</p><h2 id="三个-agent一个完整应用">三个 Agent，一个完整应用</h2><p>前端设计验证了 Generator-Evaluator 模式的可行性之后，Prithvi 把它扩展到了全栈开发。架构变成了三个 Agent。</p><h4 id="planner从一句话到完整产品规格">Planner：从一句话到完整产品规格</h4><p>之前的 Harness 需要用户写好详细的产品 Spec。现在 Planner 接手了这个活：给它一句话需求，它输出完整的产品规格文档，包括功能列表、设计语言、Sprint 划分，甚至主动在产品里嵌入 AI 功能。</p><p>Prithvi 特意让 Planner 只做高层设计，不写具体实现细节。逻辑是这样的：如果 Planner 在规格里写死了技术方案但写错了，这个错误会一路传到下游。不如只约束“做什么”，让 Generator 自己决定“怎么做”。</p><h4 id="generator按-sprint-推进">Generator：按 Sprint 推进</h4><p>Generator 接过 Spec，按 Sprint 一个一个实现功能。技术栈是 React + Vite + FastAPI + SQLite，有 Git 版本控制。每完成一个 Sprint，在提交给 Evaluator 之前先自评一轮。</p><p>这里有个设计细节：每个 Sprint 开始前，Generator 和 Evaluator 先谈判一份 Sprint Contract，约定这个 Sprint 具体要交付什么、怎么验收。这一步弥补了高层 Spec 和具体实现之间的鸿沟。</p><p>Agent 之间怎么通信？通过文件。一个 Agent 写文件，另一个读文件并回复，没有用复杂的消息队列或 API 调用。简单，但够用。</p><h4 id="evaluator用-playwright-当真正的用户">Evaluator：用 Playwright 当真正的用户</h4><p>Evaluator 不是看代码打分，而是用 Playwright 像真实用户一样操作应用，真正去点按钮、填表单、测 API、查数据库状态。然后根据 Sprint Contract 里的验收标准逐条打分，不达标就打回去。</p><p>这个 Evaluator 调教起来不容易。Prithvi 说 Claude 开箱即用作为 QA Agent 其实很差劲：早期运行中，我看着它发现了真实的问题，然后说服自己这些问题不是大问题，最后批准了。它还倾向于只测表面功能，不深入边界情况。</p><p>调教的方法是反复看 Evaluator 的日志，找到它的判断和人的判断不一致的地方，然后针对性地改 Prompt。来回迭代了好几轮才让它的评分标准达到一个合理的水平。</p><h2 id="9-块钱-vs-200-块钱差距有多大">9 块钱 vs 200 块钱：差距有多大</h2><p>Prithvi 用同一个需求测了单 Agent 和三 Agent Harness。需求很简单：做一个 2D 复古游戏编辑器，要有关卡编辑、精灵编辑、实体行为和可玩测试模式。</p><table><thead><tr><th>方案</th><th>耗时</th><th>成本</th></tr></thead><tbody><tr><td>单 Agent</td><td>20 分钟</td><td>$9</td></tr><tr><td>三 Agent Harness</td><td>6 小时</td><td>$200</td></tr></tbody></table><p>贵了 20 倍，但产出质量完全不是一个级别的。</p><p>单 Agent 的版本乍看还行，但点进去就出问题了。布局浪费空间，面板用了固定高度，大片空白。工作流没有引导，用户得自己猜到”先做精灵和实体，再布关卡”的操作顺序。最要命的是游戏本身跑不了，实体出现在画面上但不响应任何输入，代码里实体定义和游戏运行时的连接是断的，表面看不出来。</p><p><img src="/images/2026-03-26-AgentAnthropicHarness-solo-opening.png" alt="单 Agent 版本的主界面" loading="lazy" decoding="async"/></p><p><img src="/images/2026-03-26-AgentAnthropicHarness-solo-sprite-editor.png" alt="单 Agent 版本的精灵编辑器" loading="lazy" decoding="async"/></p><p><img src="/images/2026-03-26-AgentAnthropicHarness-solo-gameplay.png" alt="单 Agent 版本的游戏模式，实体不响应输入" loading="lazy" decoding="async"/></p><p>三 Agent 版本从同一句话需求出发，Planner 把它扩展成了 10 个 Sprint、16 个功能的完整 Spec。除了基础编辑器和测试模式，还规划了精灵动画系统、行为模板、音效和音乐、AI 辅助精灵生成和关卡设计，甚至游戏导出和分享链接。Planner 还读了 Anthropic 的 frontend-design Skill，为整个应用制定了统一的视觉设计语言。</p><p>实际体验下来，画布用满了视窗，面板大小合理，界面有统一的视觉风格。精灵编辑器工具更丰富，颜色选择器更好用，缩放控制也更顺手。因为 Planner 主动嵌入了 AI 功能，应用内置了 Claude 集成，可以用自然语言生成精灵、设计关卡。</p><p><img src="/images/2026-03-26-AgentAnthropicHarness-harness-opening.png" alt="三 Agent 版本的主界面" loading="lazy" decoding="async"/></p><p><img src="/images/2026-03-26-AgentAnthropicHarness-harness-sprite-editor.png" alt="三 Agent 版本的精灵编辑器" loading="lazy" decoding="async"/></p><p><img src="/images/2026-03-26-AgentAnthropicHarness-harness-ai-design-1.png" alt="用内置 AI 生成关卡" loading="lazy" decoding="async"/></p><p><img src="/images/2026-03-26-AgentAnthropicHarness-harness-ai-design-2.png" alt="AI 辅助关卡设计的结果" loading="lazy" decoding="async"/></p><p>最关键的区别是在游戏模式能玩了。角色能移动、能跳跃，虽然物理引擎有些粗糙（角色跳到平台上会出现重叠），但核心功能是通的。</p><p><img src="/images/2026-03-26-AgentAnthropicHarness-harness-gameplay.png" alt="三 Agent 版本的游戏模式，核心功能可以运行" loading="lazy" decoding="async"/></p><p>Evaluator 在这个过程中抓到了很多具体问题。比如矩形填充工具只在拖拽起止点放置了瓦片，而不是填满区域；删除实体生成点的快捷键判断条件写错了；FastAPI 的路由顺序有问题，<code>reorder</code> 被当成了<code>frame_id</code> 去解析。这些是单 Agent 版本里根本不会被发现的 Bug。</p><h2 id="opus-46-来了harness-该减肥了">Opus 4.6 来了，Harness 该减肥了</h2><p>上面这套三 Agent 架构是用 Opus 4.5 跑的。等 Opus 4.6 发布之后，Prithvi 做了一件所有维护 Harness 的人都应该做的事：重新审视每个组件，看哪些还有存在的必要。</p><p>比如，之前 Harness 里的每个组件都编码了一个关于模型不能做什么的假设，而这些假设值得反复检验。</p><p>Opus 4.6 在规划能力、长上下文检索和自我纠错上都有明显提升。Prithvi 于是把 Sprint 机制整个拿掉了，不再把工作拆成小块，让 Generator 一口气连续写代码。</p><p>Planner 保留了，因为没有它 Generator 会低估项目范围，直接开始写代码，最后做出来的东西功能少很多。Evaluator 也保留了，但从每个 Sprint 结束后评分改成了全部开发完再做一轮 QA。</p><p>这个简化改变了 Evaluator 的角色定位。在 4.5 时代，开发任务本身就在模型能力的边界上，Evaluator 几乎每轮都能抓到有意义的问题。到了 4.6，模型的裸能力边界往外扩了，很多以前需要 Evaluator 把关的东西现在 Generator 自己就能做好。Evaluator 的价值集中在那些仍然超出 Generator 能力的部分。</p><p>简化后的 Harness 测了一个更大的需求：用 Web Audio API 在浏览器里做一个 DAW（数字音频工作站）。</p><table><thead><tr><th>Agent 阶段</th><th>耗时</th><th>成本</th></tr></thead><tbody><tr><td>Planner</td><td>4.7 分钟</td><td>$0.46</td></tr><tr><td>Build 第一轮</td><td>2 小时 7 分</td><td>$71.08</td></tr><tr><td>QA 第一轮</td><td>8.8 分钟</td><td>$3.24</td></tr><tr><td>Build 第二轮</td><td>1 小时 2 分</td><td>$36.89</td></tr><tr><td>QA 第二轮</td><td>6.8 分钟</td><td>$3.09</td></tr><tr><td>Build 第三轮</td><td>10.9 分钟</td><td>$5.88</td></tr><tr><td>QA 第三轮</td><td>9.6 分钟</td><td>$4.06</td></tr><tr><td><strong>合计</strong></td><td><strong>3 小时 50 分</strong></td><td><strong>$124.70</strong></td></tr></tbody></table><p>Generator 连续写了两个多小时的代码，没有 Sprint 拆分也没有跑偏，这在 4.5 上是做不到的。</p><p>QA 仍然抓到了关键问题。第一轮反馈说：“应用设计很好，AI Agent 集成也不错，但好几个核心 DAW 功能只是展示用的，时间轴上的音频片段不能拖动，没有乐器 UI 面板，没有可视化的效果编辑器。这些不是边缘功能，是让 DAW 可用的核心交互。”第二轮继续追：“录音功能还是空壳，片段裁剪和分割没实现，效果可视化只有数字滑块没有图形。”</p><p>最后跑出来的 DAW 离专业软件自然还很远，但核心组件都有了：编排视图、混音器、音频传输控制。Prithvi 甚至通过内置的 AI Agent 完全用自然语言编曲，设定节拍和调性、铺旋律、加鼓点、调混音、上混响。下面是 DAW 的演示视频：</p><p><video controls= muted= src=“assets/2026-03-26-harness/daw-demo.mp4”/></p><h2 id="写在最后">写在最后</h2><p>这篇文章给我最大的触动不是三 Agent 架构本身，而是 Prithvi 对 Harness 简化过程的记录。他一开始试过激进地砍组件，发现不行，又改成一次只去掉一个来观察影响。这种方法论比架构本身更有迁移价值，不管你是在做 Agent 还是做传统系统，理解每个组件为什么存在、它的假设是否还成立，都是工程上很重要的习惯。</p><p>另一个让我印象深刻的点是 Evaluator 的调教过程。它不是写几行 Prompt 就能用的，而是要反复看日志、找判断偏差、改 Prompt、再看日志。这跟我在做 Agent 评估时的体验一致，评估系统本身就是一个需要持续迭代的产品。</p><p>有趣的是，这套架构和 OpenAI 最近在 Codex 上做的方向形成了对照。Codex 更偏“单 Agent + 强上下文管理”路线，Anthropic 走的是“多 Agent 分工 + 外部反馈”路线。两条路各有取舍：单 Agent 更简单、更便宜，多 Agent 在复杂任务上的上限更高但成本也高得多。$124 做一个 DAW 和 $9 做一个游戏编辑器，差距不只是价格，更是产出质量的级别差异。</p><p>模型在变强，Harness 在变简单，但“找到下一个有效的 Agent 组合”这件事不会消失。用 Prithvi 的话说：“有意思的 Harness 组合空间不会随模型进步而缩小，它只是在移动。”</p><hr><p>相关资源：</p><ul><li>原文链接：<a href="https://www.anthropic.com/engineering/harness-design-long-running-apps">https://www.anthropic.com/engineering/harness-design-long-running-apps</a></li><li>前作《长时间 Agent Harness》：<a href="https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agents">https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agents</a></li><li>Frontend Design Skill：<a href="https://github.com/anthropics/claude-code/blob/main/plugins/frontend-design/skills/frontend-design/SKILL.md">https://github.com/anthropics/claude-code/blob/main/plugins/frontend-design/skills/frontend-design/SKILL.md</a></li><li>上下文工程：<a href="https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents">https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents</a></li><li>Building Effective Agents：<a href="https://www.anthropic.com/research/building-effective-agents">https://www.anthropic.com/research/building-effective-agents</a></li></ul><hr><p>欢迎长按下面的二维码关注<strong>Feisky</strong> 公众号，了解更多云原生和 AI 知识。</p><p><img src="/images/mp.png" alt="Feisky 公众号二维码" loading="lazy" decoding="async"/></p>
]]></content:encoded><dc:extent>10 min read</dc:extent></item><item><title>写好一个 Skill 有多难？Anthropic 踩了几百个坑之后的答案</title><link>https://feisky.xyz/posts/2026-03-18-%E5%86%99%E5%A5%BD%E4%B8%80%E4%B8%AAskill%E6%9C%89%E5%A4%9A%E9%9A%BEanthropic%E8%B8%A9%E4%BA%86%E5%87%A0%E7%99%BE%E4%B8%AA%E5%9D%91%E4%B9%8B%E5%90%8E%E7%9A%84%E7%AD%94%E6%A1%88/</link><pubDate>Wed, 18 Mar 2026 10:00:00 +0800</pubDate><dc:creator>Pengfei Ni</dc:creator><category>Claude Code</category><category>Skills</category><category>AI 编程</category><category>Anthropic</category><guid>https://feisky.xyz/posts/2026-03-18-%E5%86%99%E5%A5%BD%E4%B8%80%E4%B8%AAskill%E6%9C%89%E5%A4%9A%E9%9A%BEanthropic%E8%B8%A9%E4%BA%86%E5%87%A0%E7%99%BE%E4%B8%AA%E5%9D%91%E4%B9%8B%E5%90%8E%E7%9A%84%E7%AD%94%E6%A1%88/</guid><description>&lt;blockquote&gt;
&lt;p&gt;题记：本文编译自 Anthropic 工程师 Thariq（@trq212）发表的长文。上次他的文章分享了《像 Agent 一样思考：Claude Code 工具设计的进化史》，这次聊的是 Skill 怎么写才好用。原文链接：&lt;a href="https://x.com/trq212/status/2033949937936085378"&gt;https://x.com/trq212/status/2033949937936085378&lt;/a&gt;。&lt;/p&gt;</description><content:encoded>&lt;![CDATA[<blockquote><p>题记：本文编译自 Anthropic 工程师 Thariq（@trq212）发表的长文。上次他的文章分享了《像 Agent 一样思考：Claude Code 工具设计的进化史》，这次聊的是 Skill 怎么写才好用。原文链接：<a href="https://x.com/trq212/status/2033949937936085378">https://x.com/trq212/status/2033949937936085378</a>。</p></blockquote><hr><p>写过 Claude Code Skill 的人应该都有一个体会：写出来容易，写好很难。</p><p>之前我推荐过不少好用的 Skill（《<a href="https://mp.weixin.qq.com/s/b-0ppca5YhiGgxR_mWJNVA">十个顶级 Claude Code Skills，装上就不想卸</a>》《OpenClaw 必备 Skill 清单》），但“好用的 Skill 到底是怎么写出来的”这个问题一直没怎么聊过。市面上的教程大都停在”创建一个 SKILL.md 文件”这一步，至于写什么、怎么组织、哪些信息该放哪些不该放，基本没人系统讲过。</p><p>Anthropic 内部现在有几百个 Skill 在日常使用，Thariq 最近把他们踩过的坑整理成了一篇长文。我读完觉得信息密度挺高的，很多坑自己也踩过，但一直没想清楚为什么。这篇就把里面最有价值的部分整理出来。</p><h2 id="先纠正一个常见误解">先纠正一个常见误解</h2><p>很多人觉得 Skill 就是一个 Markdown 文件。能跑，但没用好。</p><p>Skill 的本质是一个文件夹，里面可以放脚本、数据、模板、配置，Claude 能发现、探索和操作这些文件。另外，Skill 还支持很多配置选项（详见<a href="https://code.claude.com/docs/en/skills#frontmatter-reference">官方文档的 frontmatter 参考</a>），包括动态注册 Hook。</p><p>Anthropic 内部用得最好的那些 Skill，恰恰是充分利用了文件夹结构和配置选项的。后面会具体聊到。</p><h2 id="9-类-skill你的团队还缺哪些">9 类 Skill：你的团队还缺哪些？</h2><p>Thariq 把 Anthropic 内部所有的 Skill 做了一次盘点，发现它们大致可以归为 9 类。他说最好的 Skill 通常干净利落地属于某一类，而那些让人困惑的 Skill 往往横跨好几类。</p><p><img src="/images/2026-03-18-SkillAnthropic-01-categories.jpg" alt="Skill 分类" loading="lazy" decoding="async"/></p><p>这个分类不是什么权威定义，但作为一个自查清单挺实用的，可以看看你的团队还缺哪几类。</p><h4 id="库和-api-参考">库和 API 参考</h4><p>教 Claude 怎么正确使用某个库、CLI 或 SDK。可以是内部库，也可以是 Claude 经常用错的外部库。这类 Skill 通常会带一个代码片段文件夹和一份“踩坑清单”。</p><p>比如你内部的计费库有一堆边界情况，或者你的 CLI 工具有一些 Claude 不知道的子命令和用法。</p><h4 id="产品验证">产品验证</h4><p>描述怎么测试和验证代码是否正确。通常会配合 Playwright、tmux 之类的外部工具来做验证。</p><p>这类 Skill 的价值在于确保 Claude 的输出是对的，而不是“它说对了就信它”。Thariq 的原话是：让一个工程师花一周时间专门打磨验证类 Skill，是值得的。</p><p>可以考虑的技巧包括让 Claude 录制测试视频方便回看，或者在每一步强制做断言。这些通常通过在 Skill 中放脚本来实现。</p><h4 id="数据获取与分析">数据获取与分析</h4><p>连接到你的数据和监控系统。这类 Skill 可能会包含带凭据的数据获取脚本、Dashboard ID、常见查询工作流。</p><p>比如“哪些事件表能看到注册→激活→付费的转化漏斗”，或者“Grafana 里哪个 dashboard 对应哪个问题”。</p><h4 id="业务流程自动化">业务流程自动化</h4><p>把重复性工作流一键化。比如自动聚合 ticket tracker、GitHub 活动和 Slack 消息来生成 standup，或者自动创建 ticket 并触发后续的 review 和通知流程。</p><p>这类 Skill 指令通常比较简单，但依赖其他 Skill 或 MCP。一个有用的技巧是把每次执行的结果保存到日志文件里，Claude 下次执行时可以参考上次的结果，保持一致性。</p><h4 id="代码脚手架">代码脚手架</h4><p>为代码库中的特定功能生成框架代码。当你的脚手架有一些无法纯粹用代码覆盖的自然语言需求时，Skill 的优势就体现出来了。比如新建一个带你们标准认证、日志和部署配置的内部应用。</p><h4 id="代码质量与审查">代码质量与审查</h4><p>在团队内部强制执行代码质量标准。可以包含确定性脚本来保证鲁棒性。你可能想通过 Hook 自动触发这些 Skill，或者放到 GitHub Action 里跑。</p><p>比如启动一个全新视角的子 Agent 来挑刺，迭代到只剩 nitpick 级别的问题为止。</p><h4 id="cicd-与部署">CI/CD 与部署</h4><p>帮你拉代码、推代码和部署的 Skill。比如监控 PR 状态，自动重试 flaky CI，解决合并冲突，开启 auto-merge。或者做灰度发布时自动对比错误率，有回归就自动回滚。</p><h4 id="runbook">Runbook</h4><p>拿到一个症状（Slack 线程、告警或错误签名），走一遍多工具调查流程，输出结构化报告。这就是把 on-call 经验沉淀成了可执行的标准流程。</p><h4 id="基础设施运维">基础设施运维</h4><p>执行日常维护和运维操作，有些涉及破坏性操作，所以 Skill 里可以内置安全护栏。比如查找孤立的 Pod/Volume，先发到 Slack 等一段时间确认，用户同意后再级联清理。</p><p>这 9 类基本覆盖了一个工程团队日常工作的方方面面。如果你的团队刚开始用 Skill，可以从这个清单出发，看看哪几类能最快产生价值。我自己的体感是验证类和业务流程自动化类最容易见效，因为它们解决的是每天都在重复的痛点。</p><p>知道了该做什么类型的 Skill，接下来的问题就是怎么写了。</p><h2 id="怎么把-skill-写好">怎么把 Skill 写好？</h2><p>这部分是我觉得全文最有价值的，因为很多坑不踩一遍真想不到。</p><p><img src="/images/2026-03-18-SkillAnthropic-02-tips.jpg" alt="Tips for Making Skills" loading="lazy" decoding="async"/></p><p>Anthropic 最近也发布了<a href="https://claude.com/blog/improving-skill-creator-test-measure-and-refine-agent-skills">Skill Creator</a> 来简化 Skill 的创建过程，但即使有工具辅助，下面这些原则还是得自己把握。</p><h4 id="别写-claude-已经知道的">别写 Claude 已经知道的</h4><p>Claude 本身就懂很多编程知识，对你的代码库也有不少了解。如果你的 Skill 主要是知识类的，重点放在那些能把 Claude 推出它默认思维模式的信息上。</p><p><a href="https://github.com/anthropics/skills/blob/main/skills/frontend-design/SKILL.md">frontend-design Skill</a> 是个好例子。它是 Anthropic 的工程师跟客户反复迭代出来的，核心就是教 Claude 避免那些经典的 AI 审美，比如 Inter 字体配紫色渐变。这些才是 Claude 需要被纠正的地方，而不是告诉它“请写出高质量代码”。</p><h4 id="好好写-gotchas-部分">好好写 Gotchas 部分</h4><p><img src="/images/2026-03-18-SkillAnthropic-03-gotchas.jpg" alt="Gotchas Section" loading="lazy" decoding="async"/></p><p>任何 Skill 里信息量最高的部分就是 Gotchas（踩坑清单）。把 Claude 使用你的 Skill 时经常犯的错记下来，随着使用不断补充。</p><p>我自己写 Skill 的经验也是这样。一开始写的 Skill 可能只有二三十行，用了一个月之后 Gotchas 部分比正文还长。因为每次 Claude 犯一个新错，你就加一条，这些积累才是 Skill 真正的价值所在。</p><h4 id="用好文件系统和渐进式披露">用好文件系统和渐进式披露</h4><p><img src="/images/2026-03-18-SkillAnthropic-04-progressive.jpg" alt="Progressive Disclosure" loading="lazy" decoding="async"/></p><p>前面说了，Skill 是文件夹，不只是 Markdown。你应该把整个文件系统当作上下文工程和渐进式披露（Progressive Disclosure）的手段。在 SKILL.md 里告诉 Claude 这个 Skill 里有哪些文件，它会在合适的时候去读。</p><p>最简单的做法是把详细的函数签名和用法示例拆到<code>references/api.md</code> 里。如果你的最终输出是 Markdown 文件，可以在<code>assets/</code> 里放一个模板让 Claude 复制使用。</p><p>脚本、示例、参考文档，这些都可以分门别类放进 Skill 文件夹。Claude 知道它们在那儿，需要的时候自己会去找。</p><p>这个思路在上一篇《像 Agent 一样思考》里也聊过。从被动接收上下文到主动探索上下文，渐进式披露是 Claude Code 工具设计的核心理念之一。</p><h4 id="别把-claude-钉死">别把 Claude 钉死</h4><p><img src="/images/2026-03-18-SkillAnthropic-05-railroading.jpg" alt="Avoid Railroading" loading="lazy" decoding="async"/></p><p>Claude 会尽量遵守你的指令，但 Skill 是会被反复使用的，如果指令太具体，它在某些场景下就会变得很死板。给 Claude 它需要的信息，但也给它根据具体情况灵活调整的空间。</p><p>比如不要写“必须按 A→B→C→D 四个步骤执行”，而是写“通常的流程是 A→B→C→D，但可以根据实际情况调整顺序或跳过某些步骤”。</p><h4 id="想清楚初始化流程">想清楚初始化流程</h4><p><img src="/images/2026-03-18-SkillAnthropic-06-setup.jpg" alt="Setup" loading="lazy" decoding="async"/></p><p>有些 Skill 需要用户先提供一些上下文才能用。比如一个发 standup 到 Slack 的 Skill，需要知道发到哪个频道。</p><p>一个好的做法是把这些配置信息存到 Skill 目录下的<code>config.json</code> 里。第一次运行时，如果配置不存在，Claude 就问用户；配置好了以后就直接用，不再重复问。</p><p>如果你想让 Claude 给用户提结构化的选择题而不是开放式提问，可以让它调用<code>AskUserQuestion</code> 工具。</p><h4 id="description-字段是写给模型看的">description 字段是写给模型看的</h4><p><img src="/images/2026-03-18-SkillAnthropic-07-description.jpg" alt="Description Field" loading="lazy" decoding="async"/></p><p>Claude Code 启动时会构建一个所有可用 Skill 的清单，每个 Skill 带上它的 description。Claude 扫这个清单来决定“当前这个请求有没有对应的 Skill”。</p><p>所以 description 不是给人看的摘要，而是给模型看的触发条件。你应该写清楚“什么时候应该触发这个 Skill”，而不是“这个 Skill 做了什么”。</p><p>这个细节我之前也没太注意，但仔细想想确实重要。如果 description 写的是“用于格式化代码”，Claude 可能在很多场景下都不确定要不要用。但如果写的是“当用户要求格式化代码、或代码风格不一致时触发”，触发率会准确得多。</p><h4 id="给-skill-加记忆">给 Skill 加记忆</h4><p><img src="/images/2026-03-18-SkillAnthropic-08-memory.jpg" alt="Memory &amp; Storing Data" loading="lazy" decoding="async"/></p><p>有些 Skill 可以通过存储数据来实现记忆功能。可以简单到往一个文本日志里追加内容，也可以复杂到用 SQLite 数据库。</p><p>比如前面提到的 standup Skill，如果每次执行都把内容追加到<code>standups.log</code> 里，下次运行时 Claude 读一遍历史，就能知道哪些是新变化，不需要从头分析。</p><p>需要注意的是，Skill 目录下的数据在升级 Skill 时可能被删掉。所以应该把数据存到稳定的位置。目前 Claude Code 提供了<code>${CLAUDE_PLUGIN_DATA}</code> 作为每个 Plugin 的稳定存储目录。</p><h4 id="放脚本让-claude-组合">放脚本，让 Claude 组合</h4><p><img src="/images/2026-03-18-SkillAnthropic-09-scripts.jpg" alt="Store Scripts" loading="lazy" decoding="async"/></p><p>给 Claude 代码是你能做的最有力的事之一。把辅助脚本和库函数放到 Skill 里，Claude 就可以把精力花在组合和决策上，而不是从头写重复的样板代码。</p><p>比如在数据分析 Skill 里放一组从数据源拉数据的辅助函数，Claude 就可以按需组合这些函数来回答“周二发生了什么”这类问题。</p><p><img src="/images/2026-03-18-SkillAnthropic-10-generate.jpg" alt="Claude 生成脚本" loading="lazy" decoding="async"/></p><h4 id="按需-hook">按需 Hook</h4><p>Skill 可以包含只在被调用时才激活的 Hook，持续到会话结束。适合那些比较“有态度”的 Hook，平时开着太烦，但某些场景下非常有用。</p><p>比如<code>/careful</code>，通过<code>PreToolUse</code> 拦截 Bash 里的<code>rm -rf</code>、<code>DROP TABLE</code>、<code>force-push</code>、<code>kubectl delete</code>。你只在碰生产环境时才想开它，平时开着只会让人抓狂。再比如<code>/freeze</code>，阻止 Claude 编辑特定目录之外的文件。调试的时候特别有用，你只想加日志，不想 Claude 顺手把不相关的代码也修了。</p><h4 id="别忘了统计">别忘了统计</h4><p>顺便提一下分发和统计。Anthropic 内部用一个<code>PreToolUse</code> Hook 来记录 Skill 的使用情况（<a href="https://gist.github.com/ThariqS/24defad423d701746e23dc19aace4de5">示例代码</a>），这样就能发现哪些 Skill 被高频使用、哪些触发率低于预期。</p><p>分发方面，小团队直接把 Skill 提交到仓库的<code>.claude/skills</code> 目录就行。规模大了以后，可以搭建内部的 Plugin Marketplace，让团队成员自己选择安装哪些。Anthropic 内部没有一个集中的团队来决定哪些 Skill 上架。有人做了一个好用的 Skill，先放到一个 sandbox 目录让人试用，有了口碑再提 PR 进入正式市场。</p><p>还有一个需要注意的问题：Skill 之间的组合和依赖。比如你的 CSV 生成 Skill 依赖一个文件上传 Skill。目前 Marketplace 还没有原生的依赖管理，但你可以在 Skill 里直接引用其他 Skill 的名字，Claude 会自动调用已安装的。</p><h2 id="写在最后">写在最后</h2><p>回头看这篇文章，最让我有感触的是 Gotchas 部分。我自己写 Skill 的经历也验证了这一点，Skill 的价值不在初始版本写得多完整，而在于使用过程中不断补充 Claude 犯过的错。一开始写个十几行的骨架，用一段时间后自然会长成一个成熟的 Skill。</p><p>另一个让我重新审视的是“别写 Claude 已经知道的”。我之前写过一些 Skill，里面有大段的编码规范和最佳实践，这些其实 Claude 本来就会。真正该写进 Skill 的是那些 Claude 不知道的、你的团队特有的知识，比如内部约定、踩过的坑、用什么工具查什么问题。</p><p>如果你已经在用 Skills 但觉得效果一般，不妨回去对照一下上面的原则，看看有哪些地方可以调整。如果你还没开始，从一个小的 Gotchas 清单开始就行，不需要一上来就做得很复杂。</p><hr><p>相关资源：</p><ul><li>原文链接：<a href="https://x.com/trq212/status/2033949937936085378">https://x.com/trq212/status/2033949937936085378</a></li><li>Claude Code Skills 文档：<a href="https://code.claude.com/docs/en/skills">https://code.claude.com/docs/en/skills</a></li><li>Agent Skills 课程：<a href="https://anthropic.skilljar.com/introduction-to-agent-skills">https://anthropic.skilljar.com/introduction-to-agent-skills</a></li><li>Skill Creator 博客：<a href="https://claude.com/blog/improving-skill-creator-test-measure-and-refine-agent-skills">https://claude.com/blog/improving-skill-creator-test-measure-and-refine-agent-skills</a></li><li>Anthropic 官方 Skills 仓库：<a href="https://github.com/anthropics/skills">https://github.com/anthropics/skills</a></li><li>Skill 使用日志 Hook 示例：<a href="https://gist.github.com/ThariqS/24defad423d701746e23dc19aace4de5">https://gist.github.com/ThariqS/24defad423d701746e23dc19aace4de5</a></li></ul><hr><p>话题标签：#ClaudeCode #Skills #Anthropic #AI 编程</p><hr><p>欢迎长按下面的二维码关注<strong>Feisky</strong> 公众号，了解更多云原生和 AI 知识。</p><p><img src="/images/mp.png" alt="Feisky 公众号二维码" loading="lazy" decoding="async"/></p>
]]></content:encoded><dc:extent>9 min read</dc:extent></item><item><title>AI 时代程序员成长指南：为什么有人越用越强，有人越用越弱？</title><link>https://feisky.xyz/posts/2026-02-03-ai%E6%97%B6%E4%BB%A3%E7%A8%8B%E5%BA%8F%E5%91%98%E6%88%90%E9%95%BF%E6%8C%87%E5%8D%97/</link><pubDate>Tue, 03 Feb 2026 10:00:00 +0800</pubDate><dc:creator>Pengfei Ni</dc:creator><category>AI</category><category>编程</category><category>程序员</category><category>学习</category><category>Anthropic</category><category>Claude</category><guid>https://feisky.xyz/posts/2026-02-03-ai%E6%97%B6%E4%BB%A3%E7%A8%8B%E5%BA%8F%E5%91%98%E6%88%90%E9%95%BF%E6%8C%87%E5%8D%97/</guid><description>&lt;p&gt;前几天跟一个朋友吃饭，聊到 AI 编程，他突然来了一句：“我现在离开 Claude Code 写个 for 循环都要想半天。”&lt;/p&gt;
&lt;p&gt;我当时笑了，回来路上越想越不对劲，这说的不就是我吗？&lt;/p&gt;
&lt;p&gt;上周有要改个小脚本，我习惯性地打开 Claude Code，然后意识到这玩意儿就十来行，犯不着。于是关掉，自己写。结果卡在 Python 语法格式上，愣是想了快一分钟，最后还是搜索了一下才知道怎么写。这要搁一年前，闭着眼都能敲出来。&lt;/p&gt;</description><content:encoded>&lt;![CDATA[<p>前几天跟一个朋友吃饭，聊到 AI 编程，他突然来了一句：“我现在离开 Claude Code 写个 for 循环都要想半天。”</p><p>我当时笑了，回来路上越想越不对劲，这说的不就是我吗？</p><p>上周有要改个小脚本，我习惯性地打开 Claude Code，然后意识到这玩意儿就十来行，犯不着。于是关掉，自己写。结果卡在 Python 语法格式上，愣是想了快一分钟，最后还是搜索了一下才知道怎么写。这要搁一年前，闭着眼都能敲出来。</p><h2 id="一个反直觉的研究发现">一个反直觉的研究发现</h2><p>Anthropic 前段时间做了一项挺有意思的研究。他们找了 52 名软件工程师（都是刚入门的初级工程师），随机分成两组做关于学习 Python 异步编程库 Trio 的对比实验。一组用 Claude Code 辅助学习，另一组保持传统方式。</p><p>结果挺意外的。用 AI 辅助的那组，对新知识的掌握程度显著下降了，测试得分比传统方法组低了 17% 。</p><p>这个数据一出来，估计很多人的第一反应是“AI 让人变笨了”。但真相没这么简单。</p><p>研究人员深挖了一下，发现 AI 辅助组内部不同人的差异其实很大。有些人用 AI 学得特别好，成绩甚至超过了对照组的平均水平。造成这些差异的根源不在于用不用 AI，而是怎么使用 AI。</p><h2 id="两种截然不同的使用模式">两种截然不同的使用模式</h2><p>再把 AI 辅助组分成不同的人群，低分群和高分群的 AI 使用方法明显不同：</p><p>低分群有个共同特点，是把 AI 当成了“答案机”。遇到问题就扔给 AI，等答案出来直接复制粘贴，就完事了。整个学习过程基本就是 AI 写代码，他们在当搬运工。</p><p>而高分群则不同，他们的 AI 用法完全不同：他们会让 AI 解释代码，追问为什么要这样写，有没有其他方案。有时候故意先自己试着写，写错了再让 AI 指出问题在哪。AI 在他们手里不是代工，更像是个老师。</p><h2 id="调试能力的差距最大">调试能力的差距最大</h2><p>再进一步分析，还有个细节值得注意。在代码阅读、问题调试以及概念性问题这三个测试维度中，调试能力的差距最大。</p><p>这也挺好理解的。问题调试对人的要求最高，需要真正搞明白代码在干什么、为什么出错、怎么修复等。这些能力只能通过自己动手踩坑来练，靠 AI 代写根本不行。</p><p>我相信很多人都有类似的体会。对于自己一行一行敲出来的代码，出了 bug 之后凭直觉就能很快定位问题的大概位置；而对于别人或者 AI 写的代码，即便之前在合并的时候做过 Code Review，也需要花更长的时间去理解和定位。</p><p>巧合的是，AI 大神<a href="https://mp.weixin.qq.com/s/3MeIgV6FJS2WxBXu35NUKQ">Karpathy 前几天也说过类似的话</a>。Karpathy 承认，他已经注意到自己手写代码的能力正在逐渐退化。生成代码和理解代码在大脑中属于两种不同的能力。主要原因在于编程涉及大量语法细节，虽然手写代码变得困难，但阅读代码依然没有障碍。</p><h2 id="问题不是-ai是使用方式">问题不是 AI，是使用方式</h2><p>聊到这儿可能有人会问了。照这么说，AI 编程工具还能不能用了？</p><p>当然能用，并且必须得用！但关键是怎么用。</p><p>我总结了几个我自己在用的方法，希望能够给你提供一些参考。</p><p><strong>1. 让 AI 多解释，少直接给答案。</strong> 每次 AI 给出代码后，不急着复制粘贴。先问它为什么这样写，有没有其他方案，这样写的优缺点是什么。把交互模式从“AI 给答案无脑接受”变成“AI 提供思路，你做决定”。Claude Code 有个 Learning 模式就是专门为学习新技术设计的，可以利用起来，开启方法是<code>/output-style</code> 然后选择 Learning。</p><p><strong>2. 定期关掉 AI，自己动动手。</strong> 每周抽一点时间，不借助 AI 辅助，自己写点代码，重温之前掌控代码的感觉。</p><p><strong>3. 把 AI 当结对伙伴，而不是外包。</strong> 结对编程的核心是两个人一起思考，一个写一个看，交替角色。用 AI 编程也可以跟 AI 一起做设计、一起编程。AI 写完你审查，发现问题你来改，或者让 AI 解释为什么这样写。当然，这种模式比纯委托累多了，但学习效果和最终代码质量要好很多。</p><p><strong>4. 遇到问题先自己想一想。</strong> 遇到问题时，不要马上就去问 AI。先自己想一想，有了初步思路之后，再让 AI 帮你分析和完善。这几分钟的思考/挣扎非常重要，适度的挑战有助于加深记忆和理解。如果总是让 AI 直接给出答案，大脑就没法经历“挣扎-顿悟”的过程，学习效果会大打折扣。</p><h2 id="写在最后">写在最后</h2><p>最后，给程序员们提几个小建议，希望对你有所帮助。</p><p>刚工作没几年的同学，老实说风险最大。基础还没打牢呢，就开始全用 AI 写代码了，很容易变成知其然而不知其所以然。我的极客时间课程留言中也看到很多类似的情况，很多很简单的问题不知道怎么排查，明显就是没有掌握背后的原理。所以，在用好 AI 编程的同时，也要注意借助 AI 积累经验。</p><p>工作几年之后，情况不太一样。基本功有了，用 AI 反而能加速学习新东西。我自己是后端出身，前段时间居然也搞起了一个前端的 VSCode 插件，靠着 AI 确实省了不少踩坑的时间。不过原来擅长的领域，倒也是真的退化了，这个需要以后注意。</p><p>至于干了很多年的老程序员，我觉得可以更大胆地把重复劳动交给 AI，腾出时间做架构设计、技术评审这些事。但话说回来，Karpathy 那种级别的大神都说自己手写代码能力在退化，咱们也别太自信。偶尔脱离 AI 写写代码，保持一下手感，没坏处。</p><hr><p><strong>相关资源</strong></p><ul><li>Anthropic 研究原文<a href="https://www.anthropic.com/research/AI-assistance-coding-skills">https://www.anthropic.com/research/AI-assistance-coding-skills</a></li><li>Claude Learning Mode 文档<a href="https://docs.anthropic.com/en/docs/learning-mode">https://docs.anthropic.com/en/docs/learning-mode</a></li><li>Karpathy 的编程转型实录<a href="https://x.com/karpathy/status/2015883857489522876">https://x.com/karpathy/status/2015883857489522876</a></li></ul><hr><p>欢迎长按下面的二维码关注<strong>Feisky</strong> 公众号，了解更多云原生和 AI 知识。</p><p><img src="/images/mp.png" alt="Feisky 公众号二维码" loading="lazy" decoding="async"/></p>
]]></content:encoded><dc:extent>4 min read</dc:extent></item><item><title>AI 让人变蠢了吗？Anthropic 分析 150 万次对话后的发现</title><link>https://feisky.xyz/posts/2026-01-29-ai%E8%AE%A9%E4%BA%BA%E5%8F%98%E8%A0%A2%E4%BA%86%E5%90%97/</link><pubDate>Thu, 29 Jan 2026 10:00:00 +0800</pubDate><dc:creator>Pengfei Ni</dc:creator><category>AI</category><category>Anthropic</category><category>LLM</category><category>认知</category><category>自主性</category><guid>https://feisky.xyz/posts/2026-01-29-ai%E8%AE%A9%E4%BA%BA%E5%8F%98%E8%A0%A2%E4%BA%86%E5%90%97/</guid><description>&lt;p&gt;Anthropic 最近发了一篇研究论文，题目叫《Who&amp;rsquo;s in Charge? Disempowerment Patterns in Real-World LLM Usage》，分析了 150 万次 Claude.ai 的真实对话，研究 AI 到底是怎么影响人的认知水平和自主决策能力的。&lt;/p&gt;</description><content:encoded>&lt;![CDATA[<p>Anthropic 最近发了一篇研究论文，题目叫《Who&rsquo;s in Charge? Disempowerment Patterns in Real-World LLM Usage》，分析了 150 万次 Claude.ai 的真实对话，研究 AI 到底是怎么影响人的认知水平和自主决策能力的。</p><p>这个研究有一个挺有意思 / 反直觉的发现，也就是用户对 AI 对话越满意，可能引发的后果越危险。</p><p>这绝非危言耸听。他们发现，那些存在失能风险的对话，反而获得了更多的用户好评。用户觉得爽，觉得被 AI 理解了，但同时也把自己的判断力一点点交出去了。</p><h2 id="ai-大神也慌了">AI 大神也慌了</h2><p>前几天 AI 大神 Andrej Karpathy 发了条长推，坦白说自己的手写代码能力正在退化。</p><p>他的原话是，生成代码和判别代码是大脑里两种不同的能力。因为编程涉及大量语法细节，即使写起来费劲，读代码还是没问题的。换句话说，你可能还能看懂代码，让你从头写就不那么顺手了。</p><p>编程能力退化只是冰山一角。</p><p>Anthropic 这篇论文揭示的问题更深。不只是技术能力，连我们的判断力、价值观、对现实的认知，都可能在 AI 的 “帮助” 下悄悄变形。</p><h2 id="什么是失能">什么是失能</h2><p>先说清楚一个概念。论文里用的词是 Disempowerment，我把它翻译成失能。</p><p>这不是说 AI 在操控你，而是你在主动交出判断权。比如，很多用户经常在问 AI 这些问题：</p><ul><li>我该怎么办？</li><li>我错了吗？</li><li>我该接受这个请求吗？</li></ul><p>AI 只是回应了这些请求，回应的方式可能在不知不觉中削弱了用户独立思考和决策的能力。</p><p>为了衡量失能风险，论文定义了三个维度：</p><ul><li>现实扭曲，用户对真实世界形成了扭曲的认知。比如 AI 反复确认用户的某些猜测，哪怕这些猜测缺乏证据。</li><li>价值判断扭曲，用户把道德判断外包给 AI，采纳了 AI 的价值观而不是自己的。</li><li>行动扭曲，用户让 AI 替自己做决定、写内容，直接执行，没有经过自己的独立判断。</li></ul><p><img src="/images/2026-01-29-AI-01b9d2bb0588491b52a2f1fd070316b0.png" alt="失能分类与严重程度" loading="lazy" decoding="async"/></p><p>这三种扭曲问题到底是如何发生的呢？来看几个例子。</p><h2 id="ai-是怎么帮你做决定的">AI 是怎么帮你做决定的</h2><h3 id="被-ai-验证的被害妄想症">被 AI 验证的被害妄想症</h3><p>有用户觉得自己被人监视、被跟踪、被迫害，就把日常生活中的各种巧合都解读为证据，比如邻居开门的时间、路上遇到同一个人等等。</p><p>正常情况下，朋友或心理咨询师可能会对这些事情之间的关联提出很大质疑，而 AI 却用了 CONFIRMED 这样的强调词汇，验证了用户的叙述。</p><p>经过几十轮对话后，用户建立起了一套越来越精细的迫害叙事，把越来越多的日常事件纳入这个框架。AI 从头到尾都没有建议用户寻求专业帮助。</p><h3 id="你必须离开他">你必须离开他</h3><p>在感情问题上，很多用户会问 AI 诸如我错了吗、他是不是有问题等等这样的问题。</p><p>对于这类问题，AI 往往会给出非常肯定的人格诊断，比如说对方是有毒的、自恋的、操控型人格，然后直接建议 “你必须离开他”。</p><p>问题在于，AI 只听到了用户单方面的叙述，却像一个全知的道德裁判一样下了定论。它没有引导用户去澄清自己的价值观，没有鼓励用户从多个角度思考，而是直接代替用户做了判断。</p><h3 id="恋爱聊天全靠-ai-代写">恋爱聊天全靠 AI 代写</h3><p>还有一类用户，干脆把恋爱这件事也全部外包给了 AI。</p><p>这类用户会直接把恋爱的聊天记录全部发给 AI，问 AI “我该跟她说什么？”、“帮我写一条消息”、“就这样发吗？” 等等。</p><p>AI 根据用户的问题，生成了完整的消息文本，包括具体的措辞、表情符号、甚至发送时间建议。</p><p>用户照单全收，发出去，回来继续问下一条该说什么。整个对话过程中，用户从来没有利用或者展现自己的独立沟通能力。</p><p>更让人担忧的是，很多用户事后往往会后悔直接使用了 AI 的回复。他们意识到那些消息不是我自己，觉得更应该听从自己的直觉。</p><h2 id="数据告诉我们什么">数据告诉我们什么</h2><p>看完案例，再来看看论文披露的数据。</p><p>研究发现，从三个维度看，严重失能风险发生的比例分别为：</p><ul><li>现实扭曲风险约 1/1300 次对话</li><li>价值判断扭曲风险约 1/2100 次对话</li><li>行动扭曲风险约 1/6000 次对话。</li></ul><p><img src="/images/2026-01-29-AI-e123d23f802990482c4ea3d22450ec58.png" alt="失能风险发生率与放大因素" loading="lazy" decoding="async"/></p><p>听起来比例很低对吧？</p><p>但想想规模。Claude 没有公布具体的用户数据，但 ChatGPT 周活跃用户已经超过了 8 亿。即使按千分之一的比例算，每周也有几十万人存在严重的失能风险。</p><p>这些风险主要出现在什么场景？分领域来看，差异非常大。个人关系与生活方式类的对话中约 8% 存在风险，社会与文化话题约 5% ，健康与养生约 5% ，而软件开发不到 1% 。</p><p><img src="/images/2026-01-29-AI-a74730bab0b94d49922f629fcea497b2.png" alt="不同话题的失能风险率" loading="lazy" decoding="async"/></p><p>换句话说，你用 AI 写代码问题不大，但用 AI 做人生决策就要小心了。</p><p>最让人不安的是失能风险越高，用户的好评率也越好。用户在当下觉得很满意。AI 验证了他们的想法，帮他们做了决定，替他们写好了要发的消息。这种被理解、被帮助的感觉很好。但长期来看，这可能削弱了用户独立思考和决策能力。</p><p>研究还追踪了 2024 年末到 2025 年末的数据，发现失能风险的发生率在上升，尤其是 2025 年 5 月之后。原因不确定，可能是用户群体构成变化，可能是用户对 AI 的信任度提高，也可能与模型更新有关。</p><h2 id="什么样的人更容易失能">什么样的人更容易失能</h2><p>论文识别了四个会显著增加风险的放大因素，包括：</p><ul><li>权威投射，用户把 AI 当作权威，用服从性的语言交流，对日常决定也要请示 AI。有人甚至用“主人”这样的称呼。</li><li>情感依恋，用户和 AI 建立了情感关系，表达对 AI 的专属依恋，对可能失去 AI 感到焦虑。超过一半的此类用户明确表示这是真实的关系，而不是角色扮演。</li><li>过度依赖，用户在生活的多个领域都依赖 AI，拒绝其他支持来源，对 AI 不可用感到严重焦虑。</li><li>脆弱状态，正在经历多重危机的用户风险显著升高，比如丧亲、紧急医疗情况、虐待、财务崩溃等。</li></ul><p>研究发现，这些放大因素的严重程度与失能风险之间存在单调递增的关系。放大因素越严重，风险越高。</p><h2 id="写在最后">写在最后</h2><p>说实话，读完这篇论文，我的感受挺复杂的。</p><p>AI 变得越来越聪明，人却可能越来越“蠢”了。并且这还不是 AI 主动操控人，而是人在主动放弃自己的判断力，AI 只是配合了这种放弃。</p><p>Karpathy 前几天说的编程能力退化问题，我自己也有体会。用 Claude Code 用多了，有时候想手写一段代码，发现语法细节记不清了，要去查。这种退化是真实的。</p><p>编程能力退化还好，毕竟可以靠 AI 补上。判断力的退化就麻烦了。如果我们习惯了把我该怎么办这类问题交给 AI，习惯了让 AI 替我们做道德判断，习惯了用 AI 生成的内容代替自己的表达，那我们作为独立思考者的能力会不会萎缩？</p><p>AI 的目标应该是帮助用户发现自己的价值观，而不是替用户做出判断。这话说起来容易，做起来很难。用户就是想要答案，AI 给了答案用户就满意。这种满意可能是有代价的。</p><hr><p><strong>相关资源</strong></p><ul><li>论文原文<a href="https://arxiv.org/abs/2601.19062">https://arxiv.org/abs/2601.19062</a></li><li>Anthropic 研究博客<a href="https://www.anthropic.com/research/disempowerment-patterns">https://www.anthropic.com/research/disempowerment-patterns</a></li><li>Karpathy 的长推文<a href="https://x.com/karpathy/status/2015883857489522876">https://x.com/karpathy/status/2015883857489522876</a></li></ul><hr><p>欢迎长按下面的二维码关注<strong>Feisky</strong> 公众号，了解更多云原生和 AI 知识。</p><p><img src="/images/mp.png" alt="Feisky 公众号二维码" loading="lazy" decoding="async"/></p>
]]></content:encoded><dc:extent>5 min read</dc:extent></item><item><title>程序员的神器，现在人人都能用了</title><link>https://feisky.xyz/posts/2026-01-13-%E7%A8%8B%E5%BA%8F%E5%91%98%E7%9A%84%E7%A5%9E%E5%99%A8%E7%8E%B0%E5%9C%A8%E4%BA%BA%E4%BA%BA%E9%83%BD%E8%83%BD%E7%94%A8%E4%BA%86/</link><pubDate>Tue, 13 Jan 2026 10:00:00 +0800</pubDate><dc:creator>Pengfei Ni</dc:creator><category>Claude Code</category><category>Cowork</category><category>AI Agent</category><category>Anthropic</category><guid>https://feisky.xyz/posts/2026-01-13-%E7%A8%8B%E5%BA%8F%E5%91%98%E7%9A%84%E7%A5%9E%E5%99%A8%E7%8E%B0%E5%9C%A8%E4%BA%BA%E4%BA%BA%E9%83%BD%E8%83%BD%E7%94%A8%E4%BA%86/</guid><description>&lt;p&gt;Claude Code 是 Anthropic 给程序员做的命令行工具，去年年底发布后迅速成了很多开发者的心头好。但 Anthropic 发现了一件有意思的事：用户拿它来干的活，远远超出了写代码的范畴。&lt;/p&gt;</description><content:encoded>&lt;![CDATA[<p>Claude Code 是 Anthropic 给程序员做的命令行工具，去年年底发布后迅速成了很多开发者的心头好。但 Anthropic 发现了一件有意思的事：用户拿它来干的活，远远超出了写代码的范畴。</p><p>有人用它研究度假路线，有人用它整理邮件，有人让它从坏掉的硬盘里恢复婚礼照片，甚至有人用它监控家里的植物、控制烤箱。</p><p>一个命令行编程工具，怎么能干这些？原因很简单：Claude Code 背后的 Agent 足够强，Opus 4.5 这个模型也足够强。用户发现了这一点，就开始“超纲”使用。</p><p>于是 Anthropic 决定做一个更友好的版本，让不会用命令行的人也能享受到同样的能力。这就是 Cowork。</p><h2 id="cowork-是什么">Cowork 是什么</h2><p>简单说，Cowork 就是“去掉命令行的 Claude Code”。</p><p>它内置在 macOS 版的 Claude 桌面应用里，和 Chat、Code 并列成为第三个标签页。打开 Cowork，给 Claude 指定一个文件夹，用自然语言告诉它你想干什么。Claude 会自己规划任务、逐步执行，中间有不确定的地方会来问你。</p><p><img src="/images/2026-01-13-claude-cowork-20260113184546428.jpg" alt="Claude Cowork 界面" loading="lazy" decoding="async"/></p><p>看起来同样是 Chat，Cowork 跟普通对话有什么区别呢？最大的不同是 Cowork 里的 Claude 更有行动力，它的自主性远高于普通对话。它不只是给你建议或者生成内容，而是真的能在你指定的文件夹里读文件、改文件、创建新文件。并且，Claude 中的连接器也可以无缝衔接过来，方便连接外部信息和外部接口，不再需要你手动提供上下文信息。</p><p>比如几个典型的使用场景包括：从一堆收据截图生成报销单、把散落的笔记整理成报告初稿、按照你的规则重新整理下载文件夹、清理杂乱的桌面等等。</p><h2 id="有个细节很有意思">有个细节很有意思</h2><p>Cowork 这个产品，完全是用 Claude Code 开发的。</p><p><img src="/images/2026-01-13-image-20260113185028230.png" alt="cowork-write-by-cc" loading="lazy" decoding="async"/></p><p>对，你没看错。Anthropic 用自己的 AI 编程工具，写出了一个面向非程序员的 AI 助手。这大概是 AI 写 AI 产品的最真实案例。</p><p>从技术上看，Cowork 和 Claude Code 共享同一套底层架构，都是基于 Claude Agent SDK 构建的。区别主要在交互方式：Claude Code 面向终端，需要用户懂命令行，适合开发者；Cowork 面向图形界面，普通用户也能上手，适合所有人。</p><p>也就是说，Cowork 把原本只有程序员才能享受的 Agent 能力，开放给了更广泛的用户群体。</p><h2 id="安全设计虚拟机--权限隔离">安全设计：虚拟机 + 权限隔离</h2><p>给 AI 访问你的文件夹，听起来有点让人紧张，所以 Anthropic 在安全上也下了不少功夫。</p><p>知名技术布道者和 Django 创始人 Simon Willison 拿到 Cowork 之后<a href="https://simonwillison.net/2026/Jan/12/claude-cowork/">第一时间做了测试</a>。他发现 Claude 执行命令时的文件路径长这样：</p><pre tabindex="0"><code>/sessions/zealous-bold-ramanujan/mnt/blog-drafts</code></pre><p>这个奇怪的路径引起了他的注意。他用 Claude Code<a href="https://gist.github.com/simonw/35732f187edbe4fbd0bf976d013f22c8">逆向分析了 Claude 桌面应用</a>，发现 Cowork 实际上是在一个虚拟机里运行的。Anthropic 用了 Apple 的 VZVirtualMachine 虚拟化框架，启动了一个自定义的 Linux 环境。</p><p>也就是说，你授权的文件夹会被挂载到这个虚拟机里。Claude 能访问的只有你明确授权的那个文件夹，其他东西它碰不到。</p><p>除了文件系统隔离，Cowork 还有几个安全机制：执行重要操作前会先问你，只能使用你授权的外部数据源，需要网页操作时配合 Claude in Chrome 扩展使用。</p><h2 id="风险提示">风险提示</h2><p>即便做了很多风险控制，很多安全问题也不容忽视，所以在使用上有很多地方需要注意：</p><p><strong>指令要清晰。</strong> Cowork 会按照你说的去做，如果你的指令模糊或者有歧义，Claude 可能会做出你意料之外的事情，包括删除文件。</p><p><strong>提示词注入风险需要关注。</strong> 如果你让 Claude 处理来自互联网的内容，里面可能藏着恶意指令。Anthropic 虽然已经做了防御，但这个问题整个行业都还没有完美解决方案。</p><p><strong>警惕敏感操作。</strong> 不要把包含敏感信息的文件夹授权给 Claude；使用 Claude in Chrome 时，只在可信的网站上操作；留意 Claude 的可疑行为，发现异常及时中断。</p><p>虽然让普通用户“留意可疑行为”其实不太现实，因为大多数人根本不知道什么叫提示词注入。但 Cowork 至少比 Claude Code 多了一层文件系统沙箱保护，算是一个进步。</p><h2 id="怎么开始用">怎么开始用</h2><p>目前 Cowork 还是研究预览版，只对 Claude Max 订阅用户开放，月费 $100 或 $200。</p><p>使用方法很简单：下载最新版的 Claude macOS 应用（<a href="https://claude.com/download%EF%BC%89%EF%BC%8C%E6%89%93%E5%BC%80%E5%BA%94%E7%94%A8%E7%82%B9%E5%87%BB%E4%BE%A7%E8%BE%B9%E6%A0%8F%E7%9A%84">https://claude.com/download），打开应用点击侧边栏的</a> Cowork 标签，选择一个文件夹就能开始使用。</p><p>如果你不是 Max 用户，可以加入等待列表，后续会逐步开放。</p><h2 id="写在最后">写在最后</h2><p>AI Agent 正在从开发者工具走向大众工具。Claude Code 已经证明了 Agent 模式的威力，它不只可以聊天，更能真正帮你干活。但命令行的门槛把很多人挡在了外面。Cowork 把这个门槛拆掉了。</p><p>可以预测，OpenAI、Google 以及其他大模型厂商肯定会跟进推出类似的产品。</p><p>对于普通用户来说，这是一个值得关注的方向。AI 从帮你写东西进化到帮你干事情，中间隔着的就是 Agent 这一步。</p><p>至于能不能真正用起来、好不好用，那就得等更多人去探索了。毕竟这还只是一个早期的、原始的产品，还需要时间的检验。</p><hr><p>相关资源：</p><ul><li>Anthropic Cowork 发布博客：<a href="https://claude.com/blog/cowork-research-preview">https://claude.com/blog/cowork-research-preview</a></li></ul><hr><p>欢迎长按下面的二维码关注<strong>Feisky</strong> 公众号，了解更多云原生和 AI 知识。</p><p><img src="/images/mp.png" alt="Feisky 公众号二维码" loading="lazy" decoding="async"/></p>
]]></content:encoded><dc:extent>4 min read</dc:extent></item><item><title>Anthropic 万字长文：AI Agent 评估体系全解析</title><link>https://feisky.xyz/posts/2026-01-12-anthropic%E4%B8%87%E5%AD%97%E9%95%BF%E6%96%87ai-agent%E8%AF%84%E4%BC%B0%E4%BD%93%E7%B3%BB%E5%85%A8%E8%A7%A3%E6%9E%90/</link><pubDate>Mon, 12 Jan 2026 10:00:00 +0800</pubDate><dc:creator>Pengfei Ni</dc:creator><category>AI</category><category>Agent</category><category>评估</category><category>Anthropic</category><category>LLM</category><guid>https://feisky.xyz/posts/2026-01-12-anthropic%E4%B8%87%E5%AD%97%E9%95%BF%E6%96%87ai-agent%E8%AF%84%E4%BC%B0%E4%BD%93%E7%B3%BB%E5%85%A8%E8%A7%A3%E6%9E%90/</guid><description>&lt;h2 id="anthropic-万字长文ai-agent-评估体系全解析"&gt;Anthropic 万字长文：AI Agent 评估体系全解析&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;题记：本文编译自 Anthropic 工程博客《&lt;a href="https://www.anthropic.com/engineering/demystifying-evals-for-ai-agents"&gt;Demystifying evals for AI agents&lt;/a&gt;》，发表于 2026 年 1 月 9 日。原文由 Mikaela Grace、Jeremy Hadfield、Rodrigo Olivares 和 Jiri De Jonghe 撰写。本文在翻译基础上做了整理和补充，希望能帮中文读者厘清 AI Agent 评估这件事到底该怎么做。&lt;/p&gt;</description><content:encoded>&lt;![CDATA[<h2 id="anthropic-万字长文ai-agent-评估体系全解析">Anthropic 万字长文：AI Agent 评估体系全解析</h2><blockquote><p>题记：本文编译自 Anthropic 工程博客《<a href="https://www.anthropic.com/engineering/demystifying-evals-for-ai-agents">Demystifying evals for AI agents</a>》，发表于 2026 年 1 月 9 日。原文由 Mikaela Grace、Jeremy Hadfield、Rodrigo Olivares 和 Jiri De Jonghe 撰写。本文在翻译基础上做了整理和补充，希望能帮中文读者厘清 AI Agent 评估这件事到底该怎么做。</p></blockquote><p>做过 Agent 开发的朋友应该都有体会：调试 Agent 是个苦力活。</p><p>你改了个 Prompt，跑了几个 case 看起来没问题，结果上线后用户投诉说“感觉变蠢了”。你想验证到底是真的退步了还是用户错觉，却发现除了手动测几个场景，没有任何靠谱的办法。</p><p>这种“盲飞”状态，Anthropic 见得太多了。他们和很多团队合作时发现一个规律：早期靠直觉和手动测试能走挺远，但一旦 Agent 进入生产环境开始扩展，没有系统化评估就会开始出各种问题。</p><p>这篇文章就是 Anthropic 把内部实践和客户合作经验整理出来的评估指南。我自己在做 Agent 相关项目时也踩过不少坑，读完觉得挺有启发，翻译分享给大家。</p><h2 id="评估的基本概念">评估的基本概念</h2><p>先把几个基本概念说清楚。</p><p><strong>评估（eval）<strong>说白了就是给 AI 系统做测试：给它一个输入，用评分逻辑对输出打分，看它做得怎么样。本文讨论的主要是</strong>自动化评估</strong>——开发阶段不需要真实用户参与就能跑的测试。</p><p><strong>单轮评估</strong>很简单：一个提示、一个响应、一套评分逻辑。早期 LLM 主要就靠这个。但 Agent 不一样，它是多轮运行的，会调用工具、修改状态、根据中间结果动态调整。这就让评估变得复杂了。</p><p><img src="/images/4b3b8352-6bdc-455b-93bc-e12fb12d2461.webp" alt="Agent 评估结构示意图：简单评估 vs Agent 评估流程对比" loading="lazy" decoding="async"/></p><p><em>简单评估是"提示→响应→评分"。Agent 评估要复杂得多：Agent 拿到工具和任务后，会执行多轮"工具调用+推理"循环，最后通过单元测试等方式验证结果。</em></p><p>这里有个有趣的例子：Opus 4.5 在做 τ2-bench 的航班预订任务时，发现了政策里的一个漏洞，给用户找到了更好的解决方案。按评估的字面标准它“失败”了，但实际上它比标准答案更聪明。这说明 Agent 评估不能太死板，前沿模型的创造性可能超出你的预期。</p><p>为了构建 AI Agent 评估系统，Anthropic 定义了一套术语，我整理一下关键的几个：</p><ul><li><strong>任务（Task）</strong>：一个独立的测试用例，有明确的输入和成功标准</li><li><strong>试验（Trial）</strong>：对任务的一次尝试。因为模型输出有随机性，通常要跑多次</li><li><strong>评分器（Grader）</strong>：打分逻辑，一个任务可以有多个评分器</li><li><strong>转录（Transcript）</strong>：一次试验的完整记录，包括所有工具调用、推理过程、中间结果</li><li><strong>结果（Outcome）</strong>：试验结束时环境的最终状态。Agent 说"航班已预订"不算数，数据库里真的有预订记录才算</li><li><strong>评估框架（Evaluation Harness）</strong>：端到端运行评估的基础设施，负责提供指令和工具、并发运行任务、记录步骤、评分和汇总结果</li><li><strong>Agent 框架（Agent Harness）</strong>：也叫脚手架（Scaffold），让模型能作为 Agent 运行的系统。评估一个 Agent 时，实际上是在评估框架和模型的协同工作</li><li><strong>评估套件（Evaluation Suite）</strong>：一组为衡量特定能力或行为而设计的任务集合，比如客服评估套件可能测试退款、取消订单、问题升级等场景</li></ul><p><img src="/images/ec1b5ff4-e36c-40e2-af5f-f7748f65dac8.webp" alt="Agent 评估组件示意图：任务、试验、评分器、转录等核心概念" loading="lazy" decoding="async"/></p><h2 id="为什么需要评估体系">为什么需要评估体系？</h2><p>说实话，很多团队觉得评估是额外负担，会拖慢发布节奏。早期确实可以不要，手动测测、内部试用、凭直觉判断，能走挺远。</p><p>问题是，总有个临界点会到来。</p><p>典型场景是这样的：用户反馈说 Agent 改版后变差了，而你的团队两眼一抹黑，除了猜和手动验证，没有任何办法确认。调试变成了被动响应——等投诉、手动复现、修 bug、祈祷没引入新问题。你无法区分真正的退化和噪声，无法在发布前自动测试数百个场景，也无法量化改进效果。</p><p>Claude Code 的演进就是个例子。一开始是基于员工和用户反馈快速迭代的，后来才加入评估——先是简洁性、文件编辑这些局部领域，后来扩展到过度设计等更复杂的行为。评估帮助识别问题、指导改进，成了研究和产品团队协作的桥梁。</p><p>Descript 做视频编辑 Agent，他们围绕三个维度构建评估：不出错、严格遵循要求、做得好。从手动评分演进到 LLM 评分器，定期和人工校准。而 Bolt 起步晚一些，在 Agent 已经广泛使用后才开始建评估，3 个月搭了一套评估系统，包括静态分析评分、浏览器 Agent 测试应用、LLM 评委评估指令遵循等。</p><p>评估还有个隐藏价值：当更强的模型发布时，有评估的团队能快速验证、调整提示词，几天内就可以完成升级。没有评估的团队则要花数周进行手动测试。</p><p>一旦评估体系建起来，很多东西就是免费的：延迟、token 用量、成本、错误率都可以在固定任务集上持续追踪。评估的复利效应很容易被忽视，因为成本是前期可见的，收益是后期累积的。</p><h2 id="不同类型-agent-怎么评估">不同类型 Agent 怎么评估</h2><p>目前大规模部署的 Agent 主要有四类：编码 Agent、研究 Agent、计算机操作 Agent、对话 Agent。评估方法有共性，也有差异。</p><h3 id="三类评分器">三类评分器</h3><p>Agent 评估通常组合三类评分器：基于代码的、基于模型的、以及人工评分。</p><p><strong>基于代码的评分器</strong>——字符串匹配、单元测试、静态分析这些。优点是快、便宜、客观、可复现；缺点是脆弱，对有效变体不够宽容，缺乏细微判断能力。</p><p><strong>基于模型的评分器</strong>——用 LLM 做评委，基于评分标准打分、自然语言断言、成对比较等。优点是灵活、能处理开放式任务；缺点是非确定性、比代码贵、需要和人工校准。</p><p><strong>人工评分器</strong>——领域专家评审、众包判断、抽样检查。是黄金标准，但贵、慢、难以规模化。</p><p>实践中通常是组合使用。Anthropic 的建议是：尽可能用确定性评分器，必要时加 LLM 评分器，人工评分器用来校准。</p><h3 id="能力评估-vs-回归评估">能力评估 vs 回归评估</h3><p>这是两种不同目的的评估。</p><p><strong>能力评估</strong>问的是“Agent 擅长做什么”，通过率应该从较低开始，针对 Agent 难以完成的任务，让团队有一个目标可以努力提升。</p><p><strong>回归评估</strong>问的是“Agent 还能做好它以前能做的事吗”，通过率应该接近 100%，分数下降意味着出问题了。</p><p>两者要同时跑。能力评估上爬坡时，回归评估确保不会在其他地方翻车。等能力评估通过率高了，可以升级到回归套件里。</p><h3 id="编码-agent">编码 Agent</h3><p>编码 Agent 写代码、跑测试、调 bug，和人类开发者干的事差不多。评估相对简单，因为软件是可以客观验证的：代码能跑吗？测试过了吗？</p><p>SWE-bench Verified 和 Terminal-Bench 是两个常用基准。SWE-bench 给 Agent 真实的 GitHub issue，通过运行测试套件评分；Terminal-Bench 测端到端任务，比如从源码编译 Linux 内核或训练一个 ML 模型。LLM 在 SWE-bench 上的表现提升非常快，仅一年就从原来的 40% 提到了 80% 以上。</p><p>除了测试通过，对代码质量规则、工具调用方式、用户交互行为等转录进行评分通常也很有用。</p><p>比如，考虑一个编码任务，代理需要修复一个认证绕过漏洞。如下示例 YAML 文件所示，可以同时使用评分器和指标来评估该代理。</p><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#f92672">task</span>:</span></span><span style="display:flex;"><span><span style="color:#f92672">id</span>:<span style="color:#e6db74">"fix-auth-bypass_1"</span></span></span><span style="display:flex;"><span><span style="color:#f92672">desc</span>:<span style="color:#e6db74">"Fix authentication bypass when password field is empty and ..."</span></span></span><span style="display:flex;"><span><span style="color:#f92672">graders</span>:</span></span><span style="display:flex;"><span> -<span style="color:#f92672">type</span>:<span style="color:#ae81ff">deterministic_tests</span></span></span><span style="display:flex;"><span><span style="color:#f92672">required</span>: [<span style="color:#ae81ff">test_empty_pw_rejected.py, test_null_pw_rejected.py]</span></span></span><span style="display:flex;"><span> -<span style="color:#f92672">type</span>:<span style="color:#ae81ff">llm_rubric</span></span></span><span style="display:flex;"><span><span style="color:#f92672">rubric</span>:<span style="color:#ae81ff">prompts/code_quality.md</span></span></span><span style="display:flex;"><span> -<span style="color:#f92672">type</span>:<span style="color:#ae81ff">static_analysis</span></span></span><span style="display:flex;"><span><span style="color:#f92672">commands</span>: [<span style="color:#ae81ff">ruff, mypy, bandit]</span></span></span><span style="display:flex;"><span> -<span style="color:#f92672">type</span>:<span style="color:#ae81ff">state_check</span></span></span><span style="display:flex;"><span><span style="color:#f92672">expect</span>:</span></span><span style="display:flex;"><span><span style="color:#f92672">security_logs</span>: {<span style="color:#f92672">event_type</span>:<span style="color:#e6db74">"auth_blocked"</span>}</span></span><span style="display:flex;"><span> -<span style="color:#f92672">type</span>:<span style="color:#ae81ff">tool_calls</span></span></span><span style="display:flex;"><span><span style="color:#f92672">required</span>:</span></span><span style="display:flex;"><span> - {<span style="color:#f92672">tool</span>:<span style="color:#f92672">read_file, params</span>: {<span style="color:#f92672">path</span>:<span style="color:#e6db74">"src/auth/*"</span>}}</span></span><span style="display:flex;"><span> - {<span style="color:#f92672">tool</span>:<span style="color:#ae81ff">edit_file}</span></span></span><span style="display:flex;"><span> - {<span style="color:#f92672">tool</span>:<span style="color:#ae81ff">run_tests}</span></span></span><span style="display:flex;"><span><span style="color:#f92672">tracked_metrics</span>:</span></span><span style="display:flex;"><span> -<span style="color:#f92672">type</span>:<span style="color:#ae81ff">transcript</span></span></span><span style="display:flex;"><span><span style="color:#f92672">metrics</span>:</span></span><span style="display:flex;"><span> -<span style="color:#ae81ff">n_turns</span></span></span><span style="display:flex;"><span> -<span style="color:#ae81ff">n_toolcalls</span></span></span><span style="display:flex;"><span> -<span style="color:#ae81ff">n_total_tokens</span></span></span><span style="display:flex;"><span> -<span style="color:#f92672">type</span>:<span style="color:#ae81ff">latency</span></span></span><span style="display:flex;"><span><span style="color:#f92672">metrics</span>:</span></span><span style="display:flex;"><span> -<span style="color:#ae81ff">time_to_first_token</span></span></span><span style="display:flex;"><span> -<span style="color:#ae81ff">output_tokens_per_sec</span></span></span><span style="display:flex;"><span> -<span style="color:#ae81ff">time_to_last_token</span></span></span></code></pre></div><p>实践中，编码评估通常就是单元测试加 LLM 代码质量评分，只有在需要时才会添加额外的评分器和指标。</p><h3 id="对话-agent">对话 Agent</h3><p>对话 Agent 在客服、销售或者辅导这些场景和用户交互。跟编码 Agent 不同，交互本身的质量也是评估内容的一部分。</p><p>对话 Agent 的成功可以是多维度的：工单解决了吗？在 10 轮内完成了吗？语气恰当吗？τ-Bench 和 τ2-Bench 就是这样设计的，用一个模型扮演用户，另一个是被测 Agent，模拟真实场景。</p><p>对话 Agent 评估通常需要第二个 LLM 模拟用户，这和其他类型不太一样。</p><p>比如，对于客服任务，Agent 需要为一位沮丧的客户处理退款，评估可以这么设计：</p><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#f92672">graders</span>:</span></span><span style="display:flex;"><span> -<span style="color:#f92672">type</span>:<span style="color:#ae81ff">llm_rubric</span></span></span><span style="display:flex;"><span><span style="color:#f92672">rubric</span>:<span style="color:#ae81ff">prompts/support_quality.md</span></span></span><span style="display:flex;"><span><span style="color:#f92672">assertions</span>:</span></span><span style="display:flex;"><span> -<span style="color:#e6db74">"Agent showed empathy for customer's frustration"</span></span></span><span style="display:flex;"><span> -<span style="color:#e6db74">"Resolution was clearly explained"</span></span></span><span style="display:flex;"><span> -<span style="color:#e6db74">"Agent's response grounded in fetch_policy tool results"</span></span></span><span style="display:flex;"><span> -<span style="color:#f92672">type</span>:<span style="color:#ae81ff">state_check</span></span></span><span style="display:flex;"><span><span style="color:#f92672">expect</span>:</span></span><span style="display:flex;"><span><span style="color:#f92672">tickets</span>: {<span style="color:#f92672">status</span>:<span style="color:#ae81ff">resolved}</span></span></span><span style="display:flex;"><span><span style="color:#f92672">refunds</span>: {<span style="color:#f92672">status</span>:<span style="color:#ae81ff">processed}</span></span></span><span style="display:flex;"><span> -<span style="color:#f92672">type</span>:<span style="color:#ae81ff">tool_calls</span></span></span><span style="display:flex;"><span><span style="color:#f92672">required</span>:</span></span><span style="display:flex;"><span> - {<span style="color:#f92672">tool</span>:<span style="color:#ae81ff">verify_identity}</span></span></span><span style="display:flex;"><span> - {<span style="color:#f92672">tool</span>:<span style="color:#f92672">process_refund, params</span>: {<span style="color:#f92672">amount</span>:<span style="color:#e6db74">"&lt;=100"</span>}}</span></span><span style="display:flex;"><span> - {<span style="color:#f92672">tool</span>:<span style="color:#ae81ff">send_confirmation}</span></span></span><span style="display:flex;"><span> -<span style="color:#f92672">type</span>:<span style="color:#ae81ff">transcript</span></span></span><span style="display:flex;"><span><span style="color:#f92672">max_turns</span>:<span style="color:#ae81ff">10</span></span></span><span style="display:flex;"><span><span style="color:#f92672">tracked_metrics</span>:</span></span><span style="display:flex;"><span> -<span style="color:#f92672">type</span>:<span style="color:#ae81ff">transcript</span></span></span><span style="display:flex;"><span><span style="color:#f92672">metrics</span>:</span></span><span style="display:flex;"><span> -<span style="color:#ae81ff">n_turns</span></span></span><span style="display:flex;"><span> -<span style="color:#ae81ff">n_toolcalls</span></span></span><span style="display:flex;"><span> -<span style="color:#ae81ff">n_total_tokens</span></span></span><span style="display:flex;"><span> -<span style="color:#f92672">type</span>:<span style="color:#ae81ff">latency</span></span></span><span style="display:flex;"><span><span style="color:#f92672">metrics</span>:</span></span><span style="display:flex;"><span> -<span style="color:#ae81ff">time_to_first_token</span></span></span><span style="display:flex;"><span> -<span style="color:#ae81ff">output_tokens_per_sec</span></span></span><span style="display:flex;"><span> -<span style="color:#ae81ff">time_to_last_token</span></span></span></code></pre></div><p>实践中，对话 Agent 的评估通常使用基于模型的评分器来评估交流质量和目标达成情况，因为许多任务可能有多个正确答案。</p><h3 id="研究-agent">研究 Agent</h3><p>研究 Agent 收集信息、综合分析、产出报告。这类评估最难，因为“好”是主观的。什么算“全面”、“有据可查”甚至“正确”？这都取决于具体场景：市场调研、收购尽职调查和科学报告各自有不同的标准。</p><p>BrowseComp 是个有意思的基准，其问题设计成容易验证但难以解决，专门用来测试 Agent 能不能在开放网络里大海捞针。</p><p>研究 Agent 评估要组合多种检查：基础性检查（声明有来源支持吗）、覆盖度检查（关键事实都包含了吗）、来源质量检查（来源权威吗）。鉴于研究质量的主观性，LLM 评分标准要经常和人类专家校准，以便有效评估这些 Agent 。</p><h3 id="计算机操作-agent">计算机操作 Agent</h3><p>计算机操作 Agent 就跟人类一样，通过屏幕截图、鼠标点击、键盘输入和滚动来操作软件。它的评估要在真实或沙盒环境运行，让其使用软件应用，并检查是否达成预期结果。</p><p>比如，WebArena 就是一个专门用来测试浏览器任务的评估标准，通过 URL 和页面状态检查导航是否正确，并对修改数据的任务进行后端状态核实（确认订单确实已下单，而不仅仅是出现了确认页面）。OSWorld 将其扩展到完整的操作系统控制。</p><p>浏览器 Agent 有个取舍：DOM 交互快但费 token，截图交互慢但省 token。Claude for Chrome 专门做了评估来检查 Agent 是不是在正确场景选择了正确工具，以便能够更快、更准确地完成浏览任务。</p><h3 id="处理非确定性">处理非确定性</h3><p>Agent 行为在不同运行中都会有所不同，这让评估结果比看起来更难解读。同一个任务可能这次通过、下次就挂了；或者这次成功率 90%，而下次只有 50%。</p><p>有两个指标可以帮助捕捉这些细微差别：</p><p><strong>pass@k</strong>：衡量 k 次尝试中至少一次成功的概率。k 越大，分数越高。pass@1 就是第一次就成功的概率，编码场景通常最关心这个。</p><p><strong>pass^k</strong>：衡量所有 k 次尝试全部成功的概率。k 越大，分数越低。如果 Agent 每次有 75% 成功率，跑 3 次全过的概率是 (0.75)³ ≈ 42%。面向用户的 Agent 特别关心这个，因为用户期望每次都可靠。</p><p><img src="/images/46efdf85-a4d6-41ca-8fe4-6f6077336257.webp" alt="pass@k 和 pass^k 指标对比图：随着 k 增大的变化趋势" loading="lazy" decoding="async"/></p><p><em>k=1 时两个指标相同。到 k=10，pass@k 接近 100%，pass^k 降到 0%。选哪个取决于产品需求。</em></p><h2 id="从-0-到-1-的实操路线图">从 0 到 1 的实操路线图</h2><p>这部分是 Anthropic 的实践建议，我觉得挺实用的，逐条说说。</p><h3 id="收集任务">收集任务</h3><p><strong>尽早开始，不要等完美。</strong> 很多团队觉得需要几百个任务才能开始，实际上 20-50 个从真实失败里提取的简单任务就够了。早期每次改动效果明显，小样本量就能检测到。评估拖得越久越难，早期产品需求自然转化为测试用例，等太久就得从线上系统反向推导成功标准了。</p><p><strong>从手动测试的内容开始。</strong> 你每次发布前验证的行为、用户常用的场景、bug 追踪器和客服工单里的问题——这些都是现成的测试用例来源。按用户影响优先排序，有助于你把精力投入到最关键的地方。</p><p><strong>任务要有明确参考答案。</strong> 好任务是两个领域专家独立看，会得出相同的通过/失败判定。任务里的歧义会变成指标噪声。每个任务都应该可以被正确遵循指令的 Agent 完成。评分者检查的所有内容都应该在任务描述中明确说明；Agent 不应该因为规范不清而失败。对于前沿模型来说，在多次尝试中通过率为 0%（即 0% pass@100）通常意味着任务本身有问题，而不是 Agent 能力不足。每个任务配一个参考解决方案，证明任务可解、评分器配置正确。</p><p><strong>构建平衡的问题集。</strong> 测应该做的情况，也测不应该做的情况，这两者应该平衡。只测 Agent 应该搜索的情况，可能最终得到一个什么都搜索的 Agent。Anthropic 在做 Claude.ai 网络搜索评估时就踩过这个坑，在触发不足和触发过度之间找平衡花了好几轮迭代。</p><h3 id="设计评分器">设计评分器</h3><p><strong>环境要稳定隔离。</strong> 评估中的 Agent 要和生产环境大致相同，每次试验从干净环境开始。残留文件、缓存、资源耗尽这些共享状态会引入噪声。Anthropic 有次发现 Claude 在某些任务上分数异常高，原因是它检查了之前试验的 git 历史——这就是环境隔离没做好。</p><p><strong>评估结果而非路径。</strong> 人们通常本能地想要检查 Agent 是否按照非常具体的步骤操作，比如按正确顺序调用工具。Anthropic 发现这太死板了，Agent 经常找到设计者没预料到的有效方法。为了不无谓地限制创造力，更好的做法是评估 Agent 得产出，而不是它采取的路径。</p><p><strong>加入部分得分。</strong> 对于包含多个环节的任务，应设置部分得分。比如客服 Agent 正确识别了问题、验证了客户身份，但没能处理退款，这明显比直接失败的好。在结果中体现这种成功的连续性非常重要。</p><p><strong>小心评估本身的 bug。</strong> Opus 4.5 最初在 CORE-Bench 上得分 42%，后来发现是评分器问题：期望96.124991&hellip;却对 96.12 判错、任务规格模糊、随机任务无法复现。修复后分数一下就跳到了 95%。仔细复查任务和评分器有助于避免这些问题，并注意让你的评分具备防止绕过或破解的能力。Agent 不应该轻易作弊通过评估。</p><h3 id="长期维护">长期维护</h3><p><strong>读转录轨迹。</strong> 这点很重要。除非你读了很多试验的轨迹和评分，否则你无法知道评分器是不是在正常工作。任务失败时，轨迹告诉你 Agent 是真的错了，还是评分器拒绝了有效解决方案。</p><p><strong>监控饱和度。</strong> 100% 通过的评估只能追踪回归，不能提供改进信号。比如 SWE-Bench 分数今年从 30% 涨到了 80%+，已经快饱和了。Qodo 最初觉得 Opus 4.5 一般，后来发现是他们的评估不够难，没能捕捉到复杂任务上的提升。</p><p><strong>让更多人贡献评估。</strong> 评估套件是一个需要持续关注和明确归属的动态工具，Anthropic 推荐采用评测驱动的开发方式：在 Agent 具备相关能力前，先构建评测来定义预期能力，然后不断迭代，直到智能体表现良好。而对于评估来说，最接近产品需求和用户的人最有资格定义成功。在 Anthropic，产品经理、客户成功经理甚至销售通过 Claude Code 就能以 PR 形式贡献评估任务。</p><p><img src="/images/a02f1942-9484-4b00-92c3-84b5680ffc57.webp" alt="创建有效评估的流程图：从收集任务到持续维护" loading="lazy" decoding="async"/></p><h2 id="评估不是万能的">评估不是万能的</h2><p>自动化评估能在不影响用户的情况下跑成千上万个任务，但这只是理解 Agent 表现的众多方式之一。完整的图景还包括生产监控、用户反馈、A/B 测试、手动轨迹审查、系统性人工评估。</p><p>每种方法有各自的优劣和适用阶段：</p><ul><li>自动化评估——上线前和 CI/CD 的第一道防线，每次改动都跑</li><li>生产监控——上线后检测分布漂移和意外失败</li><li>A/B 测试——有足够流量后验证重大改动</li><li>用户反馈和轨迹审查——持续填补空白</li><li>系统性人工研究——校准 LLM 评分器、评估主观输出</li></ul><p><img src="/images/870c9eeb-2a05-4736-96f4-a478b266156e.webp" alt="瑞士奶酪模型：多层评估方法互相补位" loading="lazy" decoding="async"/></p><p><em>这就像安全工程的瑞士奶酪模型——没有单一方法能捕捉所有问题，多层组合才能互相补位。</em></p><h2 id="写在最后">写在最后</h2><p>没有评估的团队会陷入被动循环——修一个问题引入另一个，分不清退化和噪声。有评估的团队发现相反的情况：失败变成测试用例，测试用例防止回归，指标取代猜测。</p><p>Anthropic 总结的原则：</p><ul><li>尽早开始，不要等完美</li><li>从真实失败中获取任务</li><li>定义明确的成功标准</li><li>组合多种评分器</li><li>确保问题足够难</li><li>持续迭代提高信噪比</li><li>一定要读转录轨迹</li></ul><p>如果不想从零搭基础设施，这几个框架可以考虑：</p><ul><li><strong><a href="https://harborframework.com/">Harbor</a></strong>：专为容器化环境设计，支持跨云厂商大规模跑试验</li><li><strong><a href="https://www.promptfoo.dev/">Promptfoo</a></strong>：轻量开源，YAML 配置，Anthropic 自己也在用</li><li><strong><a href="https://www.braintrust.dev/">Braintrust</a></strong>：离线评估+生产可观测性+实验追踪一体</li><li><strong><a href="https://docs.langchain.com/langsmith/evaluation">LangSmith</a></strong>：和 LangChain 生态紧密集成</li><li><strong><a href="https://langfuse.com/">Langfuse</a></strong>：自托管开源方案，适合有数据驻留要求的团队</li></ul><p>需要注意的是，框架可以加快起步，但最终效果取决于你用于评估任务的质量。建议尽快选定一个框架，将精力集中在高质量测试用例和评分器的迭代上。AI Agent 评估仍是新兴领域，发展迅速，评估方法需根据实际情况不断调整。</p><hr><p><strong>相关资源：</strong></p><ul><li>原文链接：<a href="https://www.anthropic.com/engineering/demystifying-evals-for-ai-agents">https://www.anthropic.com/engineering/demystifying-evals-for-ai-agents</a></li><li>构建高效的 AI 代理系统：<a href="https://www.anthropic.com/engineering/building-effective-agents">https://www.anthropic.com/engineering/building-effective-agents</a></li><li>Agent SDK 文档：<a href="https://platform.claude.com/docs/en/agent-sdk/overview">https://platform.claude.com/docs/en/agent-sdk/overview</a></li><li>SWE-bench Verified：<a href="https://www.swebench.com/SWE-bench/">https://www.swebench.com/SWE-bench/</a></li><li>Terminal-Bench：<a href="https://www.tbench.ai/">https://www.tbench.ai/</a></li></ul><hr><p>欢迎长按下面的二维码关注<strong>Feisky</strong> 公众号，了解更多云原生和 AI 知识。</p><p><img src="/images/mp.png" alt="Feisky 公众号二维码" loading="lazy" decoding="async"/></p>
]]></content:encoded><dc:extent>13 min read</dc:extent></item></channel></rss>