AI
Turns unstructured text into something you can query. Give it a comment and a list of categories and it returns one of them; give it a paragraph and a set of fields and it returns them filled in.
Type: ai · Category: AI · Ports: one input · one output


When to use it
- Classifying free-text operator comments into a reportable column
- Extracting fields from a message a supplier sends in prose
- Summarising a long shift note into something a dashboard can show
Anything with a deterministic answer. If a rule can decide it, write the rule — it is faster, free, and it cannot change its mind.
Settings
| Setting | Key | Default | Purpose |
|---|---|---|---|
| Prompt | promptTemplate | — | The instruction, templated from the message. |
| Output mode | outputMode | fields | fields (structured) or a single choice. |
| Output fields | outputFields | [] | The structure to extract. |
| Choices | choices | [] | The permitted answers, for classification. |
| Output path | outputPath | payload.classification | Where the result is written. |
| Skills | skills | [] | What it may look up. At most eight; a warning past five. Gateway Variables 1.0.8 reads the values pipelines and scripts keep with system.vars — a counter, the current batch — in one look-up rather than a database query. |
| Temperature | temperature | 0 | Determinism. Leave at 0 for classification. |
| Max tokens | maxTokens | 1024 | Ceiling on the answer. |
| Tool iterations | maxToolIterations | 8 | How many look-up rounds the node may take. Bounds the loop so an unattended node gives up rather than grinding. 1.0.6 |
| Give up after | timeoutMs | 60 s | The node's own wall clock. 1.0.6 Its maximum is the administrator's AI node time limit, shown under the field as max … — 120 s unless changed, and every node's timeout is held to it, so raising that limit is what lets a node ask for longer. 1.0.8 → AI Assistant |
| Cache | cache | on, 1 h | Reuse the answer for an identical prompt. Correct only because the temperature is 0. |
| On error | onError | fail | What to do when the model is unavailable — fail, passthrough or default. |
| Model | modelId | (empty) | Escape hatch. Empty uses the globally active provider profile. |
The four fences
Every fence is fail-closed: [] reaches nothing, ["*"] reaches everything, and anything
else is the list. They are separate questions because they genuinely are — a node fenced to Line 1's
tags may still need the maintenance database, and one reading the ERP may have no business reading
tags.
| Fence | Key | Limits |
|---|---|---|
| Tag scope | scope | Which namespace folders and tags it may read. |
| Connections | connections | Which database connections it may query. |
| External systems | endpoints | Which named endpoints it may call. |
| Specialists | specialists | Which saved specialists it may run. No * exists — one at a time. |
That is the opposite of the intuition. On the platform a human writes the prompt; this node's prompt is a vendor webhook, an MQTT payload or an email body that nobody read first — so text inside it can steer the model toward a different connection or a different external system on the same installation.
Free-form SQL and every write are therefore structurally unreachable from this node, whatever is configured: it emits a decision, and a deterministic node downstream performs any action. The pipeline graph you drew is the authorization artifact.
Give the node the one database and the one endpoint it needs. Never *.
Example — classifying a downtime comment
Operators type free text; reports need categories.
Prompt: Classify this downtime comment into one category.
Comment: {{payload.comment}}
Output mode: choice
Choices: mechanical, electrical, material, changeover, operator, other
Output path: payload.category
Temperature: 0
In
{ "payload": { "id": 8814, "comment": "infeed belt kept slipping, had to retension it" } }
Out
{
"payload": {
"id": 8814,
"comment": "infeed belt kept slipping, had to retension it",
"category": "mechanical"
}
}
Write it back with a SQL node and the pipeline has turned free text into a column you can group by.
{{payload.data}} against a message with no data field renders as nothing at all — you get
Value: rather than Value: {{payload.data}}. A raw token arriving in somebody's inbox looks
like data the author meant to send, so a blank is the safer failure.
The practical consequence is that a mistyped path is invisible: the message still sends, just missing a piece. Send one to yourself, or watch a Debug node, before wiring it to an escalation.
The database nodes do the opposite with the same syntax — there an unresolved token is left as literal text.
Gotchas
- Keep temperature at 0 for anything feeding a report. The same input should produce the same category every time.
- Set
onErrordeliberately.failstops the branch, which is right when the classification is the point and wrong when it is an enrichment and the row should be stored regardless. - Every fence and the skill list are empty by default — the node can reach nothing until you grant it. Grant the narrowest thing that works.
- Fewer skills answer better. Tool selection degrades well before fifty tools; a node needing more than a handful is a signal to split it in two, or to hand part of the question to a specialist.
maxToolIterationsis a budget, not a target. A classification needs none; the default of eight covers a real look-up loop plus one wrong turn. 1.0.6 It was three, which could not finish the sequence the Database Explorer skill documents — list the databases, introspect for tables, introspect for columns, then query. A node cut off one call short answered "I don't have access to any data source", which reads as a permission problem and is not one. The ceiling is still ten, so raising it stays a decision.- The node's own clock is 60 seconds. 1.0.6 The old 15 covered every model round trip and every tool call, so the iteration budget was worth nothing if the deadline landed first.