> This is a page from the ElevenLabs documentation. For a complete page index, fetch https://elevenlabs.io/docs/llms.txt. For the full documentation in a single file, fetch https://elevenlabs.io/docs/llms-full.txt.

# Structured procedures

## Overzicht

Een structured procedure is een [procedure](/docs/nl/eleven-agents/customization/procedures) die een vaste reeks stappen uitvoert. Een [free-form procedure](/docs/nl/eleven-agents/customization/procedures/free-form-procedures) bestaat uit richtlijnen in natuurlijke taal die de agent interpreteert en aanpast aan de situatie. Een structured procedure is een geordende lijst met getypeerde stappen die de agent telkens wanneer de procedure van toepassing is op volgorde uitvoert.

Gebruik een structured procedure wanneer specifieke stappen bij elk gesprek op dezelfde manier moeten plaatsvinden: de identiteit van een beller verifiëren, een ticket escaleren of een betaling aannemen. Je schrijft deze als een korte lijst met stappen in gewone taal.

Net als elke procedure heeft een structured procedure een trigger die beschrijft wanneer deze van toepassing is. Wanneer een gesprek overeenkomt met de trigger, voert de agent de stappen van de procedure op volgorde uit en gaat daarna verder met de rest van het gesprek.

![Editor voor structured procedures](/docs/_fern-img/bc996f67b2afad8f1de5abe8febcf8af3766b4f098627b0ae60e0456b3c2703b.webp)

## Wanneer een structured procedure gebruiken

