Claude Code 默认很笨?一个 CLAUDE.md 文件彻底改变它的行为
AI 教程教程入门6 分钟阅读
学习路径:AI 教程

Claude Code 默认很笨?一个 CLAUDE.md 文件彻底改变它的行为

Claude Code会自行假设、过度工程化、改动你没要求的文件。OpenAI联创Karpathy公开吐槽后,开发者Forrest Chang写了一个CLAUDE.md配置文件,一周内4.5万人安装。本文包含完整配置代码、安装命令和前后对比。

问题背景:Karpathy的吐槽

Andrej Karpathy,OpenAI联创、前Tesla AI总监,现已转向约80%的AI Agent驱动开发。他公开总结了AI编程工具的三大核心问题:

"模型会替你做错误假设,然后一路错下去。它们不管理困惑、不寻求澄清、不暴露矛盾、不展示权衡、该反驳时不反驳"

"它们特别喜欢过度复杂化代码和API,膨胀抽象层,不清理死代码。100行能搞定的事它能写1000行"

"它们有时会作为副作用,改动和删除它们不够理解的注释和代码,即使跟任务无关"

用过 Claude Code 的人看到这三条,应该都深有体会。

解决方案:一个 CLAUDE.md 文件

开发者 Forrest Chang 根据 Karpathy 的吐槽,写了一个 CLAUDE.md 配置文件,四个核心原则,直接改变 Claude Code 的行为模式。

GitHub 仓库:forrestchang/andrej-karpathy-skills

一周内 4.5 万开发者安装了这个文件。

CLAUDE.md 是什么?

CLAUDE.md 是一个行为配置文件,Claude Code 每次启动会话时会自动读取。文件里的内容会成为 Claude 思考你项目的一部分。

完整 CLAUDE.md 配置文件(直接复制使用)

# CLAUDE.md

Behavioral guidelines to reduce common LLM coding mistakes.
Merge with project-specific instructions as needed.

**Tradeoff:** These guidelines bias toward caution over speed.
For trivial tasks, use judgment.

## 1. Think Before Coding

**Don't assume. Don't hide confusion. Surface tradeoffs.**

Before implementing:
- State your assumptions explicitly. If uncertain, ask.
- If multiple interpretations exist, present them. Don't pick silently.
- If a simpler approach exists, say so. Push back when warranted.
- If something is unclear, stop. Name what's confusing. Ask.

## 2. Simplicity First

**Minimum code that solves the problem. Nothing speculative.**

- No features beyond what was asked.
- No abstractions for single-use code.
- No "flexibility" or "configurability" that wasn't requested.
- No error handling for impossible scenarios.
- If you write 200 lines and it could be 50, rewrite it.

Ask yourself: "Would a senior engineer say this is overcomplicated?"
If yes, simplify.

## 3. Surgical Changes

**Touch only what you must. Clean up only your own mess.**

When editing existing code:
- Don't "improve" adjacent code, comments, or formatting.
- Don't refactor things that aren't broken.
- Match existing style, even if you'd do it differently.
- If you notice unrelated dead code, mention it. Don't delete it.

When your changes create orphans:
- Remove imports/variables/functions that YOUR changes made unused.
- Don't remove pre-existing dead code unless asked.

The test: every changed line should trace directly to the user's request.

## 4. Goal-Driven Execution

**Define success criteria. Loop until verified.**

Transform tasks into verifiable goals:
- "Add validation" → "Write tests for invalid inputs, then make them pass"
- "Fix the bug" → "Write a test that reproduces it, then make it pass"
- "Refactor X" → "Ensure tests pass before and after"

For multi-step tasks, state a brief plan:
1. [Step] → verify: [check]
2. [Step] → verify: [check]
3. [Step] → verify: [check]

Strong success criteria let you loop independently.
Weak criteria ("make it work") require constant clarification.

---

**These guidelines are working if:** fewer unnecessary changes in diffs,
fewer rewrites due to overcomplication, and clarifying questions come
before implementation rather than after mistakes.

四个原则的前后对比

原则1:Think Before Coding(先想再写)

