From daymade-claude-code
Optimizes CLAUDE.md (or AGENTS.md) with progressive disclosure: moves low-frequency details to Level 2 references while keeping Level 1 lean, without information loss. Activates when users request slimming, restructuring, or progressive disclosure.
How this skill is triggered — by the user, by Claude, or both
Slash command
/daymade-claude-code:claude-md-progressive-disclosurerThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> "找到最小的高信号 token 集合,最大化期望结果的可能性。" — Anthropic
"找到最小的高信号 token 集合,最大化期望结果的可能性。" — Anthropic
目标是最大化信息效率、可读性、可维护性。
本 skill 自身遵守渐进式披露:新方法论以"精炼规则 + 触发条件"留在 SKILL.md,深度战例 / 引文沉到 references/。SKILL.md 行数由信息密度决定、不设为硬目标(约 500 行量级;新增高价值规则可略超,但深度永远沉 references)——skill 自己示范它教别人的事:行数不是 KPI,自洽地不拿"≤N 行"约束自己。
禁作优化目标 / 成功指标(不可削弱——案例 7/8/9 的防线就是这条):
可作诊断症状(官方依据:Claude Code 文档"文件太长 → 规则被淹没 → Claude 不遵守"):
这些词触发的本能是「砍行数」。先 reframe,再动手:① 当场声明「行数不是目标,单一信息源 / 认知相关性才是」;② 直接进 Step 2.1 信号分诊,用「这段有没有 canonical source 重复 / 是不是反信号」决定去留,不是用「文件多长」;③ 把「太大吗」当调查的起点,不是砍的许可。用户连续追问「还是太大」时同理——回应是「再做一轮分诊找重复 / 反信号」,分诊空了就诚实说「剩下都是高频核心,再砍会丢信号」,不是继续砍有信息的内容。(实战:把「太大吗」做成减行数任务、一路用「省 39%」当成果汇报、被连续追问拽着越砍越多 → 案例 15、16。)
Level 1 (CLAUDE.md) - 每次对话都加载
├── 信息记录原则 ← 防止未来膨胀的自我约束
├── Reference 索引(开头) ← 入口1:遇到问题查这里
├── 核心命令表
├── 铁律/禁令(含代码示例)
├── 常见错误诊断(症状→原因→修复)
├── 代码模式(可直接复制)
├── 目录映射(功能→文件)
├── 修改代码前必读 ← 入口2:改代码前查这里
└── Reference 触发索引(末尾) ← 入口3:长对话后复述
Level 2 (references/) - 按需即时加载
├── 详细 SOP 流程
├── 边缘情况处理
├── 完整配置示例
└── 历史决策记录
同一 Level 2 资源可以有多个入口,服务于不同查找路径:
| 入口 | 位置 | 触发场景 | 用户心态 |
|---|---|---|---|
| Reference 索引 | 开头 | 遇到错误/问题 | "出 bug 了,查哪个文档?" |
| 修改代码前必读 | 中间 | 准备改代码 | "我要改 X,要注意什么?" |
| Reference 触发索引 | 末尾 | 长对话定位 | "刚才说的那个文档是哪个?" |
这不是重复,是多入口。 就像书有目录(按章节)、索引(按关键词)、快速参考卡(按任务)。
边界(与 SSOT 的张力,必须守住):多入口成立仅当——每个入口 keyed 方式不同(错误索引 / 任务索引 / 末尾复述),且都只指向同一 Level 2 资源、不复制它的正文。如果你把同一段规则正文抄到 3 个地方,那是违反 SSOT 的重复(会各自漂移),不是多入口。一句话判据:入口存的是"路标 + 触发条件",不是"内容副本"。
cp CLAUDE.md CLAUDE.md.bak.$(date +%Y%m%d_%H%M%S)
分两阶段。先分诊,再分层——跳过分诊会把噪音忠实搬进 Level 2,把 reference 变垃圾场。
对每个章节先问 Anthropic 官方 litmus:"删掉这一条,Claude 会不会犯错?"
安全栏(与移动同等严格,不可削弱):候选删除 ≠ 立即删除。必须事前逐项列出 + 注明属上面哪类 + 征求用户确认。说不出理由 = 不是反信号,回 2.2 当信号处理。
与案例 8/9 的边界:8/9 是把真信号(debug 提示、代码模式)在移动时压缩掉 = 永远错;这一步是移除已确认反信号(可推断 / 自明)= 正确。区别在"删的是不是信号",不在"删不删"。详见
references/progressive_disclosure_principles.md案例 10。
对通过分诊的信号分类:
| 问题 | 是 | 否 |
|---|---|---|
| 高频使用? | Level 1 | ↓ |
| 违反后果严重? | Level 1 | ↓ |
| 有代码模式需要直接复制? | Level 1 保留模式 | ↓ |
| 有明确触发条件? | Level 2 + 触发条件 | ↓ |
| 历史/参考资料? | Level 2 | 考虑删除 |
命名:docs/references/{主题}-sop.md
铁律:原样移动,禁止压缩
移动内容到 Level 2 时,必须完整保留原始内容。不要在移动的同时"顺便精简"。
✅ 正确:把 100 行原封不动搬到 Level 2(100 行 → Level 2 100 行)
❌ 错误:把 100 行"精简"到 60 行搬到 Level 2(100 行 → Level 2 60 行,40 行消失)
为什么:压缩 = 变相删除。你认为"不重要"而删掉的内容,可能是某个未来 debug session 的关键线索。优化的目标是改变信息的位置(Level 1 → Level 2),不是改变信息的存在。
怎么做:
⚠️ 写指针前的硬 gate(事中验证,最易跳过、本次最大踩坑):每写一条「→ 某 reference / 详见 X」指针前,当场 grep 确认目标文件真有这段内容。三种结果:① 目标已有完整内容 → 写指针;② 目标没有 / 不确定是否完整 → 先把原文 verbatim cut 到目标(回 Step 3),再写指针;③ 绝不写「指向一个其实没有该内容的文件」的假指针。假指针比丢内容更隐蔽——它让 5a「文件存在」通过、却在读者点进去时才发现是空的。Why:5a/5b 是事后验证,假指针那一刻已写进文件;事中 gate 才能在源头拦住。(实战:写「详见 anti-patterns」但那里 0 命中 Stripe 端点 → 案例 15。)
# 检查引用文件存在
grep -oh '`docs/references/[^`]*\.md`' CLAUDE.md | sed 's/`//g' | while read f; do
test -f "$f" && echo "✓ $f" || echo "✗ MISSING: $f"
done
对每个从原始 CLAUDE.md 移走的章节,逐一检查:
恢复原始文件:git show HEAD:CLAUDE.md > /tmp/claude-md-original.md
逐节对比:对原始文件的每个 ## 章节,确认其内容在以下位置之一完整存在:
📖 快速暴露整章遗漏的辅助脚本见 references/progressive_disclosure_principles.md 附录 C:触发场景——做下面逐节对比前的第一道筛查(脚本不替代人工逐节对比,只查章节标题是否存在)。
标记所有差异:
docs/README.md 已是文档索引的 canonical source),且在 Level 1 中有明确的指向禁止将"故意删除"作为分类来掩盖信息丢失。 每一项"故意删除"都必须说明 canonical source 在哪里。如果说不出来,就不是"故意删除",而是"遗漏"。
大量压缩时用独立 agent 做 5b(强烈推荐):执行者自审有「乐观偏差」——倾向相信自己砍掉的内容都有归属。压缩涉及多段 / 整章时,启动一个独立 sub-agent 做完整逐节 5b(读 /tmp/claude-md-original.md + 当前文件 + 所有 reference,逐个信息点 grep 验证归属,只返回「真丢失 / 指针失准」清单)。它没有你的 sunk-cost,能抓到你抽查会放过的。Why:本 skill 的真实使用中,执行者抽查 5 点「自我感觉良好」,独立 agent 逐节查 55 点才暴露真问题。prompt 模板 + 批量内容点 grep 脚本见 references/progressive_disclosure_principles.md 附录 D。
验证不以行数为通过条件,不计算"原始 X 行 vs 新 Y 行 = 减少 Z%"——这种对账会把你拉回 KPI 思维。
验证标准只有三条:
(注:诊断阶段可以看行数当怀疑信号,见开头「铁律」;但验证阶段行数不是任何标准——这两个阶段对行数的态度不同,别混。)
| 内容类型 | 原因 |
|---|---|
| 核心命令 | 高频使用 |
| 铁律/禁令 | 违反后果严重,必须始终可见 |
| 代码模式 | LLM 需要直接复制,避免重新推导 |
| 错误诊断 | 完整的症状→原因→修复流程 |
| 目录映射 | 帮助 LLM 快速定位文件 |
| 触发索引表 | 帮助 LLM 在长对话中定位 Level 2 |
| 内容类型 | Level 1 | Level 2 |
|---|---|---|
| SOP 流程 | 触发条件 + 关键陷阱 | 完整步骤 |
| 配置示例 | 最常用的 1-2 个 | 完整配置 |
| API 文档 | 常用方法签名 | 完整参数说明 |
| 内容类型 | 原因 |
|---|---|
| 历史决策记录 | 低频访问 |
| 性能数据 | 参考性质 |
| 技术债务清单 | 按需查看 |
| 边缘情况 | 有明确触发条件时再加载 |
四种引用格式各服务不同场景;规范的"触发条件"写法见下方 原则 2(已含可复制示例)。
| 格式 | 用途 | 触发场景 |
|---|---|---|
| 详细格式 | 正文中的重要引用 | 单条 reference 需展开说明何时读 |
| 问题触发表格 | 开头/末尾 Reference 索引 | 按"错误/问题"查 |
| 任务触发表格 | 「修改代码前必读」 | 按"要改什么"查 |
| 内联格式 | 简短引用 | 正文一句话带过 |
📖 四种格式的完整可复制模板见 references/progressive_disclosure_principles.md 附录 B:触发场景——产出 Reference 索引 / 任务表 / 内联 / 详细引用时。
多样性原则:不要所有引用都用同一格式。
@path import 在启动时全量展开载入——拆成 @import 只改善组织,不减少任何上下文(官方 memory 文档原文)。"我把内容拆进 @import 了所以优化了"是假优化。
全局 ~/.claude/CLAUDE.md 真正能省上下文的杠杆只有三条:
references/xxx.md",不是 @),让模型按需拉本 skill 产出的引用一律用反引号路径,禁止用 @import 做卸载。详见 references/progressive_disclosure_principles.md 案例 11。
问题:优化完成后,用户会继续要求 Claude "记录这个信息到 CLAUDE.md",如果没有规则指导,CLAUDE.md 会再次膨胀。
解决:在目标 CLAUDE.md 开头(项目概述之后)注入一段「信息记录原则」——规定 Level 1 只记核心命令 / 铁律 / 代码模式 / 触发索引,Level 2 记详细 SOP / 边缘情况 / 历史决策,并定义"用户要求记录信息时"的高频→L1、低频→L2 判断流程(引用 L2 必带触发条件)。
📖 完整可注入模板见 references/progressive_disclosure_principles.md 附录 A:触发场景——执行 Step 4 更新 Level 1 时;附录含可整块复制进目标 CLAUDE.md 的 markdown。
原因:这条规则让 Claude 自己知道什么该记在哪里,实现"自我约束",避免后续对话中 CLAUDE.md 再次膨胀。
原因:LLM 注意力呈 U 型分布——开头和末尾强,中间弱。
| 位置 | 作用 |
|---|---|
| 开头 | 对话开始时建立全局认知:"有哪些 Level 2 可用" |
| 末尾 | 对话变长后复述提醒:"现在应该读哪个 Level 2" |
📖 首/尾索引表完整写法示例见 references/progressive_disclosure_principles.md 案例 4:触发场景——决定触发索引表放哪、按什么格式写时。
错误:详见 native-modules-sop.md
正确:
**📖 何时读 `native-modules-sop.md`**:
- 遇到 `ERR_DLOPEN_FAILED` 错误
- 需要添加新的原生模块
> 包含:ABI 机制、懒加载模式、手动修复命令
原因:没有触发条件,LLM 不知道什么时候该去读。
错误:把代码示例移到 Level 2,Level 1 只写"使用懒加载模式"。
正确:Level 1 保留完整的可复制代码:
// ✅ 正确:懒加载,只在需要时加载
let _Database = null;
function getDatabase() {
if (!_Database) {
_Database = require("better-sqlite3");
}
return _Database;
}
原因:LLM 需要直接复制代码,移走后每次都要重新推导或读取 Level 2。
问题:把每条规则都标"铁律 / HIGHEST / 全局" = 没有优先级。模型无法 triage,注意力被摊薄,最关键的不可逆规则反而被淹没。指令遵循存在约 150–200 条的上限,远超即整体衰减。
解决(GitHub 2500 仓库实证最有效的结构):输出 Level 1 规则时用三态,而不是一律"铁律":
| 标记 | 含义 | 例 |
|---|---|---|
| ✅ | 总是这样做 | ✅ 提交前跑测试套件 |
| ⚠️ | 先停下问 / 谨慎 | ⚠️ 改 schema 前先确认迁移脚本 |
| 🚫 | 绝不 | 🚫 绝不提交 secret |
位置即优先级(Lost-in-the-Middle,TACL 2024):LLM 注意力 U 型分布,最高危的不可逆规则放文件首或尾,不要埋中间。真正"违反即不可逆伤害"的应是少数(5–7 条),其余降为普通规则——稀缺才有信号。
问题:不带原因的规则,一旦场景变化就被忽略(Builder.io 实证)。带 Why 的规则能跨场景泛化。
解决:Level 1 保留的每条铁律 / 禁令,跟一行 Why:,说明违反会发生什么具体坏事。
错误:🚫 禁止 fallback 默认值
正确:🚫 禁止 fallback 默认值。Why:一个 || 'sk-xxx' 兜底在 .env 缺失时静默回退明文 key,曾在 48h 内被公开仓库扫描器用掉额度。
⚠️ 重述规则时的硬边界:若原句嵌在 case study 混合段落里,原则 4/5 不得直接改写原句——见反模式 6(先整段 verbatim 移 L2,案例 14)。
案例:为了"减少行数",移走了代码模式、诊断流程、目录映射
结果:
正确:保留所有高频使用的内容。优化的判断标准是信息是否重复维护、是否与当前任务无关,而不是"文件太长"。
案例:详见 xxx.md
问题:LLM 不知道何时加载,要么忽略,要么每次都读。
正确:触发条件 + 内容摘要。
案例:把常用代码示例移到 Level 2
问题:LLM 每次写代码都要先读 Level 2,增加延迟和 token 消耗。
正确:高频使用的代码模式保留在 Level 1。
案例:删除"不重要"的章节
问题:信息丢失,未来需要时无处可查。
正确:移到 Level 2,保留触发条件。
案例:优化方案写"从 2000 行精简到 500 行,减少 75%"
问题:把行数当成功指标,会驱动错误决策——为了凑数字而砍掉有用的信息。
正确:用信息质量评估优化效果——信息是否有重复?维护负担是否降低?LLM 是否能更快找到需要的信息?
规则:移动是移动,精简是精简。这是两个独立操作,不要同时执行。
完整案例分析见
references/progressive_disclosure_principles.md案例 8、案例 14
规则:任何"删除"都必须是事前决策(征求用户确认),不是事后分类(发现少了再编理由)。
完整案例分析见
references/progressive_disclosure_principles.md案例 9
案例:🚫 不要用 X —— 没说改用什么。
问题:纯否定会让 agent 瘫痪——它知道不能走这条路,但不知道该走哪条,于是要么卡住要么乱试(Shankar + GitHub 2500 仓库均实证)。
正确:每条 🚫 必配一个 ✅ 改用 Y。
🚫 不要用全局 mutable 单例存请求状态
✅ 改用显式参数传递或 request-scoped context
优化时遇到孤立的禁令,补上正向替代再保留;补不出替代的禁令,说明规则本身没想清楚。
⚠️ 但若禁令原句嵌在 case study 混合段落里,先按反模式 6 整段 verbatim 移 L2,再在 L1 派生重述——不可改写原句(案例 14)。
案例:移走一段内容后写「详见 X.md」,但 X.md 里根本没有这段——指针指向空。
问题:比直接丢内容更隐蔽。5a「文件存在」会通过(X.md 确实存在),但内容不在那里;读者点进去才发现,且此时已无从知道原文是什么。本质是反模式 6(移动时压缩)+ 反模式 7(掩盖丢失)的组合:内容被砍 + 用一个看似合规的指针掩盖。
正确:写指针前当场 grep 验证目标真有该内容(Step 4 硬 gate)。指针指错文件(内容在 A、却写「详见 B」)是同类问题,按内容实际所在地修正、不是删指针。
完整案例分析见
references/progressive_disclosure_principles.md案例 15
| 检验项 | 通过标准 |
|---|---|
| 日常命令 | 不需要读 Level 2 |
| 常见错误 | 有完整诊断流程 |
| 代码编写 | 有可复制的模式 |
| 特定问题 | 知道读哪个 Level 2 |
| 触发索引 | 在文档末尾,表格形式 |
| 维度 | 用户级 | 项目级 |
|---|---|---|
| 位置 | ~/.claude/CLAUDE.md | 项目/CLAUDE.md |
| References | ~/.claude/references/ | docs/references/ |
| 信息范围 | 个人偏好、全局规则 | 项目架构、团队规范 |
用户级 ~/.claude/CLAUDE.md 会被所有项目加载,只能放普遍适用的东西。优化时对每节做 scope 检查:
| 内容特征 | 归属 | 不这样做的后果 |
|---|---|---|
| 项目名 / 部署目标 / 逐项目路径 / 项目凭据 | 项目级,绝不全局 | 无关项目被污染;没人按项目维护 → 路径/状态腐烂(典型 staleness) |
| 个人偏好、跨项目行为规则 | 用户级 | — |
| 团队规范、项目架构 | 项目级(入 VCS) | — |
工作流加一条:Step 2.1 分诊时,项目特定内容在用户级文件 = 自动判"搬到项目级",不是搬 Level 2、更不是原地修路径。详见 references/progressive_disclosure_principles.md 案例 13。
来源:HN 社区单源("Mr Tinkleberry"),方法论成立、成本极低,作诊断不作保证。
优化后想知道 CLAUDE.md 哪天又膨胀到"规则开始被忽略"——在文件里植入一条无害的命名指令(如"提到临时变量时命名为 tinkle_tmp")。日常对话中观察:Claude 还遵守 = 文件仍在遵守度阈值内;Claude 开始无视这条 = 文件已越过阈值,该重新分诊。比凭感觉判断"是不是太长了"廉价且客观。
优化完成后,必须逐项检查(不可跳过):
Why:(原则 5)@import 做卸载(@import 不省上下文)npx claudepluginhub p/daymade-daymade-claude-code-daymade-claude-codeOptimizes CLAUDE.md hierarchies, .claude/rules, ecosystem files, and docs/ folders per Anthropic best practices. Detects redundancies, conflicts, and suggests improvements.
Creates and refactors CLAUDE.md files following best practices for size, structure, and content organization. Includes memory hierarchy, 3-tier documentation system, and conditional rules.
Provides best practices for creating, updating, and auditing CLAUDE.md files including constraints, commands, architecture overviews, and bloat reduction for projects.