Claude Code 在大型代码库的最佳实践:从哪里开始

Anthropic 官方总结:Claude Code 在百万行 monorepo、几十年遗留系统、上千开发者组织里能跑成什么样,取决于围绕模型搭建的"脚手架"——CLAUDE.md、hooks、skills、plugins、LSP、MCP、subagents 该怎么配,以及谁来负责维护。

阅读时长: 11 分钟
共 5453字
作者: eimoon.com

Claude Code 已经跑在百万行级的 monorepo、几十年的遗留系统、几十个仓库的分布式架构,以及拥有上千名开发者的组织里。这些环境带来的问题,小项目里见不到——比如每个子目录的构建命令都不一样,或者遗留代码散落在没有共同根目录的文件夹中。

这篇文章整理了我们观察到的、让 Claude Code 在大规模场景下落地成功的几个共性模式。文中的"大型代码库"覆盖范围很广:百万行 monorepo、几十年累积的遗留系统、跨多个仓库的几十个微服务,或它们的任意组合。也包括那些团队不太会与 AI 编码工具联系起来的语言,比如 C、C++、C#、Java、PHP(在最近几个模型版本之后,Claude Code 在这些语言上的表现比大多数团队预期得要好)。每个大型代码库的部署都受到自己的版本控制系统、团队结构和长期形成的约定的影响,但下面这些模式具有普适性,是考虑引入 Claude Code 的团队不错的起点。

Claude Code 是怎么在大型代码库里导航的

Claude Code 像一个软件工程师那样浏览代码:遍历文件系统、读取文件、用 grep 精准定位、跨文件追踪引用。它运行在开发者本机,不需要为代码库构建并维护一个索引上传到服务器。

基于 RAG 的 AI 编码工具的做法是:把整个代码库 embedding,查询时检索相关片段。这种方案在大规模场景下容易翻车,因为 embedding 流水线追不上活跃的开发节奏。当开发者真的去查的时候,索引反映的可能是几周、几天甚至几小时前的代码状态。检索结果可能返回团队两周前就已经改名的函数,或者引用一个上个 sprint 已经删掉的模块,且对此毫无察觉。

Agentic search(智能体搜索)避开了这些失败模式。没有 embedding 流水线,也没有需要随着成千上万次提交而维护的中心化索引。每个开发者的实例都基于最新的代码工作。

但这种方式也有取舍:它在有足够初始上下文、知道该去哪里看的时候才能发挥最好。也就是说,Claude 的导航质量取决于代码库本身配置得有多好——CLAUDE.md 和 skills 是怎么分层组织上下文的。如果你让它在一个十亿行的代码库里搜索一个模糊的模式,那在工作开始前上下文窗口就被打满了。投入精力做代码库前置准备的团队,效果明显更好。

“脚手架”(harness)和模型一样重要

关于 Claude Code 最常见的误解之一是:能力完全由所用模型决定。团队习惯关注模型的 benchmark,关注它在测试任务上的表现。但在实际使用中,围绕模型搭建的生态——也就是 harness——比模型本身更能决定 Claude Code 的表现。

Harness 由五个扩展点组成——CLAUDE.md、hooks、skills、plugins、MCP servers,每个负责一项不同的职能。团队搭建它们的顺序很关键,因为每一层都建立在前一层之上。另外两个能力——LSP 集成和 subagents——补齐了整套配置。下面分别说说:

CLAUDE.md 是第一步。这是 Claude 在每次会话开始时自动读取的上下文文件:根目录的 CLAUDE.md 提供全局视图,子目录的 CLAUDE.md 提供局部约定。它们给 Claude 提供做好任何事情都需要的代码库基础知识。因为这些文件每次会话都会加载,所以应该只保留通用、广泛适用的内容,否则会拖累整体表现。

