第 9 章

处理大型与遗留代码库

小型项目Claude Code几分钟即可理解,真正的考验是拥有两百万文件的单体仓库。处理那些大到无法放入上下文、老到不符合现代惯例、关键到不能草率重写的代码库,需要特殊的策略。

使用 Git Worktrees 进行并行工作

最简单的扩展技术也是最少被使用的:git worktrees。

Worktree 为一个分支创建一个独立的工作目录,而无需再次克隆整个仓库。每个 worktree 有自己检出的文件、自己的索引,而且——关键的是——可以运行自己独立的 Claude Code 会话。这些会话不共享上下文,互不干扰。它们在同一个仓库上操作,但在完全独立的目录中。

git worktree add ../feature-auth feature/auth
git worktree add ../feature-payments feature/payments

现在你可以在 ../feature-auth 中运行 Claude Code 处理认证,同时在 ../feature-payments 中运行另一个实例处理支付系统。两个会话都可以完全访问仓库历史,但它们的文件更改、context window 和对话历史是完全独立的。

这对大型代码库很重要,因为最大的瓶颈通常是串行工作。你不能在同一个目录中不同分支上运行两个 Claude Code 会话——它们会互相踩文件。Worktrees 消除了这个限制。

这个模式线性扩展。三个分支,三个 worktree,三个会话。限制只是你机器的资源和你的 API 预算,而不是任何架构上的限制。对于在单体仓库中同时推进多个独立功能的团队来说,worktrees 将一个 Claude Code 体验变成了多个并行体验。

一个实际细节:如果仓库中存在 .claude/ 目录,每个 worktree 都会获得自己的 .claude/ 目录,因此项目级的 CLAUDE.md 和设置会独立应用。这意味着 CLAUDE.md 的内容(如第三章所述)可以跨 worktree 复合积累而不冲突。

单体仓库的文件建议自定义

Claude Code 的 @ 自动补全在你输入时建议文件,这对典型仓库效果很好。对于大型单体仓库,默认的文件索引可能很慢,或者遗漏深层嵌套目录结构中的文件。

解决方案是自定义索引。你可以提供一个脚本,生成 Claude Code 在你输入 @ 时提供的文件建议。这个脚本可以实现任何逻辑:优先考虑最近修改的文件,排除构建产物,只索引你关心的包,或者提供完全自定义的排序。

对于有数百个包的单体仓库,一个过滤到与你当前工作相关的包的自定义索引脚本,可以将 @ 体验从令人不知所措变为精准。你不再需要滚动数千个文件,而是看到那二十个重要的文件。

这是一个影响巨大的小功能。在一个有一万个文件的单体仓库中,能够快速引用正确的文件可以节省上下文(你直接指向正确的代码,而不是让 Claude 搜索)并节省时间(当你已经知道去哪里找时,跳过探索阶段)。

Explore Subagent

当你不知道去哪里找时,Explore subagent 专为导航而设计。

Explore 是一个只读、低成本的 subagent(其架构在第四章中介绍)。它不能修改文件或运行改变状态的命令。它只能读取、搜索和报告。这使它快速、廉价且安全,即使在你还在熟悉代码库的情况下也能放心部署。

Explore subagent 在自己的 context window 中运行,这意味着它可以在调查过程中读取数十个文件,而不消耗你主对话的上下文。它返回一个摘要。你得到了答案,而无需付出探索旅程的代价。

Explore 还支持可配置的彻底程度。对于一个关于函数定义位置的快速问题,它窄范围搜索并快速返回。对于一个关于模块如何工作的全面理解,它广泛搜索、跟踪交叉引用,并产生详细分析。彻底程度参数让你在速度和深度之间权衡。

在大型代码库中大胆使用 Explore。成本很低——它运行在最便宜的可用模型上,结果运行在隔离的上下文中。替代方案是用主会话一个一个地读取文件,用本可以委派的探索内容填满你的 context window。

并行研究 Subagent

