Trust
Honest answers
The language model never writes a database query. It writes a structured plan, and more than thirty checks test that plan against the real data before anything runs. Whatever cannot be verified ends in a clarifying question or an honest “I can’t”, with the reason.
Four kinds of “I can’t”
A refusal names its real reason, because the fix is different for each:
| Kind | Meaning | Example |
|---|---|---|
| No data | The fact is not in any dataset. | “I don’t have a charging-point dataset.” |
| No coverage | The dataset exists but has nothing where you asked. | “This register only records Aalsmeer.” |
| No anchor | A named place or address could not be found. | “I couldn’t find that address, so I can’t anchor the question there.” |
| Wrong level of detail | The fact exists, but not at the level asked for. | “Tenure is recorded per neighbourhood, not per building.” |
Every refusal also shows which dataset was chosen, which others were considered, and what GeoAI can do instead, such as “I can show all collection locations in Amstelveen”. The factual core of a refusal is written by code; the model only translates it and sets the tone, and may not add, drop or soften any claim.
The checks, grouped
Names
Invented dataset or column names are replaced or refused. A condition on a dataset that isn’t available stops the plan instead of being dropped silently.
Values
Every filter value must occur in the data. A term matching several values becomes a question; one matching none is refused. A condition that would list every value a column can take filters nothing, so it is refused as not recorded rather than applied. A place is matched in the form the column holds it, name or code.
Numbers
A threshold must appear in the question or be computed from it. A missing value is asked for, never guessed. A number that names the column itself, such as the 65 in “residents aged 65 and over”, picks the column; it is never used as a threshold on it.
Places
Only places you named are used, bound at the right level: a municipality question is never answered with a town column that leaves out Kudelstaart.
Logic
“Or” is never turned into “and”. A needed second register cannot be left out. Counting district outlines is never passed off as counting objects.
Counting
Joins can’t inflate counts: each object counts once, shared objects in combined registers count once, and rows without an identifier are kept distinct.
Zero results
A zero is checked before it is reported. A zero caused by a value found nowhere in the data becomes “that value is not in the data”, not “there are none”.
Disclosure
Every restriction, combination and repair the system made reaches you in the scope note.
System errors are labelled as such
If GeoAI itself fails, for example when a model returns something unreadable, you are told it is a system error and not a problem with your question.
Why refusals are valued. A wrong number looks exactly like a right one, and it travels: into a memo, a council question, a budget. A refusal with a reason costs the reader a minute. GeoAI is built and tested on the principle that the second is always the better failure.
Further reading on the GeoAI blog: The most useful answer is sometimes “I can’t”, on how this rule came about and the lesson behind it.