> For the complete documentation index, see [llms.txt](https://docs.borndigital.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.borndigital.ai/for-advanced-users/intent-recognition-tips/fine-tuning-intent-recognition-using-generative-ai.md).

# Fine-Tuning Intent Recognition using Generative AI

Make AI intents of the Answer node more accurate: write better meanings and descriptions, add context to the Intent recognition prompt and choose the model.

**AI intents** of the [Answer node](/digital-agent/conversation-flow/nodes-explained/answer-node.md#ai) let a large language model decide which intent the customer's message belongs to. They need no training set, understand paraphrases and typos, and you can make them more accurate in two ways:

1. **Better intents** – a clear **Meaning** and a helpful **Description** for each intent.
2. **Context in the Intent recognition prompt** – what the model should know about the conversation and the customer.

## How the recognition works

For every message, the node sends one request to the model with:

* **Behavior** – the system message, by default: *you are an assistant for intent recognition; classify the utterance and respond only with the intent name as JSON*.
* **Text before list of intents**, then the list of the node's AI intents, one line each: `- NAME: Meaning [Description]`, then **Text after list of intents**, which asks for the answer as `{ 'recognized_intent': string }` or `NOT_FOUND`.
* **User** – what to classify, by default `{current_utterance}`, the customer's last message.

The model does **not** see the conversation history – only what is in these fields. Anything else it should know, you have to put there (see [Add context](#2.-add-context-to-the-intent-recognition-prompt)).

Open the prompt with the gear icon next to the **AI** section title of the Answer node. It applies to all AI intents of the node.

## 1. Write better intents

* **Name** – the value the model returns, for example `INVOICE_NOT_RECEIVED`. Use clear, unique names; the model reads them too.
* **Meaning** – one sentence: what the customer wants. *Customer did not receive the invoice for the last month.*
* **Description** – optional details that help the model decide. Keep it short: all descriptions of the node go into every request, so long descriptions add latency and cost.

What to put in the description:

<details>

<summary>Examples of what customers say</summary>

`Customer asks about the weather forecast [Show me the weather in London; Will it rain in Seattle tomorrow; How hot will it be this weekend]`

</details>

<details>

<summary>Keywords, synonyms and alias terms</summary>

`Meaning: Complaint about a product. Description: claim, damage, broken, not working, won't turn on, defective`

</details>

<details>

<summary>What the intent is not about</summary>

Draw the line between similar intents:

`Customer asks whether a product is in stock. Not about product specifications or reviews.`

</details>

<details>

<summary>Several facets of one intent</summary>

`Customer is interested in discounts: promotional offers, seasonal sales or loyalty rewards.`

</details>

{% hint style="info" %}
Two intents that the model keeps mixing up usually have meanings that overlap. Rewrite the meanings so that each describes a different situation, or merge the intents and decide later with a Condition.
{% endhint %}

## 2. Add context to the Intent recognition prompt

Short answers like *yes*, *the second one* or *10 GB* can be classified only with context. Add it to **Behavior** or **User**, and use variables – type `{` to insert one. Keep **Text after list of intents** as it is: the node reads the model's answer in exactly that JSON format.

<details>

<summary>The question the customer is answering</summary>

Store the last question in a variable (for example `last_question`) in the Message node that asks it, then:

```
Context: The customer was asked: {last_question}
```

</details>

<details>

<summary>A summary of the conversation</summary>

```
Context: The assistant told the customer that {summary}. The customer's message probably reacts to that.
```

</details>

<details>

<summary>What you know about the customer</summary>

*"I want 10 GB of mobile data"* is an upgrade or a downgrade depending on the current tariff:

```
Context: The customer currently has the tariff {tariff_name} with {data_amount} GB of mobile data.
```

</details>

<details>

<summary>Date and time</summary>

```
Context: The customer was asked whether they can pay before {deadline_date}. Today is {current_date}.
```

</details>

You can also change **User**, for example to give the model the question and the answer together:

```
Question: {last_question}
Answer: {current_utterance}
```

## 3. Choose the model and the timeout

In the same dialog:

* **Provider** and **Language Model** – a smaller, faster model is usually enough for classification. Use a larger one only when the intents are subtle.
* **Reasoning › Effort** (reasoning models) – keep it at the lowest option. Classification rarely needs more, and every step adds latency – on a call, the customer waits for it.
* **Temperature** – GPT-5 and GPT-6 models use a fixed value; for other models keep it low for consistent results.
* **Timeout** – how long the node waits for the model, 3 seconds by default. On a call, keep it short.

{% hint style="success" %}
Test with real messages, including short answers, typos and off-topic questions. The Answer node evaluates chat buttons, Keywords, Conditions and AI intents in the order they appear, then the Training set – put cheap and certain checks (buttons, keywords) before AI intents.
{% endhint %}
