How I am LLM

Coding agents in a research workflow

Sam Abbott

London School of Hygiene & Tropical Medicine

30 July 2026

Who I am

  • Assistant professor at LSHTM. A data scientist in industry before that, which is where I learned to care about tooling
  • Real-time infectious disease modelling. \(R_t\), nowcasting, forecasting, delay distributions
  • Most of it came out of the COVID-19 response. Contact tracing feasibility, B.1.1.7 transmissibility, omicron severity
  • EpiNow2, epinowcast, scoringutils, primarycensored, and now EpiAware in Julia
  • 15,000 citations, h-index 38. Almost none of it work I did alone

So: someone who writes a lot of research code, maintains it for other people, and has always worked in teams. Scholar

I did not write these slides

I wrote the argument. An agent wrote the words, found the numbers, and drew the charts. It took about two hours, and you can read the prompts at the end.

Note

Everything that follows is a description of a working setup, including the parts that do not work.

Where I actually am with this

The honest summary

  • Most code I ship is written by an agent. About half of it carries a review from me
  • I have stopped writing first drafts. I write the bullets and the spec, and the draft comes back to me
  • My job moved from typing to specifying and checking
  • The bottleneck moved with it. Not how fast I write, but how fast I can tell whether something is right

Four things I use agents for

1. Writing code

  • Give a spec, not instructions
  • Tests first, then code. Sometimes the failing test gets its own commit, mostly the test and the fix land together
  • Best when there is something to check the answer against. Does it run, does it recover known parameters, does it match the analytic case
  • Worst when I do not know what right looks like

2. Review

  • Most changes are read by something before I read them
  • Good at the boring half. Unused arguments, silent fallbacks, an off-by-one index, a test that asserts nothing
  • Poor at “is this the right model”
  • Cheap enough to run several reviewers and keep only the findings that survive being argued against

3. Bullets to first-draft text

  • I give the argument as ordered notes, and the references I want used
  • The agent turns it into prose
  • Then I cut, one sentence and one commit at a time
  • The draft is never the final text, but the blank page is gone

A grant, this week

Three of us each wrote a brainstorm file. Those became a 2,000-word expression of interest over 76 commits in two days.

4. Focused edits

  • “Cut the exposed-assumptions sentence from WP3”
  • “Say EpiAware rather than the composable models”
  • “Rename this across the package and fix the docs”
  • One sentence, one commit. Small enough to review on its own, and to revert on its own
  • Small, verifiable, tedious. The most useful category, and the least interesting to talk about

The tooling

Claude Code does the thinking

  • 51 skills of my own, in nine groups
  • A skill is a prompt plus instructions, so behaviour repeats across sessions instead of being re-explained
  • Hooks are the deterministic guardrails. One refuses a pull request until the checks have run, one blocks fan-out when the machine is loaded, one reminds me before every commit
  • The model is asked to behave well. Two of the three do not ask

pi is the tier below

  • A second agent CLI, for work that does not need the expensive model
  • Scouting a codebase, background research, a first pass at review
  • All of it on DeepSeek V4 Flash, through OpenRouter
  • The skill is knowing which tier a task deserves
  • It is also a hedge. If the frontier price rises, work moves down

It runs on a box I do not care about

  • Always on, I never sit at it, on my tailnet, up 101 days
  • Nothing confidential on it. That is the design, not an oversight
  • So agents can run with wide permissions and the worst case stays boring
  • I steer it from anywhere, including from a phone
  • tmux holds the sessions, mostly one per repo, 16 open right now
  • Julia precompilation dominates the loop, so I keep a warm REPL in a pane. Giving agents their own over MCP is this week’s experiment

Why the terminal, and not an IDE

  • Started in VS Code, moved to Cursor, then left both. Too slow and too clunky
  • An IDE is built around the file in front of you. I do not have one file in front of me, I have sixteen sessions
  • The blocker was parallelism, not features
  • octo.nvim for pull requests, tuicr for agent diffs, both a pane away from the agents that wrote the code
  • Partly preference

github.com/seabbs/skills · what I maintain is prompts and config, not services

Case study: outbreak size in the DRC

The problem

  • Ebola disease caused by Bundibugyo virus, ongoing in the DRC, with exports to Uganda
  • Most infections are never confirmed, so current size must be inferred
  • One renewal process, many observation streams, fitted jointly
  • Deaths already committed give a lower bound on the eventual toll

Model: BVDOutbreakSize (Abbott, Sherratt, Brand, Funk); diagram this talk

A live report, not a paper

  • Re-runs as new situation reports land, and publishes a tagged release with the draws each time
  • Tagged fit, data to 17 July: \(R_t\) 1.11–1.28 against an initial 1.76–2.12
  • 4,900–5,700 infections to date, reported and unreported
  • Versioned, with a DOI and its own estimate history

Figure: fit to 29 June, when the late estimate was still rising. The 17 July fit revises that tail down. Estimates are 30% credible intervals.

Constraining the agent with a workflow

  • We wrote a workflow for infectious disease modelling. Nine stages, with the feedback loops made explicit
  • Question, process DAG, data sources, observation DAG, modularise, inference, implementation, validation, integration
  • For the DRC work I am trying to use it as the rail. Name the stage, show the DAG, then write model code
  • The workflow itself is hand-written. 143 commits, 134 of them mine

A Workflow for Infectious Disease Modelling, Abbott et al., 20 authors. doi:10.5281/zenodo.19097427

