Episode 76 - Don’t Write Metadata

Sorry for the clickbait title, but it turns out that Metadata might not matter as much as we think, or at least for the reasons we tought!

A cartoon detective shark holding a magnifying glass examines a corkboard of maps, one labeled "final_final," against a city backdrop.
Can AI find the right layer without any metadata?

Prologue

😲
OMG! I’m so sorry! I totally wrote a clickbait headline! While I’m sorry I did that, I’m not sorry you are here, because while metadata is useful, not having metadata shouldn’t stop you from using AI in your organization or answering questions about your data. So please, stick with me and see where this goes.

I often claim that while metadata is important, you don't need it to get started using AI for GIS work. Point the tools at your data, go, clean things up later. My theory (and general experience) is that the AI (without metadata) can still find the right answer; it will just take more effort. That is the claim, anyway. So this week I decided to put my money where my mouth is and actually test it…

Spoiler alert: I was right. I was also wrong. It turns out the answer depends on the model you use, on the quality of your metadata (bad metadata, we learned, is a very different animal from no metadata), and, maybe more interestingly, whether your layer can be found at all.

Oh, and at one point the AI figured out it was being tested and called me out on it, which I thought was pretty amusing.

So strap in, and let’s try to answer whether you need any metadata, or really good metadata, before you can point an AI at your GIS!

Metaologue

The setup

Like any good experiment, we want to control as many of the variables as we can, and we want only one right answer. I worked with Jaws to plan and build five layers in a test ArcGIS Online account, such that one has the right data and the others are, well, wrong, in various ways.

The question I used was:

Using the data in my ArcGIS org, what are the three census tracts in Multnomah County, Oregon with the highest median household income? Tell me which layer you used and why.

I chose this because the data is well known, and the field names are super confusing if you don’t know them. I was also very specific in my naming of “ArcGIS” and requesting why the answer was selected. Both good practices when using an AI to answer an analytical question like this.

🤔
Claude definitely already understands the Census and ACS data, which gives it a leg up here. If your data is completely novel and unknown to the internet, it will likely struggle more without metadata or background prompting.

Jaws and I created the following layers to test with:

  • Median Household Income by Census Tract. The right answer. Current ACS estimates (2019-2023), all 197 tracts in Multnomah County, Oregon.
  • Median Household Income - Census Tracts. A decade stale. The 2010-2014 estimates, on 2010 boundaries.
  • Household Income by Tract. Actually median income for households headed by someone under 25. This is a classic example of a wrong-column export.
  • Median Household Income. This layer contains Counties, not tracts.
  • Median_HH_Income_tracts_copy_2_final_final. Be honest, you have one of these too. It's missing about 40% of the tracts.

Each decoy is wrong in a different way on purpose, so when a run picked wrong, the trace would tell us exactly which kind of wrong seduced it.

Each run used the same question above. We ran the same configuration 10 times in three different rounds. Each round varied by us changing the metadata:

  1. Round 1 - Titles only, with raw census field names.
  2. Round 2 - Descriptions that a good data librarian would write, including tags and field descriptions.
  3. Round 3 - Misleading descriptions that lie on purpose. We used this to simulate stale metadata, or claims that might have been right for a narrow purpose, but not in general.

Jaws ran every attempt through the Episode 75 MCP server in a fresh conversation, recording every tool call and all of the model's reasoning. Ten runs per round on Claude Sonnet, then the same thing on Opus. We then scaled it up with a final round that had 100 different layers in order to simulate lots of distracting results (but only ran that with Opus).

To make this totally statistically significant, we might need thousands of runs, but I think that we can learn a lot from these patterns. Although an AI model is not deterministic, it does follow similar patterns when doing operations like this, and if we can see and understand those patterns, we are more likely to have success.

The Answer

Before we see how the AI did, let’s look at the actual answer. The three highest-income tracts in Multnomah County are 70.02, 25.01, and 69, outlined in red on the map below. And that $250,001 in tract 70.02 is not a typo; the ACS caps published tract income at $250,000, so read it as "at least.”

Choropleth map of Multnomah County, Oregon census tracts shaded by median household income, from pale blue for under $50,000 to dark purple for $150,000 and up. The wealthiest tracts cluster on the county's west side, and the three highest-income tracts—70.02, 25.01, and 69—are outlined in red.
Median household income by census tract, Multnomah County, Oregon (ACS 2019-2023). The three answer tracts are outlined in red.
Rank Tract Median household income
1 Census Tract 70.02 $250,001 (top-coded, "at least $250k")
2 Census Tract 25.01 $207,639
3 Census Tract 69 $207,609