Explore 是一个单独的调查员。要理解一个大型系统,你需要一个研究团队。

多个 subagent 可以并行运行,每个调查代码库的不同方面。一个读取认证模块,另一个检查数据库访问层,第三个审查 API 路由。每个返回一个聚焦的摘要。主对话编排调查并综合结果。

这种模式对于入职一个陌生系统特别有效。你不再需要花几个小时按顺序阅读代码,而是派出并行调查员,在几分钟内获得对系统的多角度理解。成本比单个 Explore 调用高——你在运行多个 subagent——但节省的时间是可观的,而且上下文隔离意味着你的主窗口保持干净(如第四章所述)。

研究团队模式也适用于变更前的影响分析。在修改一个共享工具函数之前,派出 subagent 调查每个导入它的模块。每个 subagent 报告该函数在其区域的使用方式。你获得全面的影响评估,而无需手动追踪依赖。

对于庞大的代码库,这不是可选的。没有人能在脑中容纳数百万行的代码库。并行 subagent 给你一种快速调查广大领域的方式,然后将主会话聚焦在重要的特定区域。

任务依赖管理

大型代码库上的复杂工作通常涉及相互依赖的任务。你不能在数据库 schema 迁移完成之前更新 API 端点。你不能在 API 和数据库更改都完成之前编写集成测试。你不能在测试通过之前部署。

Claude Code 的任务系统支持使用 blocksblockedBy 关系进行显式依赖声明。这实现了波次执行:没有依赖的任务先运行,依赖它们的任务接着运行,依此类推,直到一切完成。

这个模式的工作方式如下:

  • 通过将工作分解为具有明确边界的离散任务来规划工作。
  • 声明任务之间的依赖关系。任务 A blocks 任务 B。任务 C 被 A 和 B 共同 blocked。
  • 执行。Claude Code(或 agent team)按依赖顺序处理任务,并行运行独立任务,顺序运行依赖任务。

对于一个大型迁移——比如,在五十个模块中从一个 ORM 迁移到另一个——这将手动协调的噩梦变成了结构化的执行计划。第一波迁移核心数据库层。第二波更新依赖它的模块。第三波更新测试。每一波内部可以并行运行,但波次本身按顺序执行。

这是基础设施级别的项目管理,不是巧妙的提示词。它之所以有效,是因为依赖系统是显式且强制执行的,而不是因为 Claude Code "足够聪明来弄清顺序"。你定义结构,Claude Code 执行它。

文件系统驱动的分析

遗留代码库伴随着遗留数据。充满格式不一致的 CSV 文件的目录。三种不同格式的配置文件。已不存在系统的日志文件。两年前最后一次更新的文档。

Claude Code 处理这些很好,因为它将文件系统视为一等数据源。指向一个混乱数据的目录,给它一个目标——标准化这些文件、查找重复项、提取摘要、构建迁移计划——它会自主地解析、比较和组织内容。

这之所以有效,是因为 Claude Code 的工具访问包括文件读取、目录列表和命令执行。它可以编写处理文件的脚本,运行这些脚本,检查输出,然后迭代。它不局限于一次理解一个文件。它可以建立文件集合的心智模型,并对整个集合进行操作。

对于遗留系统,这种能力解锁了一个特定的工作流:在重写之前先理解。在你修改一行代码之前,将 Claude Code 指向系统的配置、数据和文档目录。让它建立一个系统实际如何运作的画面,而不是某个人曾经说它如何运作的画面。这种理解——导出为规范文档或 CLAUDE.md 的补充——成为任何后续重写的基础。

三输入工作区模式

最有效的文件系统驱动分析遵循一种特定设置,一位实践者在构建一个原本需要专业顾问数千美元的投资组合优化计划时记录了这种模式。这个模式可以推广到金融以外的任何需要结构化分析的混乱数据领域。

