AI Engineer Europe 2026
Teaching Coding Agents to do Spreadsheets
Read the talk
Teaching Coding Agents to Work with Spreadsheets
A persistent JavaScript REPL made spreadsheet operations easier to compose, but reliable calculation, rendering, and evaluation made the results worth trusting.
From a talk by Nuno Campos
Before you start: Familiarity with spreadsheet formulas, basic JavaScript, and agents that call tools will help you follow the implementation choices.
What’s the revenue?
What revenue does this spreadsheet report? Answering that question requires more than finding a cell containing a number. Nuno Campos’s team spent four months trying to make coding agents as capable with spreadsheets as with Python or JavaScript. The obstacle starts with how a workbook communicates meaning: a person opening Excel can immediately distinguish a revenue table, an assumptions area, and a chart from their positions and formatting. An agent must recover that structure before it can interpret the contents.
Even after locating revenue, the agent has to distinguish gross from net, identify the relevant quarter or year, and determine whether the cell contains an input or a formula. These are different kinds of uncertainty: what the user means, where the answer lives, and how the workbook derives it. Spreadsheet understanding depends on structure and computation as well as values.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Planning helped; rigid discovery did not
An early design divided the work among three agents. At its center, an edit agent followed a five-step process that included defining the desired end state, planning, executing, and verifying. This changed where failures happened. Without the process, mistakes appeared while the agent constructed a financial model. With it, mistakes could appear in the plan, where they were easier to correct.
The architecture nevertheless proved too rigid. Discovery happened once at the beginning, so the system could not return to exploration when editing exposed a new question. Context also failed to flow adequately between the agents. The useful part was thinking before acting; the failed part was fixing discovery and execution into stages that could not adapt to one another.
The team then explored spreadsheet representations. Familiarity alone did not make a format sufficient: SQL was well represented in model training and designed for structured data, while XML reflected how Excel files were stored. Neither worked adequately as the standalone interface. Two other approaches survived as capabilities inside the eventual system.
| Representation | Appeal | Outcome in this work |
|---|---|---|
| SQL | Familiar structured-data operations | Insufficient alone |
| XML | Excel’s on-disk representation | Ineffective as the interface |
| CSV/TSV | Compact views of selected cells | Frequently useful within a larger system |
| HTML | Layout and formatting | Led toward image rendering |
A CSV or TSV view of a selected region remained useful for inspecting data, even though it could not carry the entire interaction. HTML made layout and formatting more explicit, leading the team to build a rendering engine that could show the agent a spreadsheet range as an image. The successful design accumulated complementary ways to inspect a workbook instead of choosing one representation for every task.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Turn tool calls into composable JavaScript
The largest interface change was replacing approximately fifteen separate tools with one Node.js REPL tool. The operations did not disappear: they became JavaScript functions that the agent could combine inside a single call. Instead of asking the model to orchestrate each operation through a separate tool exchange, the system let it express that orchestration as code.
JavaScript offered a familiar scripting language that the team could sandbox. Campos thought Python would probably work equally well. The spreadsheet implementation itself remained in C#: the scripting language served the agent, while a different language handled the files. Node.js describes the historical architecture discussed here; the companion REPL account records a later migration to QuickJS-Emscripten.
Campos reports that exploring a spreadsheet and reaching an answer previously commonly required ten to fifteen tool calls. Sequential exchanges took time and often timed out. Parallel tool calling did not solve the whole problem because the agent still lacked a way to combine the results within those calls. With the REPL, it could compose several operations in code and return their results together from one tool call. The improvement was composition, not merely concurrency.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Keep state between execution steps
This composition pattern is often called Code Mode: generated code combines multiple tool operations in one call. Campos points to its growing use in the Anthropic API and at Cloudflare. A REPL adds another property: variables survive between calls. The agent can execute a small piece of code, inspect the result, reason about what it means, and continue using the state it already created.
For a small illustration, suppose the agent has already read these two rows from a workbook. The values below are teaching examples, not a reproduced workbook or a Witan API call. In its first REPL call, it keeps the rows available and inspects which revenue labels exist:
javascript
var revenueRows = [
{ metric: "Gross revenue", period: "Q1", value: 1200 },
{ metric: "Net revenue", period: "Q1", value: 1000 }
];
console.log(revenueRows.map(row => row.metric));
After resolving that the question concerns net revenue for Q1, a later call can use the same variable:
javascript
var selectedRevenue = revenueRows.find(
row => row.metric === "Net revenue" && row.period === "Q1"
);
console.log(selectedRevenue);
The second call does not reload or redeclare revenueRows. That is the persistent-state property: execution can pause for interpretation without discarding prior work.
Without REPL semantics, Campos observed agents commonly writing JavaScript scripts of around fifty lines. Those scripts combined substantial work, but committed to a longer sequence before the model saw intermediate results. With persistent state, scripts became shorter, allowing more reasoning between operations. In the team’s observations, that flexibility often produced a better answer faster.
The same interface also simplified adding capabilities. Under the separate-tool design, formula-dependency exploration could require several new tools, new schemas, and attention to how those tools interacted. Under the REPL design, it meant exposing additional JavaScript methods. A TypeScript type definition file placed in the prompt told the agent which methods were available and how to call them.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
The gains and their evaluation conditions
Campos reports internal financial-analysis benchmark accuracy of approximately 50% before the REPL, 74% after its introduction, and eventually 92% after further changes. Those later changes included better fuzzy search, formula-dependency tracing, system-prompt improvements, and bug fixes. The progression describes the team’s engineering results, not a controlled measurement of the REPL alone: the companion research log uses changing task sets and separately attributes an earlier large improvement to an extraction bug fix.
Under the usual five-minute whole-task limit, Campos reports essentially zero timeouts with the more efficient approach. That is a reported benchmark outcome, not a guarantee for arbitrary workbooks or executions. The operational benefit was that the agent could spend less of its time budget moving through separate tool exchanges.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Calculate and render before trusting the result
Coding agents work better when they can run a compiler, linter, or test suite and respond to the results. Human programmers benefit from the same loop. Spreadsheet agents need equivalent feedback: producing a plausible formula or formatting instruction is not enough to establish that the workbook behaves or looks right.
The team built two engines to supply that feedback:
- Formula calculation: Compute the workbook’s formulas so the agent can inspect their results.
- Range rendering: Produce an image of a selected range, preserving layout and formatting so the agent can inspect its appearance.
Together they support a write–calculate–render loop. The agent makes a change, observes its numerical and visual consequences, and returns to the formula or formatting when the result is wrong.
Verification is only as trustworthy as the engine supplying the feedback. An incomplete calculation engine can turn a correct Excel formula into an apparent failure. The agent writes a valid formula, asks the engine to calculate it, and receives an error because the engine does not implement that operation. It may then try to repair a formula that never needed repair. Campos’s example of an engine supporting only half of Excel’s formulas is hypothetical; the mechanism is the consequential part. Feedback that diverges from the target application can actively make the agent worse.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Separate the interface from the feedback infrastructure
The REPL and the verification engines solve different problems. The REPL is an interface chosen to fit the coding strengths of the models Campos’s team was using. If models become equally capable at mouse-and-keyboard computer use, a different interface could become preferable. That possibility does not remove the need to check the workbook’s behavior.
Calculation and rendering are therefore the more durable investment. Across several model releases during the project, Campos observed that stronger models could get more value from the verification loop. Better reasoning did not make feedback redundant; it made the agent better able to interpret and act on it.
Domain guidance also survived the interface changes. Its purpose was not to teach the model what revenue or ARR means. The model already knows many relevant and irrelevant things; the prompt directs attention toward the knowledge that matters for the current financial task. Campos reports that this guidance improved results across tool iterations, with almost the same prompt working for both individual tools and the REPL.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Compare spreadsheet behavior, not just judged answers
Reliable evaluation was necessary to decide whether an interface or representation actually helped. The team initially relied entirely on an LLM judge. That supplied a score, but introduced another source of variation: when the score changed, was the agent different, or had the evaluator simply produced a different judgment?
Where possible, the team replaced judgment with deterministic comparison against a golden spreadsheet:
- Select a reference workbook with known input and output locations.
- Put a set of values into its inputs and obtain the outputs.
- Put the same values into the corresponding inputs of the generated workbook.
- Compare the resulting outputs.
This treats each workbook as a black box. The generated spreadsheet need not have identical internal construction to demonstrate matching behavior for the tested inputs. The comparison can be more trustworthy than asking another model to grade the work, but it is not suitable for every task. The companion benchmark account retains LLM grading for QnA text; the headline accuracy progression should not be read as wholly deterministically graded.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
A reasoning failure may be a tool failure
Agent failures can originate outside the model. An incorrect example in a skill or prompt may be followed faithfully. A bug in a tool may cause repeated failures, after which the agent keeps retrying or searching for a workaround. From the final conversation, that behavior can look like poor reasoning even when the immediate cause is broken infrastructure.
Inspecting the trace makes that distinction actionable. Follow what the agent was told, what it called, and what the tool returned. The question is whether the model misinterpreted valid feedback or whether the system supplied an incorrect instruction or result. The latter is a defect the application team can fix without waiting for a more capable model.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Give agents composition and a way to check their work
A long sequence of separate tool calls can become an awkward substitute for a scripting language. Code Mode or a REPL gives the agent an explicit way to combine operations. But composition needs a feedback loop behind it: use existing domain tools when they can check the result, and invest in a calculation or rendering engine when the necessary checks do not exist.
Interface design deserves deliberate work because it changes what the agent can accomplish efficiently. It also deserves revisiting as model capabilities change. The REPL was a strong fit for this system’s models and workload, not a reason to freeze the interface permanently.
The failed three-agent architecture does not invalidate planning before acting. Nor does a powerful model remove the need to focus its domain knowledge or evaluate its outputs. Prefer deterministic checks where they fit, and use an LLM judge where that is the available option. Before attributing persistent confusion to the agent, inspect the traces and the plumbing: sometimes the most effective improvement is fixing the bug the model has been struggling around.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Resources
Further reading
- Teaching Machines to Read SpreadsheetsRepository
Witan's engineering retrospective covering spreadsheet representations, agent architectures, evaluation and the REPL.
- The REPL ToolArticle
Architecture and examples for persistent spreadsheet exploration, typed APIs and composable JavaScript operations.
How Witan evaluates spreadsheet content, layout, formatting, formula behavior and text answers.
An explanation of exposing tools as TypeScript APIs so agents can compose operations in executable code.
Updates since the talk
Current instructions for scripting workbook edits and checking calculation, rendering and lint results.
Read the transcript and explore slides
Loading transcript and slides…