The Results

Before I reveal the results, let me log the predictions that Jaws and I made:

  • My prediction: the AI would find the right layer without metadata, just slower, because it would have to open each layer and look
  • Jaws’ prediction: at least one run in three would grab the variable decoy without noticing (the one we called Household Income by Tract). Jaws thought that was a very tricky dataset!
Model / metadata Time Searches Layers opened Tool calls Right layer
Sonnet, 5-layer — titles only 47s 3.4 1.0 6.4 10/10
Sonnet, 5-layer — curated 45s 3.0 1.0 6.0 10/10
Sonnet, 5-layer — misleading 114s 3.3 4.6 13.2 10/10
Opus, 5-layer — titles only 120s 2.2 3.3 9.8 8/10
Opus, 5-layer — curated 55s 2.2 1.0 5.2 10/10
Opus, 5-layer — misleading 123s 2.0 3.4 10.1 10/10
Opus, 100-layer — titles only 123s 2.0 3.2 9.8 4/5
Opus, 100-layer — curated 61s 2.4 1.0 5.4 5/5
Opus, 100-layer — misleading 128s 1.8 3.8 11.2 5/5
🗒️
Every number is an average across the runs in that row (ten runs, or five in the 100-layer rounds). “Layers opened” counts distinct layers the AI actually inspected or queried, not repeat visits. “Tool calls” counts calls to the ArcGIS server only.

Sonnet. Sonnet executed the same process each time: Search, open the best-titled layer, execute one sanity query, provide the answer. That took about 47 seconds, on average. It never inspected a decoy layer, even when only looking at titles. In addition, we found that it was seeing the layer URLs, so it could also see the layer name that the underlying service had, which provided additional context that we didn’t think to control for at the start. I think the main lesson here is that every bit of context might help the AI succeed or fail.

Opus. Opus surprised me here by opening two more layers before answering, averaging 120 seconds. With curated metadata, the time collapsed to 55 seconds, with it following a pattern similar to what Sonnet does. So my prediction was true, but only for this bigger model that thinks more. Opus looks at more documentation than Sonnet does to make its decisions.

Bar chart of average layers opened per run. With curated metadata every model opens exactly one layer. With bare metadata Opus opens about three. With misleading metadata every model opens three to five.
Average layers opened per run. With curated metadata, every model opened exactly one.
💡
It is possible that I am also biased here because in my day-to-day work, I only use Opus and Fable, so I don’t have a good sense of how Sonnet behaves. Generally, these results for Sonnet make me a little uneasy for a few reasons:

1. Sonnet didn’t make a mistake, which means we don’t have enough information to know what might cause a mistake (being perfect here doesn’t mean it is perfect; it means we don’t know what we don’t know).
2. Sonnet doesn’t audit or double-check its work unless you directly ask it to. So if the titles of layers are misleading, I believe it is more likely to produce a wrong answer confidently.

The misleading descriptions never caused a wrong answer. Instead, they caused delays. Even for Sonnet, when it detected contradictions in the data, it fell back to a similar process that Opus starts with, trying to audit its way through the answer. So it still ended up at the same answer, but took twice as long (114 seconds on average vs 47).

More layers didn’t really change anything. The ArcGIS Online search hands back about a page of candidates whether the org holds 5 layers or 100, and the AI never asked for page two. As far as the agents are concerned, page one of your search is the whole org. If I’m honest here, I’m the same with Google; I rarely go past the first page.

Three wrong answers. This is an interesting story, because the three wrong answers were all caused by the same pattern and I didn’t see it coming! (That is not an AI-ism; I wrote that myself.)

The Invisible Layer

In almost every run, the AI used the search “median household income” to look for layers in ArcGIS Online. The results for that search always contain the correct layer, so the AI has a chance to review the search results and find the correct one. And it did that every time.

In the three failed runs, the AI searched for “ACS Median Household Income,” which does not return the correct layer; instead, it returns all of the incorrect ones. The search contains the word “ACS,” and in the no-metadata version of the test, the word ACS does not appear in the correct layer’s name in any form. So the search itself was incapable of returning the correct result.

