# Building Perspective with an LLM

**URL:** <https://forum.inductiveautomation.com/t/building-perspective-with-an-llm/112407>\
**Category:** Ignition\
**Tags:** perspective, vision\
**Created:** [November 25, 2025, 2:10am UTC](https://forum.inductiveautomation.com/t/building-perspective-with-an-llm/112407 "2025-11-25T02:10:20Z")\
**Posts on this page:** 5\
**Page:** 2

<div class="post-metadata">

**Author:** ![nminchin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nminchin/32/6911_2.png) [@nminchin](https://forum.inductiveautomation.com/u/nminchin)\
**Post date:** [June 4, 2026, 3:36pm UTC](https://forum.inductiveautomation.com/t/building-perspective-with-an-llm/112407/21 "2026-06-04T15:36:36Z")

</div>

> [@jpreese246](#):
>
> AI is absolutely ducks guts on working with the JSON files. It makes very stupid mistakes and you often have to “start over”

I would suggest you don't get Claude to process your json files, but create tools in scripts (eg python) that will do what you want, and enable deterministic repetition at the same time

---

<div class="post-metadata">

**Author:** ![Nol](https://avatars.discourse-cdn.com/v4/letter/n/8e8cbc/32.png) [@Nol](https://forum.inductiveautomation.com/u/Nol)\
**Post date:** [June 4, 2026, 5:08pm UTC](https://forum.inductiveautomation.com/t/building-perspective-with-an-llm/112407/22 "2026-06-04T17:08:22Z")

</div>

IMO Gemini is surprisingly good at working with Json files but you also have to approach it appropriately. I use a lengthy detailed GEMs instruction (~10 pages). Then also feed it in an example structure and it's quite good at making edits. I've also used it to create a few thousand line tag structure and one shot it. But as with everything, need to always verify the results.

---

<div class="post-metadata">

**Author:** ![carles.centeno](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/carles.centeno/32/67402_2.png) [@carles.centeno](https://forum.inductiveautomation.com/u/carles.centeno)\
**Post date:** [July 2, 2026, 11:28pm UTC](https://forum.inductiveautomation.com/t/building-perspective-with-an-llm/112407/23 "2026-07-02T23:28:07Z")

</div>

> [@bkarabinchak.psi](#):
>
> Genuine question, what is the value add of a lot of these commands? Any of the `list_resource` style command you are now introducing the non-determinism of a LLM where you can see it directly either in designer, in the gateway, or you could code up a very simple deterministic API endpoint to serve you the values. Same with any `read_resource` thing. Feels like you're just injecting a LLM into a spot where there's already a very simple and deterministic way to do something, and now introducing the odd hallucination.
> 
> I can see `write_style` being very helpful espeically as someone who is not well versed with CSS but that also is typically the least important of the HMI at least in terms of the damage it can do, and in terms of verifying it, I can just look at the project view and see if it looks right and if a component is being hidden it shouldn't be etc.
> 
> All these others. Are you really shipping products where a LLM wrote the code and queries and did the bindings on a view and configured the tags etc? I know you'll probably say you review it all but I also know the research shows that after a few good responses or after sufficient fatigue developers stop checking responses, so it may be true now but if you start getting on the pace of oh we can ship a project a week, your hand reviewing will start to dwindle. Not to also mention if you're reviewing every single line of code and every single component binding and every single tag config after the LLM did it, then it feels like now you actually doubled your work then if you just did it yourself the first time correctly?
> 
> I don't know maybe im turning into a crank about LLM's but even if you do the best of things, and I am not saying you don't, the possiblity that someone out there is shipping projects with code, tag configs, queries, etc etc, that they are completely trust claude or w/e did correctly after one cursory glance, is scary to me in this field specifically where physical harm is a potential outcome.
> 
> Sorry I know this is a pro LLM forum post here but I am not saying that LLMs are completely useless but I still think a lot of your commands here seem like a solution looking for a problem and maybe there is a better use case for it in iginiton in general for the mcp module?

What the MCP allows me to do is enable a code AI to handle a project that the AI ​​didn't start—for example, a project started by a vendor who has stopped working with my client.

The AI ​​summarizes technical aspects of the "how" in just a few minutes, aspects that would take me several days to figure out.

Furthermore, it allows me to learn much faster, as it has ideas and applies quite sophisticated solutions to problems I'm unable to solve.

It's clear that it's not a direct relation between LLM-\>Ignition-\>a lot of money.... by the moment, that much is obvious, but when used correctly and with a clear understanding of what it's doing and how it's doing it, it allows me to develop screens much faster than before.

And regarding the generated code, it's not obfuscated at all; quite the opposite, it's commented, structured, well-organized, and above all, highly reusable across different projects.

But I understand your opinions, and it's true that you can't use LLM for everything, because in the end we'll become stupid and won't know how to do anything ourselves.

Thanks a lot

Carlos

---

<div class="post-metadata">

**Author:** ![Rudy.Ind.Automation](https://avatars.discourse-cdn.com/v4/letter/r/a698b9/32.png) [@Rudy.Ind.Automation](https://forum.inductiveautomation.com/u/Rudy.Ind.Automation)\
**Post date:** [July 6, 2026, 11:00pm UTC](https://forum.inductiveautomation.com/t/building-perspective-with-an-llm/112407/24 "2026-07-06T23:00:37Z")

</div>

I’ve had pretty good results with this by using `SKILL.md` files instead of trying to solve everything with one giant prompt.

Fo those that dont know a skill.md is a small context file that teaches the agent how a specific thing works.

For my setup, I built a Web Dev API in Ignition 8.1+ so the agent could interact with the gateway instead of guessing. Then I had a loop where one agent would write tests, another would improve the skill, and another would add API routes when the agent needed a new way to inspect or validate something.

So this created a feedback loop.

The agent would try something, run it against the gateway, check logs/screenshots/API responses, figure out which assumption was wrong, update the skill, and try again.

That helped a lot with things like:

- not inventing fake `system.*` functions
- not writing Python 3 when the gateway needs Jython
- learning what valid Perspective JSON actually looks like
- learning module-provided scripting functions instead of guessing them
- testing assumptions before treating them as rules

I used the same approach for Perspective pages, Jython scripts, SQL helpers, UDT import/export, creating importable perspective zip files, MQTT module scripting functions, expression language, alarms, logs, and a few other areas.

it won’t solve everything. But for 80% use cases it works and as of now i have not had a halluciantion.

For Ignition 8.1+, I had to build the API myself with the Web Dev module. For Ignition 8.3, the built-in API looks like a good starting point, though you may still need extra routes depending on what you want the agent to inspect or validate.

I made a YouTube walkthrough called “Building Perspective Pages in Ignition 8.1 with AI Agents” if you want to see the setup and demo. No link here because I don’t want to trip any filters, but it should come up if you search that title.

---

<div class="post-metadata">

**Author:** ![dmetz](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/dmetz/32/86598_2.png) [@dmetz](https://forum.inductiveautomation.com/u/dmetz)\
**Post date:** [July 30, 2026, 1:10pm UTC](https://forum.inductiveautomation.com/t/building-perspective-with-an-llm/112407/25 "2026-07-30T13:10:09Z")

</div>

Long thread, so I'll try to add something concrete instead of another opinion.

The skepticism up top is mostly correct and I want to start there, because over the last several months I hit every failure mode listed here:

- invented `system.*` calls that don't exist

- Python 3 idioms in scripts that have to run as Jython

- 8.1 answers to 8.3 questions, and the reverse

- Perspective view JSON that is structurally plausible and functionally wrong — `propConfig` in the wrong place, missing `paramDirection` on a parameterized view, embedded views with the wrong component type

- bindings written against a tag path that was true two PLC rebuilds ago

- `[default]` instead of `[PLC]`, which _\*reads\*_, just not from the provider you meant

@pturmel's niche point is the root cause of all of it. There isn't enough Ignition in the training data, and the little that's there includes every broken snippet ever pasted into this forum. No amount of prompting fixes that.

What changed things for us was giving up on making the model _\*know\*_ Ignition, and instead making the environment tell it and then prove it. Two halves.

**1. Written knowledge, in one place, that the agent has to read first**

We keep a reference vault in the repo — 14 documents, about 6,700 lines: bindings, view JSON wire format, components, tags, scripting, stylesheet/CSS, REST endpoints, OPC-UA, plus a patterns-and-gotchas file that's organized symptom → root cause with a triage table at the top. That one is at 99 entries and it's the one that gets read most.

The rules around it mattered more than the content:

**One file per subject, and new findings edit the existing file.** No parallel gotcha files, ever. The moment there are two documents that both talk about bindings, the model finds the stale one about a third of the time.

**Separate static doctrine from mutable policy.** Anything that has ever flipped lives in exactly one living file, and every other document points at it instead of restating it. Concrete example: our null-guard policy has reversed three times — guard everything, then strip the guards because red nulls are useful signal, then guard device templates only. While that rule was written down in three places we got the wrong version regularly. Now the convention doc literally says "whether to guard is set by the living policy, see the brief," and the brief is the only copy.

**Version-stamp everything.** Directly to @Nol's point about 7.9 vs 8.3 — a doc that doesn't say which version it describes is worse than no doc.

**Never bind from memory.** Our PLC tag map has been through three shape generations. Anything the model "remembers" about it is wrong. The standing rule is: resolve the path live against the gateway, _\*then\*_ write the binding. Same for tag existence, data type, and OPC item path.

**Harvest at session close.** There's a routine pass at the end of a working session that takes whatever went wrong that day and files it into the right vault document. That's the part that makes the vault grow instead of rot, and it's the step I see most people skip.

**2. A verification loop it isn't allowed to skip**

@Rudy.Ind.Automation's WebDev API + skill files approach is essentially where we landed too. The thing that made ours stick was making verification a program with an exit code rather than something the agent decides it has done:

- deploy — dry run by default, `--apply` to actually copy, with a backup and an abort-before-scan guarantee

- hermetic unit tests that `exec` the _\*real\*_ gateway script source against a mocked `system` scope, so they catch drift but never touch a gateway, clock, file, or network

- live read-back of tag/OPC values through a WebDev endpoint, strictly read-only

- a headless Chrome screenshot of the actually-rendered page

Exit 0 is green. Exit 1 is a real bug: diagnose, fix, loop, three strikes then stop. Exit 2 is a blocker — expired trial, dead endpoint, auth failure — and the agent is explicitly **\*\*not permitted to work around a 2\*\***. It stops and reports to a human.

That last rule killed more bad behavior than anything else in the stack. An agent that can't route around an obstacle has to tell you about the obstacle.

The screenshot step also mattered more than I expected. "The JSON is valid" and "the screen looks right" are completely different claims, and until the agent could see the rendered page it kept confidently shipping the first one and calling it the second.

@nminchin's advice upthread is the right instinct and I'd push it further: anywhere a deterministic tool can do the job, write the tool and take the model out of the path entirely. Push and scan, tag reads, binding coverage checks, screenshots, trial status — all plain Python, all repeatable. The model decides _\*what\*_ to do and writes the view. Every fact it reasons from comes from a tool.

**On review fatigue**

@bkarabinchak.psi's post 20 is the objection I take most seriously, and "don't worry, I review everything" isn't an honest answer — the research he's pointing at is right, review quality decays. Our answer is to shrink the surface that needs reviewing:

- **One base-path template plus a parameter** , instead of N per-device views with hand-wired tags. You review the template once; the instances are mechanical and wrong-or-right as a set.

- **Semantic style classes, never inline color.** A palette decision is one file, not nine hundred components.

- **Small focused faceplates** rather than one all-encompassing one. We learned that expensively — ended up with `_Mod`, `_ModV2`, `_ModV3` of the same faceplate before admitting the mega-component was the mistake.

Our last interaction-language pass touched roughly 900 components. I did not review 900 components. I reviewed one pattern, and then walked the live screens.

**On safety**

@robertm's leaky roof concern is fair, and the answer can't be discipline — it has to be a boundary enforced by the tooling.

The PLC owns interlocks, sequencing, coordination, and restart guards. The HMI sends individual requests: one button, one drive. The AI works on the view and request layer only, and it does not write ladder.

On the controller side, our tooling is read-only at the PLC boundary _\*by construction\*_. There is no download command, no online tag write, no controller mode change, no safety signature mutation. Not "we have a policy against that" — those commands do not exist in the tool, so there is nothing to talk an agent out of. Online rung import, where it exists at all, defaults to leaving edits pending and requires a separate explicit approval to accept.

And green tests don't make anything field-ready. Green means it's ready for me to look at in a live session. That gate has never moved.

**The other direction**

Half of the interesting work has been pointing the same approach at the PLC rather than the HMI, to answer the one question every operator and every maintenance tech actually asks and the HMI has never been able to answer: _\*why is this not on?\*_

Not the fifty conditions that are satisfied. The one that isn't.

No LLM anywhere in the trace path, and read-only at the controller, forever. I don't know how much detail I can go into, but it's the part I'm most interested in, and it's the clearest illustration of the split that makes any of this work: use the LLM to build the tool, then let the tool — not the LLM — answer the question.

**Where it still doesn't work**

- Genuinely novel architecture. It's very good at "build this the way the other forty are built" and mediocre at deciding how the forty-first should have been built in the first place.

- Day one on a new gateway is slow. The entire payoff lives in the accumulated vault, and on day one you don't have one.

- It is **\*\*not\*\*** faster for a one-off screen. Drag and drop wins, and @bkarabinchak.psi is right about that. It pays off across hundreds of screens and repetitive conversion work — which happens to be exactly the work that's most miserable to do by hand.

- The base model still doesn't know Ignition. Everything above is scaffolding around that fact, not a fix for it.

Happy to get into specifics on any of it.

[Previous page](https://forum.inductiveautomation.com/t/building-perspective-with-an-llm/112407.md?page=1)
