A world of pure imagination: AI, diabetes and the data we can’t get at

Search the app stores for diabetes and AI and you will find a remarkable number of applications doing exactly one thing. You point a camera at a plate, and something on the other end of an API tells you how many grams of carbohydrate are sitting in front of you. Some add a 3D scan. Some add a coaching layer and a subscription. Almost all of them are a thin wrapper around the same handful of vision models, and almost all of them have been built by people who discovered, quite correctly, that this takes an afternoon.

I’ve spent a fair chunk of this year working out how well that actually goes, and I won’t rehearse all of it again. The short version is that the same photograph submitted 500 times doesn’t come back with the same answer, and that a good deal of the error is in identifying the food rather than sizing the portion. In that work, eight of thirteen photographs were misidentified by at least one model with near total confidence. A crema catalana became a crème brûlée for everybody. A bakewell tart became a linzer torte. One photograph of a paella, asked of a single model 510 times with an identical prompt, returned answers ranging from 78g to 213g, and the middle ninety percent of those answers spanned about eleven units of insulin. The harness and the results are all in llm-food-benchmark-academic if you’d like to poke at them.

But that’s not really the point I want to make. The point I want to make is that carb counting from a photograph is very nearly the only thing anyone has built.

The obvious thing, done a hundred times

It’s not hard to see why. Carb counting is the visible, daily bit of living with type 1. It’s the thing you can demo in fifteen seconds to a room full of people who don’t have diabetes, and they’ll nod. It’s also the one problem where the shape of the tool matches the shape of the model exactly: picture goes in, number comes out. There’s no data pipeline to build, and no obvious moment at which anybody has to ask what happens when it’s wrong.

So we’ve ended up with a great many nearly identical apps, competing on onboarding flows, while the far more interesting capability sits largely unused.

Because what these models are genuinely good at isn’t looking at a plate of food. It’s writing the code that answers a question you’d otherwise never have got round to asking.

What really changed?

The thing that’s shifted in the last couple of years isn’t that the machine got clever. It’s that the cost of asking a question of your own data fell through the floor.

I’ve had ten years of looping data sitting in a database. For most of that time, the barrier between “I wonder whether…” and an actual answer was two or three evenings of writing plumbing, followed by giving up somewhere around the point where I had to remember how “pandas” handles timezones. That barrier has more or less gone. Not the thinking, which I’ll come back to at some length, but the plumbing.

And when the plumbing gets cheap, what becomes the binding constraint is imagination, and the data you can reach.

Given a little imagination and some data, you can do a lot…

Most of what follows is public, all be it not widely distributed.

Let’s start with Smoothing-Investigations, which holds the code and four write-ups. This compares three CGM smoothing algorithms used in open source AID against 5.9 million real glucose readings from 154 people. This allowed an evaluation of an alternative smoothing model that has been offered up to both Trio and Android APS and appears to handle outliers far more effectively than the existing options. That’s not a finding you get from the machine being cleverer. It’s a finding you get from being able to build a production-realistic backtest without it costing a month.

Insulin-Kinetics asks whether you can estimate a person’s insulin action peak from ordinary closed loop data, without a clamp study or a test protocol. It turns out that you can, at least for the peak, because peak time is a shape parameter and insulin sensitivity is an amplitude parameter, and those separate. Duration of action is a different matter, and mostly isn’t recoverable, because it lives in the tail of the curve where the signal is hidden by noise.

TimSim, which isn’t public yet, came from a different frustration. The UVA/Padova simulator is the standard tool for stress-testing dosing algorithms, and it describes a body very well. But when comparing its output against real CGM data, I found that the differences that survive are mostly not about the body at all. People eat without telling the algorithm, which puts a fat tail of sharp rises into a real trace that a simulator working from announced meals can’t produce. They also eat carbohydrate when they go low, so a real hypo recovers in about an hour rather than nearly two, and then overshoots. On top of which the sensor is noisier than the model says it is, and produces compression lows the model has no mechanism for at all. Of eleven statistics distinguishing a real trace from a simulated one, the bare virtual subjects matched none. Adding those behavioural layers brought seven inside the real range. The ones that still don’t come right are reported rather than tuned away.

And oref-digital-twin is an early scaffold that tries to be honest about what a “digital twin” can be with the tools available. There’s no reliable glucodynamic model of a specific person, so it doesn’t predict glucose. What it can twin is the controller, because oref’s determine-basal is open and deterministic, so you can replay the real controller under altered settings and price how a change flips a decision, while saying plainly that the resulting glucose is unknowable.

Given how much noise there is about digital twins at the moment, that distinction seems worth labouring.

