AI 写了 10000 行才做出的后台,他只写了 406 行
先说个数字。
同样一个"管理本机 VSCode 的后台"------4 个模块的增删改查、登录页、角色权限、Excel 导入导出------两种做法:
让 AI 从零手写,最小实现也要 10000 行以上,输出 token 100K 打底,还不算改到能跑的那几轮返工。
用 erupt-skill,AI 实际产出 406 行、14434 个字符,约 4K 输出 token。4 个实体类 + 1 个 DataProxy + 菜单注册,一次编译通过,5.6 秒启动交付。
差 20 倍。
这不是提示词写得好,是分工换了。
一、先承认一件事:AI 现在写后台,写得又快又烂
2026 年了,让 AI 生成一个后台管理系统已经不是新闻。新闻是社区给这类产物起了个新词------Vibe Slop,氛围垃圾:能跑,但臃肿、脆弱、没人敢维护。
最典型的翻车不在功能,在权限。有人让 AI 写电商后台的鉴权,AI 老老实实做了登录态校验,然后把角色权限那段整个漏了。结果就是普通用户能直接调商品上架、订单修改的接口。代码跑得好好的,测试点点也没问题,漏洞躺在那儿等人发现。
Karpathy 今年 2 月自己出来把 vibe coding 这个词收了回去,改口叫 Agentic Engineering------多一层监督,多一层审查。
问题的根子其实很朴素:AI 写的每一行代码,都是一次犯错机会。 让它写 10000 行,就是给了它 10000 次机会。
那能不能......让它少写点?
二、少写点的前提,是有人替它写好了
后台系统有个特别好的性质:90% 的代码是重复的。
表格怎么渲染、表单怎么校验、分页怎么传参、登录态怎么维持、菜单权限怎么算、Excel 模板怎么下载再回传校验------换一个业务域,这些东西一行都不用变。变的只有"这张表有哪些字段"。
Erupt 这个低代码框架干的就是这件事:它把这 90% 做成了框架能力,58000 行前端 + 14000 行后端,一共 7.2 万行现成代码。你要做的只剩下一件事------写实体类,把字段标出来。
java
@Erupt(name = "候选人")
@Getter @Setter @Entity
@Table(name = "t_candidate")
public class Candidate extends MetaModel {
@EruptField(
views = @View(title = "姓名"),
edit = @Edit(title = "姓名", notNull = true, search = @Search)
)
private String name;
@ManyToOne
@EruptField(
views = @View(title = "应聘职位", column = "name"),
edit = @Edit(title = "应聘职位", type = EditType.REFERENCE_TREE)
)
private Position position;
@EruptField(
views = @View(title = "状态"),
edit = @Edit(title = "状态", type = EditType.CHOICE, search = @Search,
choiceType = @ChoiceType(fetchHandler = StatusFetch.class))
)
private String status;
}
就这样。列表、搜索、新增表单、编辑弹窗、导入导出、行级权限,全部自动生成,一行前端代码不用写。
现在回过头看那个 token 数字就不神秘了:AI 只写了实体类,那 7.2 万行框架代码是零 token 复用的。
顺带说个副作用------AI 漏写鉴权那类事故,在这套分工里不会发生,因为权限压根不归 AI 写。 UPMS 是框架自带的,菜单权限、按钮权限、行级数据权限都由框架统一执行。AI 就算想漏,它也碰不到那段代码。
三、erupt-skill:把这套分工封进一个 Agent Skill
道理讲清楚了,还差一步------得让 AI 知道该怎么写实体类。
这就是 erupt-skill 做的事:一个遵循 Agent Skills 开放标准的技能包,一个 SKILL.md 加十几篇 reference 文档,把"Erupt 该怎么用"完整喂给 AI。
装法就一行:
bash
git clone https://github.com/plinian/erupt-skill.git ~/.claude/skills/erupt-admin
因为走的是开放标准,不只 Claude Code:
| 工具 | 技能目录 |
|---|---|
| Claude Code | ~/.claude/skills/ 或 .claude/skills/ |
| Codex CLI | ~/.codex/skills/ 或 .codex/skills/ |
| Cursor | .cursor/skills/ 或 .agents/skills/ |
| Trae | .agents/skills/ |
| CodeBuddy | .agents/skills/ |
装完之后,你要做的就是说一句人话:
做一个图书管理后台
做个带状态筛选的客户订单管理系统
给刚才那个后台再加个借阅记录模块
然后打开 http://localhost:8080,erupt / erupt 登录。
没有环境准备这一步。 这是我觉得最狠的地方------机器上没装 JDK 也能跑。skill 会自己去 Adoptium 官方源拉 OpenJDK 25,国内下不动就自动切清华镜像,解压到 ~/.erupt-skill 缓存复用;Maven 3.9 同样自动准备,依赖走阿里云;数据库用内嵌 H2 文件库,不用装 MySQL。仓库本体只有 1MB 左右,clone 是瞬间的事。
非开发者也能用这句话,不是营销话术,是这个 skill 的设计目标。
四、它不是"生成完就跑",而是六步流水线,每步一道闸
这是 erupt-skill 和普通 vibe coding 最本质的区别。翻开 SKILL.md,里面是一条被反复加固过的流程:
第 0 步,收到需求立刻预热。 后台跑 warmup.sh,一边你在描述需求、AI 在解析,一边 JDK/Maven/Spring Boot/Erupt 依赖已经在并行下载了。等 AI 写完实体类,依赖基本就绪,首次构建几乎免等待。预热前还会先查一次 Maven 仓库锁定最新 Erupt 版本,避免"预热了旧版、真构建时又重下一遍"。
第 1 步,不追问。 SKILL.md 里写死了:「不要追问细节,用领域常识补全」。"图书管理" → 图书、分类、借阅记录,2~5 个实体,每个 5~10 个常识字段,关系自己推。这条规则是刻意的------AI 一旦开始反问"您需要哪些字段呢",这句话的价值就没了。
第 2 步,生成项目,只写实体类。 这里有条我很喜欢的硬规则:
版本号必须来自上述命令的实际输出,严禁凭记忆或训练数据填写(曾出现过误写 1.13.0 旧版本的情况)
------"曾出现过"。这不是防御性文档,这是踩过坑之后写回去的补丁。
第 3 步,构建启动,盯日志。 出现 Started Application 才算成功,编译错误就地修,端口占用自动换端口。
第 4 步,交付前自检------这是全流程最关键的一道闸。 跑 verify.sh:登录 → 拉菜单 → 逐表查询,只读不写数据。任何实体注解错误------联动表达式写错、权限配置写错------都会在这一步暴露,而不是等用户点进去才发现。输出 PASS 才允许交付。
第 5 步,迭代。 任何 Java 改动之后,必须先前台跑 compile.sh 编译校验,通过了才准重启。不许"改完就说好了"。
这套东西,本质上就是 Karpathy 说的 Agentic Engineering:AI 可以自主干活,但每一步都得留下可验证的痕迹。
五、坑是怎么被写回去的:一个真实模块
光有流程不够,还得有实战。
SKILL.md 底部有张"常见问题排查表",里面几条一看就知道是被真实错误打出来的:
| 现象 | 处理 |
|---|---|
提交表单报 500 ReferenceError: "xxx" is not defined |
@Dynamic 的 condition 用了字段名当变量,改用固定变量 value |
| 多个自定义按钮点击后都执行同一个逻辑 | 多个 @RowOperation 必须各设唯一 code,空串会永远命中第一个 |
启动报 Primary key not found |
eruptClass 弹窗表单类必须 extends BaseModel |
编译大量报 cannot find symbol getter/setter |
JDK 23+ 默认禁用隐式注解处理,确认 pom 配了 lombok annotationProcessorPaths |
这些坑哪来的?举个具体例子------erupt-wx,一个基于 Erupt 的微信公众号管理模块,功能对标 jeewx。
八个菜单:公众号账号(多号管理,行操作发布菜单/同步粉丝/同步标签/同步模板)、自定义菜单(两级树,一键发布到微信)、自动回复(关键字精确/包含、关注欢迎语、默认回复)、素材、粉丝(全量同步 + 关注取关事件实时更新)、粉丝标签(增删改实时同步微信)、模板消息(批量发送 + 记录下钻)、参数二维码(临时/永久,列表直显二维码图片)。
回调地址 {域名}/wx/portal/{appid},明文和 AES 安全模式都支持。Apache-2.0。
这是产物,不是玩具 demo。 它走的是 skill 的另一条分支------用户明确要做"可复用的 Erupt 功能模块"时,skill 会切到 template-module/ 模板,产出是能被别的 Erupt 应用加依赖引入的 jar,而不是一个独立应用。
而做完这个模块的当天,erupt-skill 仓库多了一条 commit:
Fix doc errors and harden workflow from erupt-wx field test
用它踩坑,坑当天写回 skill,下一个人不会再踩。 这个闭环才是一个技能包真正的护城河------它不是一份提示词,是一份不断被实战校正的经验沉淀。
六、它的边界在哪
不吹。说清楚三件事:
第一,默认模板只覆盖核心 CRUD。 定时任务、报表、通知、AI 对话、微服务这些能力不在默认模板里。需要的时候 skill 会去查 reference/erupt-ecosystem.md 里的模块清单,加依赖引入现成能力------明确禁止 AI 手写实现。这条规则同样是刻意的:AI 手写一个定时任务调度,写出来的一定不如现成模块。
第二,默认 H2,生产要换库。 H2 文件库适合演示和轻量使用,正式上生产建议切 MySQL/PostgreSQL------改 application.yml 的 datasource 加个驱动就行。
第三,reference 是快照,可能落后。 SKILL.md 里明写了兜底规则:文档和实际冲突时以发布版 jar 为准,本地文档解决不了就按 doc-map.md 去 GitHub 拉官方原文,不许猜着写代码。当前的实测核实基线是 Erupt 2.1.1(2026-08)。
最后
回到开头那个数字。
406 vs 10000,省下的不只是 token,更是 9600 行"没人写、所以也不会错"的代码。
AI 时代最反直觉的一件事可能是:衡量一个 AI 工具好不好,不该看它能写多少代码,该看它能少写多少。
如果你也在用 Claude Code、Codex 或者 Cursor,不妨花一分钟装上试一句:
bash
git clone https://github.com/plinian/erupt-skill.git ~/.claude/skills/erupt-admin
然后说:「做一个进销存后台」。
⭐ 觉得有用的话,给两个仓库点个 Star,这是对开源项目最实在的支持:
- Erupt 框架 ------
github.com/erupts/erupt - erupt-skill ------
github.com/plinian/erupt-skill