Gebruik een structured procedure wanneer specifieke stappen elke keer op dezelfde manier moeten worden uitgevoerd, maar je toch snel in gewone stappen wilt schrijven. Structured procedures zijn eenvoudiger te schrijven dan een workflow, maar minder expressief. Zie [Wanneer procedures gebruiken](/docs/nl/eleven-agents/customization/procedures#when-to-use-procedures) voor een vergelijking met free-form procedures, workflows en de system prompt.

## Anatomie van een structured procedure

Een structured procedure heeft drie onderdelen: een naam, een trigger en een geordende lijst met stappen.

### Naam

Een kort label dat de procedure in het dashboard identificeert. De naam wordt nooit naar de LLM gestuurd en heeft dus geen invloed op het gedrag van de agent.

### Trigger

Een beschrijving in gewone taal van wanneer de agent deze procedure moet uitvoeren, bijvoorbeeld *Wanneer de gebruiker vraagt om een bestelling terug te betalen*. De agent vergelijkt de intentie van de gebruiker met de trigger van elke procedure en voert de overeenkomende procedure uit. Triggers moeten daarom concreet en onderscheidend zijn. De agent ziet alleen de tekst van de trigger, nooit de naam of ID van de procedure. Een trigger werkt hetzelfde als bij elke procedure; zie [Triggers schrijven](/docs/nl/eleven-agents/customization/procedures/free-form-procedures#writing-triggers).

Laat de trigger leeg om van de procedure een subprocedure te maken die alleen wordt uitgevoerd wanneer een andere procedure deze aanroept.

### Stappen

De proceduretekst is een geordende lijst met getypeerde stappen. Er zijn meerdere staptypen, die je combineert om de taak te beschrijven.

| Stap                 | Wat deze doet                                                                                                                                                                                                                                                                    |
| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Vragen**           | Vraagt de gebruiker om informatie en wacht. Blijft vragen totdat de gebruiker antwoordt. Dit is de enige stap die voor de gebruiker pauzeert.                                                                                                                                    |
| **Vertellen**        | Laat de agent iets in eigen woorden overbrengen en gaat vervolgens door naar de volgende stap.                                                                                                                                                                                   |
| **Zeggen**           | Laat de agent een exact bericht woord voor woord uitspreken en gaat vervolgens door naar de volgende stap. Een Zeggen-stap kan een afzonderlijk geconfigureerde vertaling bevatten voor elke taal die de agent ondersteunt.                                                      |
| **Tool**             | Roept een specifieke tool aan. Je kunt de LLM in gewone taal instrueren hoe de tool moet worden aangeroepen, of parameterwaarden expliciet vastleggen wanneer maximale determinisme vereist is. Je kunt ook stappen definiëren die worden uitgevoerd als de toolaanroep mislukt. |
| **Als**              | Evalueert één of meer voorwaarden op volgorde en voert de stappen van de eerste overeenkomst uit. Een optionele Anders wordt uitgevoerd wanneer niets overeenkomt.                                                                                                               |
| **Subprocedure**     | Voert een andere structured procedure uit. Wanneer de stappen zijn voltooid, gaat de besturing terug naar de volgende stap in deze (aanroepende) procedure.                                                                                                                      |
| **Systeemtool**      | Voert een ingebouwde systeemactie uit. Momenteel wordt alleen het beëindigen van het gesprek ondersteund.                                                                                                                                                                        |
| **Opnieuw proberen** | Voert de foutafhandeling van een Tool-stap, inclusief de toolaanroep, maximaal drie keer opnieuw uit. Alleen beschikbaar binnen de foutafhandeling van een Tool-stap.                                                                                                            |

![Menu met staptypen voor structured procedures](/docs/_fern-img/14976a6b9979d21fd7c77541a49e7475f8aa0764af4940746d3390804e7c4598.webp)

Niet elke stap kan overal voorkomen. Binnen een Als-tak kun je elke stap gebruiken behalve nog een Als of een Opnieuw proberen. Binnen de foutafhandeling van een Tool-stap kun je elke stap gebruiken behalve een Als of nog een Tool.

## API-referentie voor stappen

De `content` van een gestructureerde procedure is een JSON-gecodeerd document met een `steps`-array. Elke stap is een object dat wordt geïdentificeerd door zijn `type`. De trigger is een afzonderlijk veld op het hoogste niveau van de procedure, en maakt geen deel uit van `content`. API- en SDK-payloads gebruiken `type: "deterministic"` voor de procedure zelf.

### Ask

Een Ask-stap instrueert de agent om informatie te vragen en te wachten totdat de gebruiker een passend antwoord geeft.

* API-type: `ask`
* `instruction`: Vereiste, niet-lege string.

```json focus={1-4}
{
  "type": "ask",
  "instruction": "Ask the user for their order ID."
}
```

### Tell

Een Tell-stap instrueert de agent om één bericht in eigen woorden te genereren. De agent wacht niet op een reactie van de gebruiker voordat hij doorgaat.

* API-type: `tell`
* `instruction`: Vereiste, niet-lege string.

```json focus={1-4}
{
  "type": "tell",
  "instruction": "Explain that the refund normally takes five to ten business days."
}
```

### Say

Een Say-stap spreekt de aangeleverde tekst precies uit zoals deze is geschreven en gaat vervolgens door. Geef `message_translations` op om de agent een exact bericht te geven voor elke aanvullende taal die deze ondersteunt, met de taalcode als sleutel.

* API-type: `say`
* `message`: Vereiste, niet-lege string.
* `message_translations`: Optioneel object dat een taalcode koppelt aan `{ "value": "..." }`.

```json focus={1-7}
{
  "type": "say",
  "message": "Your refund has been submitted.",
  "message_translations": {
    "es": { "value": "Su reembolso ha sido enviado." }
  }
}
```

### If, else if en else

Een If-stap bevat een of meer geordende voorwaardelijke takken. De eerste overeenkomende tak wordt uitgevoerd. De optionele `fallback`-array is de Else-tak.

* API-type: `branch`
* `branches`: Vereiste, niet-lege lijst met voorwaardelijke takken.
* `fallback`: Optionele lijst met Else-stappen.
* Elke tak vereist een `condition` en een niet-lege lijst met `steps`.

```json focus={1-23}
{
  "type": "branch",
  "branches": [
    {
      "condition": {
        "type": "llm",
        "condition": "The user is on an annual plan."
      },
      "steps": [
        {
          "type": "say",
          "message": "Your annual plan is eligible for a prorated refund."
        }
      ]
    }
  ],
  "fallback": [
    {
      "type": "tell",
      "instruction": "Explain that the account's plan could not be determined."
    }
  ]
}
```

Dit werkt als if/else-if/else:

1. Voorwaarden worden op volgorde geëvalueerd.
2. De eerste overeenkomende tak wordt uitgevoerd.
3. Als geen voorwaarde overeenkomt, wordt `fallback` uitgevoerd.
4. Nadat een tak is voltooid, voegt de procedure zich weer bij de hoofdreeks.

Het bovenstaande voorbeeld gebruikt een tekstvoorwaarde, die het model in natuurlijke taal evalueert. Voorwaarden kunnen ook expressies zijn op dynamische variabelen:

```json focus={1-14}
{
  "type": "expression",
  "expression": {
    "type": "eq_operator",
    "left": {
      "type": "dynamic_variable",
      "name": "plan_tier"
    },
    "right": {
      "type": "string_literal",
      "value": "annual"
    }
  }
}
```

Een expressievoorwaarde test dynamische variabelen, die worden ingevuld door toolresultaten of ingesteld wanneer het gesprek begint. Deze kan het meest recente antwoord van de gebruiker niet lezen. Gebruik een tekstvoorwaarde om te vertakken op basis van wat de gebruiker zei.

Alle takken in één If-stap moeten hetzelfde voorwaardetype gebruiken: `llm` of `expression`.

### Tool

Een Tool-stap roept een specifieke tool aan.

* API-type: `tool_call`
* `tool_id`: Vereiste, niet-lege tool-ID. De tool moet aan de agent zijn gekoppeld.
* `tool_name`: Vereiste toolnaam die overeenkomt met de tool.
* `instruction`: Optionele instructie die beschrijft hoe de tool moet worden aangeroepen.
* `schema_overrides`: Optionele vaste waarden voor de parameters van de tool.
* `on_failure`: Optionele handler voor fouten.

```json focus={1-6}
{
  "type": "tool_call",
  "tool_id": "tool_abc123",
  "tool_name": "lookup_order",
  "instruction": "Look up the order using the order ID provided by the user."
}
```

#### Vaste parameterwaarden

Gebruik `schema_overrides` wanneer een parameter altijd een specifieke waarde moet hebben. Het model ziet of kiest een overschreven parameter niet. Sleutels zijn parameterpaden in het schema van de tool; elke waarde geeft een bron aan:

| `source`           | Velden               | Gedrag                                                             |
| ------------------ | -------------------- | ------------------------------------------------------------------ |
| `constant`         | `constant_value`     | Verstuurt altijd de opgegeven waarde.                              |
| `dynamic_variable` | `dynamic_variable`   | Verstuurt de huidige waarde van de benoemde dynamische variabele.  |
| `llm`              | `prompt` (optioneel) | Laat het model de waarde kiezen, met een optionele promptoverride. |
| `omit`             |                      | Laat de parameter weg uit de aanroep.                              |

```json focus={1-9}
{
  "type": "tool_call",
  "tool_id": "tool_abc123",
  "tool_name": "update_ticket",
  "schema_overrides": {
    "request_body.status": { "source": "constant", "constant_value": "pending" },
    "request_body.ticket_id": { "source": "dynamic_variable", "dynamic_variable": "ticket_id" }
  }
}
```

#### Foutafhandeling

Zonder `on_failure` beëindigt een mislukte toolaanroep het gesprek. Voeg in plaats daarvan `on_failure` toe om herstelstappen uit te voeren.

* `fallback`: Vereiste, niet-lege lijst met stappen die worden uitgevoerd wanneer de tool mislukt.
* `branches`: Gereserveerd voor voorwaardelijke foutafhandeling. Laat deze leeg.

```json focus={1-14}
{
  "type": "tool_call",
  "tool_id": "tool_abc123",
  "tool_name": "lookup_order",
  "on_failure": {
    "branches": [],
    "fallback": [
      {
        "type": "tell",
        "instruction": "Explain that the order could not be retrieved and offer to connect the user with support."
      }
    ]
  }
}
```

Een fouthandler mag Ask-, Tell-, Say-, Sub-procedure-, System tool- en Retry-stappen bevatten. Deze mag geen Tool- of If-stappen bevatten. Nadat de handler is uitgevoerd, gaat de procedure verder met de stap na de Tool-stap.

### Retry

Een Retry-stap voert de fouthandler waarin deze staat opnieuw uit, inclusief de toolaanroep. Elke poging roept de tool opnieuw aan en voert, als deze opnieuw mislukt, elke stap in de handler opnieuw uit. Wanneer alle pogingen zijn verbruikt, eindigt het gesprek.

* API-type: `retry`
* `max_retries`: Optioneel geheel getal van 1 tot en met 3. De standaardwaarde is 1.
* De waarde telt pogingen na de oorspronkelijke toolaanroep.
* Retry is alleen geldig binnen `on_failure`.
* Retry moet de laatste stap in de fouthandler zijn, omdat latere stappen onbereikbaar zouden zijn.

```json focus={1-4}
{
  "type": "retry",
  "max_retries": 2
}
```

### Sub-procedure

Een Sub-procedure-stap voert een andere gestructureerde procedure uit. Wanneer de stappen van die procedure zijn voltooid, keert de uitvoering terug naar de stap na de Sub-procedure-stap.

* API-type: `sub_procedure`
* `procedure_id`: Vereiste, niet-lege procedure-ID.
* Het doel moet bestaan op dezelfde agent.
* Het doel moet een gestructureerde procedure zijn.
* Een procedure kan zichzelf niet aanroepen.

```json focus={1-4}
{
  "type": "sub_procedure",
  "procedure_id": "agtprc_6qbpwdq8n01bxhk44bgjy6f10ck3"
}
```

### System tool

Een System tool-stap voert een ingebouwde systeemactie uit.

* API-type: `system_tool`
* `system_tool_name`: Vereiste naam van de systeemtool.
* Momenteel wordt alleen `end_call` ondersteund. Later kunnen meer systeemtools worden toegevoegd.
* Omdat `end_call` terminaal is, moet dit de laatste stap zijn in de reeks, tak of fouthandler waarin het staat.

```json focus={1-4}
{
  "type": "system_tool",
  "system_tool_name": "end_call"
}
```

## Validatieregels

Bij het publiceren van de agent of het opslaan van het agentconcept wordt een gestructureerde procedure geweigerd die een van deze regels overtreedt. De fout benoemt de betreffende stap met het bijbehorende pad.

* Twee If-stappen kunnen niet direct na elkaar worden geplaatst.
* If-stappen kunnen niet worden genest.
* Een If-stap met expressievoorwaarden kan niet direct na een Ask-stap volgen.
* Alle voorwaarden in één If-stap moeten hetzelfde type hebben: `llm` of `expression`.
* Retry mag alleen binnen `on_failure` staan en moet daar de laatste stap zijn.
* `end_call` moet de laatste stap zijn in de lijst waarin deze voorkomt.
* De `fallback` van een fouthandler moet ten minste één stap bevatten.
* Een Sub-procedure moet verwijzen naar een bestaande gestructureerde procedure op dezelfde agent, en niet naar zichzelf.
* `tool_id` moet een tool op de agent zijn, `tool_name` moet overeenkomen en `schema_overrides` moet overeenkomen met het schema van de tool.
* De lijst met `steps`, elke `instruction` en elk `message` mogen niet leeg zijn.

Zie [Best practices](#best-practices) voor informatie over het herstructureren van een procedure die tegen een van deze regels aanloopt.

## Volledig API-voorbeeld

Dit voorbeeld behandelt een orderannulering op basis van de verzendstatus. Het stelt een toolparameter vast in, herstelt van een mislukte toolaanroep, roept een andere gestructureerde procedure aan en beëindigt vervolgens het gesprek.

```json maxLines=30
{
  "steps": [
    {
      "type": "ask",
      "instruction": "Ask the user for their order ID."
    },
    {
      "type": "branch",
      "branches": [
        {
          "condition": {
            "type": "llm",
            "condition": "The user says the order has already shipped."
          },
          "steps": [
            {
              "type": "tell",
              "instruction": "Explain that shipped orders must be returned before they can be refunded."
            }
          ]
        },
        {
          "condition": {
            "type": "llm",
            "condition": "The user says the order has not shipped."
          },
          "steps": [
            {
              "type": "tool_call",
              "tool_id": "tool_abc123",
              "tool_name": "cancel_order",
              "instruction": "Cancel the order using the order ID provided by the user.",
              "schema_overrides": {
                "request_body.notify_customer": { "source": "constant", "constant_value": true }
              },
              "on_failure": {
                "branches": [],
                "fallback": [
                  {
                    "type": "tell",
                    "instruction": "Apologize that the cancellation did not go through and say you will try once more."
                  },
                  {
                    "type": "retry",
                    "max_retries": 1
                  }
                ]
              }
            }
          ]
        }
      ],
      "fallback": [
        {
          "type": "ask",
          "instruction": "Ask whether the order has already shipped."
        }
      ]
    },
    {
      "type": "sub_procedure",
      "procedure_id": "agtprc_6qbpwdq8n01bxhk44bgjy6f10ck3"
    },
    {
      "type": "say",
      "message": "Thank you for contacting us. Goodbye.",
      "message_translations": {
        "es": { "value": "Gracias por contactarnos. Adiós." }
      }
    },
    {
      "type": "system_tool",
      "system_tool_name": "end_call"
    }
  ]
}
```

## Hoe een gestructureerde procedure wordt uitgevoerd

Het omzetten van de stappen van een gestructureerde procedure naar de vorm die de agent uitvoert, heet compileren. Het platform compileert elke gestructureerde procedure wanneer het agentconcept wordt opgeslagen of de agent wordt gepubliceerd; auteurs hoeven zelf nooit iets te compileren. Het gecompileerde resultaat is momenteel zichtbaar als alleen-lezen nodes op het tabblad **Workflow**.

Wanneer het verzoek van de gebruiker overeenkomt met de trigger van een procedure, gaat de agent de procedure in en voert deze de stappen op volgorde uit. Binnen de gestructureerde procedure richt de agent zich op elke stap afzonderlijk. Wanneer de agent het einde bereikt, keert deze terug naar de rest van het gesprek.

De volgende regels beschrijven hoe stappen zich tijdens de uitvoering gedragen.

#### Alleen Ask wacht op de gebruiker

Elke stap behalve Ask wordt onmiddellijk uitgevoerd en de besturing gaat binnen dezelfde beurt naar de volgende stap. Een Tell- of Say-stap levert het bericht en gaat door. Er is geen andere stap dan Ask die het gesprek pauzeert en geen stap die de huidige beurt beëindigt. Als je invoer van de gebruiker nodig hebt, gebruik je een Ask-stap. Als het gesprek moet eindigen, gebruik je de `end_call`-systeemtool.

#### Het einde van een procedure bereiken beëindigt de beurt niet

Wanneer de laatste stap is voltooid, eindigt de procedure en keert de agent terug naar de rest van het gesprek terwijl de beurt nog open is, zodat deze meer kan zeggen. Wanneer een subprocedure is voltooid, keert de besturing terug naar de volgende stap van de procedure die deze heeft aangeroepen.

#### Tool-stappen maken alleen onderscheid tussen succes en mislukking

Een Tool-stap kan niet vertakken op een statuscode of de responsebody. Als de tool slaagt, gaat de procedure verder. Als deze mislukt en de stap geen fouthandler heeft, eindigt het gesprek. Als de stap er wel een heeft, worden de stappen van de handler uitgevoerd en gaat de procedure verder met de volgende stap. Een Retry in de handler voert de tool opnieuw uit en, als deze opnieuw mislukt, elke stap in de handler, totdat de tool slaagt of alle pogingen zijn verbruikt. Als ze zijn verbruikt, eindigt het gesprek.

#### If-stappen gaan door als niets overeenkomt

Voorwaarden worden op volgorde geëvalueerd en de eerste overeenkomst wordt uitgevoerd. De Else-tak wordt uitgevoerd als niets overeenkomt. Als er geen Else is en niets overeenkomt, gaat de procedure verder met de stap na de If. Een niet-afgehandeld geval is geen fout.

#### If-takken geven geen status door

Beslissingen binnen een If-tak worden niet onthouden door latere stappen. Als iets dat in een tak is geleerd later nodig is, sla het dan expliciet op met een toolaanroep of een dynamische variabele.

#### Ask-, Tell- en Say-stappen hebben geen tools

Alleen Tool-stappen kunnen tools aanroepen. Je hoeft een Ask-, Tell- of Say-stap niet te vertellen dat deze geen tools mag aanroepen; dat kan deze niet.

## Een gestructureerde procedure beheren

#### Bouwen via het dashboard

Open je agent in het [dashboard](https://elevenlabs.io/app/agents) en selecteer vervolgens **Procedures**.
Gebruik **+** om een gestructureerde procedure te maken. Voeg een trigger toe, selecteer een type voor elke stap en publiceer de wijzigingen aan de agent.

Het dashboard valideert gestructureerde procedures terwijl je deze bewerkt. Als een procedure een
[validatieregel](#validation-rules) overtreedt, toont de knop **Publish** een foutstatus, toont het
tabblad **Procedures** een foutbadge en kan de preview pas starten wanneer de procedure is
hersteld. Selecteer de foutindicator om te zien welke procedure en stap is getroffen.

![Editor voor gestructureerde procedures met de knop Publish in foutstatus en een badge met 1 Error](/docs/_fern-img/e406c33fac3966fab26d5d07e10d364a475fc4a56fd75aad2e23edbb0d1940d5.webp)

![Dialoogvenster met validatiedetails waarin de mislukte procedure en de stap die een bericht nodig heeft worden vermeld](/docs/_fern-img/a1cc889b2d0e68ce23725609b531938d0f7c417b1c6f4375103531eaae4ada63.webp)

#### Beheren via de CLI

De [ElevenLabs CLI](/docs/nl/eleven-agents/operate/cli) maakt en publiceert gestructureerde
procedures met dezelfde opdrachten als vrije procedures. Stel `type` in op `deterministic` en geef de
stappen door als een JSON-gecodeerde string in `content`.

```bash
CONTENT=$(jq -n '{
  trigger: "When the user asks to refund an order",
  steps: [{ type: "ask", instruction: "Ask for the order ID." }]
}')

elevenlabs agents procedures create \
  --agent-id agent_7101k5zvyjhmfg983brhmhkd98n6 \
  --branch-id agtbranch_0901k4aafjxxfxt93gd841r7tv5t \
  --json "$(jq -n --arg content "$CONTENT" '{
    name: "Refund request",
    type: "deterministic",
    trigger: "When the user asks to refund an order",
    content: $content
  }')"

elevenlabs agents update \
  --agent-id agent_7101k5zvyjhmfg983brhmhkd98n6 \
  --branch-id agtbranch_0901k4aafjxxfxt93gd841r7tv5t \
  --json '{"version_description": "Publish refund procedure"}'
```

Bij het publiceren worden alle gestructureerde procedures op de branch gevalideerd. Als er één ongeldig is, wordt de opdracht afgesloten met een niet-nulstatus en worden de fouten per procedure-ID weergegeven. Herstel het procedureconcept en publiceer opnieuw.

#### Beheren via de API

API- en SDK-payloads gebruiken `type: "deterministic"` voor gestructureerde procedures. Hun `content` is
een JSON-gecodeerd document.

### Vereisten

* Een ElevenLabs API-sleutel in de omgevingsvariabele `ELEVENLABS_API_KEY`.
* De doelwaarden voor `agent_id` en `branch_id`. Zie [Agentversiebeheer](/docs/nl/eleven-agents/operate/versioning) voor branchbewerkingen.
* Versie `2.60.0` of nieuwer van het Python-pakket `elevenlabs` of het JavaScript-pakket `@elevenlabs/elevenlabs-js`.

API-bewerkingen zijn op de geselecteerde branch privé voor jou totdat je een nieuwe agentversie publiceert.

### Een concept maken of bijwerken

Maak een gestructureerde procedure met `POST /procedures` en stel `type` in op `deterministic`.
Werk een bestaande procedure bij met `PATCH /procedures/{procedure_id}/draft`, zoals hieronder getoond.

Stel `trigger` in als veld op het hoogste niveau. JSON-codeer het stappendocument in `content` in plaats van
een genest object te verzenden.

```python focus={6-18}
import json
from elevenlabs import ElevenLabs

elevenlabs = ElevenLabs()

elevenlabs.conversational_ai.agents.procedures.drafts.update(
    agent_id="agent_7101k5zvyjhmfg983brhmhkd98n6",
    branch_id="agtbranch_0901k4aafjxxfxt93gd841r7tv5t",
    procedure_id="agtprc_6qbpwdq8n01bxhk44bgjy6f10ck3",
    name="Refund request",
    type="deterministic",
    trigger="When the user asks to refund an order",
    content=json.dumps(
        {
            "steps": [{"type": "ask", "instruction": "Ask for the order ID."}],
        }
    ),
)
```

```typescript focus={5-17}
import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";

const elevenlabs = new ElevenLabsClient();

await elevenlabs.conversationalAi.agents.procedures.drafts.update(
  "agent_7101k5zvyjhmfg983brhmhkd98n6",
  "agtbranch_0901k4aafjxxfxt93gd841r7tv5t",
  "agtprc_6qbpwdq8n01bxhk44bgjy6f10ck3",
  {
    name: "Refund request",
    type: "deterministic",
    trigger: "When the user asks to refund an order",
    content: JSON.stringify({
      steps: [{ type: "ask", instruction: "Ask for the order ID." }],
    }),
  }
);
```

```bash focus={1-9}
curl -X PATCH "https://api.elevenlabs.io/v1/convai/agents/agent_7101k5zvyjhmfg983brhmhkd98n6/branches/agtbranch_0901k4aafjxxfxt93gd841r7tv5t/procedures/agtprc_6qbpwdq8n01bxhk44bgjy6f10ck3/draft" \
  -H "xi-api-key: $ELEVENLABS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Refund request",
    "type": "deterministic",
    "trigger": "When the user asks to refund an order",
    "content": "{\"steps\":[{\"type\":\"ask\",\"instruction\":\"Ask for the order ID.\"}]}"
  }'
```

Het opslaan van een procedureconcept valideert de stappen niet. Validatie vindt plaats wanneer je publiceert of
wanneer je het agentconcept opslaat met `POST /v1/convai/agents/{agent_id}/drafts`.

### De wijzigingen publiceren

Publiceer met [Agent bijwerken](/docs/nl/api-reference/agents/update). Bij het publiceren worden alle
gestructureerde procedures op de branch gevalideerd en, als ze allemaal slagen, worden de procedures in de
nieuwe versie gepubliceerd. De request heeft geen veld `workflow` nodig.

```python focus={5-8}
from elevenlabs import ElevenLabs

elevenlabs = ElevenLabs()

elevenlabs.conversational_ai.agents.update(
    agent_id="agent_7101k5zvyjhmfg983brhmhkd98n6",
    branch_id="agtbranch_0901k4aafjxxfxt93gd841r7tv5t",
)
```

```typescript focus={5-7}
import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";

const elevenlabs = new ElevenLabsClient();

await elevenlabs.conversationalAi.agents.update("agent_7101k5zvyjhmfg983brhmhkd98n6", {
  branchId: "agtbranch_0901k4aafjxxfxt93gd841r7tv5t",
});
```

```bash focus={1-5}
curl -X PATCH \
  "https://api.elevenlabs.io/v1/convai/agents/agent_7101k5zvyjhmfg983brhmhkd98n6?branch_id=agtbranch_0901k4aafjxxfxt93gd841r7tv5t" \
  -H "xi-api-key: $ELEVENLABS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
```

Als een gestructureerde procedure ongeldig is, retourneert het publiceren `400` en wordt niets opgeslagen:

```json
{
  "detail": {
    "status": "procedure_validation_failed",
    "message": "Structured procedures failed validation.",
    "data": {
      "errors": {
        "agtprc_6qbpwdq8n01bxhk44bgjy6f10ck3": [
          {
            "path": "steps[0].ask.instruction",
            "message": "Step 1: Ask step requires an instruction"
          }
        ]
      }
    }
  }
}
```

`errors` heeft procedure-ID's als sleutel. Elke invoer noemt het mislukte veld en de mislukte stap. Herstel het
procedureconcept en publiceer opnieuw.

Zie [Procedures beheren](/docs/nl/eleven-agents/customization/procedures#manage-procedures) voor
gedrag bij het verwijderen en verwerpen van concepten, of de
[API-referentie voor procedures](/docs/nl/api-reference/agents/procedures/) voor volledige schema's van
endpoints.

## Best practices

Elk type stap heeft al zijn eigen gedrag, dus je hoeft dat zelden expliciet te vermelden. Beschrijf het doel van elke stap en laat het type stap de rest doen. De onderstaande richtlijnen behandelen de gevallen die belangrijk zijn om goed in te richten.

Volg [Een procedure itereren](/docs/nl/eleven-agents/customization/procedures/free-form-procedures#iterating-on-a-procedure) om een gestructureerde procedure te testen.

### Typen stappen kiezen

#### Stel één vraag per Ask-stap

Een Ask-stap wacht op één antwoord. Als je meerdere vragen in één instructie bundelt, heeft de
agent de neiging sommige over te slaan of samen te voegen. Gebruik één Ask-stap per gegeven.

#### Gebruik Tell voor mededelingen en Ask voor vragen

Een Tell-stap brengt de boodschap over en gaat verder zonder te wachten. Een Tell-stap die als vraag is geformuleerd,
krijgt nooit een antwoord. Als een stap een reactie van de gebruiker nodig heeft, is het een Ask-stap.

#### Geef een Ask-stap een duidelijke afsluitvoorwaarde als de vraag alleen niet genoeg is

Een Ask-stap gaat verder zodra deze een passend antwoord heeft. Als uit de vraag niet
duidelijk is wat als antwoord geldt, vermeld dat dan in de instructie, bijvoorbeeld \_Vraag om de bestel-ID; een geldige
ID bestaat uit acht cijfers \_.

#### Kies Tell voor formulering, Say voor exacte woorden

Gebruik een Tell-stap wanneer de agent de boodschap zelf moet formuleren, en een Say-stap wanneer de
tekst letterlijk of vertaald moet zijn. Beide versturen precies één bericht, dus je hoeft een stap niet
te instrueren om één bericht te versturen.

#### Zeg niet tegen stappen zonder tools dat ze tools moeten vermijden

Ask-, Tell- en Say-stappen kunnen geen tools aanroepen. *Roep geen tools aan* erin schrijven voegt ruis
toe aan de instructie zonder het gedrag te veranderen.

### De procedure structureren

#### Voeg geen opvulling toe tussen twee If-stappen

Twee If-stappen kunnen niet direct na elkaar worden geplaatst. Een niet-gerelateerde Tell- of Say-stap ertussen
plaatsen om aan de regel te voldoen, zorgt ervoor dat de agent iets zegt wat niet de bedoeling is. Neem in plaats daarvan de tweede beslissing
op in de eerste If-stap als extra Else if-takken, of verplaats deze naar een subprocedure.

#### Plaats geneste beslissingen in een subprocedure

If-stappen kunnen niet worden genest. Als een beslissing van een andere afhankelijk is, plaats je de interne beslissing in een
eigen gestructureerde procedure en roep je die aan met een Sub-procedure-stap vanuit de tak die deze nodig heeft.

#### Voeg een Else toe als 'geen van bovenstaande' belangrijk is

Een If-stap zonder Else gaat door naar de volgende stap wanneer niets overeenkomt. Als het niet-overeenkomende
geval zich anders moet gedragen, voeg je daarvoor een Else-tak toe.

#### Sla alles op wat een latere stap nodig heeft

Beslissingen die binnen een If-tak zijn genomen, worden daarna niet onthouden. Als een latere stap afhankelijk is van
iets dat in een tak is geleerd, leg dit dan in de tak vast met een toolaanroep of een dynamische variabele.

#### Plaats expressievoorwaarden na de tool die ze vult

Expressievoorwaarden testen dynamische variabelen. Plaats een If-stap die ze gebruikt direct na de Tool-
stap die deze variabelen instelt. Gebruik een tekstvoorwaarde om af te takken op basis van wat de gebruiker zei.

#### Haal gedeelde stappen naar een subprocedure

Wanneer meerdere gestructureerde procedures dezelfde reeks delen, zoals escaleren naar een medewerker, plaats je die
in één gestructureerde procedure met een lege trigger en roep je deze vanuit elke procedure aan. Gekopieerde reeksen
gaan na verloop van tijd uit elkaar lopen.

### Werken met tools

#### Voorzie een Tool-stap van een If-voorwaarde, niet van een instructie

Een Tool-stap roept altijd de bijbehorende tool aan. Een voorwaarde in de instructie, zoals \_sla dit over
als het ticket al is getagd \_, kan de aanroep niet voorkomen. Als de aanroep niet altijd moet
plaatsvinden, plaats je de voorwaarde in een If-stap vóór de Tool-stap.

#### Leg parameterwaarden vast in plaats van ze te beschrijven

Wanneer een parameter altijd een specifieke waarde moet hebben, stel je die in met een `constant`-override in
`schema_overrides`. Een instructie zoals *stel status altijd in op pending* vraagt het model om
hieraan te voldoen; een override wordt afgedwongen en kan niet worden overgeslagen.

#### Geef elke Tool-stap een foutafhandeling

Zonder `on_failure` beëindigt elke toolfout het gesprek. Voeg een handler toe die de gebruiker vertelt
wat er is gebeurd en opnieuw probeert, escaleert of doorgaat.

#### Beperk Tool-stappen tot de toolaanroep

Een Tool-stap voert alleen de tool uit; de agent kan daarin niet spreken of een beslissing nemen. Om met
de gebruiker te praten of af te takken op wat de tool teruggaf, plaats je dat in een aparte stap vóór of na de
Tool-stap.

### Instructies schrijven

#### Beschrijf alleen de huidige stap

De procedure bepaalt wat er daarna wordt uitgevoerd, en de agent is zich tijdens het uitvoeren van
de huidige stap niet bewust van latere stappen. Laat de stapvolgorde de volgordebepaling doen.

#### Probeer de beurt niet met tekst te beëindigen

Zinnen in stapinstructies, zoals *dit is het laatste bericht van deze beurt*, vragen
de agent om een grens af te dwingen die het platform niet kent. Gebruik een Ask-stap om op de gebruiker te wachten of
de systeemtool `end_call` om het gesprek te beëindigen.

#### Bewaar algemene regels in de systeemprompt

Toon, opmaak, afsluitingen en weigeringsbeleid horen in de [systeem- prompt](/docs/nl/eleven-agents/best-practices/prompting-guide). Een stapinstructie moet alleen vermelden
wat specifiek is voor die stap.

### Procedures combineren

De algemene richtlijnen voor het combineren van procedures gelden ook voor gestructureerde procedures; zie [Procedures combineren](/docs/nl/eleven-agents/customization/procedures/free-form-procedures#composing-procedures) op de pagina over free-form procedures.

Eén patroon is specifiek voor het combineren van typen: een free-form procedure kan verwijzen naar een gestructureerde procedure. Houd open afhandeling in een free-form procedure en delegeer de onderdelen die altijd op dezelfde manier moeten worden uitgevoerd, zoals identiteitsverificatie of escalatie, aan een gestructureerde procedure.

## Beperkingen

* If-stappen kunnen niet worden genest en twee If-stappen kunnen niet direct na elkaar worden geplaatst.
* De enige ondersteunde systeemtool is `end_call`.
* Gestructureerde procedures kunnen niet verwijzen naar kennisbankdocumenten.
* Er is geen manier om de huidige beurt te beëindigen wanneer een procedure is voltooid; de agent houdt de beurt open en kan blijven spreken.
* Een gestructureerde procedure kan niet worden gestart vanuit een specifiek workflowknooppunt in het dashboard.
* Het starten van een procedure voegt vertraging toe: de agent doet een toolaanroep om deze te openen en doorloopt vervolgens de gegenereerde workflow.

### Ondersteuning door modelproviders

Gestructureerde procedures dwingen interne toolaanroepen af bij het openen van een subprocedure en het voltooien van een procedure. De belangrijkste modelfamilies van OpenAI, Anthropic, Gemini en Grok ondersteunen geforceerde toolkeuze. Andere modellen of aangepaste providers garanderen dit mogelijk niet, waardoor overgangen naar subprocedures of het voltooien van procedures minder betrouwbaar kunnen zijn. Controleer ondersteuning voor geforceerde toolkeuze wanneer je een andere modelprovider gebruikt.

Zie [Procedures](/docs/nl/eleven-agents/customization/procedures#limitations) voor limieten die op alle procedures van toepassing zijn, waaronder de limiet voor contentgrootte en de verschillen tussen gestructureerde en free-form procedures.