规范驱动开发SDD实战:用CLAUDE.md让Claude Code永远在轨道上

发布时间:2026/10/7 19:44:00
规范驱动开发SDD实战:用CLAUDE.md让Claude Code永远在轨道上
1. 为什么你的 Claude Code 总在“自由发挥”SDD 规范驱动开发要解决的真问题先说一个我踩过的坑。去年做内部模型网关平台时Provider 模块的代码干净得像教科书实体叫Provider返回统一Result错误码从 2000 段开始。两周后做 Agent 模块我只丢了一句“实现 CRUD 接口”结果它给我生成了AgentConfigEntity、直接返回ResponseEntity、错误码随手写了2001——和 Provider 模块的网络超时码撞了个正着。前端同学当场问我“这俩 2001 是一个意思吗”问题不在 Claude Code 变笨了而在于它没有长期记忆。每次新对话都是白纸一张你不把规则喂进上下文它就按训练数据里的“通用最佳实践”脑补一套。而训练数据里的最佳实践往往是给大型开源项目准备的工厂模式、策略接口、三层抽象能上的全上。对一个几十人用的内部平台来说这些不是资产是负债。这就是 SDDSpec-Driven Development规范驱动开发要解决的核心问题把项目规范固化成 AI 每次都能自动读到的约束文件让它在不同模块、不同阶段始终沿同一套规则工作。落到 Claude Code 上这个约束入口就是项目根目录的CLAUDE.md。它和“写好提示词”有本质区别。提示词是一次性技巧这次说清楚了下次还得重说SDD 是贯穿项目生命周期的方法论规范写一次后续所有对话自动继承。适合谁适合任何用 Claude Code 做多人协作项目、或者一个人维护多个模块、被“风格漂移”折磨过的开发者。这篇我会给你一份可直接复制的CLAUDE.md模板、配套目录结构、越界回退的验证方法以及怎么通过 TaoToken 统一 Key 和 API 通道把 Claude Code 接起来。全程可跟做。2. TaoToken 前置准备统一 Key 与 API 通道接入 Claude Code在写规范之前得先让 Claude Code 能稳定跑起来。我试过在多个项目里分别配 Key结果环境变量散落各处换台机器就要重新翻记录。后来统一走 TaoToken 的 API 通道一个 Key 管所有模型调用配置也集中。TaoToken 在这里的角色是统一的模型 API 接入层你拿到一个 Key配好 Base URLClaude Code 就能通过它调用背后的模型。官网入口在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 地址是 https://taotoken.net/api 这个不加 UTM。具体操作分三步。第一步去控制台创建 API Key。打开 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 登录后在 API Keys 页面点新建复制生成的 Key。这个 Key 只显示一次先存到密码管理器里。第二步配置 Claude Code 的环境变量。Claude Code 读取ANTHROPIC_BASE_URL和ANTHROPIC_AUTH_TOKEN两个变量。在~/.zshrc或~/.bashrc里加上export ANTHROPIC_BASE_URLhttps://taotoken.net/api export ANTHROPIC_AUTH_TOKENsk-你的TaoToken密钥改完执行source ~/.zshrc生效。注意 Base URL 结尾不要带/v1Claude Code 会自己拼路径多写一层会 404。第三步验证通道是否通。跑一个最小请求curl https://taotoken.net/api/v1/messages \ -H x-api-key: $ANTHROPIC_AUTH_TOKEN \ -H anthropic-version: 2023-06-01 \ -H content-type: application/json \ -d { model: claude-sonnet-4-20250514, max_tokens: 64, messages: [{role: user, content: 回复 OK 两个字母}] }返回里能看到content:[{type:text,text:OK}]就说明通道正常。如果返回 401八成是 Key 复制时带了空格如果返回local proxy failed检查 Base URL 是不是写成了https://taotoken.net/api/v1。模型 ID 这块Claude Code 默认会用它内置的模型名。如果你想指定可以在项目里用--model参数或者写进配置。TaoToken 支持的模型列表在文档里能查到 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。通道打通后Claude Code 的每次请求都会经过 TaoTokenKey 统一管理换机器只改环境变量不用动项目代码。这一步做完再进 SDD 正题。3. 可复制的 CLAUDE.md 模板与目录结构把规范钉进项目规范要落地先得有地方放。我的做法是在项目根目录建CLAUDE.md模块级规范放各模块目录下的CLAUDE.md任务级规范在对话里临时补充。Claude Code 会自动读取当前目录及父目录的CLAUDE.md所以根目录那份是全局地基。先看目录结构my-project/ ├── CLAUDE.md # 全局规范项目通用 ├── src/ │ ├── provider/ │ │ ├── CLAUDE.md # Provider 模块规范 │ │ └── ... │ ├── agent/ │ │ ├── CLAUDE.md # Agent 模块规范 │ │ └── ... │ └── chat/ │ └── ... └── .claude/ └── settings.json # Claude Code 项目配置根目录CLAUDE.md模板直接复制改# 项目规范 ## 命名规范 - 实体类使用大驼峰不加前缀后缀例如 Provider、Agent、ChatMessage。 - 字段使用小驼峰例如 apiKey、baseUrl、modelName。 - 接口路径统一为 /api/v1/{资源复数名}例如 /api/v1/providers。 ## 接口规范 - 所有接口统一返回 Result格式为 { code, message, data }。 - 列表字段为空时返回空数组 []不要返回 null。 - 分页参数统一使用 page 和 pageSizepage 从 1 开始pageSize 默认 20。 ## 错误码规范 - 错误码统一四位数字按模块分段 - 1000-1999 通用模块 - 2000-2999 Provider 模块 - 3000-3999 Agent 模块 - 4000-4999 Chat 模块 - 5000-5999 MCP 模块 ## 设计原则 - 不引入不必要的设计模式工厂、策略、观察者等除非明确要求。 - 不做过度抽象一层能解决的问题不要拆成两层。 - 不引入技术栈之外的新依赖如有需要先确认。 ## 行为约束 - 修改代码前先说明改动范围不要顺手重构无关文件。 - 不要全量删除再全量插入。全量删除再插入会导致并发场景下数据瞬间丢失 如果此时有请求在读取会拿到空结果。应使用差异比对方式更新。 - 不破坏已有接口契约如需变更先说明影响面。模块级CLAUDE.md只写该模块特有的东西。比如src/agent/CLAUDE.md# Agent 模块规范 ## 接口契约 - Agent 工具列表更新使用差异比对禁止全量替换。 - Agent 删除为软删除标记 deletedAt 字段不物理删除。 ## 数据流 - 对话请求先经过 Agent 路由再进入 Chat 处理。 - 工具调用结果统一包装为 ToolResult。.claude/settings.json里可以固定模型和权限{ model: claude-sonnet-4-20250514, permissions: { allow: [Read, Edit, Bash(git status)], deny: [Bash(rm -rf)] } }这里三件套要写全Base URL 走https://taotoken.net/apiKey 走环境变量ANTHROPIC_AUTH_TOKENModel ID 在 settings.json 里指定。三者缺一Claude Code 要么连不上要么用错模型。规范写完后下达任务时明确引用它。不要说“帮我做个 Agent CRUD”而要说“按照 CLAUDE.md 中的规范实现 Agent 的 CRUD 接口”。这句话在提醒它这次优先服从项目规范不要按默认经验发挥。4. 验证请求与越界回退观察 AI 是否真的在轨道上规范写好了怎么知道它真的生效我设计了一个越界测试故意给一个违反规范的指令看 Claude Code 是照做还是回退。测试一命名越界。在对话里说“创建一个叫 AgentConfigEntity 的实体类。”如果规范生效它应该拒绝或提醒“根据 CLAUDE.md实体类不加前缀后缀建议命名为 AgentConfig。”如果它直接生成了AgentConfigEntity说明CLAUDE.md没被读到检查文件是不是在项目根目录、文件名大小写是否正确。测试二返回格式越界。说“这个接口直接返回 ResponseEntity 吧。”规范生效时它应该回退到Result包装并说明原因。我实测下来第一次它可能会犹豫但只要你补一句“按 CLAUDE.md 的接口规范来”它就会改回Result。测试三设计模式越界。说“给 Provider 加个工厂模式。”规范里写了“不引入不必要的设计模式”它应该先问你是否确认而不是直接上工厂。测试四行为约束越界。说“把 Agent 工具列表全量删了重新插入。”这条规范里带了原因说明Claude Code 应该指出并发风险改用差异比对。如果它还是全量替换说明原因那段没写进CLAUDE.md补上再试。验证通过的标准很简单触发越界指令时AI 能引用规范条款回退而不是默默照做。回退时它通常会输出类似“根据 CLAUDE.md 的设计原则不建议引入工厂模式是否确认”这样的提示。再补一个正向验证。让它实现一个标准 CRUD检查输出实体名是否无前缀、返回是否统一Result、错误码是否落在对应分段、有没有多余抽象。四项全过说明规范体系跑通了。这里有个细节Claude Code 读取CLAUDE.md是自动的但如果你在子目录里启动它读的是子目录及父目录的CLAUDE.md。所以模块规范放在模块目录下进到该目录工作时会自动加载。跨模块任务就在根目录启动读全局规范。5. 本篇常见报错排查401、local proxy failed、reading choices、OAuth配置和验证过程中几个报错几乎人人都会遇到。我按真实报错逐个拆。401 Unauthorized。返回体里通常是{error:{type:authentication_error}}。原因有三个Key 复制时带了首尾空格环境变量没source生效Key 被撤销了。排查顺序先echo $ANTHROPIC_AUTH_TOKEN看有没有值、有没有空格再去控制台确认 Key 状态。如果是 Claude Code 报的 401还要检查ANTHROPIC_BASE_URL是不是写成了https://taotoken.net/api/v1多一层/v1会导致鉴权路径错位。local proxy failed。这个报错通常出现在 Claude Code 启动时提示本地代理连接失败。根因是 Base URL 配置不对Claude Code 尝试连一个不存在的本地代理。检查ANTHROPIC_BASE_URL是否完整写成https://taotoken.net/api结尾不要带斜杠也不要带/v1。改完重启终端。reading choices 相关报错。报错里出现reading choices或cannot read properties of undefined (reading choices)说明返回体结构不是 Claude Code 预期的格式。常见于 Base URL 指向了 OpenAI 兼容接口而非 Anthropic 接口。Claude Code 走的是/v1/messages路径返回体是content数组不是choices。确认 Base URL 是https://taotoken.net/api让 Claude Code 自己拼/v1/messages。OAuth 相关报错。如果 Claude Code 提示 OAuth 登录或 token 过期说明它走了默认的 Anthropic 官方鉴权流程没读到你配的环境变量。检查两点环境变量名必须是ANTHROPIC_AUTH_TOKEN和ANTHROPIC_BASE_URL拼写不能错如果之前登录过官方账号先退出登录再重启避免缓存冲突。模型不存在。报错model not found或invalid model。检查.claude/settings.json里的 Model ID 是否在 TaoToken 支持列表里。不确定就用claude --model claude-sonnet-4-20250514显式指定或者去文档页核对模型名。权限被拒。报错permission denied或工具调用被拦。检查.claude/settings.json的permissions.deny是不是拦了需要的命令。调试阶段可以先把 deny 清空跑通后再逐步收紧。排查通用思路先确认通道通curl 能返回再确认 Claude Code 读到了环境变量最后确认CLAUDE.md在正确位置。三层都过基本不会有玄学报错。6. 把规范变成习惯持续迭代与统一通道收尾规范不是写完就完事。每次 AI 跑偏别只改代码先问自己它为什么跑偏是不是规范没覆盖到如果是就补一条进CLAUDE.md。它跑偏一次你补一条以后在这个点上大概率不会再跑偏。补规范时记住三个原则。具体不模糊“代码要简洁”没用“不引入工厂模式除非明确要求”才有用。有优先级不贪多AI 反复跑偏的地方写细不容易错的地方少写上下文窗口有限。写规则也写原因涉及工程权衡的规则补上“为什么”它才能举一反三。规范分三层管理全局规范放根目录CLAUDE.md模块规范放模块目录任务规范在对话里临时补充。全局是地基模块是补充任务是临时约束。通道这边TaoToken 的 Key 统一管理后换项目、换机器只改环境变量。API Keys 页面在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。如果你要长期跑编码任务或 Agent 工作流Coding Plan 在 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 模型对话调试在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite 。最后一步实操打开你的项目建CLAUDE.md把第 3 节的模板粘进去改掉模块名和错误码分段。然后故意给一个越界指令看它回不回退。回退了说明你的 SDD 体系跑起来了。没回退检查文件位置和环境变量。跑通之后你会发现 review 从“主观判断”变成了“对着清单核查”效率提升不是一点半点。