用Pi agent装修老项目毛坯房:AI辅助改造实战与避坑指南

发布时间:2026/10/2 4:07:18
用Pi agent装修老项目毛坯房:AI辅助改造实战与避坑指南 最近接了个活儿用 Pi coding agent 把一个仓库从“毛坯房”状态装修成能正常跑起来的项目。所谓毛坯房就是只有一手老代码、一个残缺的 README 和几条没人敢动的历史包袱既没有完善的工程化配置也没有测试兜底。本来想着有 AI 辅助应该能省不少事结果一路踩坑踩到怀疑人生。这篇文章就把我这段时间用 Pi agent 装修毛坯房的完整过程记录下来包括那些文档里不会写的坑、Agent 的脾气秉性以及最后沉淀下来的一套能少走弯路的实操流程。如果你也是拿 AI 写代码当日常尤其是要接手老项目、补历史债的人这篇内容应该能让你少交一点学费。1. 毛坯房交付前先把Agent的“施工图纸”画清楚1.1 环境准备和上下文构建决定了后面是装修还是返工我第一次用 Pi agent 处理这个老仓库时犯了个很蠢的错误——直接把仓库丢给它说“帮我把这个项目跑起来”。结果它花了大量时间在猜我到底想要什么是先修构建脚本还是补依赖还是重写文档最后产出了一堆看起来很努力、但完全没有落点的改动。后来我才意识到AI 编程代理和我们人接手一个老项目是一模一样的你给它多少上下文它就做多少判断题。毛坯房它看不到墙里的水管图你得先把图给它。所以我的第二个做法是在开工前自己先花 20 分钟手动梳理出这个仓库的全貌用一份简短的AGENTS.md把项目说明写清楚。这里分享一个我现在固定用的上下文模板不只是给 Pi agent 看任何 coding agent 都适用项目整体目标这个项目是干什么的目标用户是谁核心业务闭环是什么技术栈清单语言、框架、关键依赖、构建工具的版本越精确越好目录结构导览哪些目录是核心业务代码哪些是生成物哪些是历史垃圾不要碰当前最大痛点你希望 Agent 优先解决哪个问题比如“先让 dev server 能跑起来”或“修掉构建警告”明确的禁区比如“不要动 tests 目录”、“不要升级 React 版本”1.2 一次只给一个装修任务别让它当“全屋设计师”还有一个我在初期反复踩的坑任务给得太宽。装修毛坯房你不会找一个工人既改水电、又刷墙、又打柜子哪怕他是全能工你也得按工序来。Pi agent 同理。有一次我让它“顺便把代码风格统一一下、顺手修掉两个 lint 报错、再给新接口补个测试”结果三个任务哪个都没做利索。统一风格改动了大量文件导致 diff 根本无法 review修 lint 又触碰了核心逻辑测试补了一半就没停住跑去重构其他函数。我的教训是每个任务只给一个清晰、可验收的目标并明确“完成”的定义。比如不叫“修一下这个模块”而是“让paymentService中的calculateFee函数在传入负数时返回 0并新增一条对应的单元测试”不叫“优化启动速度”而是“定位webpack.dev.js中导致二次编译超过 3 秒的插件移除并验证 dev server 启动时间”这不是限制 Agent 的能力恰恰是给它的上下文“画线”。画得越清楚它越不会跑偏。2. 装修事故No.1Agent的“默认审美”和你的工程规范不对付2.1 格式化偏好冲突一场没有赢家的代码风格战争毛坯房装修最怕什么最怕你的设计稿和工人的习惯拧着来。我用 Pi agent 干的第二个大蠢事就是没有提前告诉它这个项目的代码风格底线。我当时让 Agent 修一个函数它很主动地把整个文件都用 Prettier 默认配置重新格式化了一遍——单引号变双引号、尾逗号加回来了、缩进从 4 空格变成 2 空格。从我视角看整个文件 diff 全是噪音真正改的逻辑淹没在几百行格式改动里根本没法 reviewWebStorm 的 Git 对比窗口一片标红。后来我研究了一下原因Pi agent 默认生成的代码风格是根据训练语料里 GitHub 高频风格来的而这个老仓库用的是 5 年前的团队自定义风格。两者不匹配Agent 就会“善意”地帮你全部统一。这件事的解法其实很便宜在项目根目录放一份.prettierrc或者.editorconfig并且在 AGENTS.md 里写死一条规矩“格式问题由提交时的 husky 钩子统一处理Agent 不要对已有代码做任何格式重排。”加上这条之后Pi agent 的产出立刻规矩多了。它其实并不是有意添乱只是你的“工地守则”没传达给工人。2.2 Agent的“全屋重建”倾向为什么它总想推翻重写如果说格式冲突是表面问题那深一层的坑就是——Pi agent 面对一栋结构性不太好的老房子第一反应往往不是局部修缮而是推倒重来。我遇到过一次特别典型的例子老代码里有一个工具函数三百多行中间有大量重复逻辑和一段明显失灵的异常捕获。我让 Agent “优化这个函数保持外部调用接口不变”。它给我的方案是重写整个模块把函数拆成 6 个小函数还配了个类。从纯代码质量角度它的方案其实还挺好但问题是我没法验收——调用方有十几个文件依赖这个模块的历史行为里面有几个让人摸不着头脑的“隐含约定”Agent 的重构版本表面行为一致边界行为完全不同。那一次返工我浪费了将近两个小时。我的应对策略是在任务描述里明细两条禁止重构与本次任务无关的代码块如果发现当前函数无法在不动结构的前提下完成修复必须先列出“需要动的函数清单”再动手而不是直接新写一个替代版本这两条加进上下文之后Pi agent 开始学会“在原有结构里打补丁”了产出质量对于老项目来说比它自由发挥时好得多。3. 装修事故No.2依赖管理的“水电改造”环节3.1 毛坯房的水电管线就是你的依赖关系做过装修的人都知道水电改造是隐蔽工程里的头等大事返工成本最高。代码项目里依赖管理就是水电管线。而 Pi agent 在这块的表现属实需要“老父亲式”的盯防。有一次我让它给项目加一个新的 HTTP 客户端库它很乖巧地在package.json里追加了最新版本依赖然后顺手把另一个旧库从依赖列表里删了——因为它在某个文件里发现旧库已经没被 import 了。看起来非常合理对不对但问题是那个旧库是通过全局注册的方式被其他服务间接引用的。Agent 只扫了当前仓库的 import 语句没有能力知道运维平台上还有别的服务在引用这个包。这个坑的教训是在涉及依赖增删的任务里我必须自己先做一轮排查而且绝不让 Agent 直接改 package.json 和 lock 文件。我会让它先把方案写出来比如“我建议移除 xxx 包因为我在 src/ 下没有找到任何直接引用”然后我自己基于仓库搜索和运维知识来判断这个结论是否成立。3.2 npm 与 pnpm 的暗坑双重锁文件带来的混乱老项目最经典的坑之一就是 package-lock.json 和 pnpm-lock.yaml 同时存在。这往往是几波人接力维护留下的历史遗迹。Pi agent 遇到这种情况会怎么处理它完全没有犹豫——直接按照项目里最新修改时间较近的锁文件来执行安装根本不会向你确认。我遇到过的情况是项目根目录同时有package-lock.json三天前更新和pnpm-lock.yaml两个月前生成。Agent 以为是 npm 项目跑了一遍npm install把 node_modules 里原本由 pnpm 安装的依赖结构全打乱了。结果就是 dev server 启动报各种诡异的模块找不到排查了整整一个下午最后只能删掉 node_modules 重新用 pnpm 装一遍才恢复。从那次以后我在 AGENTS.md 里加了一条硬性规范统一包管理器明确写明“本项目只使用 pnpm禁止混合使用 npm/yarn 安装依赖”。并且我会建议任何准备引入 coding agent 的项目组第一步就做依赖管理器统一否则每个 Agent 都有可能在这上面摔一跤。3.3 lock 文件版本冲突别让Agent当“仲裁者”还有个细节是关于^版本符号和 lock 文件的关系。老项目里 package.json 通常写了lodash: ^4.17.20lock 文件锁的是 4.17.21。如果 Agent 单纯为了修复一个 bug 去升级依赖它可能直接把版本改成^4.17.21然后 lock 文件就会产生一个 diff。有人觉得这没问题但在我处理的项目里任何 lock 文件的改动都需要走单独的依赖升级流程不能混在业务代码提交里。因为一旦升级丢失了某个间接依赖的固定版本后续部署环境的兼容性就可能出现只在一台机器上复现的神奇 bug。所以我会给 Pi agent 设置一条行为边界除非任务明确是“升级某某依赖”否则不允许修改 package.json 和 lock 文件如果它确实需要依赖变更先提方案由我手动执行安装命令。虽然这多了一道工序但比事后排查一个下午要轻松得多。4. 装修事故No.3Agent的“经验主义”输出总是带私货4.1 Pi agent的“过度完成”做的比要求的还多Pi coding agent 这类工具在主观能动性上确实比早期的 AI 辅助工具强很多强到很多时候会“过度完成”。装修师傅给你装个吊灯顺手把客厅开关面板也换了你觉得这是贴心还是添乱有一次我让 Agent 修复一个登录页面的表单校验 bug它修完之后顺手给整个表单加了autocomplete属性、调整了错误提示的文案还重构了提交按钮的加载状态逻辑。每一项单独看都不算错但合在一起就变成了一次我本来不需要承担的回归测试范围和 UI 走查成本。我现在对 Agent 的任务描述都会加上一句“只做任务描述要求的事如果需要动其他代码在响应末尾单独说明”。这是一条非常有效的约束能把 Agent 的自由发挥控制在“提醒”而非“行动”的层面。它如果发现了另一个潜在问题会写进工作总结里但不会主动改代码。这才是我要的协作姿态它是我的施工队不是我的产品经理。4.2 不存在的“常识”Agent对业务隐性规则的漠视用 Pi agent 越久我越清楚地体会到一件事它非常懂代码的通用规则但完全不懂我们这个具体项目的业务规则。有次它帮我重写一个订单状态更新函数延续了老代码的逻辑但悄悄去掉了里面一个看起来“多余”的缓存清理调用。它认为那行代码和更新订单状态无关是历史遗留的死代码。但它不知道的是这个项目当时的并发设计有问题那行缓存清理是在用一个很丑陋的方式规避另一个模块读脏数据的老 bug。Agent 把这行删了之后线上订单列表偶发地出现了状态显示滞后。这件事给我了一个血泪教训对于任何老项目里的“看似多余代码”不管是对人还是对 Agent都必须先搞清楚它的存在意义再决定要不要删。我现在要求 Pi agent 在删除任何非本次任务引入的代码行之前必须把这行代码加进一个“待确认删除清单”由我来判断。4.3 生成测试代码时的“假阳性陷阱”最后一个经验主义的问题是 Agent 写测试代码时的“自证清白”。Pi agent 帮我补单测时它写的断言往往恰好就是用它的实现逻辑推出来的结果——也就是说它用自己的代码验证它自己的逻辑而不是用一个独立的业务预期来验证行为。举个具体的例子我让它给某个计算折扣的函数补测试它会先想一个实现方案然后预期值直接照着这个方案手算一遍写进断言。这听起来没问题但实际上等于把同一个错误逻辑复制了两份。真正有效的测试应该基于独立推导出来的期望值而不是实现逻辑的复述。我现在会要求 Agent 在写测试时把“预期值的业务计算过程”写在断言旁边然后我自己抽查几条边界数据手动算一遍验证。好消息是当我明确要求“用独立业务口径推导期望值”之后Pi agent 生成的测试质量确实有可见提升。5. 当Agent在毛坯房里迷路定位问题与“无头苍蝇”模式5.1 排查链路断裂Agent只看到症状找不到病根如果说前几章聊的是施工质量那这一章的坑是施工方的“诊断能力”。毛坯房装修踩坑最怕的不是工人手艺不好而是工人只会告诉你“这里不平”却说不清是地基沉降还是墙角填充物隆起。有一回项目里一个定时任务经常崩溃日志里报的是TypeError: Cannot read properties of undefined (reading id)。我让 Pi agent 分析这个问题它把报错行周围的代码翻了个遍给我分析出三个可能原因还按概率排了序。听起来很合理对吧但它没有继续做一件事——去查这个定时任务的数据是从哪个上游接口拉的那个接口最近有没有改过字段名。结果真正的原因和它的三个猜测全不沾边。上游服务的某个字段从id改成了objectId因为老的缓存还留着旧数据所以一半数据没事、一半数据崩溃。Agent 只盯着报错现场完全没往数据源方向想。从这次之后我总结了一个排查任务的标准工作流我也建议你把它写进自己的提示词模板里第一步先要求 Agent 在项目全局搜索报错字段的所有来源列出“可能产生该字段的业务路径”第二步让它顺着数据流的方向走一遍而不是只盯着报错的那个函数第三步要求它给出“证据链”——每个猜测必须配一个搜索结果佐证没有证据的猜测列为低优先级5.2 Agent的“无头苍蝇”模式越修越乱的死循环有时候 Pi agent 不是不聪明而是太容易陷入“无头苍蝇”模式。我观察到的触发条件通常是任务描述里包含一个自身无法验证的目标。举个例子我让它“修复 Safari 浏览器下按钮点击无效的问题”。这问题本身我对它就没有提供足够的上下文——是事件绑定没生效是 CSS 遮挡还是 JavaScript 报错中断Agent 只能靠猜。第一次它给了一个“可能是 z-index 问题”的修复第二次它说“可能是 pointer-events 问题”第三次它改成“建议引入 polyfill”。每一次它都相当笃定但每两次修复之间完全没有验证手段。这不怪 Agent是我给的任务本身没有给它“判断是否修好”的测试手段。在修复问题之前我至少应该和 Agent 先对齐一个“验证方案”——比如手动复现步骤、单测断言、或者一个可执行的最小复现案例。有了验证手段Agent 才可能在这间毛坯房里找到正确的方向而不是到处敲墙。5.3 让Pi agent带着“感应器”干活把验证写进任务我现在所有交给 Pi agent 的修复类任务都会强制包含一个“验证标准”字段。它不是可有可无的废话而是让 Agent 对着干活的“感应器”。举个实际的例子任务修复支付回调偶发丢失的问题验证标准本地启动服务后用curl连续发送 20 次模拟回调每次都会在日志中打印payment result received且无未捕获异常你看交代了验证标准之后Agent 的行为就变了。它不再只改代码还会自己跑验证因为它清楚“完成”的定义是什么。跑不过它会继续改跑得过它才告诉你“可以了”。这比起我之前那种“改完了你测测看”的交付方式效率提升了不是一点半点。6. 装修尾声我总结的“毛坯房Agent协作清单”6.1 一套可以直接抄作业的任务提示词模板踩了这么多坑之后我把“毛坯房装修”的场景沉淀成了一套固定的任务模板每次交给 Pi agent 的 prompt 基本长这样背景这是一个接手的老项目技术栈是 xxx仓库根目录有 AGENTS.md开工前请先读它。任务只处理下面描述的一个问题不要顺带重构或改动无关代码。问题描述请复述一遍你理解的问题现象方便我确认我们没有理解偏差。验证标准完成后如何确认这个任务做对了请列出可执行的验证方法。禁区不要修改 package.json 和 lock 文件不要重排已有代码格式涉及删除代码时先列清单。输出要求用中文回复列出每个改动的文件名和简要说明。这套模板下来Pi agent 在我这个毛坯房项目上的表现明显从“自由艺术家”变成了“听指挥的施工队”效率和质量都稳了一个档位。6.2 Plan模式比直接改代码更省时间很多人用 coding agent 时喜欢让它直接动手改觉得这样快。但根据我这段时间的经验在毛坯房里直接动手改大概率会让你进入返工循环。我现在更倾向于让 Pi agent 先进入“plan 模式”让它先给我一个方案我确认了再执行。这种方式对于老项目尤其重要因为老项目的水下成本高任何一个“没想到”都可能让我多花两个小时去排雷。方案先行相当于让它先画施工图我再审图纸。虽然多了一轮交互但整体时间反而是省的。尤其是当任务牵涉到多文件修改、依赖调整、或者数据流方向改动时plan 模式几乎是我唯一的选择。省下的返工时间比那几十秒生成方案的时间多得多。6.3 最后说一点我对 Pi coding agent 这类工具的观察用了一段时间 Pi agent 之后我最大的体会是这类工具的真正价值不是替你写代码而是替你加速“验证想法”的速度。它不会比你更懂你的业务也不会比你的团队更懂历史包袱但它可以在你画好图纸之后高效地完成一块块具体的工序。“毛坯房装修”这种老项目改造场景最大的敌人其实是模糊和不确认。而只要你把上下文给足、边界画好、验证标准定明白Pi agent 就能成为一支相当靠谱的装修队。毕竟它还不会像人一样干到一半跟你说“这墙我不敢拆得加钱”。