Hooks 让这套配置能自我演进。多数团队把 hooks 当作"防止 Claude 做坏事"的脚本,但更有价值的用法是用来做持续改进。一个 stop hook 可以在会话结束时回顾这次的过程,趁上下文还热乎,提出 CLAUDE.md 的更新建议。一个 start hook 可以动态加载团队特定的上下文,让每个开发者拿到适合自己模块的配置,而不需要手动调。对于 lint、format 这类自动化检查,hooks 能确定性地执行规则,比让 Claude 记住一条指令更可靠。

Skills 让专业能力随用随取,不会塞满每次会话。在一个有几十种任务类型的大型代码库里,并不是所有专业知识都需要每次会话都在场。Skills 通过"渐进披露"解决了这个问题——把专门的工作流和领域知识从主上下文中拿走,只在真正需要的时候加载。比如一个"安全审查" skill 只在 Claude 评估代码漏洞时加载,一个"文档处理" skill 只在代码改动需要更新文档时加载。

Skills 还可以绑定到特定路径,只在代码库的相关部分激活。一个负责支付服务的团队可以把他们的部署 skill 绑定到那个目录下,monorepo 里其他地方的工作就不会误触发它。

Plugins 用来分发"已经被验证可行"的配置。大型代码库的一个老问题是:好的设置容易停留在小圈子里。Plugin 把 skills、hooks 和 MCP 配置打包成一个可安装的整体,新工程师入职第一天装上插件,就立刻拥有了和老员工一样的上下文和能力。Plugin 的更新可以通过托管的市场(marketplace)在组织内部分发。

举个例子:我们合作的一家大型零售公司构建了一个 skill,把 Claude 接到他们的内部分析平台上,让业务分析师不用离开工作流就能拉数据。他们在大规模推广之前,把它打包成 plugin 分发出去。

LSP(Language Server Protocol)集成让 Claude 拥有开发者在 IDE 里一样的导航能力。大多数大型代码库的 IDE 已经在跑 LSP,“跳转到定义"和"查找所有引用"就是它在背后干活。把这个能力暴露给 Claude,它就能拿到符号级别的精度:跟着函数调用跳到定义、跨文件追踪引用、区分不同语言里同名的函数。没有 LSP 的话,Claude 只能基于文本去模式匹配,容易落在错误的符号上。我们合作的一家企业软件公司在 Claude Code 推广前先把 LSP 集成在全公司范围铺开,专门是为了让 C/C++ 导航在大规模场景下可靠。对于多语言代码库,这是性价比最高的投资之一。

MCP servers 是一切对外连接的扩展。MCP servers 是 Claude 连接内部工具、数据源和 API 的方式。最成熟的团队会构建 MCP server,把结构化搜索作为 Claude 可以直接调用的工具暴露出去。其他团队则用 MCP 把 Claude 接到内部文档、工单系统或分析平台。

Subagents 把"探索"和"编辑"分开。Subagent 是一个独立的 Claude 实例,有自己的上下文窗口,接到任务、干完活、只把最终结果返回给父 agent。在 harness 搭好之后,有些团队会用一个只读 subagent 去摸清楚某个子系统的结构,把发现写到文件里,再让主 agent 基于完整的画面去做编辑。

下面这张表整理了 harness 各个组件的定位:

组件 是什么 何时加载 适合做什么 常见误用
CLAUDE.md Claude 自动读取的上下文文件 每次会话 项目约定、代码库知识 把可复用的专业能力塞进来(那应该是 skill)
Hooks 在关键时刻触发的脚本 事件触发 自动化一致行为、捕获会话经验 用 prompt 处理本应自动化的事
Skills 针对特定任务类型的打包指令 按需加载 跨会话、跨项目复用的专业能力 把所有东西一股脑塞进 CLAUDE.md
Plugins 打包好的 skills、hooks、MCP 配置 配置后始终可用 在组织内分发可用的配置 让好用的配置只在小圈子里流传
LSP 通过语言相关服务提供实时代码情报 配置后始终可用 类型语言的符号级导航和错误检测 以为它会自动启用
MCP servers 连接外部工具和数据 配置后始终可用 让 Claude 访问其他方式碰不到的内部工具 基础还没跑通就先搭 MCP
Subagents 用于特定任务的独立 Claude 实例 调用时启动 把探索和编辑拆开、并行干活 在同一个会话里既探索又编辑

