Claude Code 在大型代码库中的工作原理

Hacker News Top 产品

摘要

Anthropic 的博文详细介绍了在大型复杂代码库中使用 Claude Code 的最佳实践,阐述了代理搜索以及如 CLAUDE.md 文件等扩展的“利用”如何在大规模下提升导航和性能。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/05/15 06:29

# Claude Code 在大型代码库中的工作原理:最佳实践与入门指南 来源:https://claude.com/blog/how-claude-code-works-in-large-codebases-best-practices-and-where-to-start Claude Code 已在生产环境中运行于百万行级别的单体仓库、数十年历史的遗留系统、跨越数十个仓库的分布式架构,以及拥有数千名开发者的组织中。这些环境带来了小型简单代码库所没有的挑战,无论是每个子目录各不相同的构建命令,还是散落在多个文件夹中、没有共享根目录的遗留代码。 本文总结了我们在大规模采用 Claude Code 时观察到的成功模式。我们使用“大型代码库”来指代多种部署场景:数百万行的单体仓库、历经数十年构建的遗留系统、跨越独立仓库的数十个微服务,或上述任意组合。这也包括那些运行在团队通常不认为与 AI 编程工具有关的语言(如 C、C++、C#、Java、PHP)上的代码库(在这些情况下,Claude Code 的表现往往超出大多数团队的预期,尤其是在最近的模型版本中)。尽管每个大型代码库的部署都会受到其特定的版本控制、团队结构和积累的约定所影响,但本文中的模式具有普适性,是考虑采用 Claude Code 的团队的良好起点。 ## Claude Code 如何导航大型代码库 Claude Code 导航代码库的方式与软件工程师类似:它会遍历文件系统、读取文件、使用 grep 精确查找所需内容,并跨代码库追踪引用。它在开发者本地机器上运行,无需构建、维护或上传代码库索引到服务器。 早期的 AI 编程工具依赖于基于 RAG 的检索——将整个代码库嵌入,并在查询时检索相关片段。在大规模场景下,这些系统可能失败,因为嵌入管道跟不上活跃工程团队的步伐。当开发者查询索引时,它反映的是几天、几周甚至几小时前的代码库状态。然后检索返回一个团队两周前重命名的函数,或者引用上一个迭代中已删除的模块,且没有任何迹象表明这些信息已过时。 代理式搜索避免了这些失败模式。当数千名工程师提交新代码时,无需维护嵌入管道或集中式索引。每个开发者的实例都基于实时代码库工作。 但这种方法有一个权衡:当 Claude 拥有足够的起始上下文来知道从哪里开始时,效果最佳。这意味着 Claude 的导航质量取决于代码库的配置方式——通过 CLAUDE.md 文件和技能来分层提供上下文。如果你要求它在一个数十亿行的代码库中找到所有某个模糊模式的出现,你会在工作开始之前就遇到上下文窗口限制。投入精力配置代码库的团队会看到更好的结果。 ## 框架(Harness)与模型同样重要 关于 Claude Code 最常见的误解之一是,其能力完全由所使用的模型决定。团队关注模型的基准测试结果以及在测试任务上的表现。但实际上,围绕模型构建的生态系统——即框架——比模型本身更能决定 Claude Code 的表现。 框架由五个扩展点组成——CLAUDE.md 文件、钩子(hooks)、技能(skills)、插件(plugins)和 MCP 服务器——每个都有不同的功能。团队构建这些扩展点的顺序很重要,因为每一层都建立在前一层之上。另外两项能力——LSP 集成和子代理——完善了整体设置。下面我们解释每个组件和能力的作用: **CLAUDE.md**(https://code.claude.com/docs/en/memory)**文件优先考虑**。这些是 Claude 在每个会话开始时自动读取的上下文文件:根文件用于全局视角,子目录文件用于本地约定。它们为 Claude 提供做好任何事情所需的代码库知识。由于它们在每个会话中都会加载,无论任务是什么,保持它们聚焦于广泛适用的知识点可以防止它们成为性能拖累。 **钩子**(https://code.claude.com/docs/en/hooks-guide)**使配置能够自我改进**。大多数团队将钩子视为阻止 Claude 做错事的脚本,但它们更有价值的用途是持续改进。一个 stop 钩子可以在会话结束后反思发生了什么,并在上下文仍然新鲜时提议更新 CLAUDE.md。一个 start 钩子可以动态加载团队特定的上下文,使每个开发者无需手动配置就能获得其模块的正确设置。对于 linting 和格式化等自动化检查,钩子可以确定性地执行规则,产生比依赖 Claude 记住指令更一致的结果。 **技能**(https://code.claude.com/docs/en/skills)**让正确的专业知识按需可用,而不会使每个会话变得臃肿**。在拥有数十种任务类型的大型代码库中,并非所有专业知识都需要在每个会话中存在。技能通过渐进式披露(https://platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices)来解决这个问题,将专门的工作流和领域知识卸载,否则它们会争夺上下文空间,并且只在任务需要时才加载。例如,一个安全审查技能在 Claude 评估代码漏洞时加载,而一个文档处理技能则在代码变更需要更新文档时加载。 技能还可以限定到特定路径,使其仅在代码库的相关部分激活。负责支付服务的团队可以将其部署技能绑定到该目录,这样当有人在单体仓库的其他地方工作时,它就不会自动加载。 **插件**(https://code.claude.com/docs/en/plugins)**分发有效的配置**。大型代码库的一个挑战是,好的配置可能停留在小圈子内。一个插件将技能、钩子和 MCP 配置打包成一个可安装的包,这样当新工程师第一天安装该插件时,他们立即拥有与已经使用 Claude 的同事相同的上下文和能力。插件更新可以通过托管市场(https://support.claude.com/en/articles/13837433-manage-claude-cowork-plugins-for-your-organization)在整个组织内分发。 例如,我们合作的一家大型零售组织构建了一个技能,将 Claude 连接到其内部分析平台,这样业务分析师无需脱离自己的工作流程即可拉取性能数据。他们在向业务部门广泛推广之前,将其作为插件分发。 **语言服务器协议(LSP)集成让 Claude 拥有与开发者在 IDE 中相同的导航能力**。大多数大型代码库的 IDE 已经在运行 LSP,支持“转到定义”和“查找所有引用”。将 LSP 暴露给 Claude 可以提供符号级别的精确度:它可以跟踪函数调用到其定义、跨文件追踪引用,并区分不同语言中名称相同的函数。没有 LSP,Claude 依赖文本模式匹配,可能定位到错误的符号。我们合作的一家企业软件公司在 Claude Code 推广之前,就在全组织部署了 LSP 集成,专门为了确保 C 和 C++ 导航在大规模下的可靠性。对于多语言代码库,这是最高价值投资之一。 **MCP 服务器扩展一切**。MCP 服务器是 Claude 连接到内部工具、数据源和 API 的方式,这些是它无法直接访问的。最成熟的团队构建了 MCP 服务器,将结构化搜索暴露为 Claude 可以直接调用的工具。其他人则将 Claude 连接到内部文档、工单系统或分析平台。 **子代理**(https://code.claude.com/docs/en/sub-agents)**将探索与编辑分离**。子代理是一个独立的 Claude 实例,拥有自己的上下文窗口,负责接收任务、完成工作,并仅将最终结果返回给父代理。一旦框架就位,一些团队会启动一个只读子代理来映射子系统并将发现写入文件,然后由主代理在掌握全局信息后进行编辑。 *Claude Code 扩展层一目了然*。下表总结了每个组件的作用、加载时机以及我们常见的使用误区: | 组件 | 功能 | 加载时机 | 最佳用途 | 常见误解 | |------|------|----------|----------|----------| | CLAUDE.md | Claude 自动读取的上下文文件 | 每个会话 | 项目特定约定、代码库知识 | 用它存放本应属于技能的可复用专业知识 | | 钩子 (Hooks) | 在关键时机运行的脚本 | 由事件触发 | 自动化一致的行为、捕获会话学习成果 | 用提示词代替本应自动运行的任务 | | 技能 (Skills) | 针对特定任务类型打包的指令 | 按需加载,当相关时 | 跨会话和项目的可复用专业知识 | 将所有内容加载到 CLAUDE.md 而不是使用技能 | | 插件 (Plugins) | 打包的技能、钩子、MCP 配置 | 配置后始终可用 | 在组织内分发有效配置 | 让好的配置停留在小圈子内 | | 语言服务器协议 (LSP)* | 通过语言特定服务器提供实时代码智能 | 配置后始终可用 | 符号级导航和类型语言中的自动错误检测 | 认为这是自动的 | | MCP 服务器 | 连接外部工具和数据 | 配置后始终可用 | 让 Claude 访问无法直接到达的内部工具 | 在基础配置还没做好之前就构建 MCP 连接 | | 子代理* | 用于特定任务的独立 Claude 实例 | 调用时 | 将探索与编辑分离、并行工作 | 在同一个会话中进行探索和编辑 | *LSP 通过插件层访问。子代理是一种委派能力,而非配置的扩展点。 ## 来自成功部署的三个配置模式 如何为大型代码库配置 Claude Code 很大程度上取决于代码库的结构。尽管如此,在我们观察到的部署中,始终出现三个模式。 ### 使代码库在大规模下可导航 Claude 在大型代码库中提供帮助的能力受限于它找到正确上下文的能力。每个会话加载过多上下文会降低性能,而上下文太少则让 Claude 盲目导航。最高效的部署会提前投入,使代码库对 Claude 来说易于理解。几个一致出现的模式: - **保持 CLAUDE.md 文件精简且分层**。Claude 在代码库中移动时增量加载这些文件:根文件用于全局视角,子目录文件用于本地约定。根文件应该只包含指针和关键陷阱;其他一切都会变成噪音。 - **在子目录而非仓库根目录初始化**。当 Claude 限定在代码库中与任务实际相关的部分时,效果最佳。在单体仓库中,这可能会感觉违反直觉,因为工具通常假定根目录访问,但 Claude 会自动向上遍历目录树并沿途加载每个 CLAUDE.md 文件,因此根级别的上下文永远不会丢失。 - **按子目录限定测试和 lint 命令的范围**。当 Claude 只更改了一个服务时,运行整个测试套件会导致超时,并在无关的输出上浪费上下文。子目录级别的 CLAUDE.md 文件应指定适用于该部分代码库的命令。这对于每个目录拥有自己的测试和构建命令的服务导向型代码库效果良好。在具有深层跨目录依赖关系的编译型语言单体仓库中,按子目录限定范围更难实现,可能需要特定于项目的构建配置。 - **使用.ignore 文件排除生成的文件、构建产物和第三方代码**。在 `.claude/settings.json` 中提交 `permissions.deny` 规则意味着排除项是版本控制的,因此团队中的每个开发者都能获得相同的降噪效果,而无需自己配置。在某些代码库中,生成的文件本身就是开发工作的对象。从事代码生成器开发的开发者可以在本地设置中覆盖项目级别的排除项,而不影响团队其他成员。 - **当目录结构本身不够清晰时,构建代码库地图**。对于代码没有整合到传统目录结构的组织,可以在仓库根目录创建一个轻量级 markdown 文件,列出每个顶级文件夹并附上一行描述,这样 Claude 在打开文件之前就可以扫描一个目录表。对于拥有数百个顶级文件夹的代码库,这最好采用分层方法:根文件只描述最高层结构,子目录的 CLAUDE.md 文件提供下一级细节,随着 Claude 在树中移动按需加载。对于更简单的情况,使用 @-mention 指定 Claude 应引用的具体文件或目录可以达到相同效果。 - **运行 LSP 服务器,让 Claude 按符号而非字符串搜索**。在大型代码库中对一个常见函数名进行 grep 会返回数千个匹配项,Claude 会浪费上下文打开文件来判断哪个重要。LSP 只返回指向同一符号的引用,因此在 Claude 读取任何内容之前就已经完成了过滤。设置此功能需要安装对应语言的代码智能插件(https://code.claude.com/docs/en/discover-plugins#code-intelligence)和相应的语言服务器二进制文件;Claude Code 文档涵盖了可用的插件和故障排除。 **一个注意事项**:在某些边缘情况下,即使分层 CLAUDE.md 方法也会失效,例如拥有数十万个文件夹和数百万个文件的代码库,或使用非 git 版本控制的遗留系统。我们将在本系列的后续文章中讨论它们的挑战。 ### 随着模型智能的演进主动维护 CLAUDE.md 文件 随着模型的发展,为当前模型编写的指令可能会对未来的模型产生反作用。之前指导 Claude 完成它曾经难以处理的模式的 CLAUDE.md 规则,在下一个模型发布时可能变得不必要,甚至主动限制。例如,一个告诉 Claude 将每个重构拆分为单文件修改的 CLAUDE.md 规则可能帮助早期模型保持正轨,但却会阻止更新模型进行它擅长的协调式跨文件编辑。 为补偿特定模型限制(无论是在模型的推理能力还是 Claude Code 本身的工具能力上)而构建的技能和钩子,一旦这些限制不复存在,就变成了开销。例如,一个拦截文件写入以强制在 Perforce 代码库中执行 p4 edit 的钩子,在 Claude Code 添加原生 Perforce 模式后就变得多余。 团队应预计每三到六个月进行一次有意义的配置审查,但在主要模型发布后,当性能感觉停滞不前时,也值得进行一次审查。 ### 分配 Claude Code 管理和采用的所有权 仅靠技术配置并不足以推动采用。做对这件事的组织还投资了组织层面的工作。 传播最快的推广活动是在广泛开放访问之前,先进行专门的基础设施投入。一个小团队,有时甚至是一个人,预先搭建好工具链,这样开发者第一次接触 Claude 时,它就已经适配了他们的工作流程。在一家公司,几位工程师构建了一套插件和 MCP,上线第一天就可用。在另一家公司,一个专注于管理 AI 编程工具的团队在推广开始之前就已经部署好了基础设施。在这两种情况下,开发者的首次体验都富有成效而非令人沮丧,采用率随之扩散。 目前做这项工作的团队通常归属于开发者体验或开发者生产力团队,这是典型的

相似文章

Claude Code: 智能体编程最佳实践

Anthropic Engineering

本文介绍了使用 Anthropic 的 Claude Code 这一智能体编程环境的最佳实践,重点包括管理上下文窗口、为代码提供验证标准,以及将探索与执行分离以提升性能。

深入Claude Code:当前与未来AI代理系统的设计空间

Hugging Face Daily Papers

本文分析了Claude Code作为代理编程工具的架构,识别出影响其实现的五种人类价值观和十三项设计原则,包括安全系统、上下文管理和可扩展机制。研究将Claude Code与OpenClaw进行比较,展示了不同的部署环境如何针对常见的AI代理设计挑战产生不同的架构解决方案。