# 附录 · CLAUDE.md 取舍决策记录 > 本文回答"为什么本仓库的 CLAUDE.md 这么写"。基准对照物是 Video-Tree-TRM5 项目的 CLAUDE.md(一个积累了五个月的生产级科研工程项目)。当某条规则的存在理由被质疑时,来这里查;当触发点到达时,按 C 节接入。 ## 0. 取舍标准:三问 CLAUDE.md 是**每轮对话都完整注入模型上下文的提示词,不是文档**。信噪比是第一指标:模型对长指令集中"当前不适用规则"的遵从度会明显下降,而学会忽略 CLAUDE.md 是最糟的结果。每条候选规则过三问: 1. 从第 0 天起**每轮都生效**吗? 2. 是**本项目特有**的信息吗?(通用好实践不用写,那是模型本来就该做的) 3. 它指向的**设施真实存在**吗? 三问全过 → 保留(A 节);不过且无未来场景 → 舍弃(B 节);不过但有明确未来场景 → 延迟接入并写死触发点(C 节)。 ## A. 改造保留 | 参考章节 | 我们的对应 | 改造点 | |----------|-----------|--------| | URGENT 头(生产级 + 中文) | URGENT 头 | "生产级"改为"学习驱动"——参考项目是 7×24 运行的 Agent 系统,我们是训练实验代码,健壮性需求是局部的(teacher 客户端),不是全局定性 | | §1 项目元数据 | §1 | 换成论文/参考实现/远程机/gitea | | §2.1 Conda + §2.3 ruff | §4 常用命令 | 只留 pytest/ruff | | §2.4 GPU 约定 | §5 远程规则 | 加严:显式选卡之外,加磁盘 12G 红线和"远程不改代码" | | §3 中"前序版本对照" | §6.2 | 参考 SOP 里最值钱的一条(重构前列出旧版全部行为,逐一确认保留/替代/删除),完整移植 | | §4.1-P4 显式优于隐式 | §2 配置显式化 + §7 类型注解 | 具体化:禁硬编码路径,点名参考实现的 `/fsx` 反面教材 | | §4.1-P5 防御性 | §7 硬规则 | 只留两条:禁 `except: pass`、禁默认值兜底 | | §4.1-P6 可测试性 | §2 纯逻辑核心/IO 边缘 | 升级为结构性约束:不是"优先纯函数"的劝导,而是"三个纯逻辑模块禁止 import transformers/vllm/openai"的可执行守则 | | §4.2 中文 docstring | §7 | 保留,另加张量 shape 标注(ML 项目特有痛点) | | §4.7 核心算法保真清单 | §3 模块↔论文映射表 + `01-paper-code-map.md` 差异清单 | 职能相同:防迁移走样的单一事实源;参考的 12 项是五个月长出来的,我们的 5 行随层数增长 | | §7 输出规范 | §6.4 文档规范 | 留核心三条:表格/伪代码优先、代码块 ≤15 行、引用带行号 | | §9 Research Wiki | `docs/` 章节体系 | 同构替代:知识正本在 docs/,CLAUDE.md 只做指针 | ## B. 舍弃 | 参考章节 | 舍弃理由 | |----------|----------| | §1.5 PyTorch 类比表 | 参考项目的领域知识;我们的"类比表"就是模块↔论文映射表 | | §3 SOP 全流程 + §8 Skill 门控表 | 引用的 13 个 skill 在本项目 `.claude/` 不存在,写上即死链(三问之③)。那套门控防多人长周期工程走样;我们的防走样机制是对拍参考实现 | | §4.1-P2/P3 可读性、单一职责 | 通用好实践(三问之②),写进提示词边际价值≈0,反而稀释项目特有条目 | | §4.3 feature branch 强制 | 单人学习仓库,主线提交历史 = 学习履历,特意线性;出现并行实验需求再引入 | | §4.6 覆盖率 80% + 三层测试目录 | 训练器/IO 代码需 GPU,全局覆盖率指标会逼出凑数测试;我们的标准更窄更强:纯逻辑三模块必须有对拍测试 | | §4.8 遥测 + §4.9 LLM 治理栈 | 设施不存在;真实需要的部分(teacher API 重试/并发/缓存)在层 5 作为**代码**进 `teacher.py` 而非作为规则;训练可观测性由 W&B 承担 | | §5 硬性目录规则 | "scripts 只放 .sh、根目录无 .py"与 ML 包惯例冲突:我们 `scripts/` 就是放薄 .py 入口 | | §6 迷途指南表 | 仓库目前 4 份文档,README 即地图 | ## C. 延迟接入(触发点已写死) | 参考章节 | 接入触发点 | |----------|-----------| | §2.2 Makefile 收口 | 常用命令超过 3 条时 | | §2.5 自包含实验 sh(写死全参数、零参数复现) | 层 1 第一次远程训练时采纳 | | §4.2.1 非功能性需求覆盖表(持久化/幂等/断点续跑) | 层 5 设计 teacher 缓存与 checkpoint 恢复时 | | §4.5 配置双模式(.env vs 实验 YAML) | 层 6 第一个扫参对比实验时 | | 日志规范(loguru) | 层 1 训练脚本产生第一份需被检查的运行日志时 | ## D. 新增(参考没有、本项目特有) 学习优先(每章先讲解、不替用户一次写完,URGENT 级);远程磁盘红线与 `/data/zym` 路径纪律;纯逻辑模块禁 import 清单;教学注释三类型(见 E 节);"每完成一层回填 CLAUDE.md"的增长机制本身。 ## E. 教学注释规范的决策(2026-07-17 补充) **问题**:教学项目要不要更重的注释?类型注解是否强制? **决策**:分工制——`docs/` 章节讲原理,代码注释做索引,两者不重复。注释只写三类:论文锚点、非显然约束(why + 违反后果)、差异标注。**拒绝逐行解说**:讲解性注释会让代码淹没在散文里、与章节文档重复、且随重构过期。这三类恰好都是"代码自身表达不了的信息"——即 Ousterhout 对注释存在意义的定义。 **类型注解**:公共接口强制(接口注解本身就是教学信息,成本极低)、私有 helper 从宽(强制到局部就是形式主义)。真正的硬要求是 **shape 标注**:`torch.Tensor` 注解表达不了 shape,而 shape 是 ML 代码可读性的最大杠杆。不引入 jaxtyping 之类的 shape 类型库——多一个依赖、多一层语法噪声,行注释 `# (B,T,V) -> (B,T)` 已够。 ## F. Ousterhout 原则 → 本仓库规则的对照 **决策**:原则本身不进 CLAUDE.md(书摘是通用内容,三问之②不过),翻译成的可执行规则进。对照关系: | 书中原则 | 本仓库的落地 | |----------|--------------| | 深模块(接口简单、实现有料) | 模块按论文概念划分;判据"看公式知文件、开文件知章节"(CLAUDE §2、§3) | | 信息隐藏 | 纯逻辑核心/IO 边缘 + 禁 import 清单(CLAUDE §2) | | 注释写代码表达不了的东西 | 教学注释三类型(CLAUDE §7,本文 E 节) | | 战略式编程(投资设计,不只让代码能跑) | 每层完成后的接口回看:接口复杂度逼近实现复杂度 = 浅模块坏味道,重构后才进下一层(CLAUDE §6.5) | | 适度通用(somewhat general-purpose) | YAGNI + C 节的延迟接入机制:规则和抽象都等真实场景出现才引入 | | Define errors out of existence | 不作为强制规则(与"禁默认值兜底"存在张力),作为设计品味在各章讨论——OmniOPD 本身就是范例:π̂ 的 clamp+先验下界在数学上消灭了零梯度错误态,而不是运行时捕获它 |