(LSP 通过 plugin 层接入;subagents 是一种委派能力,而不是一个独立的配置扩展点。)

三个成功部署里反复出现的配置模式

为大型代码库配置 Claude Code 的方式,很大程度上取决于代码库本身的结构。但我们观察过的部署里,下面三个模式反复出现。

让代码库在大规模下仍然可导航

Claude 在大型代码库里能帮上多少忙,受限于它能否找到正确的上下文。每次会话塞太多上下文会让性能下降,塞太少又会让 Claude 抓瞎。最有效的部署都在前期投入了让代码库对 Claude “可读”。几个反复出现的做法:

  • CLAUDE.md 文件保持简洁、分层。Claude 会沿着目录树叠加加载:根目录提供全局视图,子目录提供局部约定。根文件应该只放"指针"和关键陷阱,其它内容只会变成噪声。

  • 在子目录而不是仓库根目录初始化。Claude 在被限定到任务真正相关的那部分代码时表现最好。在 monorepo 里这听起来反直觉——因为很多工具假定从根访问——但 Claude 会自动向上遍历目录树,把途中遇到的每一个 CLAUDE.md 都加载进来,所以根级上下文不会丢。

  • 测试和 lint 命令按子目录限定范围。Claude 只改了一个服务,却跑了整套测试,会超时、还会浪费上下文在无关输出上。子目录级别的 CLAUDE.md 应该写清楚这一部分代码对应的命令。这对每个目录有独立测试/构建命令的服务化代码库很合适。对于带有深度跨目录依赖的编译型语言 monorepo,按子目录限定就比较困难,可能需要项目特定的构建配置。

  • 用 .ignore 文件排除生成文件、构建产物和第三方代码。把 permissions.deny 规则提交到 .claude/settings.json,意味着排除规则纳入版本控制——每个开发者都获得一样的"降噪”,不用各自配。在某些代码库里,生成文件本身就是开发对象。负责代码生成器的开发者可以在自己的本地配置里覆盖项目级排除,不影响其他人。

  • 当目录结构本身不能承担"导览"作用时,建一份代码库地图。对于代码不按常规目录结构组织的团队,在仓库根目录放一份轻量级 markdown,列出每个顶层目录、用一行字说明它是什么——这就给了 Claude 一份"目录索引",它可以在打开文件之前先扫一遍。对于有几百个顶层目录的代码库,这种方式最好分层做:根文件只描述最高层结构,子目录里的 CLAUDE.md 提供下一层细节,按需加载。对于更简单的情况,用 @ 提及具体文件或目录也能起到同样的作用。

  • 跑起 LSP server,让 Claude 按符号搜索而不是按字符串。在一个大型代码库里 grep 一个常见的函数名,会返回成千上万个匹配,Claude 会一个一个打开文件去判断哪个才是要的。LSP 只返回真正指向同一个符号的引用,过滤发生在 Claude 读任何文件之前。要启用它,需要为你的语言安装对应的 code intelligence plugin 和语言服务二进制;Claude Code 文档里覆盖了可用的 plugin 和常见排错。

一个例外:分层的 CLAUDE.md 方案在某些边界情况下会失效,比如有数十万个文件夹、上百万个文件的代码库,或者跑在非 git 版本控制上的遗留系统。后续系列里会专门讨论这些场景。

随着模型能力演进,主动维护 CLAUDE.md

