Claude

Claude Code 接 Kimi-K2 重构 Laravel 老项目:幻觉从哪来、怎么改

编辑部阅读约 8 分钟

用 Claude Code 搭配 Kimi-K2 重构一个 Laravel 商业项目的 VIP 模块,架构方案看着不错,落地却充满不存在的类、错位的方法签名和空壳的支付对接代码。文章梳理这类失败的常见原因——老项目改造难度、动态语言缺少编译兜底、上下文被压缩、Agent 与模型不适配、私有 SDK 只能靠 mock,并给出一套可执行的切片改造流程与工具取舍建议。

一个跑了多年的 Laravel 商业项目,VIP 模块里塞着订单、订阅、会员权益,还对接了支付宝、微信和 Google Play 内购。需求很克制:只做内部重构,拆开面条代码,不动 API、不动数据库。有人把这件事交给 Claude Code 加 Kimi-K2,等了一个多小时拿到第一版,架构分层确实有模有样,但人工 review 一开就崩——导入了不存在的类、调用方法传错参数甚至参数个数都对不上、调用了根本不存在的方法。指出问题让它修,屏幕滚了半天,错误还在原地。

后来他改策略:新开 session,一次只修一类问题。修「导入不存在的类」立竿见影,但修「方法签名错误」就又失效了。后台显示已花掉十几元人民币,代码却连逻辑验证阶段都进不去。切换到 gemini-cli、roocode 配合同一个模型再试,结果分别是「粗心中等生」式的半成品和八十个文件的过度设计——最要命的是真实支付渠道的对接代码被整体丢弃,只留了几行 mock。

这不是某一个模型的偶发翻车,而是「用 AI 改造存量项目」这一类任务里反复出现的典型模式。下面把它拆开看。

为什么会翻车

从零生成和改造存量代码是两种难度

对模型来说,新建脚手架只需要内部自洽,而改老项目要求它同时满足三件事:理解现有调用链、遵守既有约定、保证改动后全局仍然自洽。第三件事最容易漏——改了成员变量名却只改了一半调用点,就是典型的局部一致、全局断裂。存量项目里那些没写在文档里、只存在于代码习惯中的约束,恰恰最难传递。

动态语言没有编译器兜底

PHP 这类弱类型语言,类名写错、方法不存在、参数数量不对,都不会在保存文件时立刻报错,往往要跑到那行代码才暴露。这带来两个后果:模型生成时缺少即时反馈信号;Agent 也无法靠「编译通过」判断自己是否做对。同理,工具调用失败、文件写入失败这类问题在动态语言项目里更容易被掩盖。

上下文被压缩,关键签名先丢

模块跨十几个文件、几千行代码,一次任务不可能全塞进窗口,Agent 会做摘要压缩。被压缩掉的往往是接口签名、构造函数参数这类「细节」,而模型在写调用时就会凭印象补全,于是幻想出参数和不存在的方法。对话越长,这种衰减越明显,这也是为什么「一次只修一个问题」的短 session 效果明显更好。

Agent 外壳和模型之间存在适配差

Claude Code 的提示词、工具调用格式、编辑策略都是围绕自家模型调过的。换第三方模型后,工具调用容易出问题:找不到文件、写入报错、改一处问一次确认,流程被切得很碎。这不代表模型本身弱,而是组合没对齐。反过来,可自选模型的编辑器类工具(cline、roocode 一类)在这方面的容错通常更好一些。

私有对接代码,模型只能瞎猜或留空

支付渠道的 SDK 封装、签名验签、回调处理,大多不在公开语料里。模型没有可参考的实现,行为通常走两个极端:要么凭想象编出一套看似合理但跑不通的接口,要么直接写 mock 占位。这不是靠加提示词能补上的,只能把真实签名和示例代码喂给它。

大模型面对「重构」的默认审美

让它拆模块,它倾向于上六边形、DDD、分层抽象,原本两千行的逻辑膨胀成几十个文件,还顺手加了一堆没人要的扩展点。这类过度设计在 Reviewer 眼里比 bug 更烦,因为它把 diff 撑大到无法逐行核对。

一套更稳的改造流程

把「让 AI 重构模块」拆成可验收的小步,比换更贵的模型有效得多。

1. 先切片,一次只碰一个可验证单元

按「一个类 / 一个方法族 / 一条调用链」切分,每次任务控制在能完整塞进上下文的规模。判断标准很简单:改完之后你能在十分钟内 review 完 diff。

2. 准备上下文文件

在仓库根目录放一份约定文件(Claude Code 读 CLAUDE.md,其他工具用各自的规则文件),把项目约定写死:

# 项目约定
- PHP 8.x,Laravel,PSR-4,命名空间根 App\
- 不新增第三方依赖,不改动数据库结构,不改动对外 API
- 支付相关类必须沿用 App\Services\Pay\ 下现有封装,禁止新建抽象层
- 修改前先列出将触碰的文件与原因,等我确认
- 禁止输出 mock 实现,缺少信息时直接提问

同时把目标模块的目录树、关键接口签名、一个可参考的现有实现贴进对话。上下文给得越准,幻想越少。

