ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

GitHub 1.5万星项目揭秘:用CLAUDE.md配置文件让Claude写出可靠代码的四大黄金原则

GitHub 1.5万星项目揭秘:用CLAUDE.md配置文件让Claude写出可靠代码的四大黄金原则 1. 为什么你的 Claude 总在“自作主张”如果你用 Claude 写过一段时间代码大概率遇到过这种场景你让它修一个空指针的 bug它顺手把整个函数重命名了你让它加一个字段校验它给你搭了一套工厂模式加策略模式你让它改一行配置它把相邻三行注释也“优化”了。最后你 review diff 的时候发现真正需要的改动只有两行剩下八十行全是它自己加的戏。这不是你的提示词写得不好而是大模型在代码任务上的默认行为倾向它倾向于“多做一点”倾向于抽象倾向于假设自己理解了你没说的部分。Andrej Karpathy 在社交平台上吐槽过这件事大意是模型会替你做错误的假设然后一路执行下去不会管理困惑不会主动暴露权衡该反驳的时候也不反驳。这段话被开发者 forrestchang 整理成了一个单文件配置 CLAUDE.md在 GitHub 上拿到了 1.5 万星左右成为 AI 编程圈里被反复引用的一个实践样本。这个文件能做什么简单说它把四条约束写进 Claude 的项目上下文里让模型在动手之前先确认理解、优先选简单方案、只改该改的地方、把模糊指令转成可验证目标。适合谁适合所有用 Claude Code、Claude 桌面端或 API 做日常编码的人尤其是那种“代码能跑但 diff 很脏”的团队。下面我把这套配置的落地写法拆开给你一份可以直接复制的骨架再演示一次配置前后的输出对比。2. 前置准备把 TaoToken 接进你的 Claude 工作流在写 CLAUDE.md 之前先确认你的模型调用链路是通的。我这边习惯用 TaoToken 做统一入口官网在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 端点是 https://taotoken.net/api 。它的作用是让你用同一套 key 去调不同模型省得每个模型单独配一遍环境变量。你需要先拿到一个 API Key。进控制台创建https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsole_keyutm_campaignrewrite 然后在 API Keys 页面生成https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapikeys_keyutm_campaignrewrite 。生成后复制那串 sk- 开头的字符串后面配置里要用。如果你只是想先验证模型能不能正常对话可以直接用模型对话页试一句https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodels_chatutm_campaignrewrite 。这一步不涉及代码纯粹确认链路通不通。对于长期用 Claude 做编码和 Agent 任务的建议看一下 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcodingplan_ctautm_campaignrewrite 。它针对的就是这种高频、长上下文的编码场景比按次调用更划算。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdoc_ctautm_campaignrewrite 里面有各语言 SDK 的示例。环境变量这样设Linux/macOS 写进 ~/.zshrc 或 ~/.bashrcexport ANTHROPIC_BASE_URLhttps://taotoken.net/api export ANTHROPIC_API_KEYsk-你的keyWindows PowerShell 用$env:ANTHROPIC_BASE_URLhttps://taotoken.net/api $env:ANTHROPIC_API_KEYsk-你的key设完开一个新终端跑一句echo $ANTHROPIC_API_KEY确认能打印出来。这一步没通后面 CLAUDE.md 写得再好也没用。3. 可复制的 CLAUDE.md 骨架与 settings.json 关键字段CLAUDE.md 的本质是一个放在项目根目录的 Markdown 文件Claude Code 启动时会自动读取它作为项目级指令。它的位置和命名是约定好的不需要额外配置路径。下面这份骨架我按四大原则组织你可以直接复制到项目根目录再按自己项目改。# CLAUDE.md ## 核心原则 ### 1. 先思考再编码 - 不确定就提问不要猜。 - 有歧义时列出多种解读让我选。 - 如果有更简单的方案直接说出来。 - 困惑时停下明确说哪里不清楚。 ### 2. 简洁第一 - 不做需求之外的功能。 - 不为一次性代码做抽象。 - 不加没要求的“灵活性”。 - 不处理不可能出现的错误。 - 如果 200 行能简化成 50 行重写。 ### 3. 外科手术式修改 - 不改进相邻代码、注释或格式。 - 不重构没坏的部分。 - 保持现有风格即使你不会这么写。 - 看到无关死代码提一下别删。 - 只清理你的改动造成的孤儿代码。 ### 4. 目标驱动执行 - 把“添加验证”转成“为无效输入写测试然后让它们通过”。 - 把“修复 bug”转成“写一个重现 bug 的测试然后让它通过”。 - 多步骤任务先列计划每步带验证项。 ## 项目特定规则 - 使用 TypeScript 严格模式。 - 所有 API 端点必须有测试。 - 错误处理遵循 src/utils/errors.ts 中的模式。 - 提交前跑 npm run lint npm test。这份骨架的关键在于每条原则下面都是可执行的约束而不是空泛的口号。Claude 读到“不改进相邻代码”比读到“保持代码整洁”要有效得多因为前者是可判定的行为边界。然后是 settings.json。Claude Code 的配置文件在 ~/.claude/settings.json项目级可以放 .claude/settings.json。几个关键字段{ permissions: { allow: [ Read, Edit, Bash(npm run lint), Bash(npm test) ], deny: [ Bash(rm -rf *), Bash(git push --force) ] }, env: { ANTHROPIC_BASE_URL: https://taotoken.net/api } }permissions.allow 里放你允许它自动执行的操作deny 里放危险操作。env 里可以固化 base URL这样不用每次开终端都 export。注意 deny 列表不是万能的它只是减少误操作概率真正的安全边界还是靠 git 分支和 code review。如果你用的是 Claude Code 插件形式也可以把 CLAUDE.md 作为插件安装命令是/plugin marketplace add forrestchang/andrej-karpathy-skills /plugin install andrej-karpathy-skillskarpathy-skills这样所有项目都能用同一份指南。但我的建议是插件装一份做基线每个项目再放一份项目级 CLAUDE.md 覆盖特定规则两层叠加效果最好。4. 验证请求一次代码生成任务的配置前后对比光看配置说明没感觉我们跑一个具体任务。假设有一个 Node.js 项目文件 src/cart.js 内容如下function calculateTotal(items) { return items.reduce((acc, item) acc item.price * item.qty, 0); } module.exports { calculateTotal };任务给 calculateTotal 加上空数组保护避免 items 为 undefined 时报错。配置前我只给一句“修复 calculateTotal 的空数组问题”Claude 的输出 diff 大概是这样-function calculateTotal(items) { - return items.reduce((acc, item) acc item.price * item.qty, 0); -} function calculateTotal(items) { if (!Array.isArray(items)) { throw new TypeError(items must be an array); } if (items.length 0) { return 0; } const validItems items.filter(item item typeof item.price number); return validItems.reduce((acc, item) acc item.price * item.qty, 0); } function formatTotal(total) { return $${total.toFixed(2)}; } -module.exports { calculateTotal }; module.exports { calculateTotal, formatTotal };它加了类型检查、加了过滤、还顺手加了一个 formatTotal 函数并导出了。formatTotal 完全不在需求里filter 也改变了原有语义原本 price 是字符串也会被隐式转换现在被过滤掉了。这就是典型的“顺手多做”。配置后同样的任务CLAUDE.md 生效Claude 先输出一段确认我的理解是只给 calculateTotal 加 items 为 undefined 或空数组时返回 0 的保护不改动 reduce 逻辑不新增函数不改变导出。对吗我回复“对”它的 diff 是function calculateTotal(items) { if (!items || items.length 0) { return 0; } return items.reduce((acc, item) acc item.price * item.qty, 0); }三行改动只做该做的事。这就是四大原则里“外科手术式修改”和“简洁第一”叠加的效果。你可以自己跑一遍这个对比把两次 diff 存下来团队里做分享很有说服力。再跑一个目标驱动的例子。任务“让用户注册功能工作”。配置前 Claude 会问你一堆问题或者直接改 schema、改接口、改前端。配置后你按原则四写成用户注册功能排查 1. 编写测试POST /api/register 成功返回 token 2. 编写测试重复邮箱返回 400 3. 修复代码让这些测试通过Claude 会先写测试文件跑一遍看失败再改实现再跑一遍看通过。整个过程它自己循环不需要你逐步指挥。这就是 Karpathy 说的“给它成功标准看着它完成”。5. 本篇常见错排查问题一CLAUDE.md 放了但没生效。先确认文件名大小写必须是全大写 CLAUDE.md放在项目根目录。然后确认你启动 Claude Code 时的工作目录就是项目根目录如果你在子目录启动它读不到。可以用/memory命令查看当前加载了哪些上下文文件。问题二模型还是过度设计。检查你的 CLAUDE.md 里“简洁第一”那节是不是写得太抽象。把“保持简洁”改成“如果 200 行能简化成 50 行重写”这种可判定表述。另外项目特定规则里如果有“所有 API 必须有完整错误处理”这类要求会和简洁原则冲突需要明确优先级。问题三API 调用报 401 或连接失败。先确认 ANTHROPIC_BASE_URL 设的是 https://taotoken.net/api 注意结尾没有斜杠。然后确认 key 没有多余空格。可以在终端跑curl https://taotoken.net/api/v1/messages \ -H x-api-key: $ANTHROPIC_API_KEY \ -H anthropic-version: 2023-06-01 \ -H content-type: application/json \ -d {model:claude-sonnet-4-20250514,max_tokens:64,messages:[{role:user,content:ping}]}能返回 JSON 就说明链路通。报错的话对照接入文档 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdoc_troubleshootutm_campaignrewrite 里的错误码表排查。问题四settings.json 改了不生效。确认 JSON 格式合法可以用python -m json.tool ~/.claude/settings.json校验。项目级配置会覆盖全局配置检查是不是被项目里的 .claude/settings.json 覆盖了。问题五Claude 还是删了不该删的代码。在 CLAUDE.md 里加一条硬约束“删除任何非你本次改动产生的代码前必须先问我。”这条比“不要删代码”更可执行因为它定义了触发条件。6. 把配置固化下来让每次编码都从同一起点开始这套东西的价值不在于某一次任务省了几行代码而在于它把“可靠”变成了默认行为。你不需要每次开新会话都重新交代一遍规矩CLAUDE.md 就是你的项目宪法。团队里每个人拉下代码Claude 的行为基线是一致的review 的时候 diff 也干净很多。如果你还没配好调用链路先去 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapikeys_finalutm_campaignrewrite 拿个 key把环境变量设上。然后从最简单的“目标驱动执行”那条开始写进 CLAUDE.md跑一个测试驱动的任务感受一下。等你习惯了这种“先确认、再动手、只改该改的”节奏再回头看你以前那些被 Claude 改得面目全非的 diff会有种回不去的感觉。Karpathy 那句话值得再贴一次不要告诉它做什么给它成功标准看着它完成。CLAUDE.md 做的就是把这句话变成可复制的工程实践。
返回列表