配置前:

你:给这个API端点加个缓存层。

Claude:[构建了Redis集成,包含TTL配置、缓存失效钩子、
降级逻辑和完整的抽象层]

你:我只是说内存缓存……

配置后:

你:给这个API端点加个缓存层。

Claude:"开始之前,两种理解:
1. 仅当前会话的内存缓存
2. 跨请求的Redis持久缓存

你想要哪种?另外,缓存失效是基于时间还是手动触发?"

你:内存,基于时间,60秒。

Claude:[只构建你说的那个。没有多余的东西。]

困惑在动手之前就暴露了,而不是做完之后。

原则2:Simplicity First(简单优先)

配置前:

# 你要求的是:写一个检查用户是否为管理员的函数

class UserPermissionManager:
    def __init__(self, config=None, cache_ttl=300):
        self.config = config or {}
        self.cache = {}
        self.cache_ttl = cache_ttl
        self._permission_registry = defaultdict(list)

    def check_permission(self, user_id, permission_type,
                         context=None, fallback=True):
        # ... 还有47行 ...

配置后:

# 你要求的是:写一个检查用户是否为管理员的函数

def is_admin(user_id: str) -> bool:
    return user_id in ADMIN_USER_IDS

高级工程师会说第一个版本过度设计了吗?当然。所以 Claude 自己重写了。

原则3:Surgical Changes(精准改动)

配置前——你只让它修一个 null check:

- def process_order(order_id, user):
+ def process_order(order_id: str, user: User) -> dict:
    # Fixed the null check bug
-   if order == None:
+   if order is None:
        return None
+   # Refactored for clarity
-   x = get_order(order_id)
+   order = get_order(order_id)
-   # check user
+   # Validate user permissions before processing

它加了类型注解、重命名变量、重写注释、重构函数签名。你只让它修一个 null check。

配置后:

-   if order == None:
+   if order is None:
        return None

一个改动。你要求的那个。没有别的。

原则4:Goal-Driven Execution(目标驱动)

Karpathy 称这个为核心洞察:

"LLM 非常擅长循环直到满足特定目标。别告诉它做什么,给它成功标准,然后看它干。"

配置前:

你:修复登录bug。
Claude:[改了点东西]
你:没修好。
Claude:[又改了点]
你:还是坏的。
Claude:[再改了点]

配置后:

你:修复登录bug。

Claude:"计划如下:
1. 写一个能复现bug的测试 → 验证:测试失败
2. 找到根因 → 验证:能解释为什么测试失败
3. 实现修复 → 验证:测试通过
4. 确认没有破坏其他测试 → 验证:全量测试通过

现在开始。"

[Claude独立循环直到四个检查全部通过]
[你只需要review完成的工作]

你不再需要当保姆,你变成了审查者。

安装方法(两分钟搞定)

方式A:插件安装(全局生效)

打开 Claude Code,依次运行这两个命令:

/plugin marketplace add forrestchang/andrej-karpathy-skills
/plugin install andrej-karpathy-skills@karpathy-skills

立即生效,对所有项目生效。

方式B:单项目安装

直接把上面的 CLAUDE.md 文件内容复制到你的项目根目录,保存为 CLAUDE.md 文件即可。

添加你自己的项目规则

CLAUDE.md 设计为可以和项目特定指令合并。在四个原则之后,加一个这样的段落:

## Project-Specific Guidelines

- 使用 TypeScript strict 模式
- 所有API端点必须有集成测试
- 遵循 src/utils/errors.ts 的错误处理模式
- 永远不要直接提交到 main 分支

你的项目规则叠加在四个原则之上,两者同时生效。

怎么确认生效了

三个变化你马上能注意到:

  1. diff 变干净了 — 只有你要求的改动。没有重格式化、没有重命名变量、没有你没提到的注释优化
  2. 澄清问题在实现之前出现 — Claude 不再猜测,开始提问。你花更少时间扔掉错误的代码
  3. 代码第一次就简洁 — 不再因为过度工程化而重写。不再有没有人要求的抽象层

参考来源