工作区从三个输入开始:

  • 原始数据导出。 CSV 文件、数据库转储、配置导出——无论系统原生产生什么。这些文件通常是混乱的:列名不一致、编码问题、跨导出的数据重叠、非标准条目。这种混乱正是关键所在。你喂给 Claude Code 的是系统的现实,而不是经过美化的版本。
  • 补充文本文件。 总有一些信息没有导出。机构知识、未文档化的设置、手动覆盖、只存在于某人脑海中的上下文。把它以项目符号列表的形式输入到一个纯文本文件中。它不需要结构,它需要的是原始事实。
  • 详细的目标提示词。 这是最重要的一块。它描述存在哪些数据以及在哪里、期望的输出格式、你的偏好和原则、已知约束、你怀疑哪里有问题(给 Claude 留出不同意的空间),以及任何给模型提供具体反应对象的稻草人提案,而不是从空白画布开始构建。

然后工作流按照可预测的顺序进行。启动一个指向包含所有三个输入的目录的 Claude Code 会话。Claude 自主编写脚本来解析数据文件——处理编码问题、去重重叠的导出、将条目分类到目标类别,以及处理否则会被误分类的非标准条目。它在遇到问题时逐一迭代。它产生的基线分析——一个完整的差距分析、一个结构化摘要、一个与目标的对比——通常足够强大,可以立即使用。

从那里,交互转向迭代。你澄清约束、重新构建假设、要求 Claude 自我批评其输出。每次澄清都会立即传播到计划中的每个计算、表格和建议中。补充文本文件和 CLAUDE.md 积累沿途发现的决策和数据特性,因此后续会话正好从上一个会话停下的地方开始。

在过程早期创建一个 CLAUDE.md 文件,并在每次会话结束时让 Claude 用学习成果更新它——发现的数据特性、做出的策略决策、精化的目标参数。这将多会话分析变成了一个复合过程,每个未来的会话都建立在之前一切的基础上。一位实践者描述结果是相当于一周的电子表格工作或数千美元的专业咨询服务,改为在几个晚上与 AI agent 的来回交互中产生。

语言障碍正在消失

有一类遗留系统是大多数现代开发者不愿碰的:那些用他们从未使用过的语言编写的系统。运行 20 世纪 50 和 60 年代语言业务逻辑的主机系统。用同一时代数值语言维护的科学计算基础设施。早于互联网的领域特定语言。这些系统运行着薪资发放、空中交通管制、金融结算和核模拟。它们不会消失,几十年来,理解它们的工程师群体不断缩小,成为任何维护或现代化工作的瓶颈。

智能体编码工具正在消除这个障碍。对不太常见和遗留语言的支持正在扩展——不是作为事后补充,而是作为大型语言模型工作方式的自然结果。模型在训练数据中见过这些语言。它可以读取它们,理解它们的惯用法,并将它们的逻辑翻译成现代等价物。一个从未写过任何遗留语言代码的开发者可以将 Claude Code 指向一个源文件目录,并获得其中编码的业务规则的可运行解释。

这对大型代码库工作很重要,因为许多遗留系统也是庞大的系统。一家金融机构的核心处理逻辑可能跨越四十年来编写的数十万行代码。传统的现代化方法——以不断上涨的费率雇用日益缩减的专家群体,然后手动翻译每个模块——需要数年时间并花费数百万。Claude Code 的方法是根本不同的:使用模型读取遗留代码,提取业务逻辑,并生成等效的现代实现。专家的角色从编写代码转变为审查翻译和验证业务逻辑的保留。

实际影响是重大的。因为没有人有时间处理——或者没有懂该语言的人可用——而积累了多年的技术债务变得可以系统地消除。Agent 可以处理以前不可行的遗留维护任务积压。一个有三年现代化工作队列的组织可能在几个月内清理它,不是因为 agent 更快地编写相同的代码,而是因为使 95% 的工程人员无法进行这项工作的语言障碍不再存在。

遗留代码库重写

最引人注目的 Claude Code 案例研究涉及遗留重写。一个记录在案的案例涉及一个交易平台的 frontend,手动构建花了三年时间。使用 Claude Code,整个 frontend 在几周内被重写。

