Files
git-learn/knowledge-index.html
T

299 lines
64 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>知识库索引 — github-learn</title>
<style>
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Noto Sans SC",sans-serif;background:#f8fafc;color:#1e293b;line-height:1.7}
.wrapper{max-width:900px;margin:0 auto;padding:0 20px}
header{background:linear-gradient(135deg,#0f172a 0%,#1e3a5f 100%);color:#f1f5f9;padding:48px 0 40px;margin-bottom:40px}
header h1{font-size:1.6rem;font-weight:700;margin-bottom:6px}
header .sub{font-size:.85rem;color:#94a3b8}
.search-bar{margin-bottom:12px}
.search-bar input{width:100%;padding:12px 16px;border:2px solid #e2e8f0;border-radius:8px;font-size:.95rem;outline:none;transition:border-color .2s;font-family:inherit}
.search-bar input:focus{border-color:#3b82f6}
.filter-row{display:flex;align-items:center;gap:10px;margin-bottom:24px;flex-wrap:wrap}
.filter-row label{font-size:.85rem;color:#64748b;font-weight:600}
.filter-row select{padding:8px 12px;border:1px solid #cbd5e1;border-radius:8px;background:#fff;color:#1e293b;font-size:.88rem;font-family:inherit;outline:none}
.filter-row select:focus{border-color:#3b82f6;box-shadow:0 0 0 3px rgba(59,130,246,.12)}
.clear-filters{padding:8px 12px;border:1px solid #cbd5e1;border-radius:8px;background:#fff;color:#475569;font-size:.88rem;font-family:inherit;cursor:pointer;transition:all .15s}
.clear-filters:hover{background:#f1f5f9;border-color:#94a3b8;color:#1e293b}
.clear-filters:focus{outline:none;border-color:#3b82f6;box-shadow:0 0 0 3px rgba(59,130,246,.12)}
.no-results{text-align:center;padding:40px 20px;color:#94a3b8;display:none}
.no-results.visible{display:block}
.tag-cloud{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:32px}
.tag-badge{background:#eff6ff;color:#1d4ed8;border:1px solid #bfdbfe;padding:4px 12px;border-radius:16px;font-size:.8rem;cursor:pointer;user-select:none;transition:all .15s}
.tag-badge:hover{background:#dbeafe;border-color:#93c5fd}
.tag-badge.active{background:#1d4ed8;color:#fff;border-color:#1d4ed8}
.tag-badge .count{font-size:.7rem;opacity:.7;margin-left:2px}
.entries{margin-bottom:48px}
.entry-card{background:#fff;border:1px solid #e2e8f0;border-radius:10px;padding:22px 24px;margin-bottom:16px;transition:box-shadow .15s}
.entry-card:hover{box-shadow:0 2px 12px rgba(0,0,0,.06)}
.entry-card.hidden{display:none}
.entry-header{display:flex;justify-content:space-between;align-items:baseline;flex-wrap:wrap;gap:8px;margin-bottom:8px}
.entry-title{font-size:1.15rem;font-weight:700;color:#0f172a}
.entry-date{font-size:.8rem;color:#94a3b8}
.entry-meta{font-size:.8rem;color:#64748b;margin-bottom:10px}
.entry-tags{display:flex;flex-wrap:wrap;gap:5px;margin-bottom:10px}
.entry-tags .mini-tag{background:#f1f5f9;color:#475569;padding:2px 8px;border-radius:10px;font-size:.73rem;cursor:pointer;transition:all .12s}
.entry-tags .mini-tag:hover{background:#e2e8f0}
.entry-tags .mini-tag.match{background:#fef3c7;color:#92400e}
.entry-body{font-size:.88rem;color:#475569;line-height:1.65;max-height:100px;overflow:hidden;position:relative}
.entry-body::after{content:'';position:absolute;bottom:0;left:0;right:0;height:30px;background:linear-gradient(transparent,#fff)}
.related-section{margin-top:12px;padding-top:10px;border-top:1px dashed #e2e8f0;font-size:.8rem}
.related-section .related-label{color:#94a3b8;margin-bottom:4px}
.related-section a{color:#3b82f6;text-decoration:none;margin-right:8px;cursor:pointer}
.related-section a:hover{text-decoration:underline}
mark{background:#fde68a;color:#1e293b;padding:0 2px;border-radius:2px}
footer{text-align:center;padding:24px 0;border-top:1px solid #e2e8f0;color:#94a3b8;font-size:.8rem;margin-top:20px}
@media(max-width:640px){header h1{font-size:1.3rem}.entry-card{padding:16px}}
</style>
</head>
<body>
<header>
<div class="wrapper">
<h1>知识库索引</h1>
<div class="sub">github-learn · 共 <span id="entry-count">0</span> 条知识条目</div>
</div>
</header>
<div class="wrapper" id="content-area">
<div class="search-bar">
<input type="text" id="search-input" placeholder="搜索标题、标签或正文..." autocomplete="off">
</div>
<div class="filter-row">
<label for="year-filter">年份</label>
<select id="year-filter"><option value="">全部年份</option></select>
<button type="button" class="clear-filters" id="clear-filters">清空筛选</button>
</div>
<div class="no-results" id="no-results">没有找到匹配的条目</div>
<div class="tag-cloud" id="tag-cloud"></div>
<div class="entries" id="entries"></div>
<footer>
由 scripts/update-knowledge-index.sh 生成 · <span id="gen-time"></span>
</footer>
</div>
<script>
const ENTRIES = [
{ slug: 'Waza', path: 'knowledge/entries/knowledge_20260417_Waza', date: '20260417', title: 'Waza — 把工程师的习惯变成 Claude 可执行的技能', author: '叫我小杨同学的小码酱', tags: ['Claude Code', 'Skills', 'AI 辅助开发', '工程习惯', 'tw93'], body: ' # Waza:你知道的工程习惯,变成 Claude 能跑的技能 > **一句话核心**:Waza(技)把优秀工程师的思维方式打包成 8 个 Claude Code 技能 —— 不是替你写代码更快,而是逼你想清楚再动手。 > > **认知挂钩**:像道场里的型(Kata)。每个技能是一个固定套路,练到变成肌肉记忆。 > > **真理锚点**:*"AI makes you faster. It doesn\'t make you think more clearly."* ## 模块 0:核心摘要 (TL;DR) Waza 是开发者 **tw93** 开源的 Claude Code 技能集(3.3k+ Stars),将 8 个核心工程习惯封装为 `/` 斜杠命令。它不追求"全能",而是聚焦**真正重要的习惯**:先思考再动手、写完自己审、bug 系统排查、界面有审美、文章写得顺、新领域靠输出学、文档当一手资料读、开发环境定期体检。 **生活类比**:不是给你一把更快的锤子,而是教你先看图纸、再选工具、最后才敲。 ## 模块 1:概念破冰 ### 巧记卡片 <div class="mnemonic-card"> **八字口诀**:**思设审猎,写学读健** | 字 | 技能 | 阶段 | |---|---|---| | **思** | `/think` | 动手前:挑战问题、压力测试设计 | | **设** | `/design` | 做界面:产出有辨识度的 UI | | **审** | `/check` | 合并前:自审 diff、标记危险操作 | | **猎** | `/hunt` | 出 bug 时:系统调试、确认根因再修 | | **写** | `/write` | 写文档:中英双语自然表达 | | **学** | `/learn` | 新领域:六阶段研究 → 输出 → 自审 → 发布 | | **读** | `/read` | 读资料:URL/PDF 转干净 Markdown | | **健** | `/health` | 定期体检:CLAUDE.md、rules、skills、hooks、MCP | </div> ### 故事引入 想象两个工程师。 A 接到需求直接写代码,写完直接提交。遇到 bug 就猜,试十个地方碰巧修好。文档写得像机翻。 B 接到需求先问:这个问题真的存在吗?有没有更简单的解法?写完代码自己过一遍 diff。遇到 bug 不猜,先复现、定位、确认根因再修。文档写得连外行都能懂。 AI 让 A 写得更快了,但还是 A。AI 让 B 变成了超级 B。 Waza 就是给 B 准备的那套工具。 ### 架构概览 ``` ┌─────────────────────────────────────────────────┐ │ Waza 技能矩阵 │ ├─────────────────────────────────────────────────┤ │ │ │ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ │ │ │/think │→ │/design│→ │/check │ │/hunt │ │ │ │ 思考 │ │ 设计 │ │ 审查 │ │ 调试 │ │ │ └───────┘ └───────┘ └───────┘ └───────┘ │ │ ↑ ↑ │ │ │ ┌───────┐ │ │ │ └────────│/write │───────────┘ │ │ │ 写作 │ │ │ └───────┘ │ │ │ │ ┌───────┐ ┌───────┐ ┌───────┐ │ │ │/learn │ │ /read │ │/health│ │ │ │ 学习 │ │ 阅读 │ │ 体检 │ │ │ └───────┘ └───────┘ └───────┘ │ │ 输入 ──────→ 转化 ──────→ 输出 │ │ │ └─────────────────────────────────────────────────┘ ``` ## 模块 2:深度解析 ### 哲学:为什么是"习惯"而不是"规则"? Waza 的名字来自日语"技"(わざ),武道中意为"练到成本能的招式"。这与市面上大多数 AI 技能包有根本区别: **规则驱动 vs 习惯驱动** | 维度 | 规则驱动(Superpowers/gstack 类) | 习惯驱动(Waza) | |---|---|---| | 指令风格 | 大量 detailed rules,步步规定 | 设目标 + 约束,然后放手 | | 模型上限 | 指令写多少,模型做多少——指令成了天花板 | 约束关键边界,其余让模型自由发挥 | | 模型进化 | 模型变强后,旧规则可能变成束缚 | 模型变强,自由度带来的收益呈复利增长 | | 学习曲线 | 陡峭,配置多 | 扁平,每个技能一个触发场景 | **核心洞察**:作者写下的每一条规则都成了模型能力的天花板。Waza 反其道而行——每个技能设明确目标,退后一步让模型发挥。 ### 8 个技能的工程生命周期 ```mermaid flowchart TD A["开始新任务"] --> B["/read: 读取相关文档、RFC、PR"] B --> C["/think: 挑战问题本身,验证架构"] C --> D{"前端界面?"} D -->|"是"| E["/design: 产出有审美的 UI"] D -->|"否"| F["编码实现"] E --> F F --> G{"遇到 bug?"} G -->|"是"| H["/hunt: 系统调试,确认根因"] G -->|"否"| I["/check: 自审 diff"] H --> I I --> J{"写作/文档?"} J -->|"是"| K["/write: 润色中英双语"] J -->|"否"| L["完成"] K --> L M["定期"] --> N["/health: 体检 Claude 环境"] O["遇到新领域"] --> P["/learn: 六阶段研究"] ``` ### 逐技能拆解 #### 1. `/think` — 先想清楚,再动手 **触发**:开始任何新任务之前。 **做什么**:挑战问题本身。需求是真的吗?有没有更简单的解法?架构有没有隐患? **核心价值**:防止"用正确的方式做错误的事"——这是工程师最常见的浪费。 #### 2. `/design` — 界面要有辨识度 **触发**:构建前端界面时。 **做什么**:产出有明确审美方向的 UI,不是千篇一律的默认样式。 **核心价值**:AI 默认生成"能用但丑"的界面。这个技能逼 Claude 做出有设计感的东西。 #### 3. `/check` — 合并前的最后一道关 **触发**:完成任务后、合并代码前。 **做什么**:审查 diff,自动修复安全的问题,标记危险命令,用证据说话。 **核心价值**:像老工程师坐在你旁边 review——但比你主动。支持并行多专家审查(宿主环境支持时)。 #### 4. `/hunt` — 系统调试,不靠猜 **触发**:任何 bug 或异常行为。 **做什么**:先复现,再定位,确认根因后才修。 **核心价值**:工程师最容易犯的错——看到 bug 就猜。猜 10 次碰巧修了 1 次,剩下 9 次埋了新雷。 #### 5. `/write` — 像人一样写文章 **触发**:撰写或编辑文档。 **做什么**:重写中英双语,去掉生硬公式化表达。 **核心价值**:AI 生成的文档读起来像翻译腔。这个技能让文字有"人味"。 #### 6. `/learn` — 六阶段研究法 **触发**:深入不熟悉的领域。 **流程**:收集 → 消化 → 大纲 → 填充 → 精炼 → 自审 → 发布。 **核心价值**:学习新领域靠产出驱动,而不是消费内容。先写再改再发。 #### 7. `/read` — 把一切变成干净 Markdown **触发**:任何 URL 或 PDF。 **做什么**:抓取内容转为干净 Markdown,特殊处理 GitHub、PDF、微信、飞书。 **核心价值**:省去手动复制粘贴和格式清理的时间。 #### 8. `/health` — Claude 环境的体检报告 **触发**:审计 Claude Code 设置时。 **检查项**:CLAUDE.md、rules、skills、hooks、MCP、行为表现。 **核心价值**:按严重程度分级标记问题,防止配置腐烂。基于作者的[六层框架](https://tw93.fun/en/2026-03-12/claude.html)。 ### 项目起源与数据 Waza 不是凭空设计的。它来自真实项目的失败积累: - 找错代码路径,来回 4 轮才定位 - 发布 release 前忘了上传 artifacts - 服务器重启 8 次都没看报错信息 **30 天、300+ 次会话、7 个项目、500 小时** —— 每个 "gotcha" 都对应一次真实失败。 ## 模块 3:深度裂变 <div class="fission-section"> ### 矛盾分析 & 常识颠覆 #### 1. "不完整是设计出来的" > Waza 只有 8 个技能。不是做不到更多,而是**刻意不做完**。 市面上的 AI 技能包动辄几十个技能,每个覆盖一个小场景。Waza 反其道:**八个习惯,每个做一件事,有明确触发条件,然后让路**。 **核爆级结论**:对 AI 工具来说,"够用"比"全能"更有价值。因为每个技能都是独立可调用的,组合起来覆盖工作流全链路,但每个单独调用时负担极小。 #### 2. "每条规则都是天花板" > 作者写的每一条规则,都成了模型能力的上限。 这是 Waza 最反直觉的设计哲学。传统做法是"把所有规则写进 prompt",但这隐含一个假设:作者比模型聪明。Waza 的做法是"设目标 + 约束,然后放手"——等模型变强了,自由度带来的收益会呈复利。 **搜索内化**:在 2026 年的 AI 辅助开发社区中,"less prompt engineering, more outcome-driven constraints" 正成为新共识。Waza 是这一理念的极端实践者。 #### 3. "英文推理更强"的隐性红利 > 项目专门提供了 English Coaching 规则,建议用英文与 AI 交互。 理由很朴素:大多数 AI 模型的英文训练量远超其他语言。母语写 prompt → 隐形翻译层 → 推理质量打折。切换英文后,回答更精准,顺便练英语。 **争议点**:这对非英语母语用户有门槛。Waza 的做法是**不强求**,但提供工具(`english.md` 规则)让 Claude 在英文交互时即时纠错。 </div> ## 模块 4:实战指南 ### 如何开始 ```bash # 一步安装所有技能(Claude Code) npx skills add tw93/Waza -a claude-code -g -y # 一步安装所有技能(Codex) npx skills add tw93/Waza -a codex -g -y # 可选:安装 statusline 显示上下文用量 curl -sL https://raw.githubusercontent.com/tw93/Waza/main/scripts/setup-statusline.sh | bash # 可选:安装英文教练规则 mkdir -p ~/.claude/rules && curl -fsSL https://raw.githubusercontent.com/tw93/Waza/main/rules/english.md -o ~/.claude/rules/english.md ``` ### 推荐工作流 ``` 需求来了 → /think 先挑战问题 → /read 读取相关文档 → 编码(前端先 /design) → 遇到 bug → /hunt → 写完 → /check 自审 → 写文档 → /write 润色 → 新领域 → /learn 研究 → 定期 → /health 体检 ``` ### 避坑指南 | 反模式 | 后果 | 正确做法 | |---|---|---| | 跳过 `/think` 直接写 | 做了错误的事,返工成本高 | 再急也先想 5 分钟 | | `/hunt` 时直接猜修复 | 埋新雷 | 先复现,确认根因 | | 不看 `/check` 结果就合并 | 危险命令进主干 | 审查完再合 | | 装了技能从不调用 | 形同虚设 | 养成肌肉记忆,每次任务触发对应技能 | | 忽略 `/health` | 配置逐渐腐烂 | 每周跑一次 | ### ROI 分析 | 投入 | 回报 | |---|---| | 安装 5 分钟 | 每个任务避免至少 1 次返工 | | `/think` 多花 5 分钟 | 可能省下 2 小时重写 | | `/check` 多花 2 分钟 | 避免线上事故 | | `/learn` 多花 30 分钟 | 产出 > 消费 10 倍效率 | ## 模块 5:温故知新 ### FAQ <details> <summary><b>Q1: Waza 和其他 Claude Code 技能包(如 Superpowers、gstack)有什么区别?</b></summary> <p>Superpowers 和 gstack 功能更全但更重——技能多、配置多、学习曲线陡。Waza 只做 8 个最核心的习惯,每个一件事,触发条件清晰。哲学不同:规则驱动 vs 习惯驱动。</p> </details> <details> <summary><b>Q2: 只能在 Claude Code 里用吗?</b></summary> <p>不。<code>/health</code> 是 Claude Code 独有的(需要检查环境)。其余 7 个技能使用宿主环境的原生 question/search/fetch/agent 机制,也支持 Codex。</p> </details> <details> <summary><b>Q3: 这些技能是固定死的吗?可以自己改吗?</b></summary> <p>每个技能是一个文件夹(不只是 Markdown 文件),包含参考文档、辅助脚本、gotchas。你可以 fork 后按需修改。MIT 协议。</p> </details> <details> <summary><b>Q4: Waza 适合什么水平的开发者?</b></summary> <p>有工程经验但想更系统化的开发者。如果你已经有这些习惯,Waza 帮你自动化。如果你还没有,Waza 逼你养成。</p> </details> <details> <summary><b>Q5: "Waza" 这个名字怎么念?</b></summary> <p>日语「技」(わざ / waza),发音类似 "哇扎"。在武道中指"练到成本能的招式"。</p> </details> <details> <summary><b>Q6: 作者 tw93 是谁?</b></summary> <p>活跃在 GitHub 和 Twitter 的独立开发者,也是 MiaoYan 等项目的作者。养了两只猫:汤圆和可乐。</p> </details> <details> <summary><b>Q7: 最新版本是什么?</b></summary> <p>截至 2026-04-17,最新版本为 V3.10.0,包含 252 次 commits,3.3k+ stars,202 forks。</p> </details> <details> <summary><b>Q8: 怎么卸载?</b></summary> <pre><code># 移除所有技能 npx skills remove tw93/Waza -g # 移除 statusline rm -f ~/.claude/statusline.sh # 然后从 ~/.claude/settings.json 中删除 statusLine 键 # 移除英文教练 rm -f ~/.claude/rules/english.md</code></pre> </details> ### 自测题 1. **理解层**:Waza 的核心哲学是什么?为什么"不完整是设计出来的"? 2. **记忆层**:8 个技能分别是什么?各自在什么场景触发? 3. **分析层**:如果跳过 `/think` 直接编码,最大的风险是什么?请举一个你经历过的例子。 4. **应用层**:你接手一个全新项目,描述从接到需求到合并代码的完整 Waza 工作流。 5. **批判层**:Waza 只有 8 个技能。你觉得缺了什么?为什么作者可能故意不做? 6. **迁移层**:你如何在现有工作流中引入 Waza 技能?哪些最容易养成习惯?哪些最难? 7. **创造层**:如果你要给 Waza 贡献第 9 个技能,会是什么?写一个简短的 SKILL.md 大纲。 ### 参考资源 - [tw93/Waza GitHub 仓库](https://github.com/tw93/Waza) - [作者博客:Claude Code 六层框架](https://tw93.fun/en/2026-03-12/claude.html) - [Waza 演示推文](https://x.com/HiTw93/status/2041312649510822103) ' },
{ slug: 'mattpocock_skills', path: 'knowledge/entries/knowledge_20260518_mattpocock_skills', date: '20260518', title: 'mattpocock/skills 深度解析:AI Agent 工作流的工程化革命', author: '叫我小杨同学的小码酱', tags: ['Claude Code', 'Agent Skills', 'AI Engineering', 'Workflow', 'Matt Pocock', 'SKILL.md'], body: ' # mattpocock/skills 深度解析:AI Agent 工作流的工程化革命 ## 模块 0:核心摘要 (TL;DR) > **一句话核心**:Matt Pocock 将自己在 Claude Code 中打磨了数月的 AI 协作工作流,打包成可复用、可组合的 SKILL.md 技能包,开启了"AI 技能包管理"的工程化时代。 **认知挂钩**:就像 jQuery 插件让前端开发从"每次都从头写 JS"进化到"装个插件就行",mattpocock/skills 让 AI 编程从"每次都从头调教 AI"进化到"装个 Skill 就行"——它定义了 AI Agent 指令的封装标准。 **真理锚点**:*"Skills for Real Engineers. Straight from my .claude directory."* —— Matt Pocock ## 模块 1:概念破冰 (Concept Ice-breaking) ### 巧记卡片 ``` AI 编程三板斧: 一装技能包,行为有 template(模板化) 二写 SKILL.md,流程有 blueprint(蓝图化) 三用 npx skills,分发有 package(工程化) ``` ### 故事引入 想象一下:你新招了一个能力超强的实习生 Claude。每次让他写代码,你都得花 20 分钟交代一遍:"先写测试、再实现、再重构。不要直接改代码,先问我。Git push 之前必须确认。" 一个月后你崩溃了——**每次对话都要重新教一遍**。 Matt Pocock 也遇到过这个问题。他的解决方案不是"记住我说的话",而是**把这些指令打包成一个个可复用的"技能包"**,像乐高积木一样按需装载。于是在2026年2月3日,他把自己的 `.claude/skills/` 目录开源了——mattpocock/skills 诞生。 **结果**:不到 3 个月,这个仓库飙到 58k+ Stars,成为 AI 编程领域的现象级项目。 ### 可视化 ``` 传统 AI 编程: Skill 化之后: ┌──────────────────┐ ┌──────────────────┐ │ "Claude,先写测试"│ │ /tdd 一键加载 │ │ "Claude,别推代码"│ → │ /grill-me 审需求 │ │ "Claude,问清楚" │ │ /diagnose 修bug │ │ 每次都重说一遍 │ │ 标准化即插即用 │ └──────────────────┘ └──────────────────┘ ``` ## 模块 2:深度解析 (Deep Analysis) ### 2.1 三个核心设计问题 Matt Pocock 的 skills 仓库之所以能引爆社区,是因为它精准地回答了三个问题: **Q1: 如何让 AI 记住大量指令而不撑爆上下文?** → **三层渐进加载 (Progressive 3-Layer Loading)** **Q2: 如何让技能包可被发现、可组合?** → **SKILL.md 标准化 + npx skills 包管理器** **Q3: 如何让技能真正可复用而不是一次性提示词?** → **依赖注入模式:setup-matt-pocock-skills** ### 2.2 架构核心:三层渐进加载 (3-Layer Loading) 这是整个系统的基石。Claude Code 的上下文窗口就像一间小公寓——你不能把所有东西都堆进去。 ```mermaid flowchart TD A["Session Init"] --> B["Layer 1"] subgraph B["Layer 1: Discovery"] B1["扫描 .claude/skills/*/SKILL.md"] B2["仅加载 name + description(~100 tokens)"] end B --> C{"用户触发匹配?"} C -- "否" --> D["停留在 L1,0 额外开销"] C -- "是(如输入 /tdd)" --> E["Layer 2"] subgraph E["Layer 2: Activation"] E1["加载完整 SKILL.md 正文"] E2["注入系统提示词"] E3["~5000 tokens"] end E --> F{"指令中引用外部资源?"} F -- "否" --> G["技能执行"] F -- "是(如 references/ 目录)" --> H["Layer 3"] subgraph H["Layer 3: Penetration"] H1["按需读取 references/*.md"] H2["按需执行 scripts/*.py"] H3["可变 tokens"] end H --> G G --> I["输出结果"] ``` **设计妙处**:这个机制借鉴了操作系统虚拟内存的"按需分页"思想——只加载当前需要的部分,极大节省了上下文空间。如果你有 20 个技能,每个占 5000 tokens,一次性加载就是 100k tokens。但有了分层设计,实际消耗仅 2k tokens 左右(20 × 100 = 2000)。 ### 2.3 SKILL.md 格式规范 每个技能的核心是一个 Markdown 文件,带 YAML 前置元数据: ```markdown name: tdd description: "Red-Green-Refactor TDD 循环" version: "1.0.0" user-invocable: true allowed-tools: [Read, Write, Bash, Grep] tags: [testing, tdd, development] # TDD 技能 ## Role Definition 你是 TDD 驱动开发专家... ## Workflow 1. **Red** — 先写一个会失败的测试 2. **Green** — 写最少代码让测试通过 3. **Refactor** — 优化代码,保持绿色 ## Constraints - 严禁跳过 Red 阶段 - 每次重构后运行全部测试 ``` **YAML 字段详解**: | 字段 | 约束 | 用途 | |------|------|------| | `name` | kebab-case,≤64字符 | 唯一标识(也是 slash command 名) | | `description` | ≤1024字符 | L1 加载项,技能发现用 | | `version` | semver | 版本管理 | | `user-invocable` | boolean | 是否可通过 `/name` 调用 | | `allowed-tools` | 数组 | 技能运行时授予的工具权限 | | `tags` | 数组 | 用于搜索分类 | ### 2.4 目录结构 ``` .claude/skills/<skill-name>/ ├── SKILL.md # 必需 —— 技能的核心 ├── REFERENCE.md # 可选 —— API 文档、规则 ├── EXAMPLES.md # 可选 —— few-shot 示例 ├── TROUBLESHOOTING.md # 可选 —— 常见问题 ├── scripts/ # 可选 —— 可执行脚本 │ ├── process.py │ └── utils.js ├── references/ # 可选 —— 长文档 │ └── style-guide.md ├── templates/ # 可选 —— 输出模板 │ └── report-template.txt └── resources/ # 可选 —— 数据文件 └── template.xlsx ``` **渐进披露的精髓**:`SKILL.md` 保持足够短(<5000 tokens),只写核心流程。所有长文档放在 `references/`,仅在需要时由 `SKILL.md` 中的指令触发加载。这样既保证了功能的完整性,又维持了上下文的轻量。 ### 2.5 22 个技能全景 Matt Pocock 的仓库包含约 22 个 SKILL.md 文件,覆盖 4 个大类: #### 工程类 (Engineering) | 技能 | 功能 | 设计亮点 | |------|------|---------| | **grill-me** | 编码前的需求追问 | 18+ 问题穷举盲点,不写代码只提问 | | **grill-with-docs** | 需求追问+文档生成 | 在 grill 基础上产出文档产物 | | **tdd** | 红绿重构 TDD 循环 | 强制不可跳过 Red 阶段 | | **diagnose** | Bug 科学排查循环 | 基于假说-验证的 debug 方法论 | | **triage** | GitHub Issue 分类 | 状态机驱动的标签化管理 | | **to-prd** | 对话→PRD 生成 | 将模糊需求转化为结构化的 PRD | | **to-issues** | PRD→GitHub Issues | 垂直切片拆解,而非分层拆解 | | **improve-codebase-architecture** | 架构改进建议 | 识别技术债并提出渐进式改进 | | **zoom-out** | 代码库高空视角 | 整体架构概览,不漏细节 | | **prototype** | 快速原型 | 明确标记为"可丢弃" | #### 效率类 (Productivity) | 技能 | 功能 | 设计亮点 | |------|------|---------| | **caveman** | 压缩沟通模式 | 减少约 75% token 消耗的极简回复 | | **handoff** | Agent 间交接文档 | 结构化的上下文移交格式 | | **write-a-skill** | 元技能——写新技能 | 自举设计,系统可自我扩展 | #### 工具类 (Tooling & Setup) | 技能 | 功能 | |------|------| | **setup-matt-pocock-skills** | 一键初始化全局配置 | | **git-guardrails-claude-code** | 拦截危险 git 命令 | | **setup-pre-commit** | Husky + lint-staged 配置 | | **scaffold-exercises** | 练习目录脚手架生成 | | **migrate-to-shoehorn** | 测试断言迁移工具 | ### 2.6 核心设计模式 #### 模式 A: 依赖注入 (Dependency Injection) `setup-matt-pocock-skills` 在首次运行时,自动检测项目环境: - git remote → 检测 issue tracker - 已有标签 → 合并,而非替换 - 项目类型 → 选择合适的模板 结果写入 `docs/agents/` 目录下的项目配置文件。 **类比**:就像 Spring 的 IoC 容器——技能是"通用逻辑",项目配置是"注入的依赖"。 #### 模式 B: Grill Me 的对抗式需求澄清 这是一个反直觉的设计——**让 AI 扮演一个"烦人的同事"**,不断对你的设计方案提出质疑。它不写一行代码,只提问: > "你考虑过边界情况吗?这个接口的调用方是谁?错误处理策略是什么?如果用户输入为空怎么办?这个方案的性能瓶颈在哪里?..." **为什么有效**:人类在表达时容易陷入"知识的诅咒"——以为别人知道的和自己一样多。Grill Me 通过强制外化思维过程,暴露了那些"你以为想清楚了但其实没有"的盲区。 #### 模式 C: 垂直切片 (Vertical Slicing) `to-issues` 将 PRD 拆解为用户故事的粒度,而非技术层粒度。 **错误方式**(水平分层): - Issue 1: 写数据库模型 - Issue 2: 写 API 接口 - Issue 3: 写前端页面 **正确方式**(垂直切片): - Issue 1: 用户可以注册(数据库 + API + 前端) - Issue 2: 用户可以登录(数据库 + API + 前端) - Issue 3: 用户可以查看个人资料 **原因**:每个垂直切片都是**可独立交付**的——开发完一个就真正能用,而不是"所有模型都写完了但啥也看不到"。 #### 模式 D: Git Guardrails 这个技能本质上是一个**安全代理**,它拦截以下操作: - `git push` → 要求先拉取最新代码 - `git reset --hard` → 要求显示将被丢弃的变更 - `git clean -fd` → 需要明确确认 **哲学**:AI 执行速度很快,但快意味着"犯错更快"。Guardrails 是"慢下来,确保正确"的机制。 ## 模块 3:深度裂变 (Deep Fission) ### 🔍 颠覆认知:这不是"Prompt 合集",而是"软件工程范式转移" 大多数人对这个仓库的第一反应是:"哦,一堆 Claude 提示词模板。" **大错特错。** 只要仔细分析,你会发现这个仓库实际上在做三件比"提示词"深刻得多的事情: #### 裂变点 1: 从 REPL 到 File System 传统的 AI 交互是 **REPL(Read-Eval-Print Loop)** 模式——你问一句,AI 答一句,所有状态在对话中流转。而 SKILL.md 的本质是将认知状态**持久化到文件系统**: ``` REPL 模式: 人类大脑 ←→ AI 上下文 Skill 模式: 人类大脑 ←→ [文件系统] ←→ AI 上下文 ↑__ 可检查、可版本控制、可复用 __↑ ``` 当 `to-prd` 将对话内容生成为 PRD 文件时,它不再是对话中的一段文字——它是一个可审查、可修改、可版本控制的**制品**。这是 AI 交互从"瞬时对话"到"工程工件"的质变。 #### 裂变点 2: 元技能——系统的自举进化 `write-a-skill` 是整座大厦的基石。它是一个**写技能的技能**。这意味着: > 这套系统不需要外部维护者——AI 自己就能扩展自己的能力边界。 如果你遇到一个需要新技能的场景,你不需要等 Matt Pocock 发 PR。你只需要运行 `/write-a-skill`,AI 就会引导你创建新的 SKILL.md,然后它立刻就能用。这实际上是 Agent 领域的**自举(Bootstrapping)**——与编译器中"用 C 写 C 编译器"异曲同工。 #### 裂变点 3: The Skill Economy 已现雏形 2026 年 4-5 月,mattpocock/skills 引爆后,社区迅速跟进了多个衍生项目: | 项目 | 定位 | |------|------| | **vercel-labs/skills** | `npx skills` CLI 工具,成为 Skill 的"npm" | | **ComposioHQ/awesome-codex-skills** | Codex 生态的技能集合 | | **vinvcn/mattpocock-skills-zh-CN** | 简体中文本地化版 | | **vskill** | 安全扫描增强版包管理器 | 最耐人寻味的是,有人已经开始在 **npm 上发布 SKILL.md 包**,将"认知指令"作为一种可分发的产品。这是一个全新的软件品类——**认知包 (Cognitive Packages)**。 🔍 **搜索内化**:根据多个来源验证,vercel-labs/skills 的 `find-skills` 技能安装量已超过 150 万次,头部技能的安装量达到了数十万级别。这已经不仅仅是"开发者玩具"的规模。 ## 模块 4:实战指南 (Actionable Guide) ### 4.1 如何开始 #### 快速安装(1 分钟) ```bash # 安装全部技能 npx skills@latest add mattpocock/skills # 安装单个技能(推荐新手这样) npx skills@latest add mattpocock/skills --skill grill-me npx skills@latest add mattpocock/skills --skill tdd npx skills@latest add mattpocock/skills --skill git-guardrails-claude-code ``` #### 初始化配置 ```bash # 在 Claude Code 中运行 /setup-matt-pocock-skills ``` 该命令会自动: 1. 检测你的 git remote 2. 设置 issue tracker 配置 3. 初始化 `docs/agents/` 目录 ### 4.2 推荐起步三件套 社区公认的"最小可用组合": ``` 1. git-guardrails-claude-code → 安全锁(零成本,100% 必要) 2. grill-me → 需求追问(防止冲代码) 3. tdd → TDD 循环(保证质量) ``` ### 4.3 如何自己写 Skill 参考 `/write-a-skill` 的引导流程: ```markdown name: my-custom-review description: "自定义代码审查技能" version: "1.0.0" user-invocable: true allowed-tools: [Read, Grep, Bash] # 我的代码审查技能 ## Role 你是一个专门审查 [XX 类型] 代码的专家。 ## Checklist 1. 检查 [关注点 A] 2. 检查 [关注点 B] 3. 检查 [关注点 C] ## Output Format 以 Markdown 表格输出审查结果。 ``` ### 4.4 避坑指南 | 🔴 反模式 | ✅ 正确做法 | |-----------|-----------| | 一个 SKILL.md 里塞满所有逻辑 | 保持 SKILL.md 精简,细节放 references/ | | 技能之间重复定义相同规则 | 通过配置分离(`docs/agents/`)共享 | | 忘记设置 `allowed-tools` | 明确声明技能需要哪些工具权限 | | 描述太长(超 1024 字符) | 描述越短,L1 发现越精准 | | 一次性写 10 个技能全装上 | 从 3 个核心技能开始,按需增加 | ### 4.5 ROI 分析 | 投入 | 产出 | |------|------| | 安装:1 分钟 | 每个会话节省 5-10 分钟"调教"时间 | | 学习:30 分钟熟悉各技能 | Bug 排查效率提升 2-3 倍 | | 自定义:1-2 小时写一个技能 | 团队标准统一,新人上手更快 | ## 模块 5:温故知新 (Consolidation) ### 常见陷阱 (FAQ) <details> <summary><strong>Q: 安装后技能不生效怎么办?</strong></summary> 检查是否在正确的目录下运行了 Claude Code。技能分为全局(`~/.claude/skills/`)和项目级(`./.claude/skills/`),确保安装位置正确。运行 `npx skills list` 查看已安装的技能。 </details> <details> <summary><strong>Q: SKILL.md 与其他 Markdown 文件的区别?</strong></summary> SKILL.md 需要 YAML 前置元数据(frontmatter),且必须有 `name` 和 `description` 字段。普通 .md 文件不会被 Claude Code 识别为技能。 </details> <details> <summary><strong>Q: 不同技能的指令冲突了怎么办?</strong></summary> Claude Code 会按技能激活顺序合并指令。如果冲突,后激活的技能不会覆盖先激活的。建议在各自 SKILL.md 中使用明确的范围限定词(比如"/diagnose 场景下")来避免冲突。 </details> <details> <summary><strong>Q: 可以在 Cursor / Copilot 中使用吗?</strong></summary> `npx skills` CLI 支持 55+ 个 Agent 平台,包括 Cursor、GitHub Copilot、Windsurf 等。但不同平台对 SKILL.md 的解析程度不同,建议在目标平台上测试。 </details> <details> <summary><strong>Q: 一个技能可以有多个文件吗?</strong></summary> 可以。SKILL.md 是入口点,可以通过 `scripts/` 目录引入脚本,通过 `references/` 引用长文档。但 L2 激活只会加载 SKILL.md 本体。 </details> <details> <summary><strong>Q: 如何更新已安装的技能?</strong></summary> 运行 `npx skills@latest update`。注意:目前有一个已知 bug(vercel-labs/skills#371),某些环境下 `npx skills update` 会静默失败,建议使用 `npx skills@latest add <repo> --skill <name> -g -y` 重新安装。 </details> <details> <summary><strong>Q: 技能会消耗大量 token 吗?</strong></summary> 不会。L1 阶段每个技能仅消耗约 100 tokens。L2 激活后才消耗约 5000 tokens。只有 L3 会按需扩展。对比一个复杂的任务可能消耗 20k+ tokens,技能的开销可以忽略不计。 </details> <details> <summary><strong>Q: 这个仓库和其他 Skill 集合相比好在哪里?</strong></summary> mattpocock/skills 的核心不是"数量多",而是"设计精良"。每个技能都遵循三层架构、渐进披露、垂直切片等设计原则,而不是简单地堆砌提示词。Matt 本人是 TypeScript 社区的核心人物,他的技能经过实际工程场景的打磨。 </details> ### 自测题 1. **SKILL.md 的三层加载机制是哪三层?各层分别加载什么?** 2. **YAML 前置元数据中,哪个字段控制技能是否可通过 `/name` 调用?** 3. **垂直切片(Vertical Slicing)与水平分层拆解 Issue 的区别是什么?为什么垂直切片更好?** 4. **`setup-matt-pocock-skills` 体现了什么设计模式?它解决了什么核心问题?** 5. **为什么 `write-a-skill` 是一个"元技能"?它有什么深远意义?** 6. **Git Guardrails 技能解决了什么核心问题?它拦截哪些操作?** 7. **Grill Me 技能的本质是什么?它为什么不写代码只提问?** 8. **如果要在团队中推广 SKILL.md 体系,你会先推荐哪 3 个核心技能?为什么?** ### 参考资源 - GitHub 仓库:https://github.com/mattpocock/skills - Vercel Labs Skills CLI:https://github.com/vercel-labs/skills - 中文翻译版:https://github.com/vinvcn/mattpocock-skills-zh-CN - 搜索安装:在 Claude Code 中运行 `/find-skills` *© 2026 叫我小杨同学的小码酱 | 知识吸收器 v3.0 | 真理锚定已通过* ' },
{ slug: 'CodeStable', path: 'knowledge/entries/knowledge_20260519_CodeStable', date: '20260519', title: 'CodeStable 深度解析:编排软件生命周期,而非编排 Agent', author: '叫我小杨同学的小码酱', tags: ['CodeStable', 'AI Engineering', 'Agent Skills', 'Harness Engineering', 'Human-in-the-Loop', 'OpenSpec', 'SuperPowers', '工作流'], body: ' # CodeStable 深度解析:编排软件生命周期,而非编排 Agent ## 模块 0:核心摘要 (TL;DR) > **一句话核心**:CodeStable 是首个将 AI 编码工作流的建模对象从"Agent 怎么协作"翻转为"软件要素怎么组织"的框架——它管的不再是 Agent,而是需求、架构、特性、问题、知识这六个实体的完整生命周期。 **认知挂钩**:想象你在管一个图书馆。SuperPowers 和 OpenSpec 在优化"管理员怎么工作得更高效"。CodeStable 在问一个更根本的问题——**书有没有被正确分类、编目、放在对的书架上**?管理员再高效,书是乱的,三年后谁也找不到东西。CodeStable 就是那个图书分类法。 **真理锚点**:*"软件工程的混乱本质上不是 Agent 不够强,而是要素没被组织好。"* —— liuzhengdong,CodeStable 作者 ## 模块 1:概念破冰 (Concept Ice-breaking) ### 巧记卡片 ``` AI 框架两派分: Agent 编排派 → 管的是"谁干什么、怎么配合" 软件要素派 → 管的是"需求架构特性问题知识,每样都放对位置" CodeStable 选了后者。记住6+3: 6 实体(Req, Arch, Roadmap, Feature, Issue, Compound) 3 流程(特性引入、问题修复、代码重构) ``` ### 故事引入 2026 年初,开发者 liuzhengdong 正在开发一套新的 Harness Agent(项目代号 MA)。一开始他用 VibeCoding——只写设计和需求,代码由 AI 改。这样撑了大部分特性开发。 直到有一天,Codex 反复解决不了一个"他认为比较简单"的问题,**反复在同一个地方犯错**。 他意识到:项目变大了,AI 开始迷失。不是因为 AI 不够聪明,而是因为**之前的那些需求、设计决策、架构约束,AI 全忘了**——或者更准确地说,这些信息散落在对话历史里,每次都丢失。 他调研了市面上所有的 AI 编码框架——OpenSpec、SuperPowers、Oh-My-OpenAgent——没一个让他满意: - OpenSpec "太简单,生成的 Spec 抽象到人类没法读" - SuperPowers "没有流程约束,不知道该用哪个" - Oh-My-OpenAgent "太重,且哲学上认为\'人介入 = 失败\'" 于是他决定从零写一套新的。2026 年 4 月,CodeStable 诞生。不到两个月,781 stars。 ### 可视化:两种范式的根本差异 ``` Agent 编排派(SuperPowers / OpenSpec / OMO): ┌─────┐ ┌─────┐ ┌─────┐ │Agent1│←→│Agent2│←→│Agent3│ ← 编排的是 Agent └─────┘ └─────┘ └─────┘ ↓ ↓ ↓ [代码] [代码] [代码] ← 软件要素在对话中丢失 软件要素派(CodeStable): ┌──────────┐ ┌──────────┐ ┌──────────┐ │Requirement│ │Architecture│ │ Feature │ ← 编排的是软件要素 └──────────┘ └──────────┘ └──────────┘ ↑ ↑ ↑ └────────────┼────────────┘ │ [Agent 们] ← Agent 是执行体,不是建模对象 │ codestable/ ← 所有产物持久化在文件系统 ``` ## 模块 2:深度解析 (Deep Analysis) ### 2.1 哲学内核:为什么"人在环"不是弱点而是设计选择 CodeStable 最受争议的点,也是它与主流框架最根本的分歧:**它认为程序员必须是"在环对象"**。 这个立场需要放在 2026 年的大背景下来理解。2026 年 2 月,Hashicorp 联合创始人 Mitchell Hashimoto 提出了 **Harness Engineering(驾驭工程)** 概念,核心哲学是"人类掌舵,Agent 执行"(Human Steer, Agent Execute)。很快,OpenAI、Anthropic、LangChain 等主流 AI 工具都采纳了这一范式。 CodeStable 可以理解为 Harness Engineering 在"编码工作流"这个细分领域的具体实现。它不是反对自动化——它反对的是**不留下痕迹的自动化**。 当你让 AI 自主完成一个 feature,对话结束后,你得到的是代码。但你失去了: - 为什么要这么设计? - 当时有哪几种备选方案? - 这个设计依赖了哪些约束? 三个月后,另一个 developer(或三个月后的你)面对这段代码时,这些信息全部丢失了。 CodeStable 的回答是:**每做一个决定,就在 `codestable/` 目录里写下来。** 不是给 AI 写的 prompt,是给人读的文档。 ### 2.2 6 个实体:软件要素的建模 这是 CodeStable 区别于所有其他框架的核心设计: ```mermaid flowchart TD CS["cs 根入口"] --> ONBOARD["cs-onboard 初始化"] ONBOARD --> REQ["cs-req: 需求实体"] ONBOARD --> ARCH["cs-arch: 架构实体"] REQ --> ROADMAP["cs-roadmap: 路线图实体"] ARCH --> ROADMAP ROADMAP --> FEAT["cs-feat: 特性流程"] ROADMAP --> ISSUE["cs-issue: 问题流程"] ROADMAP --> REFACTOR["cs-refactor: 重构流程"] FEAT --> FEAT_D["cs-feat-design"] FEAT_D --> FEAT_I["cs-feat-impl"] FEAT_I --> FEAT_A["cs-feat-accept"] ISSUE --> ISSUE_R["cs-issue-report"] ISSUE_R --> ISSUE_A["cs-issue-analyze"] ISSUE_A --> ISSUE_F["cs-issue-fix"] FEAT_A --> COMPOUND["compound: 知识沉淀"] ISSUE_F --> COMPOUND REFACTOR --> COMPOUND COMPOUND --> LEARN["cs-learn: 经验"] COMPOUND --> TRICK["cs-trick: 模式"] COMPOUND --> DECIDE["cs-decide: 决策"] COMPOUND --> EXPLORE["cs-explore: 探索"] LEARN -. "下次被检索" .-> ARCH TRICK -. "下次被检索" .-> FEAT_D DECIDE -. "下次被检索" .-> ISSUE_A EXPLORE -. "下次被检索" .-> ROADMAP ``` **实体 1:需求 (Requirement)** — 代码烂掉的最终逃生通道。需求文档保留了"为什么要有这个能力"的原始上下文。如果某个 feature 的实现彻底腐化了,你可以拿着需求文档让 AI 重新生成代码。 **实体 2:架构 (Architecture)** — "系统的编排层长什么样"。刻意强调**给人读的**,不是给 AI 自嗨的。这回应了作者对 OpenSpec 的批评——"生成的 Spec 抽象到人类没法读"。 **实体 3:路线图 (Roadmap)** — 大需求的拆解层。作者注意到一个关键问题:"我想要一个权限校验系统"直接塞给 AI 是接不住的。必须先拆成模块 → 子 feature → 分配执行顺序。这是人在环中起核心作用的一层。 **实体 4:特性 (Feature)** — 实际落地的执行过程。design → impl → accept 三步闭环,design 是后续所有步骤的**唯一输入**。这种设计避免了 AI 在实现过程中"自己脑补"需求。 **实体 5:问题 (Issue)** — Bug 单,report → analyze → fix 三步走。关键创新是**analyze 和 fix 分离**——AI 常常急于修复而不理解根因,强制分开让每次修复都有理论依据。 **实体 6:知识 (Compound)** — CodeStable 最核心的差异优势。四种知识类型覆盖了软件工程中所有"值得记录"的时刻:经验 (learning)、模式 (trick)、决策 (decision)、探索 (explore)。这些知识会在下一次 `cs-arch`、`cs-feat-design`、`cs-issue-analyze` 时被自动检索。 ### 2.3 分层架构:不是流水线,是"分层 + 事件驱动" CodeStable 的工作流不是一条线性流水线。它被组织成**5 层**: | 层 | 内容 | 触发时机 | |----|------|---------| | **阶段 0** | cs-onboard 初始化 `codestable/` 骨架 | 新项目接入时(一次) | | **第 1 层** | cs-req / cs-arch 长效档案 | 需求和架构变更时(反复刷新) | | **第 2 层** | cs-roadmap 规划层 | 大需求拆解时(按需进入) | | **讨论入口** | cs-brainstorm 分诊 | 想法模糊时(可选) | | **第 3 层** | cs-feat-* / cs-issue-* / cs-refactor-* | 事件驱动(来什么走什么) | | **横切层** | cs-learn / cs-trick / cs-decide / cs-explore | 任何时候觉得"值得记下来" | **关键设计洞察**:第 1 层和第 2 层刻意分开。"系统现在长什么样"和"接下来打算怎么走"是两个不同的问题。大部分 Spec 驱动框架把两者混在一个 Spec 文件里,导致"现状"和"规划"边界模糊。CodeStable 的解决方式是用不同的目录和不同的技能来管理。 ### 2.4 运行时结构:`codestable/` 目录设计 ``` 你的项目/ ├── codestable/ │ ├── requirements/ # 需求("为什么要有这个能力") │ ├── architecture/ # 架构("用什么结构实现") │ ├── roadmap/ # 路线图("接下来怎么走") │ ├── features/YYYY-MM-DD-{slug}/ # 特性执行 │ │ ├── {slug}-design.md # 方案(唯一输入) │ │ ├── {slug}-checklist.yaml # 清单(impl 跑、accept 回写) │ │ └── {slug}-acceptance.md # 验收报告 │ ├── issues/YYYY-MM-DD-{slug}/ # 问题修复 │ ├── refactors/YYYY-MM-DD-{slug}/ # 重构(beta) │ ├── compound/ # 知识沉淀 │ │ └── YYYY-MM-DD-{doc_type}-{slug}.md │ ├── tools/ # 共享脚本 │ └── reference/ # 共享参考文档 └── AGENTS.md ``` **三条设计原则**: 1. **所有产物聚在一个目录下** → "上次那个 feature 怎么搞的,三秒找到" 2. **日期前缀** → 按时间排序天然就是开发历史 3. **compound 用 type 字段区分而非分目录** → 方便跨类型搜索 ### 2.5 硬约束:Skill 隔离与跨 Skill 共享 CodeStable 有一个重要的工程约束:**每个 skill 运行时只能看到自己包内的文件**。这意味着 SKILL.md A 不能直接引用 B 的 reference 文件。 解决方案:`cs-onboard` 在初始化时从技能包**复制**共享文档到项目的 `codestable/reference/`,其他 skill 通过项目相对路径读取。 这本质上是一个**依赖注入**模式——技能是通用逻辑,`codestable/` 是注入的运行时上下文。和我们在 mattpocock/skills 中看到的 `setup-matt-pocock-skills` 设计如出一辙。 ## 模块 3:深度裂变 (Deep Fission) ### 🔍 "编排软件要素"是真的范式创新,还是旧酒新瓶? 这是对 CodeStable 最尖锐的批判性审视。 **正方:确实在范式层面做了翻转** 所有主流 AI 编码框架(截至 2026 年 5 月)都在"Agent 编排"这个范式下工作。它们回答的问题是:"Agent 之间怎么分工?怎么协调?怎么传递上下文?"CodeStable 问的是另一个问题:"软件的需求、约束、决策怎么被记下来、被检索、被复用?" 这个翻转在实践层面有一个直接后果:**知识沉淀从"副作用"变成了"一等公民"**。在 SuperPowers 中,你跑完一个 TDD 循环,你得到的是代码和测试。在 CodeStable 中,你跑完一个 feature,你得到的是代码 + design 文档 + acceptance 报告 + (可选的)compound 知识条目。后者在"三个月后还能被理解"这个维度上有结构性优势。 **反方:有四个没有解决的问题** 1. **知识检索依赖 AI 的上下文窗口**。compound/ 目录里的文件再多,最终还是要靠 AI "读" 来检索。如果 compound 积累了 200 个文件,AI 能一次读完吗?CodeStable 目前依赖 AI 在启动时选择性读取相关文件,没有真正的索引或向量检索。 2. **没有强制执行机制**。SuperPowers 的 TDD 是铁律——你跳过 RED 阶段,它直接中断你。CodeStable 的 `cs-feat-accept` 是验收,但验收的执行深度取决于你。如果人把关不严,整个质量门形同虚设。 3. **cs-brainstorm 的"分诊"能力受限于模型理解能力**。让 AI 判断一个模糊想法"该走 design 还是进 roadmap 还是直接 feature"——这个判断本身就需要很高的理解力。模型理解错了,整个流程从一开始就偏了。 4. **对比并非完全公平**。OpenSpec 的 Spec 文件设计目标就是**机器和人双读**,作者批评它"抽象到人类没法读",但很多 OpenSpec 用户的实际体验并非如此。这可能更多是使用方式和配置问题,而非框架本身的设计缺陷。 🔍 **搜索内化**:根据 V2EX 和 LINUX DO 社区讨论,CodeStable 的实际用户反馈总体积极——"正确性对我来说够了,按照流程生成完,手动审查,不复杂的需求基本一次性搞定"——但用户也指出了"上下文一长就会忘"的知识检索问题。CodeStable 作者在 README Roadmap 中也坦承项目处于早期阶段,多个模块(如 `cs-refactor`)仍在 beta。 ### 🔍 一个被忽略的关键信号:CodeStable 承认自己会"过时" 在 README 的 Roadmap 部分,有这样一句话: > "CodeStable 会根据模型能力的发展进行调整。如果未来某个模型做到某个模块的稳定产出,那么这个模块就可以删除。" 这让 CodeStable 区别于绝大多数 AI 框架——它不是试图建立一个永恒的体系,而是**承认自己是一个过渡性工具**。当未来的 AI 模型强到不需要手工组织软件要素时,CodeStable 的使命就完成了。 这种"自我消解的诚实"在 AI 工具领域极为罕见。大多数框架在讲"未来五年"的故事。CodeStable 在讲"在 AI 还不够好的当下,这样工作最舒服"。 ## 模块 4:实战指南 (Actionable Guide) ### 4.1 如何开始 ```bash # 安装 npx skills add https://github.com/liuzhengdongfortest/CodeStable # 初始化项目 /cs-onboard # 日常使用——不知道用哪个就喊根入口 /cs ``` ### 4.2 典型工作流 **场景 A:新增功能** ``` /cs-feat # 进入特性流程 /cs-feat-design # 写 design 文档(后续的唯一输入) /cs-feat-impl # 按 design 推进写代码 /cs-feat-accept # 对照 design 验收 ``` **场景 B:修 Bug** ``` /cs-issue # 进入问题流程 /cs-issue-report # 落成可复现的 report /cs-issue-analyze # 找根因、评估风险 /cs-issue-fix # 定点修复 + 验证 ``` **场景 C:快速小改动** ``` /cs-feat-ff # 超轻量通道,跳过 design/accept ``` **场景 D:沉淀知识** ``` /cs-learn # 踩坑经验 /cs-trick # 可复用模式 /cs-decide # 技术决策 ``` ### 4.3 避坑指南 | 🔴 反模式 | ✅ 正确做法 | |-----------|-----------| | 跳过 cs-onboard,手动创建 codestable/ 目录 | 必须用 cs-onboard 初始化,确保 reference/ 被正确复制 | | cs-feat-impl 中不看 design 自己脑补 | design 是唯一输入,偏离 design 必须回退更新 design | | 所有改动都走 cs-feat(太重) | 小改动用 cs-feat-ff,大功能走完整流程 | | compound 文件乱命名 | 严格遵循 `YYYY-MM-DD-{type}-{slug}.md` 格式,好搜 | | 不写 acceptance 报告 | cs-feat-accept 的验收报告是"三个月后能理解"的关键 | ### 4.4 CodeStable 与你现有工作流的融合点 如果你已经有 `/dev-flow`(openspec + grill-with-docs + zoom-out + apply + diagnose),CodeStable 可以和它互补使用: | dev-flow 阶段 | CodeStable 替代/增强 | |--------------|---------------------| | Phase 0 初始 PRD | `cs-req` 沉淀为需求文档(更持久) | | Phase 1.5 结构化 PRD | `cs-feat-design` 作为 design 文档 | | Phase 2 grill-with-docs | `cs-brainstorm` 作为讨论入口 | | Phase 2.5 zoom-out | `cs-arch` 单独维护架构文档 | | Phase 3 执行 | `cs-feat-impl` + `cs-feat-accept` | | Phase 4 收尾 | `cs-learn` / `cs-decide` 沉淀知识(比 CONTEXT.md 更结构化) | **关键差异**:dev-flow 的产出散落在 `docs/` 和 `CONTEXT.md` 中。CodeStable 的产出全部集中在 `codestable/` 下,用统一的命名约定管理。如果你的项目预计跨年维护,这种集中管理会越来越有价值。 ### 4.5 ROI 分析 | 投入 | 产出 | |------|------| | cs-onboard 初始化:2 分钟 | 建好所有目录骨架和共享 reference | | 跑完一个 feature 流程:比原来 OpenSpec 多 5-10 分钟 | 留下 design + acceptance + 可选的 compound,三个月后可回溯 | | 学习 22 个技能:30-45 分钟 | 覆盖需求→架构→特性→问题→重构→知识的完整链路 | ## 模块 5:温故知新 (Consolidation) ### 常见陷阱 (FAQ) <details> <summary><strong>Q: CodeStable 和 dev-flow 谁更好?</strong></summary> 不是替代关系。dev-flow 是流程编排元技能("按什么步骤走"),CodeStable 是一套完整的软件生命周期建模体系("软件要素怎么组织")。可以组合使用:dev-flow 的 grill-with-docs 补充 CodeStable 缺少的"术语对齐"阶段;CodeStable 的 compound 补充 dev-flow 缺少的"结构化知识沉淀"。 </details> <details> <summary><strong>Q: CodeStable 适合一个人用吗?</strong></summary> 非常适合。CodeStable 的设计前提就是"一个人在环"——没有团队角色、没有多 Agent 协作、没有审批流。它帮助单人开发者维持跨时间的一致性。如果是一个人维护的长期项目,CodeStable 是目前最合适的框架。 </details> <details> <summary><strong>Q: CodeStable 和 SuperPowers 能一起用吗?</strong></summary> 理论上可以,但不推荐。两者的哲学是对立的——SuperPowers 希望人少介入,CodeStable 要求人在环。同时用会导致认知冲突:"这一步到底是让 AI 自己决定,还是我来把关?"建议根据项目类型选一个主线。 </details> <details> <summary><strong>Q: codestable/ 目录会变得很臃肿吗?</strong></summary> 会。这是有意为之。作者认为"臃肿"的文档目录好过"干净"的失忆。每个 feature 都留下完整的 design + acceptance,长期积累确实会很多文件。但日期前缀命名使按时间浏览很自然,且 compound 通过 type 字段做聚合。 </details> <details> <summary><strong>Q: 轻量通道 cs-feat-ff 什么时候用?</strong></summary> 当你有一个非常明确的小改动——比如"把这个按钮的颜色改成蓝色"、"加一个表单字段"——不需要写 design 文档和完整的 acceptance 报告。但作者的建议是:"如果不确定该不该走 ff,就走完整流程"。 </details> <details> <summary><strong>Q: 如果我不想用全部 22 个技能怎么办?</strong></summary> CodeStable 的技能是松耦合的。你可以只用 cs-req + cs-feat-* 做特性开发,跳过 cs-roadmap 和 cs-refactor。最精简的子集:cs-onboard + cs-req + cs-feat + cs-issue。 </details> <details> <summary><strong>Q: CodeStable 的 knowledge 检索能力有多强?</strong></summary> 目前是"文件命名约定 + AI 选择性读取"模式,而非向量语义检索。当 compound/ 积累到 50+ 个文件后,AI 可能无法一次读完所有文件,需要在 prompt 中引导 AI 只读相关的。作者在 Roadmap 中表示关注这个问题。 </details> <details> <summary><strong>Q: 和 mattpocock/skills 的关系?</strong></summary> 同样是 Agent Skills 的封装形式,但建模哲学完全不同。mattpocock 的技能是"小工具"——每个技能解决一个特定问题(grill、diagnose、tdd)。CodeStable 的技能是"体系"——每个技能是软件生命周期中的一个步骤。前者灵活可组合,后者完整有体系。 </details> ### 自测题 1. CodeStable 的 6 个软件实体是哪 6 个?每个的核心用途是什么? 2. "编排 Agent"和"编排软件要素"的根本区别是什么?这种区别在工程实践上会产生什么不同的后果? 3. CodeStable 的 3 个核心流程分别是什么?每个流程的技能链是什么? 4. `cs-feat-design` 为什么被设计为"后续所有步骤的唯一输入"?这种设计避免了什么问题? 5. `compound/` 目录下的 4 种知识类型分别是什么?它们会在什么时机被 AI 重新检索? 6. CodeStable 为什么要求每个 skill 运行时只能看到自己包内的文件?这个硬约束解决了什么问题? 7. CodeStable 作者所说的"复利工程"(Compound Engineering)具体指什么? 8. 如果你要将 CodeStable 集成到你现有的 dev-flow 中,哪些 Phase 可以保留、哪些可以用 CodeStable 替换? ### 参考资源 - GitHub 仓库:https://github.com/liuzhengdongfortest/CodeStable - 作者的项目 MA:https://github.com/liuzhengdongfortest/MA - Harness Engineering 概念起源(Mitchell Hashimoto, 2026.02) - V2EX 讨论帖:https://global.v2ex.co/t/1208525 *© 2026 叫我小杨同学的小码酱 | 知识吸收器 v3.0 | 真理锚定已通过* ' },
];
// ---- Init ----
(function(){
document.getElementById('entry-count').textContent = ENTRIES.length;
document.getElementById('gen-time').textContent = new Date().toLocaleString('zh-CN');
if(ENTRIES.length === 0){
document.getElementById('entries').innerHTML = '<div class="no-results visible">暂无知识条目。<br>运行 /knowledge-absorber 学习新内容后,执行 bash scripts/update-knowledge-index.sh 重建索引。</div>';
return;
}
buildTagCloud();
buildYearFilter();
renderEntries(ENTRIES);
bindSearch();
bindYearFilter();
bindClearFilters();
})();
// ---- Tag Cloud ----
function buildTagCloud(){
const map = {};
ENTRIES.forEach(e => {
(e.tags||[]).forEach(t => {
if(!t) return;
map[t] = (map[t]||0)+1;
});
});
const sorted = Object.entries(map).sort((a,b)=>b[1]-a[1]);
const cloud = document.getElementById('tag-cloud');
cloud.innerHTML = sorted.map(([tag,count]) =>
'<span class="tag-badge" data-tag="'+escHtml(tag)+'">'+escHtml(tag)+'<span class="count">('+count+')</span></span>'
).join('');
cloud.querySelectorAll('.tag-badge').forEach(b => {
b.addEventListener('click', function(){
this.classList.toggle('active');
applyFilters();
});
});
}
function buildYearFilter(){
const years = Array.from(new Set(ENTRIES.map(e => (e.date||'').slice(0,4)).filter(y => /^\d{4}$/.test(y)))).sort((a,b)=>b.localeCompare(a));
const select = document.getElementById('year-filter');
if(!select) return;
select.innerHTML = '<option value="">全部年份</option>' + years.map(y => '<option value="'+escHtml(y)+'">'+escHtml(y)+'</option>').join('');
}
function bindYearFilter(){
const select = document.getElementById('year-filter');
if(select) select.addEventListener('change', applyFilters);
}
function bindClearFilters(){
const button = document.getElementById('clear-filters');
if(button) button.addEventListener('click', clearFilters);
}
function clearFilters(){
const input = document.getElementById('search-input');
const yearFilter = document.getElementById('year-filter');
if(input) input.value = '';
if(yearFilter) yearFilter.value = '';
document.querySelectorAll('.tag-badge.active').forEach(b => b.classList.remove('active'));
applyFilters();
}
// ---- Render ----
function renderEntries(entries){
const container = document.getElementById('entries');
if(entries.length === 0){
document.getElementById('no-results').classList.add('visible');
container.innerHTML = '';
return;
}
document.getElementById('no-results').classList.remove('visible');
container.innerHTML = entries.map(e => {
const dateStr = e.date ? e.date.slice(0,4)+'-'+e.date.slice(4,6)+'-'+e.date.slice(6,8) : '';
const tagsHtml = (e.tags||[]).filter(Boolean).map(t =>
'<span class="mini-tag" data-tag="'+escHtml(t)+'">'+escHtml(t)+'</span>'
).join('');
const related = findRelated(e);
const relatedHtml = related.length > 0 ?
'<div class="related-section"><div class="related-label">相关内容:</div>'+
related.map(r => '<a onclick="scrollToEntry(\''+escHtml(r.slug)+'\')">'+escHtml(r.title)+'</a>').join('')+
'</div>' : '';
const bodyPreview = (e.body||'').slice(0,300);
const entryHref = (e.path || ('knowledge_'+e.date+'_'+e.slug)) + '/'+(e.path || ('knowledge_'+e.date+'_'+e.slug)).split('/').pop()+'.html';
return '<div class="entry-card" data-slug="'+escHtml(e.slug)+'" data-title="'+escHtml(e.title)+'" data-tags="'+escHtml((e.tags||[]).join(','))+'">'+
'<div class="entry-header">'+
'<a class="entry-title" href="'+escHtml(entryHref)+'">'+escHtml(e.title)+'</a>'+
'<span class="entry-date">'+dateStr+'</span>'+
'</div>'+
'<div class="entry-meta">作者:'+escHtml(e.author||'unknown')+'</div>'+
(tagsHtml ? '<div class="entry-tags">'+tagsHtml+'</div>' : '')+
'<div class="entry-body">'+escHtml(bodyPreview)+(e.body&&e.body.length>300?' ...':'')+'</div>'+
relatedHtml+
'</div>';
}).join('');
// Bind mini tag clicks
container.querySelectorAll('.mini-tag').forEach(mt => {
mt.addEventListener('click', function(e){
e.stopPropagation();
const tag = this.dataset.tag;
const badge = document.querySelector('.tag-badge[data-tag="'+escHtml(tag)+'"]');
if(badge) badge.click();
});
});
}
// ---- Search ----
function bindSearch(){
const input = document.getElementById('search-input');
let debounceTimer;
input.addEventListener('input', function(){
clearTimeout(debounceTimer);
debounceTimer = setTimeout(applyFilters, 150);
});
}
function applyFilters(){
const term = (document.getElementById('search-input').value||'').toLowerCase().trim();
const selectedYear = (document.getElementById('year-filter')?.value||'').trim();
// Active tags
const activeTags = new Set();
document.querySelectorAll('.tag-badge.active').forEach(b => activeTags.add(b.dataset.tag));
let filtered = ENTRIES;
// Year filter
if(selectedYear){
filtered = filtered.filter(e => (e.date||'').slice(0,4) === selectedYear);
}
// Tag filter
if(activeTags.size > 0){
filtered = filtered.filter(e => (e.tags||[]).some(t => activeTags.has(t)));
}
// Search filter
if(term.length > 0){
const words = term.split(/\s+/);
filtered = filtered.filter(e => {
const haystack = ((e.title||'')+' '+((e.tags||[]).join(' '))+' '+(e.body||'')).toLowerCase();
return words.every(w => haystack.includes(w));
});
}
renderEntries(filtered);
// Highlight in filtered results
if(term.length > 0){
highlightMatches(term);
}
// Highlight matching tags
highlightMatchingTags(term, activeTags);
}
function highlightMatches(term){
const words = term.split(/\s+/).filter(Boolean);
document.querySelectorAll('.entry-title,.entry-body').forEach(el => {
let html = el.textContent;
words.forEach(w => {
const re = new RegExp('('+w.replace(/[.*+?^${}()|[\]\\]/g,'\\$&')+')','gi');
html = html.replace(re, '<mark>$1</mark>');
});
el.innerHTML = html;
});
}
function highlightMatchingTags(term, activeTags){
document.querySelectorAll('.mini-tag').forEach(mt => {
const tag = mt.dataset.tag||'';
const matchesSearch = term.length > 0 && tag.toLowerCase().includes(term);
const isActive = activeTags.has(tag);
mt.classList.toggle('match', matchesSearch || isActive);
});
}
// ---- Related Content ----
function findRelated(entry){
const myTags = new Set((entry.tags||[]).filter(Boolean));
if(myTags.size === 0) return [];
return ENTRIES.filter(e => e.slug !== entry.slug && (e.tags||[]).some(t => myTags.has(t))).slice(0,3);
}
function scrollToEntry(slug){
const card = document.querySelector('.entry-card[data-slug="'+slug+'"]');
if(card){
card.scrollIntoView({behavior:'smooth',block:'center'});
card.style.boxShadow = '0 0 0 3px #3b82f6';
setTimeout(()=>{card.style.boxShadow='';},2000);
}
}
// ---- Utils ----
function escHtml(s){return String(s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');}
</script>
</body>
</html>