Anthropic 上周发了一篇文章,讲 Claude Code 在企业级代码库里的最佳实践。
文中覆盖的场景包括百万行级别的 monorepo、跑了几十年的遗留系统、几十个微服务分散在不同仓库。内容中包含了非常多针对于大型项目的精细化管理,非常值得学习和借鉴。

📌 苏米注:随着 AI 编程工具从"个人玩具"走向"企业级基础设施",如何在大型代码库中高效使用 Claude Code 已经成为 2026 年工程团队最关注的问题之一。Anthropic 这篇官方指南首次系统性地梳理了从配置层到组织层的完整实践框架,对国内团队尤其有参考价值。
CLAUDE.md 的最佳实践
分层写,不要全堆根目录
Claude 在启动时自动加载 CLAUDE.md,沿目录树向上查找,逐层叠加。你可以这样组织:
repo/
├── CLAUDE.md # 全局约定:代码风格、提交规范、关键路径
├── services/
│ └── payments/
│ └── CLAUDE.md # 支付服务专属:测试命令、部署流程、特殊约束
└── infra/
└── CLAUDE.md # 基础设施专属:terraform 规范、云账号信息
根目录 CLAUDE.md 只放真正全局的内容:
# Repo 全局约定
## 提交规范
使用 conventional commits。feat/fix/chore,不要缩写。
## 测试
每个 PR 必须有对应测试。集成测试放 tests/integration/,单元测试和源码同目录。
## 关键路径
- 支付相关代码在 services/payments/,任何改动需要额外审查
- 共享类型定义在 packages/types/,改动会影响所有服务
- 不要直接修改 generated/ 目录,那是自动生成的
子目录 CLAUDE.md 只放局部的东西:
# 支付服务
## 测试命令
cd services/payments && go test ./... -tags=integration
## 部署
不要直接 kubectl apply。走 internal/deploy.sh,它会做 canary 检查。
## 注意
Stripe webhook 处理在 handlers/webhook.go。幂等性逻辑很脆,改之前读注释。
从 services/payments/ 启动 Claude,它会同时加载两个 CLAUDE.md。根级上下文不会丢。
错误做法是把什么都堆进根目录。内容越多,每次会话的噪音越大,性能反而下降。原则很简单:只放广泛适用的内容,专项知识放 Skills。
从子目录启动,不要总从 repo 根目录启动
从子目录进去效果明显更好:
# 不推荐:在 repo 根目录启动,上下文太宽
cd ~/projects/myrepo
claude
# 推荐:在任务相关的子目录启动
cd ~/projects/myrepo/services/payments
claude
不用担心根级的 CLAUDE.md 被丢失,因为它会自动地进行向上加载,不会丢失全局的约定。
用 .ignore 排除噪音,权限配置提交到版本库
一个非常小但见效特别快的配置。生成文件、构建产物、第三方代码不应该出现在 Claude 的搜索结果里:
// .claude/settings.json
{
"permissions": {
"deny": [
"Read(.next/**)",
"Read(dist/**)",
"Read(node_modules/**)",
"Read(vendor/**)",
"Read(generated/**)",
"Read(**/*.pb.go)"
]
}
}
后续可以把排除规则提交进版本库,整个团队共享同一套配置。对于只在专门处理生成代码的情况,可以在本地的 ~/.claude/settings.json 里覆盖,不影响其他人。
对代码库结构写一份地图
目录结构本身不够直观时,在根目录放一个 markdown 文件当索引。格式越简单越好:
# 代码库地图
## 核心服务
- services/api/ — REST API 网关,处理鉴权和路由
- services/payments/ — 支付处理,对接 Stripe 和微信支付
- services/notify/ — 消息推送,支持短信/邮件/APP
## 基础设施
- infra/terraform/ — 所有云资源定义
- infra/k8s/ — Kubernetes manifests
## 共享库
- packages/types/ — 跨服务共享的类型定义
- packages/utils/ — 公共工具函数
## 不要碰
- generated/ — proto 自动生成,不要手动修改
- vendor/ — 依赖快照
几百个顶层目录的情况分层处理:根目录地图只描述最高层结构,子目录 CLAUDE.md 提供下一层细节,按需加载。
接 LSP 加速代码搜索
这是大型代码库里收益最高的单项投入之一。
| 场景 | 无 LSP | 有 LSP |
|---|---|---|
| 搜索函数引用 | grep 返回 3247 个结果,逐个判断 | 精准返回 12 个真正调用点 |
| 符号定位 | 文本匹配,误报率高 | AST 级别识别,零误报 |
| 跨文件重构 | 手动逐个修改 | 一键重命名所有引用 |
配置方式是安装对应语言的代码智能插件,再在机器上安装对应的 language server binary。Claude Code 文档里有各语言的插件列表和排错指引。
Harness 五个扩展点
Anthropic 把配置层叫做 harness,分五个扩展点:
| 扩展点 | 特性 | 适用场景 |
|---|---|---|
| CLAUDE.md | 每次会话自动加载 | 全局约定、代码规范 |
| Hooks | 确定性执行 | Lint、格式化、安全检查 |
| Skills | 按需加载 | 专项流程(部署、审查) |
| Plugins | 打包分发 | 团队配置共享 |
| MCP | 连接外部工具 | 内部搜索、Jira、数据库 |
Hooks:确定性执行,不依赖模型记忆
需要每次都执行的事情用 Hooks,不要用 prompt 提醒。最常见的用法是写完文件自动跑格式化和 lint:
// .claude/settings.json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write",
"hooks": [{
"type": "command",
"command": "npm run lint:fix"
}]
}
]
}
}
也可以在提交前做安全检查:
# .claude/hooks/pre-commit.sh
#!/bin/bash
# 阻止提交包含密钥的文件
if git diff --cached --name-only | grep -qE '\.(env|key|pem)$|creds\.'; then
echo "BLOCKED: 检测到可能包含密钥的文件"
exit 1
fi
Hooks 是确定性的,Skills 是概率性的。需要每次都发生的事情,不要靠 prompt 提醒模型,用 Hooks 保证执行。
Hooks 还有一个被低估的用途:Stop hook 在会话结束后运行,趁上下文还在可以触发任意脚本。比如把会话摘要写入日志,或者提示工程师手动更新 CLAUDE.md。
Skills:上下文按需加载
一个大型代码库可能有几十种任务类型。Skills 解决的是上下文膨胀问题:Claude 读取 skill 的描述,判断当前任务是否相关,相关才加载。
比如给支付服务单独写一个部署 skill,放在 services/payments/.claude/skills/ 下,它只在支付服务目录的会话里自动激活。在 services/api/ 里工作时,这个 skill 不会出现在上下文里。
Plugins:把好配置打包分发
团队里往往只有少数人搭出了好用的配置,Plugin 解决分享问题:
company-claude-plugin/
├── .claude-plugin/
│ └── plugin.json # 插件元数据
├── skills/
│ ├── deploy/
│ │ └── SKILL.md # 部署流程
│ └── security-review/
│ └── SKILL.md # 安全审查清单
├── hooks/
│ └── hooks.json # lint、格式化、密钥检查
└── mcp/
└── mcp.json # 内部工具连接配置
新员工入职只需一条命令:
claude plugins install @company/claude-plugin
安装后立即获得:部署流程 skill、安全审查 skill、自动 lint hook、内部搜索 MCP。拿到的是和之前完全一样的配置,不用从零摸索。
MCP:连接内部工具
MCP 让 Claude 访问它原本够不到的东西:内部文档、系统数据库、自建工具。对大型代码库最直接的价值是把结构化代码搜索暴露给 Claude:
// .mcp.json
{
"mcpServers": {
"codesearch": {
"command": "npx",
"args": ["-y", "@internal/codesearch-mcp"],
"env": {
"INDEX_URL": "https://search.internal.company.com",
"TOKEN": "${CODESEARCH_TOKEN}"
}
},
"jira": {
"command": "npx",
"args": ["-y", "@internal/jira-mcp"],
"env": {
"JIRA_URL": "https://company.atlassian.net",
"JIRA_TOKEN": "${JIRA_TOKEN}"
}
}
}
}
接入后,Claude 在会话里可以直接:
- 查一下 handlePayment 这个符号在哪些服务里被调用 → 返回精确的跨 repo 引用列表
- 看一下 PAY-1234 这个 ticket 的需求 → 直接读取需求描述,不用离开终端
📌 苏米注:国内团队在落地 MCP 时最常见的误区是"先配工具再想场景"。正确的做法是反过来——先列出团队日常最耗时的 3-5 个操作(比如查日志、看监控、提工单),然后针对性地接入对应的 MCP Server。每个 Server 都应该解决一个明确的痛点,而不是为了"集成"而集成。
配置要随模型版本迭代
Anthropic 建议每三到六个月做一次配置 review,在大版本模型发布后也做一次。
原因是模型能力在变。比如之前 CLAUDE.md 里面可能这样写:
## 重构规范
每次只改一个文件,改完确认无误再改下一个。
旧模型做跨文件重构时能力有限,但新模型跨文件协调能力强了,这条规则反而变成约束,让本来可以一次完成的重构被强制拆成十几步。
所以定期清理过期配置和写新配置一样重要。review 的时候可以问自己:这条规则是为了弥补模型的局限写的,还是代码库本身的约定?前者要定期重新评估,后者长期有效。
组织层面怎么落地
技术配置做好了,在团队和公司中推广还是会卡在组织层面。Anthropic 总结了几个规律。
先把基础设施做好,再推给所有人
推广效果好的团队,在大范围推广之前都有一个小的先行投入。从最低配置版本开始,推广前一周,指定一个人把下面这几件事做完:
- 写根目录 CLAUDE.md(全局约定)
- 把常见噪音文件加入 .claude/settings.json 的 deny 列表
- 把 lint/格式化 hook 配好并提交
- 写一份代码库地图(CODEBASE.md)
- 打包成 plugin,让所有人 install 即用
📌 苏米注:Anthropic 提到了一个很有意思的角色——Agent Manager 工程师。这个角色类似于 PM/工程师混合定位,管 CLAUDE.md 体系、Plugin 市场、权限策略,负责让好配置在组织内传播。在国内,这个职责可能落在 DevOps 团队或技术委员会身上。如果你的团队规模超过 20 人且已经开始用 AI 编程工具,建议尽早指定专人负责。
如果没有专职团队,最低配置是一个 DRI:一个人对整套 Claude Code 配置有决策权和维护责任。具体工作包括:
- 维护根目录和各子系统的 CLAUDE.md
- 管理公司内部的 plugin 版本和分发
- 定期做配置 review(新模型发布后、采用率停滞时)
- 收集各团队的好配置,整合进公司 plugin
- 处理权限和安全策略(哪些工具 Claude 可以调用)