ai newsDo., 5. Nov.
EilmeldungTencent releases Hy4 with vision and computer use, claims second place among Chinese AI models

AI + PLC Programming: The Missing Layer Is Project Context, Not Model Quality

Ask an AI agent "who reads and who writes additional_variables.tag3 ?" in a real TIA Portal project, and you can tell within one reply whether it is guessing. A grounded answer is four rows: two contacts reading it at lines 152 and 222 , two coils writing it at lines 217 and 262 , all inside Auto_m

dev.toMittwoch 14:41 · 04.11.6 Min. Lesezeit

Posted on Nov 4 • Originally published at tia.hubwiz.com

Ask an AI agent "who reads and who writes additional_variables.tag3?" in a real TIA Portal project, and you can tell within one reply whether it is guessing.

A grounded answer is four rows: two contacts reading it at lines 152 and 222, two coils writing it at lines 217 and 262, all inside Auto_mode, network 1. An ungrounded answer is a paragraph that sounds right.

That gap — four rows versus a paragraph — is not a model-quality problem. Current models write SCL fine. It is a project-context problem: a PLC project is a graph, and we keep handing the model a stack of files.

Chunking is the worst of the three, because the relationships you most need are exactly the ones that cross the chunk boundary. In a ladder program that boundary is everywhere: a coil in network N3 writes a tag that a contact in network N7 reads, and the tag itself is defined in a tag table that is a third file.

The graph we used has four kinds of content, and you need all four:

That third row is the part people skip. In a graph built from a real project, " tag3 is written by a coil in Auto_mode " and " tag3 is written by a coil in Auto_mode, per an operand parse, line 217" are different claims with different trust levels. If your agent cannot separate them, you are back to prose.

Target: PLC_SCADA_HMI, an MIT-licensed open-source project ( rassulz/multirobot_painting_control_system ), opened in TIA Portal V19 on an S7-1500 / ET200MP station, CPU 1513F-1 PN ( 6ES7 513-1FL02-0AB0, firmware V2.9). Read-only the whole way: no imports, no block edits, no save, project dirty flag unchanged.

1.2 seconds is not the interesting number. The interesting number is 517 edges against 227 nodes — the relationship layer is twice the size of the object layer. That ratio is the reason a context window is the wrong container: you don't have a document of 227 things, you have a network of 517 claims about them.

Any graph-derived answer is only as good as its freshness, and the failure here is silent. Before asking your first real question, get three facts:

If any of the three is unclear: rebuild, then ask. Two related traps: an empty graph gets rejected outright (the previous graph is kept, so you may be looking at yesterday's), and a graph query that hits its result cap says so — "there's more" — which means you have not seen the project, you have seen a page of it.

The single most repeated mistake in this kind of analysis is batching six questions into one prompt, getting a long answer, and not noticing that section four was truncated. Six probes, six turns, each verifiable on its own:

Probe 2 is worth its own paragraph. On this project, Auto_mode matched four things — the FB, a call site Main::N1::I1, its file, and its network — and the answer came back with "there is more". Without the "was it truncated" question you would have concluded "four references" and been wrong. Ask about truncation every single time. It costs one sentence and it is the difference between an inventory and a sample.

Probe 4, verbatim result for additional_variables.tag3:

Two things to notice. First, reads and writes are separate columns of truth: 2 reads + 2 writes means a change to this tag touches four ladder positions, all between lines 152 and 262 — that is the entire software blast radius of the change, stated as a list of places. "This tag is used in the auto mode block" is not that; it cannot be checked and it cannot be assigned.

Second, the line numbers make the claim auditable. Not "trust me, the graph says so" — open the XML, go to line 217, look at the coil. If an audit finds the graph wrong at line 217, you now know something about the graph for every subsequent answer. This is the whole reason to prefer a graph over a summary: it gives reviewers a way to be lazy safely.

For FB::Auto_mode, the default relation set (call / instantiate / read / write) gives:

Which reads as one honest sentence: Auto_mode is called from network 1 of the main program and its instance DB is Block_1_DB; change the interface and both need a look.

But "which block does it live inside?" is not in that answer, because containment is not part of the default set. Add containment and walk up:

These are two different questions, and conflating them is the fastest way to a wrong edit plan: the first says who is affected (callers, instance DBs, tag readers), the second says where it is nested (file → network → block → file). Keep them as two probes.

Eight references in this project point at objects the project does not define. The graph does not invent edges for them; it puts them in a table:

Cross-check: all eight are timer coils writing an instance — and both of these FBs have empty interfaces, and no global DB with those names exists. So this is not a parser miss. The blocks reference timer instance DB names that were never created in this project. A search finds the name; only a project-wide graph can tell you the name resolves to nothing.

Then the compile: No block was compiled. All blocks are up-to-date.

Read that sentence carefully before you put it in a report. It does not mean "the program is fine." It means "nothing needed compiling." A green compile is evidence about the compiler's queue, not about the program — and it is exactly how a dangling timer instance survives to commissioning.

The last step of the probe is the one only a human can do: classify each row as truly missing (add the object), external library (this project cannot define it; import something), or to be added later. The agent assembles the evidence; the judgment stays with the engineer who owns the machine.

Expect the surprises to come from steps 4 and 6. Impact analysis on a block you "know" is where the containment layers show you the file you forgot, and the tag probes routinely find a writer in a block nobody wanted to touch.

The industry conversation about AI and PLC programming is mostly about generation — better SCL, better ladder, better conversions. That is the part that got solved first, because it only needs the spec.

The part that did not get solved is context, and prompt engineering cannot fix it, for a structural reason: a graph does not fit in a sequence. You can always paste more text, but pasting more text makes the coupling you need less visible, not more, because the relationships are spread across the very boundaries you are introducing.

Three things are worth taking from this even if you never build a graph:

The lesson this came from is Lesson 6 of PLC AI in Practice — a free, text-based course (no video) that walks the same project through six probes with copy-paste prompts, ~30 minutes. The tool behind it is TiaLink, an MCP gateway that connects TIA Portal to an agent and runs locally, so project data stays in the plant.

If you'd rather start from the human problem than the tooling:

Disclosure: every measured number above — 227 nodes, 517 edges (220/2/2/87/52/154), 8 unresolved references, 1.2 s build, lines 152–262, the `IEC_Timer_0_DB ` rows — comes from the course's own published run on 2026-10-27 (TIA Portal V19, TiaLink 1.4.0.0). I did not re-run the measurement independently for this post. Prompt examples were written in Chinese in the lesson and are translated here.*

Quelle: dev.to (dev.to). Original öffnen