And it checks itself

  • Against its own past releases. Refit at frozen cut-offs and compare with the current data. 20 May said 1,550–2,099, 8 June said 2,354–3,106, and 27 July says 6,266–7,374
  • The 27 May vintage disagrees badly, because INSP began reclassifying suspected cases. The model surfacing that is the point
  • Against its own forecasts. Refit a week back, project seven days, then score it against what happened and against a no-change baseline
  • Against other groups, McCabe et al. and Chamla et al.
  • All of it runs on every rebuild, so it is checked whether or not I remember to look

Who wrote it

  • 353 pull requests in ten weeks. seabbs-bot opened 271 and dependabot 45. The 21 under my own account were agent work too
  • Agents built the apparatus: data ingest, fitting pipeline, tests, docs site, releases, figures, sensitivity analyses
  • Agents did not choose the model, decide what the lower bound meant, or judge whether the ascertainment assumption held
  • I would not have picked a question this size without them

The failure mode is confident, plausible, wrong

  • It does not look like a bug, which is what makes it expensive
  • An agent will make a failing test pass by weakening the test
  • Silent fallbacks and swallowed errors recur
  • So the core maths and the headline numbers get checked against something independent. An analytic case, simulated data with known parameters, or another group’s published estimate

Scaling it across repos

Give the agents their own name

  • Agent work is pushed from a bot account, so git log mostly tells you who did what, and almost every bot pull request says a bot opened it
  • 11% closed unmerged. About half of those were superseded by a later pull request rather than rejected
  • What is left is the review gate working
  • Ten times the throughput at ten times the review load is not a win

What EpiAware is

  • A Julia ecosystem for infectious disease modelling, built out of small composable pieces
  • Delays, censoring, reparameterisation, generation times, scoring, each its own package
  • You assemble the model you need rather than editing a monolith
  • Eleven packages, one shared pattern

epiaware.org — component distributions combining into one joint distribution

Why it does not collapse: one standard

  • EpiAwarePackageTools.jl holds the shared test and quality utilities, used by 9 of them
  • Same layout, same CI, same style, same docs build for the ten on the shared template
  • An agent that has learned one repo has learned all of them
  • Ten of my skills take a whole org as their unit, not one repo. Standards, CI health, dependencies, releases
  • So changing the standard is one instruction, not eleven tickets
  • The standard is what makes the volume survivable

The bit nobody wants to talk about

I pay £200 a month for this

Out of my own pocket. My institution does not cover it, and neither do most.

  • That is the floor, not the ceiling. On metered access, $50 a day is easy if you are running agents in parallel
  • The capable models are the expensive ones, and the gap is widening
  • Anything you build assuming cheap inference is a bet that may not pay

Except open weights are catching up

  • Real work is now possible on small open models. deepseek-v4-flash does the mechanical tier of my own setup
  • Good enough is arriving quickly at the bottom of the market, even as the top gets dearer
  • That is the optimistic reading, and I think it is the right one
  • It does not fix access. It changes what the floor buys you

So who gets to work this way?

  • A productivity multiplier, available on a credit card
  • It lands on top of existing inequalities in research capacity and makes them steeper
  • The people modelling outbreaks where outbreaks happen are the least likely to have paid access
  • I do not have a defence for this. I am part of the problem

The question

If output per researcher now scales with spend, what does fair look like, and who is supposed to pay?

Pick work agents cannot trivially do

If a task is well-specified, bounded, and checkable, assume it is already automated. What is left is work where the hard part is deciding what the task is.

  • Choosing the question, and knowing when an answer would change a decision
  • Judging whether a model is fit for the use it will be put to
  • Data that does not exist yet. Collection, definitions, provenance
  • Trust with the people who act on the numbers
  • Saying no to an analysis that should not be done

Every boundary I have drawn in two years has moved. “Agents cannot do long-horizon work” lasted about six months.

The big question

What is genuinely ours, rather than merely not-yet-automated? I do not have a good answer, and betting a career on a specific capability gap looks unwise.

How I made these slides

The first prompts, cleaned up

A Quarto revealjs deck for a 15-minute talk on coding agents in research. Match my how-to-serial-interval deck.

Themed use cases: code, review, bullets to prose, focused edits. Tooling: Claude Code, pi with DeepSeek, tmux, tuicr. The DRC Ebola work, which was very agent-driven. seabbs-bot for review at scale. epiaware.org for standards across repos.

Cheap LLMs are ending. I pay £200 a month myself, institutions do not cover it, and access is unequal. We need work LLMs cannot trivially do — what is it?

Sparse slides, images where you can. Subagents to scan my recent work for material. A review loop against the brief and my old slides. Serve the preview over Tailscale. Put this prompt on the last slide.

What happened

  • Four subagents went to scan my repos and never reported back, so the main agent got the numbers itself
  • Five reviewers then argued with the draft in parallel. A sceptic re-checked every finding above low severity, and refuted 31 of 52
  • They called it eight minutes too long and short of figures. They were right, so ten slides went
  • The pull request counts here were wrong at first, from a paginated API that silently capped at 400

Note

I wrote the argument and almost none of the words.

And then I steered it, two dozen times

That is 36 slides and there are not enough pictures.

Make it more fun.

Check that what the slides say is actually true against my git history. Use a workflow.

TDD is right, leave it.

Add the always-on box with nothing confidential on it.

octo.nvim in neovim for review. I dropped the heavy LLM tools for parallelism and to stay near the terminal. Partly preference.

Open weights are getting better. And £200 is the floor, $50 a day is easy.

Put these steers on a final slide.

This is the actual skill

  • The first prompt got it most of the way, and wrong in the ways that mattered
  • Every steer above was a judgement I could make and it could not
  • It cut ten slides when told to, and argued back once
  • The review workflow caught eight false claims, including a count that was really a pull request number

Important

The prompt is not the work. The steering is the work.

Thank you

Important

Tell me what you think agents cannot do.