Kimi K3实战:重构万行代码,AI如何根治Vibe Coding遗留的技术债

近期在升级 JClaude 的过程中,我注意到 Tokens 消耗异常剧烈。深入排查后发现,有一个源文件已经膨胀到近 10000 行。初步估算,单是这一个文件的上下文就要占用十几万 Token。虽然程序功能一切正常,但技术债务明显在累积,必须启动一次彻底的重构。
恰好我最近在体验 Kimi K3,于是把这项任务交给了它。相比做一个花哨的动画效果,这种真实的工程优化场景显然更有考验价值。
下面完整记录它的重构过程以及最终成果。
项目背景与现状
先快速介绍一下这个项目的全貌:

这是我为 Claude Code 打造的中文界面版,界面完全复刻了 Claude 桌面端的视觉风格,底层通过与 Claude Code 终端交互,能自动接入第三方模型。换句话说,第三方模型可以通过这个软件,直接调用 Anthropic 的最强编程智能体,且不受账号限制。如果你配置了 Opus 4.8,这个工具的体验几乎可以媲美官方的 Claude 桌面版。
近期由于集成了角色与技能相关的能力,项目文件体量迅速失控。这个项目最初只是一个界面复刻的小实验,起初并没有认真考虑代码架构。在后续持续迭代时,也没有明确向 AI 提出架构优化的需求,结果就是 AI 在不断“堆砌”代码。我猜测,大量 Vibe Coding 项目都会遭遇同样的困境——起初只是试着玩,玩得顺手了就一路放大,技术债也随之滚雪球般扩大。
代码现状分析
项目基于 Tauri + Rust 构建,安装包小巧、内存开销极低,能够生成多平台的发行包。界面部分主要使用 JS、CSS 和 HTML,表现力出色;后端采用 Rust,能高效地与系统底层交互。开发过程支持热更新,效率很高。这是整体的技术背景。
要对代码进行重构,必须先摸清具体哪些文件最臃肿。
因此,我们的对话是这样开始的:
当前代码中有哪些文件代码行数特别多?有没有做一下优化的必要性?
得到的结果清晰显示,main.js 已经达到 9338 行,几乎触及万行大关,内部还塞进了将近 400 个函数。
接下来就是进一步拆解它的内部构成。
main.js 的内部结构
它本质上是一个纯脚本文件,没有使用 import 或模块化机制,全靠 30 个 // ==== 注释来人工分段。
体积最大的几个部分包括:
• Claude Code CLI bridge——约 2160 行,是整个文件中最庞大的单一模块
• Experts & Skills 管理——约 800 行
• i18n——约 620 行,几乎全都是翻译数据
• Code workspace panels / Projects / Settings / Providers——各 500–600 行
模块边界其实很清晰,但文件体积确实已经超出合理范围。
是否有必要优化?
了解基本情况后,下一步就是判断重构的必要性。
K3 给出的结论是:有必要,但需结合后续的开发节奏来看,不推荐一次性大规模改动。
支持拆分的理由:
• 单文件接近万行,已经突破可维护性的常见阈值,多人协作时合并冲突几乎无可避免
• 有几个段落是天然的拆分候选,成本低、收益高:
• i18n 是纯数据,抽成 i18n/zh.json、i18n/en.json 之类几乎零风险
• CLI bridge 超过 2000 行且自成体系,独立成模块后主文件立刻瘦身四分之一
• Tauri 本身支持原生 ES modules,通过 <script type="module"> 拆分为模块化文件,不一定需要引入额外的打包工具
这里特别提到了多人协作冲突的隐患。对我个人而言,虽然是“多 AI 协作”,但依然是一人主导,冲突问题不算尖锐。
需要权衡的方面:
• 现有测试覆盖非常薄弱,大规模重构缺少安全网,回归风险较高
• 大文件本身并非原罪——如果这部分代码已经稳定、变动极少,依赖分段注释依然可以维持基本可维护性
建议的优先级是:如果近期还会持续增加新功能(尤其是 CLI bridge、Skills 相关),就按照“i18n → CLI bridge → 各 workspace 面板”的顺序逐步拆分,每拆出一块就运行现有测试;如果已经进入维护期、改动不多,也可以暂缓,只把 i18n 数据分离出去。
从多视角评估重构必要性
当前的情况是文件很大,但暂时没有出现严重缺陷。真正让我担忧的是,大文件场景下 AI 对代码的读写能力以及 Token 的无谓消耗。
于是我提出了第二轮需求:
下面我们从代码设计、AI 读写以及 Token 消耗的角度来判断一下优化的必要性。
以下是 K3 的分析结果。
- 代码设计视角
• main.js 的问题不仅是“长”,更关键的是无模块化的长:约 400 个函数全部暴露在全局作用域,
通过一个全局 state 对象和 DOM id 隐性耦合。你无法只修改“设置”模块而完全不惊动“对话”
模块,因为它们共享同一片命名空间。
• 这种结构直接导致可测试性极差——仅有 3 个针对性测试,很大程度上正是这种架构的宿命,而不
是先天的缺陷。函数无法独立 import,也就难以编写单元测试。
• lib.rs 同样有 4148 行,但 Rust 拥有成熟的模块系统和编译器保障,拆分安全且容易,风险远
远小于 main.js。
• styles.css 有 4836 行,在 CSS 世界里并不算离谱,危害最低,可以最后再处理。
单从代码设计来看:有必要拆分,但属于“慢性病”,不致命。
- AI 读写视角
这里是大文件最直观的成本:
• 读不完整:主流 AI 工具单次读取文件的上限大约 1000 行,9338 行的文件 AI 永远只能看到局部。
修改一个功能时,它能关联到目标段落,但看不到 3000 行外依赖同一全局状态的函数——改坏联动
的概率会显著增加。
• 编辑容易误伤:AI 编辑基于精确字符串匹配。万行文件中相似代码片段众多(比如那 14 个结构
几乎一致的 persistXxx() 函数),匹配的唯一性低,误替换风险高。
• 定位成本高:虽然靠 // ==== 分段标记加 grep 还能勉强工作,但跨段依赖(全局 state、跨段
调用)对 AI 是不可见的,每次任务都要重新摸索。
拆成模块后,每个文件能被 AI 一次性完整读取,心智模型清晰,改动质量会明显提升。
- Token 消耗视角
按照中英文混合代码约 3.5 字节/token 粗略估算:
• main.js 全量读入 ≈ 13 万 tokens,一次就能吃掉大半个上下文窗口。
• 实际工作模式是 grep + 分页读取若干段,但每次任务通常需要读取 state 定义段、目标功能段以
及相关 persist/i18n 段,累计轻松达到 3–5 万 tokens,而且每次会话都会重复消耗。
• 拆成模块后,一个任务通常只需完整读取 1–2 个相关文件(几千 tokens),单次任务大约能节省
80% 以上的 Token,而且这是持续性收益——以后每次让 AI 改代码都在省钱。
• i18n 那 620 行纯数据最为冤枉:经常被带入上下文,却几乎不需要全部展示。
这确实是一个大问题,浪费太严重。如果能通过重构节省 80% 的 Token,这个诱惑相当大。
- 综合判断
单看代码设计,拆分是“应该做却并不紧急”的事;但叠加 AI 读写以及 Token 成本之后,重构的必要性明显升级——因为我本身就是重度使用 AI 辅助开发,大文件的“税”是每次任务都在交的。
结论保持不变:增量拆分,按照 i18n → CLI bridge → 各面板的顺序推进。
深入拆解方案
其实我心里早有打算,因为之前已经让 Opus 4.8 尝试过一次拆分。这次显然也是朝着拆分的路径引导 K3。但为了更稳妥,也为了更好地引导它完成任务,我又提出了第三个问题:
那我们就先把 main.js 这个文件拆分一下吧。
那你觉得如何来拆分这个文件比较合适?
拆分到什么样的颗粒度比较合适?
拆分过程中应该注意什么?
如何保障成功完成这个重构任务?
- 怎么拆
对齐现有的 // ==== 分段标记,采用分层、自下而上的方式。加载方式从原来的 <script src="./main.js"> 改为 <script type="module" src="./main.js">。
然后按照现有分段逐层抽取,形成合理的依赖关系:
• 第 0 层(纯数据,零依赖):i18n、DEFAULTS、MODEL_BLURB/system prompt、action chip prompts
• 第 1 层(基础工具):state(全局 state + KEYS + 14 个 persistXxx)、storage、Tauri API 封装
• 第 2 层(UI 基础设施):theme、sidebar、tooltip、菜单
• 第 3 层(功能域):chat、projects、settings、providers、experts/skills、code panels、
CLI bridge、browser、code stats、mentions
• main.js 最终只保留入口:import 和 init/boot 的顺序调用
- 颗粒度
一个分段对应一个模块,控制在 200–800 行/文件:
• 目标:每个文件能被人类或 AI 一次性完整读取(<1000 行),预计拆出 15–20 个文件,收进
src/js/ 之类的子目录。
• 不要过度拆分:如果拆成 50 个 100 行的小文件,import 清单本身会成为新的维护负担,跨文件
跳转反而更累。
• 也不要追求完美:chat/projects/settings 核心段耦合最重,如果拆到一定程度发现代价陡增,
保留一个较大的 app.js(控制在 2000 行以内)也完全可以接受——80% 的收益往往来自前 20%
的抽取工作。
- 注意事项(按翻车风险排序)
1. 测试 eval 耦合:搬移 DEFAULT_EXPERTS 等被测代码块时,必须同步更新测试中的 SRC 路径,
标记字符串原样保留。
2. 循环依赖:功能模块之间必然相互调用(chat ↔ workspace ↔ projects)。ESM 循环导入在“仅
运行期调用、无顶层副作用”的条件下是安全的——所以搬移时保持 function foo() {} 的声明形式
(具有提升),严禁在模块顶层执行跨模块调用,由 main.js 统一触发 init。
3. 共享 state 的唯一性:state 对象(main.js:474)必须从 state.js 导出同一个引用,所有
模块 import 这同一份实例,绝不能复制。
4. 只搬不改:每次提交只做机械搬移 + 补充 import/export,不要在过程中顺手优化逻辑。重构
成败的关键就是 diff 可审查、可回退。
5. import 清单遗漏:400 个函数分散后,漏掉一个 import 就会导致运行时的 ReferenceError,
而静态检查很难发现(项目没有 lint)。对策见后文。
6. init 顺序:boot splash、applyWorkspace 等具有 DOM 时机依赖(index.html 的注释专门
提过),入口处的初始化顺序必须原样保留。
虽然看起来只是拆一个文件,但实际难度并不低。不同模块之间存在耦合,我之前让 Opus 分析过,有些模块间的耦合点多达几十个。一旦拆开,文件行数和文件数量都会变化,模型必须重新学习新结构,然后再进行后续的解耦操作。
- 如何保障成功
这一条非常关键:
• 先试点:第一步只拆 i18n + state 两个部分,走通“搬移 → 修改测试 → 验证”的全流程,
确认模式可行后再批量推进。
• 每步三道闸:npm test 全绿(3 个 node 测试 + cargo test)→ npm run dev 启动冒烟测试
(主界面、聊天、设置、Code workspace 各项点一遍,观察控制台报错)→ 独立 commit。遇到
问题单步回退即可。
• 明确的完成标准:main.js 只剩下入口(<300 行)、测试全绿、冒烟清单通过、每个搬移出去
的段落都能在新文件中被 grep 到。
• 顺序:i18n → 纯数据 → state/storage → UI 基建 → CLI bridge(体积最大但自成一体,
主文件瘦身四分之一就看这一步)→ experts/skills、code panels、browser → 核心段(视
情况收尾)。
从它的回答来看,对整体思路已经理解得比较透彻了。经过三轮引导,K3 应该已经抓住了关键信息。于是,最后只剩下一句话:开干!
重构执行实录
下面这张图是它自己拆解出的 todo 任务列表:

改动完成后,它还主动提了两个确认问题:

第一个是询问是否在用 Git 进行版本管理,以便回退;第二个是讨论冒烟测试的具体方式。这种谨慎的态度相当靠谱。不过,我对它推荐的测试选项不太满意——怎么能把“手动启动 dev”放在优先建议里呢?这种情况应该是你来自动启动,我来观察结果。
还有一处细节可作对比参考:当初 Opus 4.8 修改时,虽然拆得很细致,但它十分自信地告诉我它会自行完成 dev 测试,我就放手掌柜了。K3 在第一轮修改中,因为独立性强,整体推进速度很快。
我简单测试后发现没有大问题,唯独一个异常是 Claude Code 的调用出现中断。

我不太明白它为什么跳过了内置的 Claude Code,正常情况下不应该弹出这个提示。我把现象反馈给它后,它很快就定位并解决了这个缺陷。既然关键功能正常了,那就可以继续往下推进。
随着重构深入,复杂度也在上升。

到了中间阶段,需要验证的点越来越多,每次修改耗时也随之变长。
重构结果与收益
整个重构过程大约耗费小半天时间。
最终,main.js 从 9938 行压缩到了 263 行,减少 97%。

代码全部改为模块化设计,共拆分为 24 个独立模块,每个文件 33 至 2177 行不等。

整个变更分布在 13 个 commit 中,每一步都可以独立回退。
基础的语法检查和其他校验均由它自动完成。随后我人工验证了各项功能,全部正常运行。
这次重构不但非常成功,而且过程毫无波澜。
重构这件事需要清晰的思路,而且对精确度要求极高,容不得一丁点差错。K3 能够顺利完成,且在过程中没有引入任何功能性错误,这一点确实有些超出我的预期。2.8T 参数加持下,其稳定性果然有了质的提升。
这次实测结果相当理想!
下一篇,我将用它来修复桌面软件中的一个疑难 Bug,敬请期待。