3. 先要计划,再要代码

第一轮只让模型输出:要改哪些文件、每个文件改什么、有哪些不确定点。人工确认后再让它动手。这一步能拦掉大部分过度设计——只要计划里出现「新增 20 个文件」,立刻打回去。

4. 把静态检查做成闭环

这是投入产出比最高的一环。在项目里装好静态分析,让 Agent 每改完一轮就跑一遍,把报错原样贴回对话:

composer dump-autoload -o                 # 类名、命名空间错位最先在这里暴露
vendor/bin/phpstan analyse app/Modules/Vip --level=5
vendor/bin/pint --test                    # 风格与语法层面问题
php artisan test --filter=VipModule       # 有测试就先跑测试

phpstan 配合 Laravel 扩展能抓出「类不存在」「方法不存在」「参数数量不符」这三类最常见的幻觉。级别从 5 起步,跑通后再往上加。

5. 用 diff 而不是直接写文件

让模型把改动以 diff 或「原文 / 新文」对照的形式输出,再由人在 IDE 里应用。写入失败的循环、格式被整体重排、缩进全乱这类问题基本可以避免,review 也变得可逐行核对。对于跨多个文件的改动,可以让模型先给 patch,逐块接受。

6. 小步提交,用行为快照保底

每完成一个切片就提交一次,commit message 写清改了什么。重构不改行为的模块,可以先补几个覆盖主流程的测试或录制一份接口响应快照,改完对比。没有测试的项目,至少把关键入口的手工验证脚本固化下来。

7. 长任务放到稳定的常驻环境

这类重构动辄跑一两个小时,本地机器休眠、网络抖动导致会话中断,前面的上下文就白攒了。如果经常遇到断线重来,把 Agent 放到一台长期在线的机器上跑是可选做法,例如整机放在机房的远程 Mac,按月租用、远程连接,网络环境比家用宽带稳定,适合长时间挂着 Claude Code 这类 CLI 工具;本地设备性能不足或需要无人值守时也可以考虑。注意这只是减少环境干扰,不会提升模型本身的正确率。

工具怎么选

组合 适合场景 注意点
Claude Code + 官方 Claude 模型 复杂改造、多文件联动 成本高,先用小任务验证收益
Claude Code + 第三方模型 预算敏感、任务已被切得很小 工具调用与上下文管理未必适配,需实测
cline / roocode + 自选模型 想灵活换模型、需要较强的人工确认粒度 效果波动大,看具体模型
Cursor 等 IDE 内 Agent 单文件、函数级修改,想边看边改 大范围重构仍要人工兜底
gemini-cli 等 CLI 出规划、写测试、生成文档 工具调用稳定性一般,写入失败易触发整文件重写

比较务实的做法是固定同一个可验收的小任务,用两三种组合各跑一遍,比较「一次通过率」和「人工修正耗时」,而不是看榜单分数。不同工具之间的评测差异很大一部分来自 Agent 工程实现,很难据此断定模型强弱。另外,CLI 类工具的确认粒度往往很碎,改一行也弹一次确认,长任务下会很累,可以配合允许批量确认的模式或分层放权。

需要留意的风险

  • 第三方中转与共享账号:为省钱走中转 API,可能遇到被悄悄换成更弱模型、限速、日志留存等问题;买卖或共享账号本身也违反多数平台条款,存在封号和数据泄露风险。稳妥做法是走官方渠道,或者用一组固定 prompt 做指纹测试,验证返回是否与官方一致。
  • 代付、代理充值类渠道:涉及支付合规与账号安全,不建议使用,正规云厂商的按量实例和官方订阅已经够用。
  • 资金相关代码必须人工把关:支付签名、金额计算、回调校验、幂等处理这些位置,模型生成的代码只能当草稿,必须逐行核对并跑真实沙箱回调。
  • 成本要提前估算:长任务容易在反复修补中烧钱,给每个切片设一个 token 或时间上限,超了就停下来重新切片,而不是继续对话。
  • 营销声量与实测表现无关:模型的热度和它在你的技术栈上的表现是两件事,PHP 这类语料相对少的语言尤其如此。

小结

AI 改造存量项目失败,通常不是「模型不够聪明」这一个原因,而是任务粒度、上下文供给、错误反馈闭环、工具适配四件事同时没做好。落地时按这个清单自查:

  1. 任务是否小到 diff 能在十分钟内 review 完?
  2. 有没有把接口签名、目录结构、项目禁忌写进约定文件?
  3. 是否先要计划再要代码,并驳回了过度设计?
  4. 静态分析和测试能不能让 Agent 自己跑、自己看报错?
  5. 改动是不是以 diff 形式产出、由人确认落盘?
  6. 支付等关键路径是否人工逐行核对过?
  7. 长任务的环境是否稳定,断线成本是否可接受?

先把这七条落实,再去纠结换哪个模型,成功率会高得多。

(各工具与模型的能力、价格和可用性变化较快,具体以官方最新说明为准。)

Claude CodeAI编程静态分析Kimi-K2Laravel重构