LLM Integration
One AI call — no tools, no loop. It is also the best place to learn prompting, because the whole node is the prompt.
Most AI work in a workflow is not a conversation. It is one question asked once: what is this message about, write a summary of that, pull the three fields out of this text. There is nothing to decide and nothing to look up — just an input, a prompt, and an answer.
That is this node. One call, no tools, no back-and-forth. If the task needs the model to go and find something, or to try, check and try again, that is the Core Agent in the next lesson. If the task is a single transformation, use this — it is cheaper, faster, and far easier to reason about when it goes wrong.
It is also where you learn to write a prompt, because a prompt is all this node is.
The fields
| Field | What it holds |
|---|---|
integration_id | LLM integration to use |
model | LLM model to use (dropdown selection) Defaults to gpt-4.1-mini. |
temperature | Sampling temperature (0.0 to 2.0) Defaults to 0.2. |
system_prompt | System prompt to set context (compiled from prompt_sections when prompt_mode='builder') |
prompt_template | Prompt template with variable substitution Defaults to {{message}}. |
response_format | Response format configuration (e.g., JSON mode) |
timeout | Request timeout in seconds Defaults to 60. |
max_retries | Maximum number of retries on failure Defaults to 2. |
integration_id
- What it holds
- LLM integration to use
model
- What it holds
- LLM model to use (dropdown selection) Defaults to
gpt-4.1-mini.
temperature
- What it holds
- Sampling temperature (0.0 to 2.0) Defaults to
0.2.
system_prompt
- What it holds
- System prompt to set context (compiled from prompt_sections when prompt_mode='builder')
prompt_template
- What it holds
- Prompt template with variable substitution Defaults to
{{message}}.
response_format
- What it holds
- Response format configuration (e.g., JSON mode)
timeout
- What it holds
- Request timeout in seconds Defaults to
60.
max_retries
- What it holds
- Maximum number of retries on failure Defaults to
2.
Two fields hold the prompt and they do different jobs. system_prompt is the standing instruction — who the model is, what it is for, what the rules are. prompt_template is the thing being asked about this time, and it is where the variables go.
Temperature is documented as 0.2 and defaults to 0.7 when the field is absent. The panel writes 0.2, so a node you configured in the builder behaves as documented. A node created through the API or by an agent, without the field set, runs at 0.7 — noticeably less predictable on exactly the classification tasks this node is best at. Set temperature explicitly and the ambiguity goes away.
Writing the prompt
You can write the prompt as one block of text or build it from labelled sections. The sections are not decoration — they are the difference between a prompt you can debug and a paragraph you keep rewriting. Five of them carry almost all the weight:
| Section | What goes in it |
|---|---|
| Who the model is. One sentence. It sets vocabulary and assumptions more than people expect. | |
| What this call is for, in the singular. If you need “and also”, you probably want two nodes. | |
| The rules, as a list. This is where the enumerated choices go — classify as exactly one of these five. | |
| What it must not do. Not invent an order number. Not promise a date. Under eighty words. | |
| The shape you want back. With JSON mode on, name the exact keys. |
- What goes in it
- Who the model is. One sentence. It sets vocabulary and assumptions more than people expect.
- What goes in it
- What this call is for, in the singular. If you need “and also”, you probably want two nodes.
- What goes in it
- The rules, as a list. This is where the enumerated choices go — classify as exactly one of these five.
- What goes in it
- What it must not do. Not invent an order number. Not promise a date. Under eighty words.
- What goes in it
- The shape you want back. With JSON mode on, name the exact keys.
Constraints are the section beginners leave out and then need. A model asked to draft a reply will cheerfully invent a delivery date, because a helpful reply contains one. Nothing in the objective forbade it. Every unwanted behaviour you find in testing becomes a line in this section.
A worked example
An inbound message is classified and a reply is drafted in a single call. The workflow then branches on what the model decided.
One call, structured output, then a decision
JSON mode is what makes the branch below it possible.
Scroll for all 5 steps →
Read that prompt as five decisions rather than as prose. The intent list is closed — five values, no “or similar” — so the output is something a Condition can compare. Urgency has an explicit rule for when high applies, because “use your judgement” produces a different judgement every run. And the constraints name the two things this model would otherwise do wrong.
JSON mode is what turns an answer into a decision. With response_format set to JSON, the response is parsed and each key becomes readable as {{alias.parsed.<key>}} — which is how the condition below reaches urgency without any string matching. Without it, you would have one blob of prose and no way to branch on it.
What comes back
| Reference | What you get |
|---|---|
{{alias.output}} | The model's text. In JSON mode this is the raw JSON string. |
{{alias.parsed}} | The parsed object — and {{alias.parsed.intent}} for a field. Only populated in JSON mode. |
{{alias.tokens_used}} | What the call cost, with prompt and completion counts alongside. Log it while you are tuning. |
{{alias.model}} · {{alias.runtime_ms}} | Which model actually answered, and how long it took. |
{{alias.output}}
- What you get
- The model's text. In JSON mode this is the raw JSON string.
{{alias.parsed}}
- What you get
- The parsed object — and {{alias.parsed.intent}} for a field. Only populated in JSON mode.
{{alias.tokens_used}}
- What you get
- What the call cost, with prompt and completion counts alongside. Log it while you are tuning.
{{alias.model}} · {{alias.runtime_ms}}
- What you get
- Which model actually answered, and how long it took.
What breaks
Reaching into parsed without JSON mode fails in the worst way. The field is only filled when response_format is set to JSON. Reference {{alias.parsed.intent}} without it and you get the literal text <llmintegration_1.parsed.intent not found> — pasted into whatever came next, including a message to a customer. If you are branching on a model's answer, JSON mode is not optional.
JSON mode guarantees valid JSON, not the keys you asked for. The model will return well-formed JSON reliably. Whether it contains intent or category depends on your prompt saying so, exactly, in the output-format section — and on it being the only place a key name appears. Name the keys once, precisely.
A closed list is only closed if you enumerate it. “Classify the intent” gets you whatever words the model likes, differently each time, and every downstream Condition slowly stops matching. “Exactly one of: delivery_status, billing, complaint, sales, other” gets you one of five. Add other to every list — without it the model forces a bad fit rather than admitting the message is none of them.
Retries are not free and not idempotent in effect. max_retries defaults to 2, so a flaky provider costs three calls' worth of tokens for one answer, and each attempt may answer slightly differently. That is fine here, and it is worth remembering when a bill looks larger than the number of runs suggests.
Try it
- Build the smallest version: a trigger, this node with a one-line
system_prompt, andprompt_templateset to{{trigger_1.message}}. Read{{alias.output}}. - Now ask it to classify into three named categories, run the same message five times, and note whether the answer is stable. Then add
temperatureof 0 and do it again. - Turn on JSON mode, name your keys in the output-format section, and read
{{alias.parsed}}. Then turn JSON mode off and reference{{alias.parsed.intent}}— the angle brackets are the failure worth seeing once. - Ask it for a reply without a constraints section and count how many drafts promise a date. Add the constraint and count again.
- Finally set
temperatureto 1.5 and run the classifier. That is what the undocumented default drifts toward, and why setting it explicitly matters.
Next: Core Agent — the same model, given tools and permission to use them until the job is done.
Related lessons
Base rates — what a piece of evidence is actually worth
A face-recognition system that is 99.9% accurate and almost entirely wrong, and a number that sent an innocent woman to prison. Both are the same arithmetic, and it is the arithmetic that decides what any piece of evidence is worth.
ReadConfirmation and survivorship — what you never looked for
Two questions about evidence you did not go looking for. One is a rule you have to discover, and one is a pattern in five famous people — and in both, the thing that would have told you the truth is the thing nobody checks.
ReadLoss aversion, sunk cost and regression — what it costs you
Four questions you answer about yourself rather than about a scenario, and your own answers are the finding. Then the pattern that makes praise look useless and criticism look like it works, whatever you actually do.
Read