Finally, we have dynamic-isf-calculations. Dynamic ISF makes correction sensitivity a function of total daily dose and current glucose level. There are two equations in circulation: the original, in which sensitivity is inversely proportional to TDD, and a later revision in which it’s inversely proportional to TDD squared. Which of them is closer to how people actually behave is not a matter of opinion, it’s a matter of arithmetic against real data. So we reconstructed both, per person, for 171 people using open source AID, from their own insulin and glucose history, and tested them against sensitivity calculated directly from the data. The answer is that neither is right. Sensitivity in that cohort follows roughly TDD to the power of minus 0.4 to minus 0.56, which is shallower than the first equation and nowhere near the second. The best simple fit under leave-one-user-out cross validation is sensitivity proportional to one over the square root of TDD. That took three days of work instead of being a non-starter.

The same work has a second axis, and it turned out to be the more interesting one. Dynamic ISF also lowers sensitivity as glucose rises, on the assumption that insulin works less well when you are high. Measured across roughly 62,700 carb-screened overnight windows, that didn’t appear to be the answer. Effective sensitivity appeared to be at its lowest near target and flat or slightly higher when glucose is high, which is the opposite shape to the one the equations encode. The explanation seems to be that high glucose is mostly carbohydrate rather than physiology. For people who announce their carbs the carb model already accounts for it, so the fasting curve tends towards flat, although the models perhaps don’t account for carb absorption as well as we’d like. For people who do not, unannounced food leaks into the data and reads as resistance, which is why one such user’s curve fell steeply by day and flattened overnight when they genuinely were not eating. What accuracy dynamic ISF does buy comes from personalising each person’s overall level, not from the glucose curve on top.

Alongside that, in the same repository, I decided to do a re-test of Walsh’s constants. The 1700 rule for insulin sensitivity, the 500 rule for carb ratio and the convention that half the daily insulin goes in as basal come from clinical observation of injection users in the 1980s, and they are still what gets taught when somebody starts on a pump. Nobody had checked them against people running closed loops. On 138 anonymised open source AID users, most from the OpenAPS Data Commons, the bootstrap interval excludes the textbook value in all three cases: 2381 rather than 1700, 402 rather than 500, and basal at 45% of the daily total rather than 50%. The shape is the more interesting failure. The rules assume sensitivity falls in inverse proportion to total daily dose, a slope of minus one in log space, where the cohort sits at minus 0.43. At the median dose, that leaves the 1700 rule starting a new pump user around 28% more aggressive than the people already living with these systems have settled on. Walsh isn’t wrong enough to abandon, but it is wrong enough to teach as an opening estimate rather than a target. This kind of re-analysiswith all the data available should be a shoe-in.

On vibe coding, and what it doesn’t do

Insulin-Kinetics went from nothing to a validated method with a full write-up in about twenty commits across two days. The dynamic ISF work was fifty-six commits in three. Those numbers look like productivity, and to an extent they are. But they’re also the reason to be careful, and I want to be specific about why, because “AI helps you code faster” is both true and almost entirely beside the point.

Here is what actually happened in that Insulin-Kinetics repository. The first physiological estimator was built, ran clean, and produced a confident and nicely bounded number for every participant. It looked like a result. Then it was given a positive control it hadn’t previously had: replace the observed glucose with glucose simulated from a known peak, using the real dose series and that person’s own noise level, and check that the estimator gives the known answer back. It didn’t, reliably. The insulin term turned out to be collinear with the overnight drift it has to be separated from, with correlations up to 0.99 on short windows, and turning that one control on or off moved the answer by up to 45 minutes for some people. The commit is called “Gate 2 fails its own positive control: not validated, results withdrawn”, and the results were withdrawn. The method that replaced it makes no assumption about the curve’s shape at all.

Nothing in that sequence came from the machine. The machine wrote the estimator, and it wrote the self-test too, and it did both well. What it would never have done unprompted is insist on the self-test, or understand the context of the response and challenge the answer when the self-test came back wrong. Models are relentlessly agreeable. Ask one whether your result holds up and it will find reasons that it does.

A smaller example from a few days later, which I like even more. A validation step reported that reconstructed insulin doses matched the true treatment stream on 1928 out of 1928 deliveries. A perfect match. That is a lovely number and it was completely wrong:  microsecond-resolution timestamps we’re being incorrectly returned, and dividing by a billion had quietly compressed thirty days of data into forty-three minutes, so everything overlapped everything. The real recovery rate was 62% of individual deliveries and 88% of total units. The only thing standing between that bug and a published claim was a person looking at a perfect score and thinking, no, that’s not how this data behaves.

That’s the human constraint, and it’s not a small residual. It’s knowing which question is worth asking in the first place, and knowing what a plausible answer looks like in this domain so that an implausible one stands out. It’s knowing that an unidentifiable fit will still hand you a confident-looking number, and building the control that catches it. Above all it’s being willing to throw away two days of work when that control fails. None of that is generated. All of it is judgement, and it comes from having lived with this condition and this data for a long time.

