AI-Assisted Activity-Data Extraction
A carbon accountant opens a shared folder named "Q3 energy" and finds 340 files: scanned PDF utility bills, a fuel card export in a spreadsheet with merged cells, three supplier invoices in a language she does not read, and a photographed delivery note where the litres are half cut off by the flash. Somewhere in that mess is the activity data for the GHG inventory, the kilowatt-hours and litres and tonne-kilometres that, multiplied by an emission factor, become a number an external assurer will read line by line. The temptation is to let an AI "just pull the numbers." The discipline is to make it pull the numbers and bring the source location with every single one.
Extraction Is Reading, Not Estimating
The single most important sentence in this lesson is the one that separates a defensible inventory from a misstatement waiting to happen: extraction is reading, not estimating. When you ask an AI to extract activity data, you are asking it to do one job and one job only: find a value that already exists on a document and transcribe it faithfully, with the place it came from attached. You are not asking it to guess what the meter probably read, to fill a missing month with an average, or to infer litres from a euro amount. The moment the model crosses from "I read this off line 14 of the invoice" to "this is roughly what a facility this size would consume," you have left extraction and entered estimation, and the two have completely different evidence requirements.
Activity data is the physical quantity of an emissions-causing activity: the kilowatt-hours of electricity purchased, the litres of diesel burned, the tonne-kilometres of freight moved, the cubic metres of gas combusted, the tonnes of a purchased material. It is the raw input that, paired with an emission factor (a published coefficient that converts the activity into a quantity of greenhouse gas), produces an emissions figure. Why you care: under the GHG Protocol, the credibility of your whole inventory rests on activity data that traces to a real, verifiable source. An assurer running even a limited-assurance engagement will sample your data points and ask a brutally simple question, "where did this number come from?" If your answer is "the AI extracted it from somewhere in the folder," you do not have evidence, you have a guess wearing a number's clothing.
This is why we treat document extraction as a transcription task with a provenance requirement, not as an intelligence task. A scanner that misreads a 3 as an 8 is a known, bounded risk you can check. A model that helpfully "corrects" an odd-looking value because it pattern-matched to what bills usually say is a silent corruption you may never catch. Your job is to design the work so the model stays in the lane of reading, and so that every value it hands you carries a return address.
It helps to picture the worst version of the failure, because it is so much quieter than people expect. Imagine a model that, asked for a facility's gas consumption, finds the field genuinely illegible on a poor scan and, rather than admit defeat, produces 11,400 cubic metres because that is a typical value for a building of that size in that month. The number is plausible. It is in range. It will multiply cleanly against a factor. It will reconcile against last year if last year happened to be similar. Nothing about it looks wrong, and there is no flag, no asterisk, no hesitation in the model's tone. The only thing wrong with it is that it is not what the document says, and the document is the only thing that counts. That is the entire category of risk you are guarding against, and it is precisely the category that does not announce itself.
The Source Must Travel With the Number
Here is the rule that should govern every extraction you ever run, the one to write on a sticky note and put on your monitor: the source must travel with the number. A kilowatt-hour value with no file name, no page, and no line reference is not activity data. It is a rumour. It might be correct, but you cannot prove it is correct, and in disclosure the inability to prove a number is functionally the same as the number being wrong, because the assurer cannot accept what they cannot trace.
Concretely, "the source" means at minimum three things attached to every extracted value: the file it came from (the exact document, ideally with a stable identifier, not just "the September bill"), the page within that file, and the location on the page, which might be a line item, a table cell reference, a labelled field, or for a scanned image the region. When all three travel with the value, anyone, including an assurer who has never met you, can open the document, go to the page, find the line, and confirm the number with their own eyes. That act, reopening the source and seeing the same figure, is the entire game. It is what turns a transcribed number into traceable evidence.
A number you cannot point back to a file, a page, and a line is not activity data. It is a rumour you have agreed to publish.
There is a second reason provenance has to be captured at the moment of extraction rather than reconstructed later: documents move, get renamed, get superseded. If you pull 12 monthly kilowatt-hour figures today and only record the values, then six weeks from now when the assurer asks for support on the March figure, you are reverse-engineering which of 340 files it came from. Capture the file-page-line at extraction time and that question takes ten seconds instead of an afternoon, and your answer is certain instead of "I think it was this one."
What Good Provenance Looks Like
Good provenance is specific enough to be reopened and precise enough to be trusted. "utility_bill_facility_Lyon_2026-09.pdf, page 1, line item 'Consommation: 48,210 kWh'" is good. "the Lyon electricity bill" is not, because there may be three of them and you cannot tell the estimate-correction from the meter reading. The standard you are aiming for is that a colleague who has never seen the work can use your provenance string to land on the exact figure without asking you a single clarifying question. If they would have to ask, the provenance is incomplete.
There is a useful mental test for whether your provenance is good enough: imagine the assurer has your provenance string but not you, because you are on leave when the engagement happens. Can they confirm the number? If the answer depends on something only you know, "oh, that's the corrected bill, the first one was wrong," then the knowledge lives in your head rather than in the file, and a file that depends on a particular person is not an assurable file. Provenance is the mechanism for getting the knowledge out of your head and into the record, where it belongs and where it survives you moving teams, going on holiday, or leaving the company. Treat every provenance string as a message to a stranger who will need to trust your number without trusting you.
The Mess You Actually Receive
Real activity data does not arrive in clean tables. It arrives as the wreckage of a hundred different business processes, and each format hides a different trap. Understanding the traps is how you decide where AI extraction genuinely helps and where it quietly hurts.
Scanned and photographed documents are read by optical character recognition before any model sees them, which means the first failure can happen below the AI entirely: a 1 read as a 7, a decimal comma dropped, a "kWh" smudged into "kW." A vision-capable model can be remarkably good here, but it can also confidently invent a clean number where the underlying scan is genuinely illegible. The trap: fluency. The model's output looks just as confident for a guessed digit as for a clear one.
Utility bills mix the number you want with numbers you do not: the current reading, the previous reading, the estimated reading, the consumption, the standing charge, the amount in currency, the prior-year comparison the utility helpfully prints. Ask for "the electricity figure" and you have not specified which one. The trap: the model picks a plausible field, often the largest or boldest number, which may be the euro total, not the kilowatt-hours.
Fuel logs and fuel-card exports arrive as spreadsheets with merged cells, mixed units (some rows in litres, some in gallons, a header that says one thing and data that says another), and totals interleaved with line items so a naive extraction double-counts. The trap: unit confusion and summing a "total" row on top of the lines it already totals.
Supplier invoices and delivery notes may be in another language, may express quantity in a unit you have to convert, and may bundle the activity quantity inside a description field rather than a tidy column. The trap: the activity quantity is buried in prose ("delivery of 3 pallets, 1,200 kg net") and the model either misses it or reformats it without flagging the conversion it just performed.
How to Run the Extraction So It Stays Honest
The way you frame the task determines whether the AI reads or invents. A few disciplines turn a risky "pull the numbers" prompt into a controlled, assurable extraction.
Force the model to one document at a time, or to clearly separated documents. Bulk "extract everything from this folder" is where cross-contamination happens: a value from one bill gets stapled to the file name of another. Keep the unit of work a single document so provenance cannot get scrambled.
Demand the quote, not just the value. Ask the model to return, for every figure, the exact text it read it from, the file, the page, and the line or field label. "48210" is a value. "Read from line 'Consommation 01/09-30/09: 48 210 kWh' on page 1 of invoice_Lyon_Sept.pdf" is a value with a verifiable source. The quote is your check: you can confirm the model is reading and not reasoning by seeing the original characters it claims to have read.
Name the exact field you want and forbid substitution. Tell it you want metered consumption in kilowatt-hours, not the billed amount, not an estimated reading, and that if the document shows an estimated rather than actual reading it must say so rather than hand you the estimate as if it were measured. Estimated meter readings are a real and common case, and an estimate silently passed off as actual activity data is exactly the kind of finding that surfaces in an assurance engagement.
Make missing data return as missing, never as a helpful guess. The most dangerous instruction you can give an extraction model is one that implies it must always produce a number. If a value is not on the document, the correct output is "not present," and the correct next step is a human decision about estimation, documented as an estimate. A blank you can see is safe. A fabricated fill you cannot see is the failure mode that ends careers.
Preserve units exactly and flag every conversion. If the model converts gallons to litres or kg to tonnes, that conversion is a calculation, not a reading, and it must be visible and checkable. Better still, extract the original unit and value verbatim and do the conversion in a separate, transparent step you control.
A Worked Example: The Fuel Log That Almost Lied
Watch a single fuel-card export move from a careless extraction to an assurable one. The file is fuelcard_fleet_Q3.xlsx: 214 rows of refuelling transactions, a few merged header cells, two depots, and a "Quarterly total" row near the bottom. The analyst needs total diesel litres for the Scope 1 mobile-combustion calculation.
Before, the careless version. The prompt is "extract the total diesel used this quarter from this file." The model returns a single clean figure: "Total diesel used in Q3: 9,940 litres." It looks authoritative. It goes into the inventory. Three problems are hiding inside that one tidy number. First, there is no source location, just an answer, so no one can reopen the file and confirm it. Second, the model read the "Quarterly total" row, which a previous user had typed manually and which is actually stale, it does not match the sum of the line items below it. Third, eleven of the 214 rows are in gallons because one depot uses a different card provider, and the model either ignored them or silently converted them with no flag. The published figure is wrong, and nothing in the output reveals it.
After, the assurable version. The prompt changes the job entirely: "From fuelcard_fleet_Q3.xlsx, list every refuelling transaction as a separate record. For each, return the row number, the date, the depot, the original quantity, and the original unit exactly as written. Do not total anything. Do not convert units. If any row is missing a quantity, mark it 'missing' and keep it in the list. Ignore any pre-calculated total rows but tell me they exist." Now the model returns 214 line records plus a note: "Row 209 labelled 'Quarterly total: 9,940 L' appears to be a pre-calculated total and is excluded from the line list per instruction." The analyst sees the eleven gallon rows clearly flagged by their unit, converts them in a documented step, sums the 213 genuine line items herself (one row was missing a quantity and is now visibly flagged for follow-up), and lands on 9,610 litres plus one open item, not 9,940. Every litre traces to a row number. The stale manual total is caught. The unit mix is visible. The missing value is a known gap, not a silent zero.
The second version took a few more minutes and a more demanding prompt. It also produced a figure the analyst can hand an assurer with a straight face, alongside a provenance trail that reconstructs the total from raw rows. That is the entire difference between AI as a speed tool and AI as a liability.
Where Traced Extraction Fits in the Inventory
Activity-data extraction is the first hands-on step of the goldmine workflow, the externally-assured GHG inventory, and getting it right early pays off at every stage downstream. The traced values you produce here feed directly into emission-factor selection (the subject of the next lessons), and a value with clean provenance is one you can confidently pair with a factor and defend. A value without provenance poisons everything it touches: even a perfect factor applied to an untraceable quantity yields an untraceable emission figure.
This step is also where the primary-versus-secondary-data distinction begins. A kilowatt-hour figure read directly off a metered utility bill is primary data, the supplier or the meter measured it. A figure you had to estimate because the document was missing is secondary data, and it must be labelled as such from the moment it enters your records. Extraction keeps these honest because it draws a bright line: what the document actually says is primary and traceable; what you had to fill in is secondary and must be disclosed as estimated. Conflating the two is one of the most common ways an inventory loses its assurance.
Finally, remember that the extraction is not the end of the chain of custody, it is the start. The provenance you capture here has to survive into your reporting platform and your assurance file. That is why the output format matters as much as the values, a theme the lesson on structured output develops in full. For now, hold the principle: you are not just getting numbers out of documents, you are building the first link in a chain that has to reconstruct, end to end, from a published emissions figure all the way back to a line on a scanned bill.
Key Takeaways
- Extraction is reading, not estimating. The model's only job is to transcribe a value that already exists on the document. The moment it infers, averages, or "corrects," it has crossed into estimation, which has entirely different evidence requirements and must be labelled.
- The source must travel with the number. Every extracted value needs its file, page, and line or field location attached at the moment of extraction, so anyone can reopen the document and confirm the figure with their own eyes.
- A number with no traceable source is a rumour, not activity data. In disclosure, an unprovable figure is treated the same as a wrong one, because the assurer cannot accept what they cannot trace.
- Demand the quote, not just the value. Asking the model to return the exact text it read from lets you confirm it is reading and not reasoning, and it doubles as your provenance.
- Make missing data return as missing. Never instruct a model in a way that forces it to always produce a number. A visible blank is safe; a silent fabricated fill is the failure mode that fails assurance.
- Preserve original units and flag every conversion. A unit conversion is a calculation, not a reading, and must be visible and checkable. Extract verbatim, convert in a separate documented step.
- Watch the format traps. Utility bills hide the kilowatt-hours among currency and estimated readings; fuel logs mix units and bury totals among line items; scanned documents fail at OCR before the model even sees them.
- Traced extraction is the first link in the chain of custody. It seeds the primary-versus-secondary distinction and feeds emission-factor selection, and its provenance has to survive all the way into the assurance file.
Skill.re