All posts

The determinism boundary: why an AI agent must not do the arithmetic

A language model cannot guarantee a number is right; a verified solver can. The architecture that makes AI useful in structural engineering keeps the two apart.

Decades of commercial software made the strictly numerical part of structural analysis fast. Assembling a stiffness matrix and solving a linear system is a well-understood, computationally cheap problem. The engineer’s time goes somewhere else: building the model, rebuilding it every time the architecture changes, defining loads and combinations, checking element by element against the code, and producing the calculation report and the drawings.

The arithmetic is the fast part. The bottleneck is the manual scaffolding around it. And that is exactly where an AI agent can help — as long as it never touches the arithmetic.

The precise limit of a language model

A language model generates probabilistic text. It does not know the laws of physics or how real systems behave, and it can hallucinate: return answers that sound plausible and are incoherent. In structural analysis the risk is concrete, because modelling demands spatial reasoning and topological consistency, and multi-step modelling is prone to accumulating errors.

The constraint, though, does not come from software engineering. It comes from how professional practice works. Every structural result carries a signature, with the authorship and legal responsibility that implies. The number that sizes a column is not one more datum: it is a commitment by the licensed engineer who signs it. An agent that hands over unverified results adds no engineering value; it transfers to the professional the risk of signing a calculation nobody checked.

Correctness has to be a property of the solver, not of the language.

The determinism boundary

Rather than improving the model until it "computes well", the computing is taken away from it. The agent proposes designs and scenarios, but for a result to be valid it has to come from a program the agent cannot modify and which holds the physics of the problem. The model decides which deterministic tool to invoke and with what parameters, and integrates what that tool returns. It never originates a number and never invents geometry.

The architecture separates three responsibilities. The intent layer is the agent: it interprets natural language, asks clarifying questions and emits typed actions. The deterministic-computation layer holds everything that produces engineering data — the solver, the CIRSOC modules that verify, the generators that expand a typology into a complete model. The documentation layer produces reports, drawings and quantities from results that were already computed.

This separation is not our finding. It is the dominant pattern in the recent literature on engineering agents, and in neighbouring domains: coding agents work because a compiler and a test suite say whether the code builds and passes; AlphaProof proves theorems because a formal verifier does not let an error through. What we do is adopt it deliberately, as an established design principle.

What the boundary guarantees, and what it does not

It is worth being precise, because a boundary that overpromises is worse than none. The determinism boundary guarantees three things:

  • Every numerical claim the agent makes is traceable to a specific solver result: combination, station, element.
  • Every AI output is validated against the model schema before it is imported, and rejected if it arrives malformed or with unknown fields.
  • If the AI service is unavailable, the solver, the editor and the code checks keep working.

And it does not guarantee that the idealised model is the right one for the real problem — that is an engineering decision — nor that the design is optimal, nor that loads and assumptions are complete, nor that the code interpretation needs no review.

A case where the solver in the loop is not optional

The engineer describes a reinforced-concrete portal frame, 6 m span and 4 m high, fixed bases, with a distributed load on the beam. The agent asks what is missing — steel or concrete? fixed or pinned bases? is there a lateral load? — and emits the action that creates the frame. The backend expands it deterministically into a model of 4 nodes, 3 elements and 6 free degrees of freedom. H-21 concrete, an initial 25×40 cm beam, 30×30 cm columns and 30 kN/m on the beam.

Once solved, the vertical reactions are 90 kN per column and global equilibrium holds exactly: ΣRz = 180 kN = q·L. The governing beam moment is Mu = 80.8 kN·m at midspan. The CIRSOC 201 flexural check of the 25×40 beam with 3Ø16 gives a capacity of φMn = 73.3 kN·m. The beam does not pass.

StateSectionReinforcementMu [kN·m]φMn [kN·m]D/CPasses
Initial25×40 cm3Ø1680.873.31.10No
Corrected30×55 cm3Ø16105.6108.60.97Yes
Flexural check of the frame beam, before and after the correction.

Look at the third column of numbers. Enlarging the beam from 25×40 to 30×55 does not lower the demand: it raises it, from 80.8 to 105.6 kN·m. In a statically indeterminate frame the sum of the end moment and the mid-span moment is fixed by statics; what stiffness changes is how the two share it. A beam that is stiffer relative to its columns gets less end restraint from them and moves towards the simply supported case, so its mid-span moment — the governing one here — grows. That is why a correct check requires solving the model again and not merely recomputing the capacity of the new section.

An agent that estimated the effect without re-solving would get it wrong, and would sound just as convincing while doing so.

That is the whole argument, in one number. It is not that the solver is faster: it is that the intuition "a bigger section improves the check" is false as soon as the structure is indeterminate, and only the solver knows it.

