Raw PLC tags to a Unified Namespace, with LLMs in the loop
UNSHelper
A visual, node-based pipeline builder that puts language models to work on the hardest manual step in any Industry 4.0 program: deciding what every tag in every PLC actually represents. It ingests real Rockwell/Allen-Bradley exports, classifies equipment, generates descriptions, and proposes the namespace hierarchy.
- Status
- Working prototype · 834 commits
- Context
- 2026 · Independent work
- Role
- Sole designer & engineer
- Code
- Private — available on request
A Unified Namespace is the organizing idea behind most modern industrial data architectures — one coherent, hierarchical, self-describing view of everything a plant knows about itself. Getting there requires deciding what every tag in every controller means.
The raw material is a legacy L5K export with thousands of tags whose names are abbreviations invented by whoever commissioned the skid, sometimes decades ago. Classifying them by hand is the work that quietly stalls UNS programs: it is enormous, it is tedious, and it demands exactly the domain knowledge that is scarcest on the team.
It is also, for a language model, close to an ideal task. Pattern recognition over short, dense, domain-specific strings — where a knowledgeable engineer can verify an answer in seconds but would need hours to produce one.
- 01
A canvas, not a script
Roughly fourteen composable node types — DataSource, Model, Swarm and JSwarm for per-item calls, Transform, Clean, Route, Partition, GroupByPattern, PredicateRouter, Downsample, ForEach, Merge, Reduce, Output — wired together on a drag-and-drop canvas and serialized to portable pipeline files. The reason it is visual rather than a script: the person who knows what a tag means is a process or controls engineer, and the tool has to meet them where they are.
- 02
Reading the controller, not a spreadsheet
An L5K parser ingests real Rockwell/Allen-Bradley exports directly, expanding UDT and AOI tag members so nested structures resolve into the individual points they actually represent. Starting from the controller export rather than a hand-cleaned inventory is the difference between a demo and something usable on a real site.
- 03
Structured output enforced per provider
Zod schemas define what the model must return, and each provider enforces them differently: Azure OpenAI in strict JSON-schema mode, OpenRouter in json_object mode, local LM Studio and Ollama through prompt instruction plus markdown-fence stripping. One environment variable switches the whole pipeline between cloud and fully local inference — which is what makes it viable inside an OT security boundary.
- 04
Deterministic work between the model calls
Transform, Clean, Route, and Partition nodes do the reshaping between inference steps, and a character-budget batching system keeps prompts inside context limits. Every step that can be deterministic is deterministic — the model is asked only to do the part that genuinely needs judgment.
- 05
The content-filter problem
Azure's safety filter trips on legitimate industrial hazard and alarm terminology — the vocabulary of a plant's most important tags reads, out of context, like something to be blocked. The fix is a targeted one-shot retry with an injected safety preamble rather than a blind retry loop, so genuine filter events stay visible instead of being papered over.
Design principle
“The model does the tedious pass; the engineer does the judging. Any design that inverts that ordering fails on contact with a real plant.”
It attacks the specific bottleneck that stalls real Unified Namespace programs — the manual classification pass — rather than the parts that are already tractable.
The local-inference path means the tool can run entirely inside an OT security boundary, which is a precondition for touching production controller data at all.
The content-filter finding is the kind of problem you only discover by pointing a real model at real industrial data. It does not appear in any tutorial.
The engineer stays in the verification seat throughout. The model does the tedious first pass; a human decides what is true.
- Frontend
- React 18ViteReact FlowZustandTailwind
- Backend
- TypeScriptExpress 5Node.jsZod
- AI providers
- Azure OpenAIOpenRouterLM StudioOllamagpt-tokenizer
- Industrial
- Rockwell L5K parserUDT / AOI expansion
- Infrastructure
- TerraformAzureVitest
Want the architecture in more depth, or a walk through the code? I'm glad to go there.
Get in touch