k10s 作者在 5 月 9 日发文说,他要把用 Claude 辅助开发的 k10s go-v0.4.0 分支归档,然后从头手写重构。
这个项目不是玩具脚本。k10s 是一个面向 NVIDIA/GPU Kubernetes 集群的 TUI 工具,用 Go 和 Bubble Tea 写,目标有点像 k9s,但更关注 GPU 利用率、DCGM 指标、节点空闲、显存等信息。
反常点在这里:它不是没做出来,而是做得太快了。约 7 个月、30 个周末、234 次提交之后,功能已经不少,但代码开始不听话。
我更在意的不是“作者又回去手写代码”这个姿态,而是它暴露了 AI 编程里很容易被 demo 掩盖的一段路:前半程像开挂,后半程开始还债。
从 10 倍速度到空表:k10s 怎么失控
作者从 2025 年 9 月底开始做 k10s,主要靠 Claude 的 vibe coding 会话推进。早期体验很顺。
pods、nodes、deployments、services、命令面板、日志流、describe 面板、Vim 快捷键,很多功能都能在一次会话里落地。对个人项目来说,这种速度很诱人。
转折点出现在 GPU fleet view。
这个视图是 k10s 的核心卖点:用一张表展示每个节点的 GPU 分配、利用率、温度、功耗和显存,并用颜色区分空闲、繁忙和饱和状态。Claude 一次生成了 FleetView、GPU/CPU/All 标签过滤和自定义渲染。
然后问题来了。
切回 pods 视图,表格为空,live updates 停止。切到 nodes 视图,又出现 fleet view 过滤遗留的旧数据。再回 fleet view,标签计数也错了。
作者这时第一次完整读代码,发现 model.go 已经有 1690 行,Update 方法约 500 行,里面有 110 个 switch/case 分支。
| 阶段 | 看起来赚到的东西 | 后来付出的代价 |
|---|---|---|
| 早期功能生成 | 单次 prompt 就能加视图、日志、快捷键 | 功能不断贴到同一个 Model 上 |
| GPU fleet view | 很快做出项目核心卖点 | 打破 pods、nodes、logs 等视图状态 |
| 全局 Update | 初期改动少,见效快 | 500 行分发逻辑难定位副作用 |
| 通用 Kubernetes 能力 | 让 k10s 更像 k9s | 产品范围从 GPU 工具滑向通用 TUI |
这张表里最要命的不是“代码多”。代码多可以拆。真正麻烦的是,状态没有主人。
崩盘点:一个 Model 管了太多事
k10s 的关键问题,是所有视图状态都混在一个 Model 里。
UI 组件、Kubernetes client、logs、describe、fleet、navigation history、缓存、鼠标处理,都塞进同一个结构体。短期看省事,长期看就是上帝对象。
更危险的是,代码靠 currentGVR.Resource 这个字符串判断当前视图。fleet view 的特殊逻辑,被塞进通用资源加载路径。logs、describe、yaml 等视图之间,则靠手动 nil 清理维持隔离。
作者数到至少 9 处手动清空字段。漏掉一次,旧数据就会串到新视图里。
这类问题,在真实项目里很常见。大型前端、移动端、后端服务都怕它。成熟团队通常会让模块拥有自己的状态,入口层只做路由和分发。原因很简单:状态一旦共享,副作用就会躲起来。
AI Agent 正好会放大这个弱点。
它很擅长完成局部目标。比如“给 pods 加 shell 快捷键”。最短路径往往是在全局 key handler 里加一个 if 分支。一次看没事,二十次以后,s 在 logs 里是 autoscroll,在 pods 和 containers 里又变成 shell。
代码还能编译,功能也像是加上了。但人已经很难局部推理。
这不是说 AI 写不了代码。原文的判断更窄,也更有用:AI 适合写功能,但不会自动替你生成好架构。你不给边界,它就会沿着最短路径继续补丁式生长。
真正该改的,是给 AI 写约束
作者没有停在吐槽。他给出的改法很具体:把架构不变量写进 CLAUDE.md 或 agents.md,让 AI 每次工作前都能看到。
这些规则不是“代码风格建议”,而是硬边界。
| 约束对象 | 应该写死的规则 | 解决什么问题 |
|---|---|---|
| App / Model | 只能做薄路由,不承载所有业务状态 | 防止继续长成上帝对象 |
| View | 每个 view 独立实现接口 | 避免视图之间互相读写状态 |
| 异步数据 | 必须通过 AppMsg 进入 | 让数据流可追踪 |
| Keymap | 每个 view 有自己的 keymap | 避免同一个按键在不同场景串义 |
| 新功能 | 新增 view 不能随意修改既有 view | 降低局部改动的副作用 |
| 产品范围 | 禁止随意扩展 scope | 防止 GPU 工具滑成通用 Kubernetes TUI |
这里最有价值的一点,是产品范围也要写进约束。
k10s 原本服务 GPU 集群运维者,不是要覆盖所有 Kubernetes 用户。可 AI 会让 pods、deployments、services、contexts、namespaces、鼠标支持这些功能显得很便宜。
便宜的是生成代码,不是复杂度预算。
对正在用 Claude、Copilot Workspace 或其他 Agent 写真实项目的开发者,这意味着一个很直接的动作:不要只写“实现某功能”的 prompt,要先写“不允许怎么实现”。比如状态归属、模块边界、禁止改哪些文件、哪些路径必须先提设计。
对技术负责人,动作更硬一点:把 AI 生成代码纳入架构评审,而不是只看 PR 能不能跑。尤其要盯三件事:有没有上帝对象,状态是否跨模块串用,新增功能有没有悄悄扩大产品范围。
个人项目还能靠重写止损。团队项目不一样。一个 500 行 Update、一个到处手动 nil 的状态机,最后会落到 code review、排障和值班上。
现实限制也要说清。这个案例只能说明一个个人项目在 AI 辅助开发中的经验样本,不能直接推出“AI 编程失败”。下一版 k10s 手写重构后会保留多少功能、架构效果如何,目前也还看不清。
但它至少给了一个可观察变量:如果一个 AI 辅助项目的功能增长很快,却没有同步沉淀架构不变量、状态所有权和产品边界,那速度本身就可能是在透支。
回到开头,k10s 不是因为 Claude 写不出功能才被归档。恰恰相反,它是因为功能来得太容易,边界没有及时跟上。
AI 可以把实现速度推得很高。但掌舵这件事,还是得有人负责。