时间线压缩是真实的,但背后的模式比头条数字更重要。

使用 Claude Code 进行遗留重写在三个条件成立时成功:

  • 期望的架构定义明确。 Claude Code 需要知道你正在构建什么,而不仅仅是今天存在什么。一个清晰的目标架构——在规范文档中、在 CLAUDE.md 中、在详细的提示词中——给了 Claude Code 一个目的地。
  • 现有代码就是规范。 遗留代码通常是业务逻辑唯一准确的文档。Claude Code 可以读取现有实现并提取其编码的规则,即使这些规则埋藏在意大利面条式代码中。它不需要干净的代码来理解行为。
  • 重写是模块化的。 一次性重写整个系统与手动一样有风险。有效的模式是逐模块迁移:重写一个组件,针对遗留行为测试它,验证,然后转到下一个。每个模块是一个适合单次会话的有界任务。

从三年到几周的压缩来自并行性(通过 worktrees 或 subagent 同时重写多个模块),来自 Claude Code 在架构清晰后快速生成代码的能力,以及来自消除手动重写中占主导地位的知识获取阶段。Claude Code 读取遗留代码的速度和读取任何其他东西一样快。一个人类团队可能花六个月理解现有系统后才会写一行新代码,这个时间缩短到了几小时。

大规模自主实现

在极端情况下,Claude Code 已被用于超过一千两百万行代码的代码库上的自主实现。一个记录在案的案例涉及在如此规模的代码库上用大约七个小时实现一个功能。

七个小时。一千两百五十万行代码。一个功能。没有人类编写代码。而且与参考实现相比,数值准确率达到 99.9%。

最后一个数字是最重要的。没有准确性的速度只是快速失败。实现不是一个需要人工清理的粗略近似。它在跨越多种编程语言的代码库上,自主地实现了与预期结果的近乎完美的保真度。

这不是典型用法。它代表了当前工具可能达到的上限。但它展示的模式具有启发意义:Claude Code 在大型代码库上的有效性不受代码库大小的限制,而是受任务定义的清晰度和所提供上下文质量的限制。

一个一千两百万行的代码库无法放入任何 context window。能放入的是任务描述、相关文件子集和编码在 CLAUDE.md 中的架构知识。Claude Code 使用其工具——文件搜索、grep、目录遍历——来找到相关代码、理解它并修改它。代码库的绝大多数从未加载到上下文中。它不需要被加载。

这种选择性加载方法就是大型代码库变得可处理的原因。Claude Code 不需要理解整个系统。它只需要理解与当前任务相关的系统部分。Explore subagent、文件搜索工具和 grep 处理导航。主会话处理实现。CLAUDE.md 提供架构护栏。

用于入职的代码库导航

Claude Code 在大型代码库上最高价值的应用之一与编写代码完全无关。

加入大型项目的新团队成员传统上面临数周的入职。他们阅读部分过时的文档。他们问同事问题,打断了生产性工作。他们通过半随机地打开文件来探索代码。他们通过积累和渗透缓慢地建立心智模型。

Claude Code 大幅压缩了这个过程。一个新的开发者可以启动一个会话并询问关于代码库的问题:

  • "这个系统中的认证是如何工作的?"
  • "支付处理逻辑在哪里,它调用了哪些外部服务?"
  • "Order 和 Fulfillment 模块之间是什么关系?"
  • "为什么这个项目有两个不同的数据库连接池?"

Claude Code 派出 Explore subagent,读取相关代码,并提供基于实际代码库的回答——而不是可能过时的文档。这些回答引用了具体的文件、具体的函数、具体的模式。它们与代码本身一样新。

这取代了数据目录、架构 wiki 和同事咨询,适用于大部分入职问题。它不取代入职也需要的人际关系和文化上下文。但对于"这段代码如何工作?"的问题,Claude Code 比任何人类导师都更快、更准确、更有耐心。

