用 Claude 摸清老项目技术栈:一份可落地的分析流程与提示词实战 每个老项目都是一座没插路标的森林。这周我开始执行自己的只管去写计划Day2的任务很明确从本地仓库里挑一个尘封多年的旧系统用 Claude 把它的技术栈彻底摸一遍底。这个项目是一位已经离职的同事留下的没有设计文档没有接口说明连根README都是五年之前写的。面对这样一座代码债矿山我决定先不急着写任何功能而是让 Claude 先当一次侦察兵把整个项目从入口到出口的技术脉络全部拉出来。选择 Claude 而不是自己硬啃代码不是因为懒而是因为这类老项目有个通病你永远不知道哪些文件是真在用的哪些是当年实验失败的尸体。人工翻目录容易陷入局部最优——看到某个熟悉的框架就觉得懂了实际上整个系统的组装逻辑藏在 config 和脚本里。让模型先从全局视角做一次粗扫我再针对可疑点深挖效率会高很多。这篇文章就记录一下我用 Claude 分析老项目技术栈的完整过程、提示词设计思路以及几处差点被忽略的坑。1. 接手陌生老项目的第一个问题你的入口在哪里1.1 先别急着问这是什么先问文件怎么组织很多人在分析老项目时会犯一个错误上来就让 AI 介绍一下这个项目。这种问法得到的回答往往泛泛而谈比如这是一个基于XX的管理系统毫无价值。因为大型代码库里真正决定架构的信息不在单个文件里而在文件之间的组织关系里。我让 Claude 做的第一件事是输出项目的目录树并标出每个一级目录的职责。这一步相当于给整个森林拍一张航拍图。命令很简单直接让 Claude 读取项目根目录结构然后逐层展开遇到关键文件如 package.json、requirements.txt、build.gradle、Dockerfile就停下来读内容再反过来告诉我是哪个目录在用它们。实测下来这种方法有个明显好处Claude 会先建立目录-文件-依赖的映射关系而不是像搜索引擎一样东看一眼西看一眼。最终它给出的报告里每个模块都携带了被谁引用引用谁的链路信息我拿着这份图再去翻具体代码时基本不会迷路。1.2 Claude 处理这种任务的边界在哪里这里必须泼一盆冷水Claude 再聪明它看到的也只是你喂给它的那些文件内容。老项目里真正的隐知识——比如某段逻辑为什么这么写、某个定时任务为什么只在周二跑——往往不在代码里而在人的脑子里。所以我把 Claude 定位成高并发的信息整理器而不是全知全能的架构师。它能快速帮你完成三类工作第一从海量文件中筛选出高信号文件第二把散落在各处的框架用法、依赖版本、脚本命令汇总成结构化清单第三基于代码特征推测模块职责供你复核。但涉及业务规则推导、历史原因复盘这类事它只能提供假设最终判断权必须留在你自己手里。提示送给 Claude 的上下文窗口是有限的老项目动辄几十万行代码不可能一次全塞进去。我采用的方式是分层投喂——先给目录树再给关键配置文件最后给核心源码文件每一步都让 Claude 把发现写进一份备注逐步收敛。2. 我用三个维度把老项目拆成了三层扫描把 Claude 当侦察兵之后我给它设计了一套标准的三层扫描流程。这三个维度分别对应技术栈的三个不同切片装了什么东西、怎么组装、内部结构长什么样。缺任何一个维度分析报告都是残缺的。2.1 依赖清单层从包管理器文件读出技术栈体温第一层最机械也最必要把项目里所有依赖清单文件翻出来。前端看 package.json后端看 requirements.txt 或 go.modJava 系看 pom.xml另外还要留意 Gemfile、composer.json 这类历史产物。我让 Claude 先用代码读取工具把这几个文件全部拿出来然后生成一张依赖版本清单表。但光列出版本号还不够我追加了一个指令对于每一个依赖用一句话说明它是干什么的如果你发现它已经不在主流维护周期内单独标出来。这一步立刻让报告从流水账变成了体检单。比如我发现这个老项目里有一个内部日志组件锁死在某个旧版本上引用它的只有两处代码但整个系统启动时都要加载它——这种技术债如果不做依赖分析阶段后面根本不会注意到。2.2 构建与配置层从脚本和配置文件还原组装方式依赖清单告诉你项目用了哪些零件但零件怎么拼成整车要看构建与配置。老项目的构建脚本往往经历了多任开发之手里面残留着各种时代的痕迹可能既有 Makefile又有 docker-compose.yml还有一个不知道什么时候加的 shell 脚本。我让 Claude 针对每个构建文件回答三个问题这个文件负责什么阶段的什么任务它是否被其他文件引用直接执行它需要哪些前置条件特别要检查环境变量。老项目里有些配置直接写在代码里的常量中有些写在.env.local还有些藏在启动脚本的 export 里——这些散落的配置项是后来部署时的最大雷区。Claude 把这些配置点位全部捞出来之后我对着实际部署环境一一核对还真发现了一个已经失效的数据库连接配置指向的实例早已销毁。2.3 架构模式层从代码调用关系推断骨架结构前两层回答的是有什么第三层回答的是怎么长的。Claude 可以通过人类可读代码分析工具去查看 C、Java、Python、JS/TS 等语言的代码库结构我可以让它针对某个模块阅读源码摘要然后用一个提示词要求它总结模块间调用关系。我选择先扫描最核心的主流程入口比如后端的主应用类、前端的路由表、消息队列的消费者注册处。让 Claude 从这些入口出发顺着调用链画出模块依赖草图然后输出一份关键模块清单及职责推断。这个过程看起来简单但实际效果很好。它直接帮我定位到一个被大量模块引用、却没有任何文档说明的中间件模块后来翻源码才确认那是前前前任开发写的全局拦截器。这种藏在调用关系里的核心组件靠人工逐文件翻可能得花一整天。3. 五组提示词的实测对比同一份代码不同问法结果差很多分析过程中我明显感觉到提示词的质量直接决定 Claude 输出的价值密度。同样一份代码泛泛地问和定向地挖结果完全像两个东西在回答问题。我把实测的五组提示词放在一起做了个对比供参考。3.1 泛泛而问与定向追问的差距第一组测试是最朴素的问法请分析这个项目的技术栈。Claude 的回复确实列了框架名和版本但除此之外全是套话比如该项目具有良好的模块化设计。这种回答听着舒服实际上等于没答。第二组我换成了带约束的问法请忽略一切修饰性描述直接输出核心语言与版本、框架清单、包管理器、构建工具、测试工具、部署方式。每项都必须指出我是从哪里看出来的否则标注为‘待确认’。效果完全不一样。Claude 开始引用具体文件路径和关键代码行作为证据整个报告从读后感变成了尽职调查报告。3.2 让 Claude 自己生成追问清单分析到中间阶段我遇到了一个典型困境不知道该往哪里深挖。这时候我有一个非常管用的技巧把问题抛还给 Claude我已经了解了该项目的依赖和目录结构但不确定从哪些角度切入才能全面评估它的技术栈现状。请你列出 15 个我下一步应该问的问题每个问题都要能指向一种潜在的技术债或架构风险。这招比我想象中好用得多。Claude 生成的 15 个问题里有几个非常尖锐比如数据库连接池配置是否存在硬编码是否有两个模块重复实现了同一个 HTTP 客户端封装。这些追问补位了我自己惯性思维容易漏掉的盲区。老项目不怕代码复杂怕的是你带着想当然去分析追问清单本质上是让模型帮你做了一次对抗性思考。3.3 给 Claude 一个输出模板的奇效第三组实验是关于输出格式的。同样要分析某个核心模块第一种问法是帮我看看这个模块是做什么的得到的是大段描述需要自己二次提炼。第二种问法是我预先定义了一个模板请按以下格式分析指定模块 模块名称 核心职责不超过50字 主要输入/输出 依赖的其他模块 被哪些模块依赖 使用的关键技术点 是否需要重点关注是/否原因效果立竿见影。表格化的输出让多个模块的对比变得极其轻松我能直接横向扫视哪些模块职责重叠、哪些模块几乎没被引用。更重要的是这种模板化输出让 Claude 的回答风格稳定可控连续分析二十个模块后我能直接把这二十张卡片拼成一张全景图。分析老项目时结构感比文采重要得多。四组提示词里只有一组让我觉得效果一般让 Claude 直接读一份几千行的单文件源码并归纳逻辑。这种任务不是它做不好而是单文件阅读方式绕过了代码之间的调用关系归纳出来的结论常常浮于表面。后来我改用先梳理这个文件被谁调用、调用了谁再读内部逻辑准确率立刻上来了。我将五组关键提示词的实测情况整理成了下面的对比表方便按需取用提示词类型问题示例实测效果适用阶段泛泛介绍式请分析这个项目的技术栈输出偏套话缺少证据链基本不推荐定向盘点式按指定字段输出技术栈清单并给出判断依据信息密度高可核查性强项目技术栈初扫追问生成式请生成15个下一步要问的问题能补充分析盲区效果惊喜中期深挖方向模板约束式按固定卡片格式输出模块分析输出稳定易于拼合对比逐模块分析阶段单文件归纳式读透某源码文件并总结逻辑结论浮于表面需结合调用链仅在定位问题时用4. 技术债探测器Claude 帮我筛出的三处 EOL 隐患依赖清单出来后真正的重头戏开始技术债排查。老项目最危险的地方不在于代码写得差而在于它和你当下的认知存在巨大时间差。你以为正常的东西可能早在几年前就被官方判了死刑。4.1 已停维护的运行时版本Claude 在分析前端构建脚本时注意到运行环境的基础镜像被固定在一个非常旧的长期支持版本上。我让 Claude 去查这个版本的生命周期状态它很快指出这个版本早就不再有安全更新而且当前项目的某些语法特性已经超过了它的解析范围。如果你只是写业务功能可能一辈子碰不到这个问题但只要你想在 CI 环境里升级任何构建工具这个旧运行时立刻会成为拦路虎。我把这个问题标记成 P0先把运行时版本升级到仍在维护的版本区间其后再谈其他依赖升级。4.2 被官方标记废弃的 API 调用第二种技术债更隐蔽。项目里有一个历史悠久的配置模块用的是某框架的旧式配置文件写法。这种写法在功能上依然能跑但官方文档已经明确标注为废弃状态新版本里默认关闭了兼容开关。Claude 定位到这个问题的方式很有意思它在读取项目里的配置文件和启动日志转储文件时发现有一段警告信息被项目开发者有意屏蔽了——日志级别被调低导致废弃警告根本没显示出来。这显然不是错误的代码而是一种眼不见心不烦的鸵鸟策略。这种问题靠 AI 自动定位比较难因为它能运行只是你不知道它在带病运行。4.3 隐藏的重复实现与幽灵依赖第三类技术债也值得一提幽灵依赖。所谓幽灵依赖指代码里 import 的包不在 package.json 里声明之所以能跑起来是因为它还寄生在某个直接依赖的依赖树中。一旦上层依赖升级幽灵依赖就可能消失代码当场暴毙。Claude 在对比依赖清单和源码 import 语句时发现了多处这类幽灵引用。它无法确定这些引用是故意的还是手滑但把每个跨版本冲突点都标了出来。我拿到清单后逐一尝试清理其中两个直接锁定为历史遗留问题处理另外一个意外的反而是运行时通过全局方式挂载的模块属于有意为之但没人写注释。如果没有 Claude 先做交叉比对这种问题靠人工逐文件 grep 也能找但效率绝对没有这么高。5. 从一份分析报告到一份可执行的重构清单分析到这一步轮到一个老生常谈的问题报告写出来了然后呢很多技术分析文章死于写得很好毫无用处。我给自己定的规矩是技术栈分析不是终点它必须能落到下一步行动里。5.1 报告的结构化写法最终我让 Claude 把所有分析结论汇总成一份 Markdown 报告结构按风险等级排序而不是按模块顺序排序。主要内容包括四个区块现状概览技术栈全景图、模块架构图、关键目录说明遗留问题清单每条标注风险等级、影响范围、可能的修复路径以及问题来源证据的文件路径升级建议按依赖优先级排序附上兼容性说明待人工确认项Claude 无法从代码中判断的事项比如该配置是否仍在生产环境使用定时任务的执行时机是否有业务硬约束我把这份报告作为 Day2 的产出物直接塞进了项目的 docs 目录。它的价值不只是给我一个人看后续任何人接手这个项目先读这份报告就能省下至少两天的摸索时间。这也是只管去写最有价值的副作用——你写下的东西最终会变成团队的共同资产。5.2 哪些结论可以信哪些必须人工复核必须强调Claude 的分析不是真理。它可能把某个模块的职责推断错也可能因为没看到业务上下文而给出离谱的优化建议。我的复核策略是所有标为高风险、需要动代码的结论都必须找到原始代码行做二次确认所有标为待确认的框必须找一个熟悉业务的人逐一回答。具体来说框架和依赖清单这类机械性结论可信度极高模块职责推断这类语义性结论可信度中等必须结合代码阅读验证至于建议把 XX 重构为 YY这类建议性结论我一律只把它当成思路参考不直接采纳。老项目的病根常常不在技术而在业务理解AI 看不到业务这一点必须保持清醒。5.3 只管去写的真正含义先写下来再谈重构Day2 结束的时候我并没有立刻开始重构——那不是这个阶段该做的事。我的输出物是一份技术栈分析报告、一张依赖风险清单、一份待确认问题表以及十几条分析和思考的批注。这些东西全部变成了文字而不是停留在我的脑子里。只管去写这个动作放到技术分析里我想表达的其实是面对老项目先别急着动手改先把理解写下来。写的过程会强迫你结构化思考逼你面对那些我觉得大概是的模糊地带。等到有一天真的要重构这份记录就是你最可靠的方向盘。如果你也准备用 AI 辅助分析老项目我的建议是从目录树开始按依赖、构建、架构、技术债四个层次推进过程中的每一步让模型生成结构化输出最后一定要有人工复核环节。老项目不会因为你用了一个聪明的工具就变得简单它只是从一团迷雾变成了一张带标注的地图。剩下的路还得靠你自己走。