We use cookies to understand how you use our site and improve your experience. Privacy Policy

Back to Blog
Automation Workflows

$fromAI() in n8n: Build Dynamic AI Tools

n8n
n8n Resources Team
May 11, 2026

Ready to automate?

Browse 5,000+ copy-paste n8n workflow templates.

Most n8n builders start with the AI Agent node and quickly hit the same wall: the tools they attach to the agent need static, predefined parameters. You pick a field value, and it never changes. The agent can reason all it wants, but when it calls a tool, it sends the same thing every time.

That's where $fromAI() changes the picture. It's a built-in n8n expression function that makes tool parameters dynamic — letting the AI agent itself decide what value to pass when it calls a tool. Combined with clear descriptions, it turns a rigid HTTP Request or code node into something that adapts to each piece of incoming data.

This guide walks through what $fromAI() does, where to use it, and a concrete workflow you can build today.

What $fromAI() Does

$fromAI() is an expression function available inside any node that's configured as a tool for n8n's AI Agent node. When the agent decides to call that tool, it fills in the $fromAI() placeholders based on its understanding of the current task.

The syntax is:

{{ $fromAI('parameterKey', 'A description the AI uses to understand this field', 'type') }}

The three arguments are:

  • key — an internal name for the parameter (no spaces, lowercase recommended)
  • description — plain-language text the AI reads to understand what to put here. Write it the way you'd explain the field to a new team member.
  • type — one of string, number, boolean, or json. Defaults to string if omitted.

At runtime, n8n passes the key, description, and type to the AI model as part of the tool schema. The model evaluates the current context — the incoming data, the system prompt, prior reasoning — and fills in an appropriate value.

When to Use $fromAI() vs. Static Parameters

Use $fromAI() when:

  • The field value should change depending on what the agent is processing
  • You want the AI to extract a specific piece of information from unstructured input
  • The tool needs to behave differently for different categories of data

Use a static parameter (a regular expression or hardcoded value) when:

  • The value is always the same regardless of input
  • You don't want the AI to deviate from a fixed format
  • The field is an internal identifier like an API key or base URL

A common pattern is to mix both: static values for credentials and base URLs, $fromAI() for the body fields that should vary.

Example Workflow: AI-Powered Request Classifier

Here's a practical workflow that demonstrates $fromAI() in action. The goal: receive incoming requests from any source, let an AI agent extract the relevant fields, and route each item to the right destination.

Step 1: Webhook Trigger

Add a Webhook Trigger node and set the HTTP method to POST. This is the entry point — it can receive data from a form submission, an internal app, a Zapier webhook, or any other source that can send HTTP. Set the path to something memorable like /classify-request.

Step 2: AI Agent Node

Add an AI Agent node and connect it to the Webhook Trigger. In the system prompt, define what the agent should do:

You receive incoming requests and must classify each one. Based on the content, call the appropriate tool: use the CreateTask tool for requests that describe a bug, feature, or technical issue; use the LogEntry tool for general inquiries, feedback, or anything else. Fill in all required fields accurately.

Connect your preferred language model (OpenAI, Anthropic, or any compatible provider) in the Chat Model slot. Leave memory off for stateless, single-pass classification.

Step 3: HTTP Request Node as "CreateTask" Tool

Add an HTTP Request node. In the AI Agent's Tools section, attach it as a tool named CreateTask with a description like "Creates a task for bugs or feature requests."

In the HTTP Request node's body, use $fromAI() for each field the AI should fill in:

{
  "title": "{{ $fromAI('task_title', 'A short, descriptive title for the task', 'string') }}",
  "priority": "{{ $fromAI('priority', 'Priority level: low, medium, or high', 'string') }}",
  "description": "{{ $fromAI('description', 'Full context for the task, including steps to reproduce if it is a bug', 'string') }}"
}

Point the URL at your project management tool's API endpoint — Linear, Jira, Asana, or any service with a REST API.

Step 4: HTTP Request Node as "LogEntry" Tool

Add a second HTTP Request node as a second tool named LogEntry. This handles general inquiries, feedback, or anything that doesn't fit the task category. Its body uses:

{
  "category": "{{ $fromAI('category', 'One of: feedback, question, other', 'string') }}",
  "summary": "{{ $fromAI('summary', 'One sentence summarizing the request', 'string') }}",
  "raw_content": "{{ $fromAI('raw_content', 'The full original text of the request', 'string') }}"
}

Point this at an Airtable endpoint, a Notion API call, a Google Sheets row append, or any datastore you prefer.

Step 5: Respond to Webhook

Add a Respond to Webhook node at the end. Return a simple confirmation JSON so the calling system knows the request was received and processed.

How the Agent Decides

When the workflow runs, the AI Agent reads the full webhook payload, evaluates which tool to call, fills in all the $fromAI() fields from the content, and calls the tool. You don't write any classification logic — the model handles it based on the tool descriptions and system prompt.

If the input is ambiguous, the agent can call multiple tools in sequence within a single execution.

Tips for Writing Good $fromAI() Descriptions

The description argument is the most important part. The model uses it literally when deciding what value to generate.

Be specific about format. Instead of 'The priority', write 'Priority level: must be one of low, medium, or high'. Constrained options reduce hallucination.

Match the description to the data type. If the type is number, the description should make clear you expect a numeric value: 'Number of items affected, as an integer'.

Use json for structured objects. If a tool needs a nested object, set the type to json and describe the expected schema in the description field: 'A JSON object with keys "name" (string) and "email" (string)'.

Keep descriptions under 80 characters. Longer descriptions still work, but concise ones tend to produce more reliable outputs.

Combining $fromAI() with Other n8n Features

$fromAI() works in any node used as a tool — HTTP Request, Code, custom function nodes. It also composes well with:

  • IF node after the agent — for additional conditional logic after classification
  • Sub-workflow tools — call another n8n workflow as a tool, with $fromAI() filling the input fields of that workflow
  • Error handling — wrap tool nodes in a Try/Catch to handle API failures gracefully without stopping the entire agent run

Finding Pre-Built AI Agent Templates

If you want a head start, n8nresources.dev has a growing collection of ready-to-copy AI agent workflows in the template library. The AI agents use case collection covers common patterns including classifiers, summarizers, and multi-tool routing workflows — all of which use $fromAI() for their dynamic parameters.

For broader context on where AI agent automation fits into a modern workflow stack, the AI workflow automation section covers the category in more depth.

$fromAI() is one of the more useful primitives n8n exposes for AI-powered workflows. Once you understand how the description field shapes the model's output, you can wire up tools that handle a surprisingly wide range of inputs without writing classification logic by hand.

Enjoyed this article?

Share it with others who might find it useful