维护精心策划的 CLAUDE.md 的团队放大了这种效果。新开发者既获得了 Claude Code 探索中从代码衍生的答案,也获得了 CLAUDE.md 中捕获的机构知识。这种组合提供了一种本来需要资深工程师数周时间才能手动交付的入职体验。

规范驱动重构:一个存储层迁移

遗留重写和大型重构共享一个常见的失败模式:在没有足够理解目标的情况下直接跳到代码。规范驱动方法通过将研究和规范作为第一阶段而非事后来扭转这种情况。

一位实践者记录了一次完整的存储层迁移——将编译到浏览器的数据库替换为同步引擎的原生浏览器数据库。旧方法可以工作但有诸多问题:大型二进制依赖、初始加载性能差,以及与框架内置同步能力的冲突。迁移涉及十五个或更多文件,需要理解一个不熟悉的框架的存储模式。

工作流按照不同的阶段进行。首先,研究:一个提示 Claude 调查目标框架的单一提示词产生了五个并行研究 subagent,每个研究不同的方面——框架的数据模型、同步协议、存储层、冲突解决模式和 API 表面。每个 subagent 返回一个聚焦的摘要。合并后的发现成为一份综合研究报告,开发者本需要数天的文档阅读才能汇编。

其次,规范:Claude 将研究综合成详细的迁移规范——一份涵盖架构决策、分阶段实施计划、十四项任务清单、风险缓解策略和成功标准的结构化文档。规范被写入磁盘上的文件,而不是保存在对话上下文中。这很关键。磁盘上的规范能经受上下文退化、会话重启和压缩。它是持久的真相来源。

第三,精化:在实施之前,Claude 就迁移策略中的歧义提出了澄清问题——冲突解决方法、过渡期间的同步行为、回退处理。这些问题暴露了设计决策,如果这些决策在实施而非规划阶段被发现,就会变成 bug。

第四,执行:十四个任务,每个委派给一个 subagent,每个产生一个原子提交。Subagent 从规范工作,而不是从积累的对话上下文。每个完成了其有界任务,提交了结果,然后返回。十四个提交,十五个以上文件更改,一个准备好审查的 pull request。

整个迁移花了一个下午。实践者估计手动完成需要两到三天。但时间节省是次要的,更重要的是质量提升:研究阶段发现了开发者自己找不到的框架模式,产生了比手动编码更符合惯用法的实现。

尽管编排了十四个 subagent,主会话的上下文仍保持在限制范围内——编排器只持有任务列表和 subagent 摘要,而实际的文件读取和代码生成发生在隔离的 subagent 上下文中。这就是大型重构的模型:广泛研究、精确规范、并行执行,保持编排器精简。

CLAUDE.md 作为数据目录替代

CLAUDE.md 在大型代码库中更出人意料的应用之一与代码风格或构建命令完全无关。一个数据基础设施团队发现他们的 CLAUDE.md 文件可以取代传统数据目录和可发现性工具用于入职。

当新的数据科学家加入团队时,他们被指导使用 Claude Code 导航庞大的代码库。Claude Code 会读取 CLAUDE.md 文件,识别特定任务的相关文件,解释数据管道依赖,并帮助新人理解哪些上游数据源输入到哪些仪表板。传统上存在于独立数据目录工具中的信息——而且因为没人记得更新而永远过时——现在存在于代码旁边,并作为正常 Claude Code 工作流的一部分进行维护。

团队通过持续改进循环来强化这一点。在每个工作会话结束时,他们让 Claude 总结完成的工作并提出改进建议——不仅针对代码,还针对 CLAUDE.md 文档和工作流指令本身。每次会话都精化了项目的机构知识。CLAUDE.md 文件从实际使用中有机增长,而不是从永远不会重复的专门文档冲刺中产生。