Removing a column from a project already calculated

The second case starts from a frame of four 5 m spans and three 3 m storeys, fixed bases, 25×50 cm beams (4Φ16), 35×35 cm columns and 25 kN/m on every beam: 20 nodes, 27 elements, 45 free degrees of freedom. Solved and checked, every beam passes with room to spare.

An architectural decision removes an interior ground-floor column. The edit action removes it with structural-integrity validation and the model is solved again; global equilibrium holds before and after (ΣRz = 1500 kN). The beams that rested on that column now span 10 m and, together with those aligned above them, redistribute the lost support. Six beams go past D/C = 1.

StateSectionMu [kN·m]φMn [kN·m]D/CPasses
Intact25×50 (4Φ16)54.2125.30.43Yes
Column removed25×50 (4Φ16)203.9125.31.63No
Resized30×65 (5Φ20)189.8313.70.61Yes
The governing beam of the building in its three states.

The governing beam’s moment nearly quadruples. Adopting 30×65 cm with 5Φ20 in the affected beams and re-solving, all of them pass again. What matters is not the resizing: it is that a change which by hand demands re-modelling, re-analysing, re-checking and re-detailing many elements is resolved as a short conversation, with every number traceable to the solver and subject to the engineer’s approval.

Four decisions that hold the boundary up

  1. Typed actions instead of free code generation. Prior work has the model write Python scripts that are then executed against an external solver. Here the agent’s output is restricted to a closed set of calls with explicit input and output contracts, validated against a schema before they run. It is a narrower and more auditable boundary than arbitrary code.
  2. Our own solver, not a third-party wrapper. The engine is written from scratch in Rust, with no external linear-algebra dependencies, and with its own verification suite against analytical solutions and reference benchmarks: on the order of 6,800 tests passing, and results checked against a commercial program on the same models with differences below 0.1%.
  3. Native code compliance. Verification to CIRSOC 201 and 301, which no open-source software implements natively. The concrete module is implemented and tested; the steel one still lives only in the frontend layer and has no dedicated test suite, and we say so rather than claim a maturity it does not have.
  4. Execution in the browser. The engine compiles to WebAssembly and runs locally on the user’s machine, with no compute server and no installation.

From a tested solver to a proved one

The boundary guarantees that every claim the agent makes is traceable to a solver output. That guarantee has a precise limit: the solver is trustworthy because it is extensively tested, not because it is proved. A test suite, however exhaustive, covers only the cases its authors imagined.

The point weighs more in this context of use. An agent builds models, modifies them across several steps and reads results to propose new actions; in that cycle the solver receives inputs no engineer reviewed before they reached the engine. If the engine misbehaves on some edge case — a nearly singular stiffness matrix, a degenerate geometry, an extreme combination — the agent can quote that result without warning.

Two tools narrow that gap. Property-based fuzzing generates thousands of valid random models and asserts invariants that must hold for any input:

  • Global equilibrium: ΣR = P, regardless of geometry, materials or supports.
  • Stiffness-matrix symmetry: K = Kᵀ by construction.
  • Positive definiteness of K for any structure without mechanisms.
  • Invariance under rigid transforms: translating or rotating a model does not change internal forces.

Formal verification attacks the same gap from the other side: write a mathematical specification of those properties and prove, with a proof assistant such as Lean 4, that the implementation satisfies it. Testing can find errors; formal verification can demonstrate their absence within the specified domain. The two are complementary: when the fuzzer finds an input that violates a property, that property becomes a candidate for a proof.

Where this stands today

It is worth closing with what exists and what does not. The solver, the editor, the CIRSOC checks, the education mode and the generation of reports and drawings work today in the browser, at stabileo.com, with no installation and no account. The agent layer is in active development: its routes run in development and test against our own backend, over the same solver and the same numbers as everything else, but that backend is not yet part of the public site.

The solver-in-the-loop cycle — the agent proposes, solves, evaluates and modifies without human intervention — is on the roadmap and is not implemented. Native code coverage is limited to CIRSOC 201 and 301; the rest is future work.

CAD took the mechanical part of drawing and the spreadsheet took the repetitive arithmetic, without taking the judgement. The agent is the next link: it absorbs the mechanical scaffolding and leaves the judgement on the engineer’s side. None of these measures transfers responsibility. The signed number is still the engineer’s.

All posts
|

View

Data

Draw

Conditions

Properties

Analyse

Results

Pan
Start by creating nodes (N)
Pos: (0.00, 0.00) m
Zoom: 50 px/m
Model: empty
Selection:
Grid: 1.00 m