DEV Community

wenjianzhang
wenjianzhang

Posted on

Why AI-Generated Code for Your Go Project Compiles But Still Needs a Rewrite

Why AI-generated code for your Go project compiles but still needs a rewrite

A familiar scene

You ask Claude Code, Cursor, or whatever AI coding tool you're using to "add a product management module." Most of the time it produces something that compiles. The endpoints respond. You can even hit them from Postman.

Then you open the frontend, and the menu item isn't there. Or it is, and clicking into it gives you a 403. Or the code works, but it's written in a completely different style from the rest of the codebase, and two weeks later you can't tell which parts were AI-written and which weren't.

The model isn't the problem. It just has no idea what your project actually looks like right now.

Why "just ask the model" fails

Take go-admin, an open-source Gin + Vue 3 admin framework, as an example. It's been public for several years. In earlier versions, every business module required hand-written Api and Service files — at least seven functions per Api. That style makes up a large share of what's publicly visible on GitHub, and it's almost certainly overrepresented in what any model has seen during training.

The current codebase, though, recommends an Actions-based pattern for single-table CRUD: a module only needs three files — model, dto, router — with parameter binding, data-scope filtering, and pagination handled by the framework's built-in Actions.

Both styles compile. The model won't warn you either way, and you won't notice immediately. By the time the two styles are mixed across a real codebase, unifying them again costs real engineering time.

And that's just backend code style. The part that's easy to miss — and that fails silently — is something else entirely: for a module to actually be usable in the UI, you also need correct seed data across four tables: sys_api, sys_menu, sys_menu_api_rule, and casbin_rule — route registration, menu mounting, the menu-to-API relationship, and the actual permission policy. Miss any one of them and the symptom is identical: everything looks fine, but the menu doesn't show up, or the button doesn't do anything. No error, anywhere.

What we did about it

The first layer is AGENTS.md — a convention file written specifically for AI coding tools, one in the root of go-admin and one in go-admin-ui (the frontend). It's deliberately short: only rules that cause a real failure if ignored. Stack versions and commands are left to go.mod and package.json to answer for themselves, so the file doesn't drift out of sync with the code.

The second layer is a reference implementation that actually compiles, has tests, and runs in CI (app/demo/). Prose goes stale. Code that CI keeps exercising doesn't — it's a more reliable source of truth than any spec document.

Those two layers get style alignment right, but they're not enough on their own. The code can be idiomatic and the permissions can still be wrong, and the user still ends up staring at a sidebar with no menu. So we turned "add a new business module" from a paragraph of prose into a structured, invocable Skill — one end-to-end procedure covering table design, migration, Actions-mode scaffolding, and the menu/permission seed data step that's easiest to forget, with every step pointing at a real, runnable reference file instead of asking the model to reconstruct it from memory. The frontend side has a matching skill for scaffolding a standard list+form page, and the two are kept in sync by one shared string: the permission identifier.

The part worth stealing, even if you don't use go-admin

Not every project needs a formal Skill right away, but the layering underneath it generalizes:

  1. Write down what's actually a hard rule — an AGENTS.md-style file, scoped to "ignore this and something breaks." Keep it short.
  2. Point at a real, running reference implementation instead of describing the pattern in prose. Text lies eventually; code that CI exercises doesn't.
  3. Call out the step that's easy to skip and fails silently. For go-admin that's the permission seed data. Most nontrivial systems have an equivalent hidden dependency.
  4. Only turn genuinely repetitive workflows into a Skill. One-off tasks are better served by documentation; not everything needs to be tooled.

The built-in code generator handles the deterministic, reproducible part — standard CRUD from a table definition. AI generation covers what the generator doesn't: business logic, refactors, tests. They're not competing approaches; which one you reach for depends on the task.

If you want the details

go-admin is an open-source admin framework built on Gin and Vue 3. The docs have a full writeup on prompting AI to generate code for it — what three things a good prompt needs, plus copy-paste templates for adding a module, cross-table business logic, refactoring existing code, backfilling tests, and writing migrations.

Repos: go-admin (backend), go-admin-ui (frontend, Element Plus edition). Feedback on the AGENTS.md files or the skills themselves is welcome.

Top comments (0)