这种模式之所以有效,是因为 CLAUDE.md 在每次会话开始时以完全保真度读取。与可能六个月过时的 wiki 页面不同,CLAUDE.md 与上次更新它的会话一样新。对于数据模型与代码本身一样复杂的大型代码库——理解哪个表通过哪个中间转换输入到哪个仪表板是必备知识——CLAUDE.md 成为传统工具渴望成为但很少实现的活数据目录。

大规模技术债务

每个大型代码库都有一个没人处理的技术债务积压。不是因为它不重要,而是因为经济性从未证明投资的合理性。需要经验丰富的工程师三周时间的重构每次构建节省两分钟。需要涉及两百个文件的迁移来现代化一个弃用依赖。需要同时理解测试框架和业务逻辑的测试覆盖率改进来防止每季度的生产事故。

智能体编码工具系统地改变了技术债务的经济学。当 agent 可以长时间自主工作时,以前不可行的项目变得可行了。三周的重修变成了三小时加审查的任务。两百个文件的迁移变成了使用并行 subagent 的结构化执行计划(如上文的任务依赖管理部分所述)。测试覆盖率改进变成了一个周末的自主运行加上周一的人工审查。

模式不是"把 agent 放到积压上"。它是结构化的:识别债务,编写清晰的规范,建立验证标准(必须通过的测试、必须满足的 linting 规则),然后让 agent 系统地处理这些项目。自动验证的反压力(第八章)确保 agent 生成的修复确实有效。任务依赖系统确保依赖的更改按正确的顺序执行。

及早认识到这种转变的组织获得了复合优势。消除的每一项技术债务都使代码库更容易被人类和 agent 使用。更干净的代码产生更好的 agent 输出。更好的 agent 输出清除更多债务。飞轮加速。

面对庞大与古老的策略

处理大型和遗留代码库最终是关于管理两种稀缺资源:上下文和理解力。

大型代码库的上下文管理意味着积极使用 subagent 进行探索、选择性文件加载,并将主对话聚焦于当前任务而不是理解系统。不要将本可以委派给 Explore subagent 的文件读入主上下文。当你可以窄范围搜索时,不要广泛探索。

理解力管理意味着增量地构建理解并将其持久化。使用规范文档和 CLAUDE.md 来捕获 Claude Code 对系统学到的内容。使用任务依赖管理来结构化复杂的迁移。使用并行研究来比任何顺序阅读更快地构建理解。

那些看起来不可能处理的代码库并不是不可能的。它们只是理解起来很昂贵。Claude Code 通过更快地阅读、更广泛地搜索、以及不忘记你写入 CLAUDE.md 的任何内容——大幅降低了这个成本。

要点总结
  • Git worktrees 支持在同一仓库不同分支上并行运行 Claude Code 会话,会话之间互不干扰。
  • Explore subagent(Haiku、只读、隔离上下文)足够廉价,可以大方地用于在陌生代码中导航。
  • 并行研究 subagent 在几分钟而非几小时内提供对大型系统的多角度理解。
  • 使用 blocks/blockedBy 的任务依赖管理支持复杂迁移和重构的波次执行。
  • 遗留重写在目标架构清晰、现有代码作为规范、工作模块化时成功。
  • Claude Code 在大型代码库上的有效性受任务清晰度和上下文质量限制,而不受代码库大小限制——一个记录在案的案例在 1250 万行的代码库上实现了 99.9% 的数值准确率。
  • 用旧语言编写的遗留系统的语言障碍正在消失;agent 可以阅读、理解和翻译大多数现代开发者无法处理的业务逻辑。
  • 三输入工作区模式(原始数据导出、补充文本文件、详细目标提示词)将文件系统驱动的分析变成一个结构化的、可重复的过程。
  • 规范驱动重构——先研究、精确规范、并行执行——产生比直接跳到代码更好的结果,即使开发者本来可以手动编写。
  • CLAUDE.md 可以取代传统数据目录用于入职,通过每次会话结束时的持续改进循环来维护。
  • 当 agent 将经济学从"不值得工程师三周时间"变为"三小时加审查"时,技术债务变得可以系统地消除。