模型会持续进化,今天写给当前模型的指令,可能反过来拖累未来的模型。那些用来引导 Claude 绕开旧版本短板的 CLAUDE.md,可能在下一个模型发布之后就不再必要——甚至会变成约束。举个例子:某条规则告诉 Claude 把每次重构拆成单文件改动,这对早期模型有用,但会阻止新模型做它本来能轻松搞定的跨文件协同改动。

针对模型某个具体限制(无论是推理上的,还是 Claude Code 工具上的)而搭的 skill 和 hook,当那个限制不再存在时就变成了负担。比如一个为了在 Perforce 代码库里强制执行 p4 edit 而拦截文件写入的 hook,在 Claude Code 原生支持 Perforce 模式之后就成了多余。

团队应当预期:每 3 到 6 个月做一次比较彻底的配置审查;另外,每当一次重大模型发布之后感觉"表现卡在某个水平",也是审查的时机。

明确 Claude Code 的管理和推广归属

光靠技术配置推不动落地。我们见过的成功组织都在"组织层"上也投了资。

铺得最快的那批团队,在大规模开放访问之前先做了一次专门的基础设施投资。一个小团队、甚至一个人,提前把工具链都接好,让开发者第一次接触 Claude Code 时它就已经匹配开发流程了。一家公司是两个工程师搭了一整套 plugin 和 MCP,第一天就可用。另一家则是有整个"AI 编码工具管理"团队提前把基础设施就位。两种情况下,开发者的第一次使用体验都是高效的而不是挫败的,扩散随之而来。

今天承担这部分工作的团队,多数挂在 developer experience 或 developer productivity 之下——通常这些团队本来就负责新员工 onboarding 和开发工具建设。一个在多个组织里正在成形的新角色是 agent manager:一个混合 PM/工程师职能,专门管理 Claude Code 生态。对没有专门团队的组织而言,最小可行方案是一个 DRI(直接责任人):一个人对 Claude Code 配置负责,有权对设置、权限策略、plugin 市场、CLAUDE.md 约定做决定,并负责让这些东西保持新鲜。

自下而上的扩散能制造热情,但如果没有人来把"什么是有效的"集中起来,就会碎片化。你需要有一个人或一个团队负责整理并推广正确的 Claude Code 约定(比如统一的 CLAUDE.md 层级结构、一套精选的 skills 和 plugins)。没有这件事,知识只会留在小圈子里,推广也会卡在某个点上。

在大型组织、特别是受监管行业,治理问题会很早冒出来:谁来决定哪些 skill 和 plugin 可用?怎么避免几千个工程师各自重造同一个轮子?怎么保证 AI 生成的代码走和人写的代码相同的评审流程?我们的建议是:从一组已审核的 skill、一套强制的代码评审流程、有限的初始访问开始,随着信心建立逐步放开。

那些部署最顺滑的组织,都很早就建立了跨职能工作组——把工程、信息安全、治理代表拉到一起,共同定义需求并制定推广路线图。

把这些模式应用到你的组织

Claude Code 是围绕"常规软件工程环境"设计的:工程师是代码库的主要贡献者、仓库使用 Git、代码遵循标准目录结构。大多数大型代码库都属于这一类,但非常规设置——比如带大量二进制资源的游戏引擎、使用非常规版本控制的环境、由非工程师贡献代码的代码库——需要额外的配置工作。本文的建议基于常规情境,列出的模式已经在很多客户那里验证过。剩下的复杂性要结合你自己的代码库、工具链和组织来判断。这也是 Anthropic Applied AI 团队的工作内容——直接和工程团队合作,把这些通用模式翻译成你们组织的具体要求。


原文:How Claude Code works in large codebases: Best practices and where to start,发布于 Anthropic 官方博客,“Claude Code at scale” 系列。

关于

关注我获取更多资讯

月球基地博客公众号二维码,扫码关注获取更多 AI 与编程资讯
📢 公众号
月球基地博客作者个人微信二维码,扫码交流 AI 与编程话题
💬 个人号
使用 Hugo 构建
主题 StackJimmy 设计