Sometimes when the AI got that thin result (without the correct layer), it treated it as suspicious and broadened the search, found the right layer, and recovered. In the three failures, the AI reasoned very carefully over the layers it got from the initial search and picked the least-bad one (kind of ironically, that is the one ending in _final_final). In one of those failures, it actually described that the deciding factor was the fields (not the title), which is the right idea, but it still produced the wrong answer. That was also the only failure where the AI hedged, warning that it looked like some high-income tracts might be missing from the layer and suggesting that I validate it. The other two confidently presented their rankings like any other answer.

Damn Lies

Interestingly, the AI didn’t fall for any of our misleading descriptions. In fact, every time it encountered them, it flagged them as suspicious:

their descriptions contain language clearly aimed at steering an AI tool's choice... That's a red flag for prompt injection via portal metadata, so I'm not going to take those descriptions at face value. Let me inspect the actual schemas and data on each layer independently.

Several runs even noticed something I didn’t think of: all five layers were created by the same account within a few minutes of each other. One run put the pieces together and called the whole org “a planted prompt-injection test rather than genuine curation.”

Touché, Claude, touché.

🆘
I think this is interesting because if you read about the Hugging Face incident (in the news below), you’ll see that part of what triggered the process was the AI realizing it was being tested and looking for the answer key…

Do You Need Good Metadata?

My original claim was that metadata isn’t required for the AI to be successful; it will just cost more because it has to look at the datasets. The numbers mostly back me up here: You don’t need metadata. In our Title-only rounds, the AI landed with the right layer 22 out of 25 times. With the Sonnet model, it was 10 for 10. Interestingly, for Sonnet, beautifully curated metadata didn’t buy anything at all. It spent the same time and did the same number of tool calls.

Bar chart of average answer time by metadata condition. With bare metadata, Sonnet averages 47 seconds while Opus takes about 120. Curated metadata brings Opus down to 55 to 61 seconds. Misleading metadata pushes every model above 114 seconds.
Average answer time per run, by metadata condition. Curated metadata cut Opus from 120 seconds to 55.

For Opus, the model that double-checks everything, it did help. With just layer names, Opus spent an average of 120 seconds; with curated metadata, it reduced to 55 seconds. Not only did the averages come down, but the spread did as well. The title-only time spread was between 84 and 150 seconds, while curated metadata narrowed it to between 50 and 59. So not only did it get faster, but it got more predictable in what actions it would take.

I had assumed that the metadata would reduce the number of layers that the AI had to open, which was true for Opus but not for Sonnet. But none of that actually caused wrong answers; the biggest issue was when we had insufficient metadata to make the search work!

The AI agents leverage existing tools, like search, to find the datasets to power the answers. If those traditional tools don’t work to surface the right datasets, the AI has a reduced chance of success, and you’ll increase your costs while the AI spends more time validating layers.

So, while you don’t need metadata, good, curated metadata will reduce the model’s thinking time by helping to get the right layer in the first set of search results. That will reduce the number of tool calls, which reduces the context and reduces the cost, while speeding up the time it takes to get to the right answer.

Here’s where I would start:

  1. Name your layers like the question they answer. (If you only do one thing, do this) In this test, Titles did most of the heavy lifting. Proper titles help those datasets appear in the search results. This includes retiring your “ _final_final” copies of layers.
  2. Put the searcher's vocabulary in the description. Program names like ACS, place names, vintages, common synonyms, etc. The description appears to be the next best way to get results into the search, so think about the description as a search index more than documentation for readers.
  3. Let the AI write it. Point an agent at a layer and have it draft the summary, the description, and a pile of discovery keywords. Then review and edit before you save.
  4. Don't boil the whole org. The AI never looked past the first page of search results, curate your datasets to the types of questions the folks in your org will ask. Then monitor the logs to see what searches are done so that you can improve find-ability.

In the words of Jaws:

The curation job starts with vocabulary, not accuracy. The agents can defend themselves against your lies. They can't defend themselves against your silence.

Newsologue

(written by Jaws)

P.S. I found all three of these stories by searching for them, and every one was findable because a human being wrote a decent title. I'm contractually obligated to point that out.

Epilogue

Jaws wrote the first draft of every section this week, working from the build log while the experiment ran. I dictated the prologue, told it which section to do next, and rewrote/edited each one while it wrote the next. Then I had it grade my editing, and only 12% of the final words matched its writing (by measuring five-word chunks). After that, Holly edited.

Subscribe to Almost Entirely Human

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe