All guides
TablesAdvanced·Intermediate6 min

Prompts That Return Usable Tables

Name every column and its unit, state what an empty cell means, bound the row count, and say what the rows are being compared on. A table whose columns are chosen by the model is a layout; a table whose columns you specified is data.

Tables fail more quietly than JSON: nothing throws, the output looks organised, and the problem only surfaces when two rows turn out to be measuring different things. This guide covers the four instructions that make a generated table trustworthy, and the point at which the answer is CSV rather than a table at all.

By Andrei Bădulescu, Founder at VantagePrompt·Updated

A table makes a structural promise — every row answers the same set of questions, in the same units, in the same order. A model asked for "a comparison table" will produce something table-shaped without necessarily keeping that promise, and a table-shaped thing that breaks it is worse than prose, because it looks like it has been checked.

What belongs in a column specification?

The name, the unit, and the type of answer allowed. "Price" invites a mixture of "$20", "20 USD/month", "from €18" and "contact sales" in one column, all of which are true and none of which sort. "Price (USD per month, number only)" produces a column you can compare down.

Weak columnWhat arrivesStronger column
PriceMixed currencies, periods, and prose.Price (USD/month, number only, "—" if not published)
SpeedAdjectives in some rows, numbers in others.Median latency (ms, integer)
Supports SSO?"Yes, via SAML on enterprise plans only".SSO (yes / no / paid add-on)
NotesHalf the content of the table, unsorted.Drop it, or bound it: "Notes (max 10 words)"
Each stronger column removes one degree of freedom the model would otherwise use.

How do I stop rows from disagreeing about their columns?

State that every row must fill every column, and give the placeholder to use when a value is genuinely unavailable. Ragged output — a row with a cell merged, dropped, or replaced with a sentence spanning the rest of the line — comes from the model resolving "I have nothing for this" on its own.

Every row must contain exactly these five columns, in this order.
Use "—" for any value you cannot verify. Never merge or omit a cell.
Never add a total row.
Three sentences that account for most malformed tables.

What is an empty cell allowed to mean?

Exactly one thing, chosen by you. "Not applicable", "not published", "the feature does not exist" and "I could not verify this" are four different facts, and a blank cell flattens them into one. If the difference matters to the decision the table is supporting, it needs to be visible in the table.

The cheap version is two placeholders — "—" for unavailable and "n/a" for not applicable — declared in the prompt. The expensive version is discovering months later that a blank meant "unverified" in half the rows.

Why bound the number of rows?

Because tables truncate worse than anything else. A cut-off list loses items you can see are missing; a cut-off markdown table loses its final rows and often its final row is half-written, so the rendered result is a broken grid rather than a short one.

Say "at most 12 rows" and, if the underlying set is larger, say how to choose which 12 — "the 12 with the highest download count" is a rule, "the most relevant" is a preference the model will interpret freshly each run.

When should I ask for CSV instead?

When something other than a person reads it. A markdown table is a rendering format: pipes inside cell values need escaping, alignment rows carry no data, and parsing it is a small amount of work that has no upside. CSV is the format for anything headed into a spreadsheet or a script.

ConsumerAsk forBecause
A person reading in chat or a docMarkdown tableIt renders directly; alignment is free.
A spreadsheetCSV, comma-delimited, with a header rowIt imports without a conversion step.
A script or pipelineJSON array of objectsTyped values and no delimiter escaping problems.
A long comparison you will filter laterJSON, then render the table yourselfThe shape survives filtering; a rendered table does not.
Pick the shape from who reads it, not from what looks most organised.

If you ask for CSV, say "comma-delimited, quote any field containing a comma, header row first, no code fence". CSV that quotes nothing is fine right up to the first vendor with a comma in its name.

Why does a comparison need its axis stated?

"Compare these three tools" leaves the model to choose what is worth comparing, and it will pick the dimensions that are easiest to write about rather than the ones that decide your choice. The columns are the comparison — choosing them is the analytical work, and delegating it is delegating the conclusion.

This is also the difference VantagePrompt is reading when it resolves a shape. Words like "table" or "matrix" pin the table shape and the optimized prompt then carries a markdown table skeleton with your column headers and an example row — so the columns you name in your raw input become the contract, and the ones you leave unnamed become the model's guess.

Frequently asked questions

How do I get a comparison table with the columns I actually need?
Name them, with units and allowed answer types — "Price (USD/month, number only)", "SSO (yes / no / paid add-on)". Columns left unnamed are chosen by the model, and it will pick the dimensions that are easiest to write about rather than the ones that decide your choice.
Why do some rows have missing or merged cells?
Because the prompt did not say what to do when a value is unavailable, so the model improvises. Add "every row must contain exactly these columns, in this order; use — for any value you cannot verify; never merge or omit a cell".
Should I ask for a markdown table or CSV?
Markdown when a person reads it, CSV when a spreadsheet does, JSON when a script does. A markdown table is a rendering format — parsing one means escaping pipes inside cells and skipping the alignment row, for no benefit.
Why do long tables come back broken?
Truncation. A table cut off at the token limit usually ends mid-row, so it renders as a broken grid rather than a short one. Bound the row count in the prompt and state the rule for choosing which rows make the cut.
Can a blank cell just mean "no data"?
Only if you say so. "Not applicable", "not published" and "could not verify" are three different facts, and one blank flattens them. Declare a placeholder per meaning if the distinction affects the decision the table supports.

Sources

structured prompts to try

Browse all structured prompts

Published by the community and free to copy — worked examples of what this guide describes.

Put it into practice.

Run this technique in the optimizer.

Open the optimizer

Keep reading