The speed is real. But if you don’t have the knowledge to go with it you have Garbage In, Garbage Out. But very confidently.

Which brings us to the data

Every piece of work above depends entirely on having data, and this is where the whole thing starts to bind.

Some of it exists because of a genuinely generous piece of community infrastructure. The OpenAPS Data Commons, hosted on Open Humans and administered by Dana Lewis, is a pool of donated data from people running open source closed loops, made available to researchers who agree to share back what they learn. The smoothing comparison used the n=240 release and drew on 5.9 million readings from 154 people. That work simply couldn’t have happened otherwise, and it’s worth saying plainly that it exists because a community decided it should, not because anyone was obliged to build it.

But look at what that pool is. It’s people running DIY systems who were technical enough to set up an uploader and then motivated enough to donate what it collected. That’s a real population and a valuable one, and yet, it is not the population of people with t1D. Everything I’ve described is an observation about people who look and act like me.

The data that would fill in the rest sits with the manufacturers, and getting at it in any useful form ranges from awkward to impossible. You can generally get a report. A PDF, or a dashboard showing fourteen days of summary statistics laid out for a clinic appointment. What you very often can’t get is the underlying record: every reading and every delivery, timestamped, in a format a machine can read, covering the whole period you’ve been using the thing. Where an API exists it tends to sit behind a partnership agreement, which is a polite way of saying that access is granted to organisations rather than to people. Where an export exists it’s frequently a subset, and not necessarily the same subset as it was last time.

And this isn’t only a commercial problem. In the insulin kinetics work, extending the analysis to a wider archive turned out to hinge on whether the uploading software happened to send one particular field alongside the others. One system sends it, another doesn’t. Nobody decided that; it’s just how it turned out. The reach of a piece of research was set by an implementation detail in an uploader rather than by anything to do with the mathematics. If that’s the situation in open source, where you can go and read the code, it’s not hard to imagine how it looks everywhere else.

So the constraint on interesting work is no longer really the ability to build. It’s whether anyone can get at their own data in a form that supports a question.

The charter

This is why the diabetes data rights charter matters more than it might appear to at first glance. Downey and colleagues set out the case in The Lancet Diabetes & Endocrinology at the end of last year, and the associated work is being co-produced with the diabetes community rather than written at it.

The argument runs roughly as follows. The instinctive framing, that we own our data, doesn’t hold up legally; the general consensus is that we don’t own our health data in any meaningful sense. GDPR does give a right of access and a right to portability, but those rights were not designed for this and don’t do the job. Portability doesn’t require anyone to maintain compatible systems, and doesn’t guarantee complete or real-time access. Enforcement is impractical when it’s unclear which jurisdiction covers the processing. Meanwhile manufacturers hold what the authors describe as de facto control through technical design and contractual means, which is the accurate description of what it feels like when the export button gives you a PDF.

What the charter proposes instead is a set of principles: that people receive their data safely and securely, in real time and in a format they can use; that the export is complete and genuinely usable rather than nominally portable; that consent is granular and opt-in, and that declining to share doesn’t cost you the use of your device; that data holders are transparent about where data goes and what models get built on it, and about when it’s eventually destroyed; and that the communities generating the data see some of the benefit from it.

None of that is radical. Most of it is what people assumed was the case until they tried to get their data out.

I’d add one thing from the position I’ve been writing about here. Open data doesn’t only serve formal research. It serves the person at their kitchen table who has a decent question and, for the first time, the means to answer it. Some of what comes out of that will be wrong. Some of it will be embarrassing to the assumptions currently baked into the algorithms we all use. The dynamic ISF work is a fairly gentle example of the second sort, and it exists only because a group of people made their data available.

The tools to do that kind of work have become close to free. The data has not. That asymmetry is now the whole game, and it’s a policy question rather than a technical one.

And so

We spent the last two years teaching a camera to look at a sandwich, and it still thinks it’s looking at something else and has no idea how thick bread is. Meanwhile the more interesting capability, the one that turns a question into an answer overnight, is sitting there mostly untouched, waiting on access to the very data that we generate ourselves, every five minutes, for the whole of our lives.

If you want to view paradise, as the song has it, simply look around and view it. The trouble is that most of us can’t. Somebody else is holding the camera.

There is, as Wonka also observed, no life he knows to compare with pure imagination. He was right, but he left out the boring half of it. Imagination is the cheap bit now. Ask for the data.


Discover more from Diabettech - Diabetes and Technology

Subscribe to get the latest posts sent to your email.

1 Comment

Leave a Reply

Your email address will not be published.


*