Building a Schema With an AI Agent Without Naming a Single Column
· Updated
Ask an AI agent for a discussion-board schema and you’ll get one in about four seconds. Here is the part nobody mentions: you’ll also get is_deleted in this table and del_yn in the next one, because the model is pattern-matching against every schema on GitHub, and those schemas disagree with each other and with you.
The fix is not a better prompt. It is giving the agent the same thing you’d give a new hire — the list of words your team actually uses — and making it impossible to ignore.
I did that with a threaded discussion board. I never typed a column name. The whole run fits in three and a half minutes:
The setup, in one call
The agent starts by binding a new project to our team standard:
create_erd {
name: "Threaded Discussion Board",
workspaceId: "…",
target: { server: true }
}
get_erd_overview
// → { glossaryLinked: true, dictionaryEntryCount: 28, domainCount: 15 }
Twenty-eight words and fifteen domains arrive with the project. That is the whole trick. From here the agent isn’t choosing names — it’s resolving them.
Describing the work
Then I talked to it the way I’d talk to a colleague: members post articles, a post can reply to another post, members comment on posts.
The agent called the tools with logical names — business terms, not column names:
upsert_entity { logicalName: "Post" } // → POST
upsert_attribute { logicalName: "Post Content",
domain: "Content" } // → POST_CNTS
upsert_attribute { logicalName: "Delete Flag",
domain: "Flag" } // → DELETE_YN
Content → CNTS and Flag → YN aren’t the model’s taste. They’re our word list’s abbreviations, applied exactly as they were applied in every table we’ve built before. The domain carries the type, so Content is varchar(1000) everywhere — nobody decides column widths per table anymore.
Notice what didn’t happen: I didn’t review a name and correct it. There was nothing to correct.
The part most tools get wrong
Then the board needed threading — a post that replies to another post. A self-referencing foreign key.
This is where diagram tools quietly fall over. The child column can’t reuse the parent’s name (POST_NO referencing POST_NO in the same table), so something has to give it a role. Most tools either refuse, or let you type whatever you want, which is how you end up with parent_id in one table and prnt_post_no in another.
Here the role prefix is itself a naming rule, resolved through the same word list as everything else:
`PARENT_POST_NO` varchar(20) COMMENT 'Parent Post Number'
Register Parent → PRNT in the word list and it becomes PRNT_POST_NO instead — team-wide, in every self-referencing relationship anyone ever draws. The prefix is a decision made once, by the standard’s owner, not per-table by whoever is typing.
What happens when a word is missing
Real modelling hits words nobody registered. Ours didn’t have “Delete”, which is why DELETE_YN came out unabbreviated. The lint said so:
lint_erd
// → { code: "unknown-word", severity: "warning", objectName: "Delete Flag" }
The agent’s move here is the interesting one. It does not invent DEL. It files a proposal:
propose_dictionary_word {
logicalWord: "Delete", physicalWord: "DELETE", abbreviation: "DEL",
note: "Found while modelling the discussion board"
}
// → { status: "pending" }
A human approves it, and the abbreviation propagates to every connected project. The agent is a proposer, not an authority. That distinction is the entire difference between an assistant and a liability — and it’s the thing a chatbot with no shared state cannot do, no matter how good the model gets.
Checking work that already exists
The same computation runs backwards. Give it a name someone already wrote and it tells you what the standard would have produced:
check_naming { logicalName: "Customer Phone Number",
physicalName: "CUSTOMER_PHONE_NUMBER" }
// → { generatedPhysicalName: "CUST_TEL_NO", compliant: false }
That runs in CI with no agent involved — npx sqemo-mcp lint schema.erd.json exits 1 on violations. Humans, agents, and pull requests all get held to the same computation.
The output
CREATE TABLE `POST` (
`POST_NO` varchar(20) NOT NULL COMMENT 'Post Number',
`POST_CNTS` varchar(1000) NOT NULL COMMENT 'Post Content',
`DELETE_YN` char(1) NOT NULL DEFAULT 'N' COMMENT 'Delete Flag',
`PARENT_POST_NO` varchar(20) COMMENT 'Parent Post Number',
PRIMARY KEY (`POST_NO`)
);
The business terms survive as column comments, so the meaning reaches the database instead of dying in a diagram nobody opens.
What it doesn’t do
Being straight about the edges:
- The self-reference prefix is one global rule, not a per-relationship choice. It defaults to
Parent, and abbreviating it means registeringParentin the word list like any other word. A project that already has a self-referencing relationship keeps the prefix those columns were built with, so their names don’t shift underneath it. - Naming rules aren’t retroactive. Change a rule and existing physical names keep what they have. Self-referencing FKs are the exception: their names are derived, so they get rewritten on their next edit.
- The agent still models badly if you describe the work badly. Nothing here checks whether your entities make sense — only that they’re named the way your team agreed.
The point
Look at who decided what:
| Decision | Made by |
|---|---|
| Which tables and relationships exist | Me, in business terms |
| Abbreviations, separators, case | The team standard |
| Data types | Domains |
| New words entering the standard | The standard’s owner, by approval |
The agent did the typing and none of the deciding. A naming convention in a wiki asks every person and every tool to remember it. This one is computable, which means it can be applied, checked, and enforced without anyone remembering anything.
The step-by-step version, with every call and its output, is in the walkthrough. If you want the argument before the tutorial, an ERD MCP server covers what these tools are and where they stop; database naming conventions covers what to put in the word list in the first place.
Try it in the app — no signup — or point your agent at npx sqemo-mcp.