
TL;DR
- Geochemistry tables carry conventions that general-purpose code treats as errors: “<0.005” for a result below the detection limit, commas as decimal separators, and rock names typed several ways. An AI agent that “cleans” these on its own can quietly change the data it is about to interpret.
- The Geocluster Research Harness handles them with deterministic cleaning tools that diagnose first, write every fix to a new file, and never modify the source.
- The agent must show the diagnosis to the user and get confirmation before applying any fix. Nothing is cleaned automatically.
Key Takeaways
- Detection-limit strings, comma decimals and inconsistent terms each break naive code differently. Treat “<0.005” as missing and a real low result vanishes from the statistics; treat it as zero and averages drift down; leave it as text and the column cannot be clustered at all.
- Diagnosis is a separate, read-only step from cleaning.
validate_geologyanddetect_cleaning_issuesreport the problems; the data-operations agent’s job ends there, and nothing is fixed until a person decides. - Every cleaning tool is deterministic and non-destructive. Each writes a new file and reports exactly what it did -
fix_decimalseven refuses to guess on three-digit values that could be a thousands separator, and hands the ambiguity back instead. - The Meridian Ridge test dataset exposes both kinds of trap at once. 52 “<0.005” values force the diagnose-confirm-clean sequence, and a report that rounds sample counts (about 70 basalt) against the CSV’s real count (62) is only caught because every number in an answer must cite its source file.
A geologist looking at an assay table reads “<0.005” in a gold column and knows what it means: the laboratory tested the sample and found less gold than its method can measure. A pandas script reads the same cell and sees a string in a numeric column. Depending on who wrote the script, that value becomes an error, a missing value, a zero, or the reason the whole column is treated as text.
Exploration data is full of these conventions. The Geocluster Research Harness, our open-source browser workbench for AI-assisted geological analysis, gives its agents dedicated data-cleaning tools for them. This post goes through the traps and how the tools handle each one.
The traps
Detection limit strings. Results below the detection limit are recorded as <0.005, results above an upper limit as >100, and some labs write ND, BDL or trace. A single such value makes a column non-numeric. Treat it as missing and a real low-grade result disappears from the statistics. Treat it as zero and averages drift down. Leave it as text and the column cannot be clustered at all.
Comma decimals. Data from many countries writes 1,25 for one and a quarter. The same comma also appears as a thousands separator, so 1,234 might be one thousand two hundred and thirty-four or one point two three four.
Inconsistent terms. Lithology columns collect Basalt, basalt and BASALT. Chemical codes such as SiO2 depend on capitalisation, so lowercasing everything breaks them.
Duplicates and impossible values. Repeated sample rows and negative concentrations in geochemical columns are common artefacts of merging and export.
Diagnose before touching anything
Two tools look at a file without changing it.
validate_geology classifies each column and reports the geology-specific problems it finds: which columns contain detection-limit strings, which use comma decimals, which geochemical columns hold negative values, how many duplicate rows there are, and the row count. detect_cleaning_issues goes column by column: missing values, non-numeric values, detection-limit strings, outliers by interquartile range, and the number of distinct values.
In the harness, a data-operations specialist agent runs these first whenever an analysis involves cleaning. Its job ends at the diagnosis.
Every fix is a separate, deterministic tool
Each trap has its own tool, and each writes a new file into a results/ folder beside the input. The source file is never modified.
| Tool | What it does |
|---|---|
parse_detection_limits | Converts <X, >X, ≤X, ≥X, <=X and >=X to numbers using a chosen method: half the limit (half, the default), zero, or the limit value itself. ND, BDL, trace, nil and - become missing values. Reports how many values were parsed per column and which method was used. |
fix_decimals | Converts comma decimals to points cell by cell, detecting the affected columns automatically. A value with exactly three digits after the comma is skipped and reported as ambiguous, because it could be a thousands separator. |
standardize_terms | By default only tidies whitespace and keeps capitalisation, so SiO2 survives. A custom mapping can merge spellings, and the result reports unique values before and after. |
remove_duplicates | Removes repeated rows by chosen key columns or exact match, keeping the first, last or none, and reports rows before and after. |
The rule for three-digit values in fix_decimals is the kind of decision a model should not make silently. The tool refuses to guess and hands the ambiguity back.
Using half the detection limit is a common default for putting censored values into statistics, and the tool makes that choice visible in its output, so the method used can be stated alongside any result built on it.
The user confirms before the data changes
The harness splits work between agents. The agent the user talks to cannot inspect or modify data itself. An orchestrator plans the analysis and hands steps to specialists. For cleaning, the orchestrator’s instructions set a fixed order:
- The data-operations specialist runs
validate_geology. - The orchestrator hands the diagnosis back to the user-facing agent, which presents it to the user.
- The user confirms which fixes to apply.
- Only then does a transform specialist run the matching tools:
fix_decimalsfor comma decimals,parse_detection_limitswith the half-limit method for detection-limit strings,remove_duplicatesfor repeats, andstandardize_termsfor inconsistent names.
The instruction is explicit: do not clean without a diagnosis, and do not apply every fix automatically. A detection-limit convention is a scientific choice about censored data. A person who knows the dataset should make it.
A sample dataset that tests exactly this
The harness ships a synthetic exploration project, Meridian Ridge, with 240 geochemistry samples across five lithologies. Its gold column holds 52 values recorded as <0.005. Loaded naively, Au_ppm is a text column, and the first request to cluster the geochemistry runs straight into it. That triggers the diagnose-confirm-fix sequence above.
The same project also tests a different failure. Its technical report lists the number of samples per rock unit as rough figures (around 70 basalt samples, around 50 andesite). The CSV holds the real counts: 62 basalt and 43 andesite. An agent that quotes the report when asked about the data gets it wrong. An agent that counts from the file and cites the file gets it right. The harness requires every number in an answer to carry a source citation pointing at a file and column, which makes the difference visible.
Why tools and not generated scripts
A model can write a pandas script for any of these fixes. Deterministic tools have three advantages for this kind of work. The same input gives the same output every time. Each tool returns a short summary and a file path instead of printing the data into the model’s context. And each call is logged with its arguments, so a reviewer can see exactly which method was applied to which columns, and rerun it.
Specialists can still fall back to a script when no tool fits, such as normalising within groups. The tools come first.
The cleaning tools are in mcp-server/tools/cleaning.py in the Geocluster Research Harness repository. For how the harness is put together, see Meet the Geocluster Research Harness, and for how numbers in the final answer are checked against the data, see our companion piece on making AI data analysis checkable.