版本: v0.2.0
时间: 2026-03-29
变更: 新增
CLAUDE.md 应该是精简的策略文档,而非详尽的规范手册。精简才是美德。Claude 每次对话都会读取它,太长反而干扰。
# CLAUDE.md 编写指引 ## 核心原则 ### 1. 按「代码推断难度」分层 | 内容类型 | 代码可见后推断难度 | 是否写入 CLAUDE.md | |---------|------------------|------------------| | 技术栈(FastAPI、PostgreSQL) | 低,import 一目了然 | ❌ 不写 | | API 格式(JSON 结构) | 低,看 models.py | ❌ 不写 | | 架构决策(为什么用后台服务) | 高,代码只展示"是什么"不展示"为什么" | ✅ 写 | | 陷阱和坑(session_id 必须稳定) | 极高,踩过才知道 | ✅ 必写 | | 配置位置(环境变量名) | 中,但分散在多处 | ✅ 写索引 | ### 2. 写「为什么」而非「是什么」 ``` # ❌ 是什么(代码可见) - 使用 asyncio 定时器 - 飞书 token 缓存 7200 秒 # ✅ 为什么(决策原因) - Timer 在服务端管理:Hook 生命周期秒级,无法计时 - token 缓存不超过 expire-60:有边界过期风险 ``` ### 3. 项目阶段决定内容 **阶段一:创建前(无代码)** ``` # 必须写的内容 - 技术选型决策及原因 - 核心架构设计 - 关键约束 ``` **阶段二:开发中(代码不完整)** ``` # 必须写的内容 - 已实现的模块索引 - 待办事项 - 临时约定 ``` **阶段三:成熟期(代码完整)** ``` # 只写这些 - 架构约束(为什么这样设计) - 常见陷阱(踩过的坑) - 编码偏好(多种写法时的选择) - 禁止事项(明确不做什么) - 文档索引(指向详细文档) ``` ## 推荐结构 ```markdown # 项目名 一句话描述 ## 架构约束 # 不可妥协的设计决策,必须说明「为什么」 ## 文档索引 # 指向详细文档的位置 ## 常见陷阱 # 踩过的坑,必须说明「后果」 ## 编码偏好 # 多种写法时的选择倾向 ## 禁止事项 # 明确不做什么,必须说明「原因」 ## 开发流程 # 开发 → 测试 → 提交的具体命令 ``` ## 判断清单 写之前问自己: 1. **代码能直接推断吗?** - 能 → 不写 - 不能或需要大量阅读 → 考虑写 2. **是「为什么」还是「是什么」?** - 是什么 → 不写 - 为什么 → 写 3. **有惨痛教训吗?** - 有 → 必须写,并说明后果 4. **是独特约定吗?** - 是 → 写 - 行业惯例 → 不写 5. **详细内容在其他文档吗?** - 是 → 只写索引链接 ## 示例对比 ### ❌ 不好的写法 ```markdown # lark-notify-service ## 技术栈 - FastAPI 作为 Web 框架 - uvicorn 作为 ASGI 服务器 - httpx 作为 HTTP 客户端 ## API 格式 所有接口返回 JSON 格式,包含以下字段: - status: 状态码 - data: 数据 ## 代码规范 - 使用 snake_case 命名 - 函数要有 docstring ``` ### ✅ 好的写法 ```markdown # lark-notify-service Claude Code 空闲提醒服务。 ## 架构约束 - **Hook 脚本必须无状态**:每次执行独立进程,生命周期秒级,无法保持连接 - **Timer 在服务端管理**:Hook 无法计时,必须在后台服务实现 - **配置用环境变量**:方便 systemd 部署,避免配置文件路径问题 ## 文档索引 - 部署指南:[README.md](README.md) - API 文档:启动服务后访问 `/docs` ## 常见陷阱 - **`session_id` 必须稳定**:随机值会导致同一会话重复通知 - **时区用 `zoneinfo`**:`pytz` 已废弃,Python 3.9+ 内置替代 - **静默期跨天判断**:`start > end` 表示跨午夜(如 23:00-06:00) ## 禁止事项 - 不在 Hook 脚本里重试:会阻塞 Claude Code 主进程 - 不缓存 token 超过 expire-60 秒:有边界过期风险 ``` ## 精简原则 - 每次对话都会读取 CLAUDE.md - 超过 50 行考虑拆分到独立文档 - 超过 100 行必须拆分 - 详细内容放 README,CLAUDE.md 只放索引