Skip to content
Expedify
AI & the Knowledge Base

Module · The AI nodes

Core Agent

Lesson 2 of 6 · 8 min

The last node asked the model one question and used the answer. This one gives the model a job and a set of things it can do, and lets it decide what to do first. It looks something up, reads what came back, decides that is not enough, looks up something else, and eventually answers.

That loop is the whole difference. An LLM Integration node is a step in your workflow. A Core Agent is something closer to a colleague you brief once — and like a colleague, most of what you configure is not what it does but what it is not allowed to do.

The fields

Ten of twenty-two. The rest are prompt-builder storage and saved-prompt references.

llm_integration_id

What it holds
LLM provider integration to use (required)

model

What it holds
LLM model to use Defaults to gpt-4.1-mini.

temperature

What it holds
Temperature for response generation Defaults to 0.2.

system_prompt

What it holds
System prompt for the agent (compiled from prompt_sections when prompt_mode='builder')

max_iterations

What it holds
Maximum iterations for agent loop Defaults to 10.

memory_type

What it holds
Type of memory to use ('summary' was never implemented and is treated as 'buffer'; real persistent memory lands in P3) One of: none · buffer Defaults to buffer.

max_memory_messages

What it holds
Maximum messages to keep in memory Defaults to 50.

max_tool_result_chars

What it holds
Maximum characters of a tool result fed back to the agent per call (0 = unlimited). Truncated results can be paged with the built-in fetch_tool_output tool; full results are always kept in execution history. Defaults to 4000.

max_agent_depth

What it holds
When this agent is used as another agent's tool (agent-as-tool), the maximum nesting depth of agents-calling-agents before the delegation is refused. Guards against runaway recursion. Defaults to 3.

output_schema

What it holds
Structured output (P3): a JSON Schema for the agent's final answer. When set, the LLM is asked to return JSON matching it (provider response_format), and the parsed object is exposed as `structured_output` for downstream nodes. Empty = free-form text (default). Providers: OpenAI + Gemini enforce it; others degrade to plain text.

The prompt works exactly as in the last lesson, and the sections are the same. The difference is that an agent's prompt has to say when to use which tool, because nothing else tells it. A tool the prompt never mentions is a tool the agent will mostly ignore.

The source material — and a lot of older documentation — lists three memory types. There are two. none and buffer. The product's own schema says that summary was never implemented and is treated as buffer if you set it. So a workflow configured for summarised memory is running a plain buffer, and the only real lever on memory size is max_memory_messages.

Tools are attached, not wired

A tool node does not sit in the flow. You attach it to the agent, and it is then off the execution path entirely — the agent calls it when it decides to, as many times as it likes, or never.

How you configure that tool is the part worth getting right. Each field is either pinned — you set it, and the agent cannot change it — or left for the agent to fill. That choice is your security boundary.

A worked example

An agent that answers questions about accounts. It can search contacts and it can file a note, and it may not do anything else.

One agent, two tools, and the pinning that matters

look_up_contact and file_a_note are attached to the agent, not wired into the flow.

Scroll for all 5 steps →

Read the two tools. On the lookup, entity_type and operation are fixed — this tool searches contacts, and there is no phrasing of a question that turns it into a delete. Only search_query is left as {{ai}}, because that is genuinely the agent's job. The note tool is the same shape: what it does is pinned, what it says is not.

That is the pattern for every tool you attach. Pin the verb and the target; let the agent fill the content. An agent given a CRM Manager with everything left open can, in principle, be talked into any operation on any entity — which is a sentence worth reading twice before you build a support bot.

Note also that the agent's own instructions name both tools and say when to use them, including what to do when the lookup finds nothing. Without that last line, an agent that finds no contact will answer from whatever it can infer, confidently.

Where it has to stop

max_iterations

What it bounds
How many times round the loop. One to twenty, ten by default. Each iteration is at least one model call.

max_tool_result_chars

What it bounds
How much of a tool's output is fed back per call — 4000 by default, zero for unlimited. Long results are truncated for the agent but kept in full in the execution record, and the agent can page through them.

max_memory_messages

What it bounds
How much conversation it carries. Fifty by default.

max_agent_depth

What it bounds
How deep agents-calling-agents may go before a delegation is refused. An agent can be another agent's tool, and this is what stops that becoming a recursion.

The truncation limit is the one people meet by accident. A tool returning a hundred rows of CRM data hands the agent the first four thousand characters. The agent then reasons about a partial answer and does not necessarily know it is partial. For tools that return a lot, either narrow the tool — a smaller limit on the search — or raise the ceiling deliberately, remembering that every character goes into the next prompt and is paid for.

What it hands back

{{alias.output}}

What you get
The final answer. Usually what you send to the user.

{{alias.structured_output}}

What you get
The answer parsed as JSON, when an output_schema is configured. OpenAI and Gemini enforce the schema; other providers fall back to plain text, so do not rely on it universally.

{{alias.steps}}

What you get
What it thought and did, in order. The first thing to read when an answer is wrong.

{{alias.tool_calls}}

What you get
Which tools it called, with inputs and outputs. The second thing to read.

{{alias.metrics}}

What you get
Duration, model calls, tool calls and tokens. What an agent costs, per run.

What breaks

Running out of iterations does not fail. When the loop hits its limit, the agent writes a fallback answer from what it has so far and returns normally. There is no error and no obvious marker — the reply is simply worse than it should be, in a way that looks like the model being unhelpful. If answers degrade under load or on hard questions, count the entries in {{alias.steps}}: if it equals your limit, the agent was cut off rather than finished.

A tool the prompt does not describe is a tool that mostly goes unused. Attaching a node makes it available; the prompt is what makes it likely. The corollary is worse — an agent with eight attached tools and a prompt that mentions three will use the three, and you will conclude the other five do not work.

Judgement is not a control. If a rule must hold — a discount cap, an approval, a refund limit — put it in a Condition after the agent, not in its prompt. A prompt is a strong suggestion evaluated by a probabilistic system. A Condition is a rule. This is the single most important habit in building with agents, and the reason the previous path spent so long on branching.

Agents are expensive in a way single calls are not. Ten iterations is at least ten model calls, each carrying the conversation and every tool result so far. Cost scales with the square of the conversation, roughly. Start with max_iterations at four or five, and raise it only when you have watched a real run need more.

Try it

  1. Build the agent with one attached tool and a prompt that never mentions it. Ask a question that needs it, and watch {{alias.tool_calls}} stay empty.
  2. Add one sentence naming the tool and saying when to use it. Ask the same question. That sentence is the whole lesson about agent prompts.
  3. Pin the tool's operation to search and then try to talk the agent into deleting something. It cannot — the field is not its to fill.
  4. Set max_iterations to 1 and ask something that needs two steps. Read the answer, then read {{alias.steps}}. The reply looks like a bad model; the steps show a cut-off agent.
  5. Lower max_tool_result_chars to 200 and ask about something with a long result. Then read the execution record and confirm the full result is still there.

Next: Voice Agent — the same brain with the same tools, holding a conversation out loud while somebody waits on the line.