
1. 为什么你的 Claude Code 总在“自作聪明”如果你用 Claude Code 写过超过一周的代码大概率遇到过这些场景让它加一个参数校验它顺手把整个文件重构成三层抽象让它修一个空指针它把相邻函数的变量名全改了一遍让它实现一个 100 行能搞定的接口它给你写了 600 行还带一个“为未来扩展预留”的工厂类。这不是模型变笨了而是 LLM 在编码任务上的默认行为模式就是“猜测式补全”——它在训练时见过太多“专业代码”于是把复杂当成了专业。Andrej Karpathy 在长期使用 AI 辅助编程后把这类问题归纳成三条静默假设、过度工程化、副作用式修改。对应的解法就是四条原则——Think Before Coding、Simplicity First、Surgical Changes、Goal-Driven Execution。这套思路在社区里被整理成一份可直接放进项目的 CLAUDE.md配合 Claude Code 的配置就能把“发散”压成“收敛”。这篇不聊理念只交付三样东西一份可复制的 CLAUDE.md 骨架、一段 settings.json 配置、以及一个用同一提示词对比配置前后输出稳定性的验证动作。适合正在用 Claude Code 做真实项目、被返工和 diff 噪音折磨的开发者。2. 前置准备把 TaoToken 接进 Claude CodeClaude Code 默认走 Anthropic 官方端点但很多团队需要统一网关来管理 Key、配额和审计。TaoToken 提供 Anthropic 兼容接口Claude Code 可以直接指向它。这一步只做两件事拿 Key、配环境变量。2.1 获取 API Key打开 https://taotoken.net/api-keys 登录后创建一个新 Key。建议按项目命名比如claude-code-karpathy方便后续在控制台按 Key 维度看用量。创建后立刻复制页面刷新后不再显示完整值。控制台地址是 https://taotoken.net/console 里面能看到每个 Key 的调用量、模型分布和错误率。如果你打算长期跑 Agent 类任务建议先在这里设一个日限额避免某次循环把额度打满。2.2 配置 Claude Code 指向 TaoTokenClaude Code 读取ANTHROPIC_BASE_URL和ANTHROPIC_API_KEY两个环境变量。在~/.zshrc或~/.bashrc里加export ANTHROPIC_BASE_URLhttps://taotoken.net/api export ANTHROPIC_API_KEYsk-你的TaoToken密钥然后source ~/.zshrc让配置生效。验证一下echo $ANTHROPIC_BASE_URL # 期望输出https://taotoken.net/api注意这里不要加 UTM 参数Claude Code 的 SDK 对 URL 路径比较敏感带查询串可能导致 404。如果你之前配过其他网关先把旧变量清掉再设新的。2.3 确认模型可用在项目目录下启动 Claude Code输入/status看当前端点。如果显示的是taotoken.net/api说明接入成功。接着用一句简单指令测一下claude -p 用一句话说明什么是幂等性能正常返回就说明链路通了。如果报 401检查 Key 是否复制完整如果报 404检查 BASE_URL 是否多了斜杠或参数。3. 可复制配置CLAUDE.md 骨架与 settings.json这一节是全文的核心。CLAUDE.md 放在项目根目录Claude Code 每次会话都会读取它作为系统级约束。settings.json 放在.claude/目录下控制工具权限和模型参数。3.1 CLAUDE.md 四条原则骨架直接复制下面这份按项目改“Project-Specific Rules”部分即可# Karpathy-Inspired Claude Code Guidelines ## The Four Principles ### 1. Think Before Coding - 遇到歧义时先列出 2-3 种可能解释请用户确认不要默认选一种。 - 不确定技术选型时说明不确定性并询问团队偏好不要用“常见方案”蒙混。 - 发现更简单的实现路径时主动提出不要沉默地按复杂路径执行。 - 无法理解上下文时明确说出困惑点请求澄清。 ### 2. Simplicity First - 用最少的代码解决问题不添加任何投机功能。 - 判断标准高级工程师会认为这是过度复杂吗 - 单次使用的函数/类内联到使用处。 - 为“未来可能”设计的接口删除等需要时再加。 - 函数参数只保留当前必需的不要预留扩展位。 ### 3. Surgical Changes - 只触碰必须修改的代码每一行改动都要能追溯到用户请求。 - 禁止“顺便”调整相邻代码格式、重命名变量、删除注释。 - 如果自己的修改导致某些代码变成孤儿清理这些孤儿。 - 匹配现有代码风格即使自己不喜欢。 - 验证标准git diff 的修改范围 任务范围。 ### 4. Goal-Driven Execution - 把“做什么”转化为“如何判断成功”。 - “添加验证” → “编写测试覆盖无效输入然后使测试通过”。 - “修复 bug” → “编写能复现 bug 的测试然后修复使测试通过”。 - “重构 X” → “确保重构前后所有现有测试都通过”。 - 弱标准“让它工作”不接受必须给出可自动验证的强标准。 ## Project-Specific Rules - 技术栈TypeScript Node 20 - 测试Vitest覆盖率 80% - 禁止引入新的运行时依赖除非用户明确要求 - 所有 API 端点必须有对应的集成测试 ## Common Pitfalls - 不要在修 bug 时顺手格式化整个文件 - 不要为单次调用创建抽象层 - 不要在未确认的情况下更换已有依赖这份骨架的关键在于“Common Pitfalls”段。Karpathy 原则是元规则但 LLM 对具体反例更敏感。把你团队最常出现的三种坏习惯写进去效果比抽象原则更直接。3.2 settings.json 配置片段在项目根目录创建.claude/settings.json{ permissions: { allow: [ Read, Glob, Grep ], deny: [ Bash(rm -rf *), Bash(git push --force*), Write(.env*) ] }, model: claude-sonnet-4-20250514, maxTokens: 8192, temperature: 0.2 }几个参数说明temperature设 0.2 是为了降低输出发散度Karpathy 原则本身是行为约束低温能让模型更严格地遵守maxTokens设 8192 是防止单次输出过长导致“为了填满而注水”deny列表里把危险命令和敏感文件写死避免 Surgical Changes 原则被绕过。如果你用的是团队共享配置可以把这份 settings.json 提交到仓库CLAUDE.md 也一起提交。新成员 clone 下来就自动继承约束不需要口头传达。3.3 验证配置是否被读取启动 Claude Code 后输入/memory这个命令会显示当前加载的 CLAUDE.md 内容。如果能看到你写的四条原则说明配置生效。如果显示为空检查文件是否在项目根目录、文件名是否大小写正确必须是CLAUDE.md。4. 验证请求同一提示词对比配置前后光配好不算数得用同一个提示词跑两遍看输出差异。我试过用一个典型的需求来测给一个已有的 Express 路由加限流。4.1 测试提示词给 src/routes/user.ts 里的 /login 路由加一个限流防止暴力破解。这个需求故意留了歧义限流按 IP 还是按账号阈值多少窗口多长用内存还是 Redis正好能触发 Think Before Coding 和 Simplicity First。4.2 配置前的输出特征在没有 CLAUDE.md 的情况下Claude Code 大概率会直接动手引入express-rate-limit写一个 50 行的配置对象加上自定义 keyGenerator、handler、skip 逻辑再顺手把/login路由的代码格式调整一遍。diff 里会出现 3-4 个不相关文件的改动。4.3 配置后的输出特征加载 CLAUDE.md 后同样的提示词输出会变成先提问在实现之前我需要确认几点 1. 限流维度按 IP、按账号还是两者结合 2. 阈值和窗口比如 5 次/分钟还是 10 次/15 分钟 3. 存储内存够用还是需要 Redis 做分布式限流 4. 超限后的行为返回 429还是加验证码 如果你没有特殊偏好我可以用内存存储 按 IP 5 次/分钟实现一个最小版本。你确认后它给出的实现通常只有 20-30 行且 diff 只涉及/login路由和必要的 import。这就是 Goal-Driven Execution 在起作用它把“加限流”转化成了“5 次/分钟、按 IP、返回 429”这个可验证目标。4.4 量化对比指标配置前配置后首次响应是否提问否是涉及文件数3-41-2新增代码行数50-8020-30是否引入新依赖是视确认结果diff 是否只含相关改动否是这个对比不需要跑很多次同一个提示词跑两遍就能看出差异。如果你想要更严格的验证可以把两次的 diff 都存下来用git diff --stat对比文件数和行数。5. 本篇常见错排查配置过程中最容易踩的坑集中在环境变量、文件位置和模型行为三个层面。5.1 环境变量不生效现象/status显示的还是官方端点。原因通常是 shell 配置文件没 source或者 Claude Code 在另一个终端会话里启动。排查步骤# 确认当前 shell 能看到变量 env | grep ANTHROPIC # 如果为空检查配置文件 cat ~/.zshrc | grep ANTHROPIC如果用的是 IDE 内置终端可能需要重启 IDE 才能继承新环境变量。5.2 CLAUDE.md 没被读取现象/memory显示为空。检查三点文件名必须是全大写CLAUDE.md必须放在项目根目录不是.claude/下如果项目有多个子目录Claude Code 只读根目录那一份。如果你想让子目录有额外规则可以在子目录再放一份但根目录那份是全局生效的。5.3 模型仍然过度复杂现象配了 CLAUDE.md但输出还是 500 行。原因可能是 temperature 太高或者提示词本身太模糊。两个动作把 settings.json 里的 temperature 降到 0.1-0.2在提示词里显式引用原则比如“记得 Simplicity First先给我最小实现”。LLM 对显式引用比隐式约束更敏感。5.4 请求报 404 或 401404 通常是 BASE_URL 带了多余路径或参数。确认是https://taotoken.net/api结尾没有斜杠。401 是 Key 问题去 https://taotoken.net/api-keys 重新生成一个注意复制时不要带空格。如果 Key 没问题但还是 401检查是否在控制台把该 Key 禁用了。5.5 diff 里仍然有不相关改动这说明 Surgical Changes 原则没被严格执行。在 CLAUDE.md 的 Common Pitfalls 里加一条具体反例比如“不要在修改 A 函数时调整 B 函数的缩进”。具体反例比抽象原则有效因为 LLM 在生成时会对具体模式做匹配。6. 把原则变成工程约束Karpathy 这四条原则的价值不在于理念多新而在于它能被写成一份文件、一段配置然后被工具强制执行。CLAUDE.md 是行为约束settings.json 是权限约束两者叠加才能把“发散”压住。如果你只是偶尔用 Claude Code 写脚本配一份 CLAUDE.md 就够了。如果你在团队里推 AI 辅助编程建议把这份配置提交到仓库配合 CI 检查 diff 范围。长期跑编码 Agent 的话可以在 https://taotoken.net/coding-plan 看下套餐按 Key 维度做配额和审计避免某个 Agent 循环把额度跑满。接入文档在 https://taotoken.net/doc 里面有 Claude Code、Cursor 等工具的完整配置示例。模型对话入口在 https://taotoken.net/chat 想先手动测几条提示词看输出风格的话可以从那里开始。