☰
Andrej Karpathy Skills 实战:用 CLAUDE.md 四条原则驯服 Claude Code 的 LLM 编码混乱
2026/9/28 4:14:56 网站建设 项目流程

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 Code

Claude 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 指向 TaoToken

Claude Code 读取ANTHROPIC_BASE_URL和ANTHROPIC_API_KEY两个环境变量。在~/.zshrc或~/.bashrc里加:

export ANTHROPIC_BASE_URL="https://taotoken.net/api" export ANTHROPIC_API_KEY="sk-你的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 或 401

404 通常是 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 ,想先手动测几条提示词看输出风格的话,可以从那里开始。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询