DEV Community

Cover image for Why We Parse Industrial Code Instead of Embedding It
Dylan McCarthy
Dylan McCarthy

Posted on

Why We Parse Industrial Code Instead of Embedding It

Most of the industrial AI you have seen is a retrieval pipeline with a chat box on it. Chunk the manuals, embed them, stuff the top matches into a context window, let the model talk. It demos well. It falls apart the first time somebody asks a question where the answer depends on what a machine is doing right now.

We are an applied research lab called Nodeblue, and the system we build is called Nexus. This is a writeup of the architectural decision at the center of it, which is that the language model is the smallest and least interesting part.

The failure that set the design

Here is the test that made the decision for us.

Industrial control programs live in two places. There is the project archive, which is the file in source control, and there is the program actually running in the processor. Those drift, constantly, because engineers go online to fix a timer during a downtime event and do not always upload the change back. Anyone who has worked on a plant floor knows this. It is Tuesday.

We took a real production controller with exactly that situation, a live edit present in the processor and absent from the archive, and asked eleven frontier models which version of the routine was executing. We gave them the export, the docs, the context, everything a careful human would get.

All eleven answered confidently. All eleven were wrong. Not garbled, not obviously broken. They read the export correctly, described the rung correctly, and then told us the archived version was running, because the archived version was the only version they had ever seen.

Then we put the same eleven models on top of our engine and asked again. All eleven got it right, cited to the rung.

The models did not improve. They got access to a fact that lives in a processor rather than in a corpus. That is the entire lesson, and it generalizes past our domain: when a model is asked something it structurally cannot know, it does not abstain, it produces the most probable sentence. In a domain where the answer dispatches a human to a piece of equipment, that is the expensive kind of wrong.

What sits under the model

Four layers, roughly.

Deterministic parsing. We do not embed control logic and hope similarity search finds the right rung. We parse it. Ladder, structured text, AOIs, UDTs, tag databases, device configs, into a resolved model where a tag reference is a real edge to a real definition, not a nearest neighbor. The same question resolves to the same cited answer on every run. Not usually. Every run. A system that is right most of the time is not one you hand a maintenance tech at two in the morning with the line down.

So far that is 4,386 real production files parsed with zero parse errors, spanning Rockwell, Siemens, Ignition, and the CODESYS family. Real exports off live floors, including files too large to open in any chat interface at all.

Live access. OPC UA reads and subscriptions against the running controller, read only, inside the plant, under the site's own network rules. This is the layer that no amount of context window replaces, and it is also the layer that is genuinely hard for reasons that have nothing to do with AI: it is physical, on premise, safety gated work.

Correlation. A signal on an operator screen has a path. Screen binding to OPC path to controller tag to the rung where the value is born. The correlation engine walks that path in both directions, so when something misbehaves you get where the state started, not just where it surfaced. Trace a PackWeight from the display back through the multiply on rung 14 to the load cell, and forward to the timer on rung 31 that latched the fault.

Citation. Every claim carries the rung, tag, or document it came from. This is not a UX nicety, it is the thing that makes the output usable by a professional. An answer you cannot verify is a rumor with good grammar.

The model sits on top of all of that and does what models are good at, which is turning a resolved, grounded, cited result into a sentence a human can read. Swap it out and the system still works.

The efficiency side effect

We did not set out to optimize tokens, but resolving the graph properly means you send the model the six things that matter instead of the whole export and a prayer.

That works out to roughly seventeen times fewer tokens per answer and about nine and a half times faster than pointing a frontier model at the raw export and asking it to grep. Same cited answer on every run, which grepping does not give you.

Breadth without a rewrite per vendor

The obvious problem with parsing rather than embedding is that you now own a parser per vendor, and industrial automation has a lot of vendors.

We handle the big ones directly: Studio 5000 and RSLogix 5000, Siemens TIA Portal and STEP 7, Ignition, and the CODESYS family. Current IDEs and the legacy ones still running plants, because the plants running twenty year old code are exactly the plants with the worst comprehension problem.

For the long tail we lean on PLCopen XML, which gets one parser to more than 500 OEM brands. A vendor becomes a module, not a rewrite. That tradeoff is the only reason the parsing approach is tractable at all.

Checking ourselves

Benchmarks you write yourself are marketing. For the generated documentation we hired three independent controls engineers with no stake in the outcome and had them grade 137 documents rung by rung against the running logic. Zero errors found.

One reviewer noted that even through nested AOIs it never lost track of a variable, and that this was the part he had not expected it to get right. Nesting is where these tools usually break, so that is the correct thing to have been skeptical about.

Open where it counts

The early connectors the engine was built on are public under MIT at github.com/Nodeblue-AI. The ones shipping in Nexus today have gone well past them, but the originals are still how we show we are not a black box: you can read exactly how we handle SCADA access, PLC parsing, and cross system correlation.

If you work in this space and you think our parsing approach is wrong, the code is right there. We would rather be checkable than impressive.

What the lab is actually after

Nodeblue is an independent applied research lab. The research question is how machines come to understand and act inside physical environments, and it runs along four lines: operational intelligence, knowledge and memory, collaboration between humans and agents, and autonomy.

Nexus is the first system that came out of that. It holds a persistent on premise memory of an operation and keeps building it, so every export, fault, answer, and correction sharpens the next one, and it flags a source the moment it goes stale. The direction from here is one view across every controller and server in a facility, then every device on the wire with document versus logic verification across a whole site.

The broader bet, and the part I think transfers outside industrial work: agents acting in physical environments need a substrate that is deterministic, live, and citable. The reasoning was never the bottleneck. Grounding was.

If you build in this space, I would like to hear where you think this breaks. The connectors are on GitHub and we read every message.

Top comments (0)