---
title: "Agentsteg och överlämningar"
description: "Dela upp en agent i steg med egna instruktioner, verktyg och insamlade värden, och överlämna samtal mellan agenter mitt under samtalet."
---

En enda prompt ger modellen hela uppgiften på en gång. **Steg** ger den en
fas i samtalet i taget: varje steg har egna instruktioner, egna verktyg,
en valfri rad som sägs ordagrant och värden som den måste samla in innan den går
vidare. **Överlämningar** låter en annan agent i din organisation ta över mitt i
samtalet, med transkriptionen intakt, så att uppringaren aldrig behöver upprepa sig.

Varje agent börjar som en enda prompt. Ingenting med den ändras förrän du lägger till
steg eller överlämningar.

## Steg eller en enda prompt?

| Använd steg när | Behåll en enda prompt när |
| --- | --- |
| Samtalet har faser som måste ske i ordning: verifiera, sedan boka. | Konversationen är öppen: vanliga frågor, reception, allmän support. |
| Ett värde måste samlas in innan agenten går vidare. | Ingenting behöver samlas in i en fast ordning. |
| En regel aldrig får frångås, till exempel ”uppringare under 18 går till en vårdnadshavare”. | Modellens bedömning är tillräckligt bra för varje gren. |
| En uppslagning måste köras vid en bestämd punkt i samtalet. | Verktyg kan anropas när uppringaren ber om det. |
| En del av samtalet tillhör en annan agent, med egen prompt och röst. | En persona hanterar allt. |

Steg är inte en skriptad telefonmeny. I ett steg driver modellen
konversationen på samma sätt som med en enda prompt. Steget avgör vad den
arbetar med, vilka verktyg den kan använda och vad den behöver innan den kan lämna det.

## Så byggs en agent med steg

När en agent har steg innehåller dess `prompt` de **delade instruktionerna**:
personan och reglerna som gäller i varje steg. Varje steg lägger till sina egna
instruktioner ovanpå dessa. Vid varje tur ser modellen de delade instruktionerna,
det aktuella stegets namn och instruktioner samt de värden som har samlats in hittills.

I byggaren växlar du agenten från **En enda prompt** till **Steg**. Du får ett
kort per steg med namn, instruktioner, sägrad, verktyg, insamlade värden
och övergångar, en väljare för överlämningar samt ett skrivskyddat flödesdiagram över stegen.
När du växlar tillbaka till en enda prompt erbjuds en sammanfogad prompt som sammanför de
delade instruktionerna och varje steg.

Via API:t är `steps` och `handoffs` fält på
[agenten](/api-reference/agents). Precis som alla agentfält förbereder en `PATCH`
dem i utkastet; `POST /v1/agents/{agent_id}/deploy` publicerar dem. Om du skickar
`"steps": null` växlar agenten tillbaka till en enda prompt. Testsamtal och
**Prata** kör utkastet.

<Tip>
  [Copiloten](/sv/guides/ask-the-copilot) kan skapa steg från en beskrivning
  (”lägg till ett steg som verifierar födelsedatum före bokning”) och redigera ett steg
  utan att påverka de andra.
</Tip>

### Stegfält

| Fält | Betydelse |
| --- | --- |
| `id` | Krävs. Små bokstäver, siffror och understreck, börjar med en bokstav, upp till 40 tecken. Unikt inom agenten. |
| `name` | Obligatoriskt visningsnamn, 1 till 80 tecken. |
| `instructions` | Krävs, upp till 20 000 tecken. Stöder `{{var}}` [samtalsvariabler](/sv/guides/call-variables), precis som `prompt`. |
| `say` | Valfri rad som sägs ordagrant när steget öppnas, upp till 1 000 tecken. Stöder `{{var}}`. |
| `tools` | `null` ger steget alla verktyg som är kopplade till agenten. En lista begränsar steget till dessa verktyg, efter namn. Inbyggda åtgärder som `end_call` och `transfer_call` följer agentens inställningar i varje steg. |
| `collect` | Upp till 20 värden som steget samlar in. Varje värde har `name`, `type`, `description` och `required` (standardvärdet är `true`). |
| `on_enter_tool` | Valfritt verktygsnamn som anropas automatiskt när steget öppnas. Se [Webhook-steg](#webhook-steps). |
| `transitions` | Ordnad lista över vart steget kan gå härnäst. Se [Övergångar](#transitions). |
| `global_when` | Valfritt. Gör steget tillgängligt från alla steg. Se [Globala steg](#global-steps). |
| `voice` | Valfritt röst-id för detta steg. Ignoreras när agenten använder en anpassad röstkonfiguration. |

Diagrammet i sig är `{"start_step": "<step id>", "steps": [...]}`. Samtalet
börjar i `start_step`.

## Övergångar

Varje övergång har `to`, ett steg-id, och exakt ett av följande:

- **`when`**: vanligt språk, och **modellen avgör**. Agenten får ett
  inbyggt verktyg, `go_to_step`, som listar de steg den kan gå till, där varje
  `when` anger skälet att välja det.
- **`condition`**: en regel för insamlade värden, och **kod avgör**. Modellen
  kan inte hoppa över den eller prata sig runt den.
- **`"always": true`**: gå vidare utan kontroll. Koden avgör först: så snart
  ett steg öppnas, eller när dess obligatoriska värden har samlats in, väljs
  den första matchande `condition`- eller `always`-övergången innan modellen
  kan välja en `when`. Placera därför `always` efter villkoren som reserv, eller
  ensamt för att kedja ett steg direkt till nästa. Ett steg med `always` väntar
  aldrig på ett `when`-val.

En `condition` är `{"value": <collected name or dotted path>, "op": <op>, "target": <literal>}`:

| `op` | Sant när värdet |
| --- | --- |
| `eq`, `ne` | är lika med, eller inte lika med, `target` |
| `lt`, `lte`, `gt`, `gte` | är mindre än, högst, större än eller minst `target` |
| `in`, `not_in` | är, eller inte är, ett av värdena i listan `target` |
| `exists`, `missing` | har, eller inte har, samlats in (ingen `target`) |

`eq`, `ne`, `in` och `not_in` jämför text utan hänsyn till versaler och gemener
efter att mellanslag har tagits bort. Tal jämförs som tal och datum som
`YYYY-MM-DD`-strängar. Ett värde som aldrig samlades in gör varje op falskt,
utom `missing`.

Skriv `when` och `global_when` som ett villkor, till exempel "Uppringaren vill
boka en tid", inte som något som ska sägas. Agenten ser dem som interna
routningsanteckningar och instrueras att aldrig läsa upp dem eller nämna att
den byter steg.

När modellen anropar `go_to_step`:

1. Alla `required`-värden i steget måste finnas. Om ett saknas får modellen
   veta vilket det är och frågar uppringaren efter det.
2. Värdena lagras.
3. `condition`- och `always`-övergångar kontrolleras i ordning. Den första
   matchningen väljs.
4. Annars går agenten till steget som modellen valde.
5. Om inget matchar och modellen inte angav något steg stannar agenten där den är.

Ett hopp till ett [globalt steg](#global-steps) är undantaget: uppringaren har
bytt ämne, så det genomförs även när det aktuella steget fortfarande har
obligatoriska värden som saknas, och innan stegets villkor kontrolleras.

`condition`- och `always`-övergångar kontrolleras också varje gång ett steg
öppnas, så en serie kodstyrda steg genomförs i ett svep. Kedjan stoppas:

- vid ett steg som den redan har besökt i den här körningen;
- efter 8 hopp;
- vid ett steg som fortfarande har obligatoriska värden att samla in, om inte
  steget har ett `on_enter_tool` (ett webhook-steg routas alltid utifrån sitt resultat).

Endast raden `say` i steget där kedjan stoppas sägs upp.

Ett steg utan övergångar är **slutgiltigt**. Agenten avslutar där och avslutar
eller kopplar vidare samtalet med sina vanliga inbyggda åtgärder.

## Samla in värden

Lista vad ett steg behöver i `collect`. Modellen skickar värdena när den anropar
`go_to_step`, och de är tillgängliga under resten av samtalet.

| `type` | Innehåller |
| --- | --- |
| `string` | Valfri text |
| `number` | Ett tal |
| `boolean` | `true` eller `false` |
| `date` | Ett datum som `YYYY-MM-DD` |

Insamlade värden är samtalsinnehåll. De visas vid samtalet bredvid
transkriptionen och följer samma regler för lagringstid, radering och
maskering. När agentens samtalsinspelning är avstängd lagras insamlade värden
varken eller skickas i webhooks; stegets tidslinje finns fortfarande kvar. Se
[Var du ser det i ett samtal](#where-to-see-it-on-a-call).

## Säg-repliker

`say` uttalas exakt som det skrivs när agenten går in i steget. Modellen
fortsätter sedan i det nya steget i samma svar, med vetskap om att repliken
just har sagts, så den upprepar den inte. Använd `say` för hälsningar,
obligatoriska meddelanden och fasta formuleringar, och låt modellen hantera
resten av svaret.

Startstegets `say` är agentens inledande replik när den talar först, efter
eventuella samtyckesmeddelanden. När uppringaren talar först inleder den
agentens första svar till en person, aldrig till ett IVR-system eller en
röstmeddelandehälsning.

Ett stegs `say` uttalas inte igen när samtalet återvänder till det via
`__previous__` eller en återlämning. Skriv det så som det ska låta: skriv ut
allt som rösten kan misstolka. Säg-repliker stöder samtalsvariabler som
`{{var}}`, men inte insamlade värden.

## Webhook-steg

Ange `on_enter_tool` som ett av agentens verktyg, så körs det så snart steget
öppnas utan att vänta på modellen. Dess argument är de insamlade värden vars
namn matchar verktygets parameternamn. Resultatet lagras som ett insamlat värde
med namnet `<tool>_result`, trunkerat till 4 KB, och stegets övergångar för
`condition` och `always` kontrolleras direkt, så uppslaget kan dirigera
samtalet baserat på sitt eget resultat.

Det lagrade värdet har två fält:

| Fält | Innehåller |
| --- | --- |
| `status` | HTTP-statuskoden som din slutpunkt returnerade. |
| `response` | Svarstexten. |

Dirigera baserat på ett fält i svaret med `lookup_account_result.response.<field>`, och baserat på
statuskoden med `lookup_account_result.status`.

Uppslaget körs i upp till 8 sekunder, eller verktygets egen tidsgräns om den
är kortare. Om det tar längre än 3 sekunder säger agenten en kort replik så
att uppringaren inte lämnas i tystnad. Om din slutpunkt returnerar status 400
eller högre, eller inte svarar i tid, berättar agenten för uppringaren att den
inte kunde kontrollera det just nu och fortsätter med det den kan göra.

## Globala steg

Ett steg med `global_when` kan nås från vilket steg som helst när den
beskrivningen stämmer. Modellen avgör detta, precis som med `when`. Använd det
för ämnen som en uppringare kan ta upp när som helst: faktureringsfrågor, en
begäran om en människa eller ett klagomål.

En övergång med `"to": "__previous__"` i ett globalt steg återför samtalet till
steget som var aktivt före det, så att uppringaren fortsätter där den slutade.
Steget återupptas: dess `on_enter_tool` körs inte igen, dess `say` upprepas
inte och agenten fortsätter utan att börja om.

## Överlämningar

`handoffs` listar andra agenter i din organisation som kan ta över samtalet:

```json
[{"agent_id": 413, "when": "The caller asks about billing or a refund"}]
```

Agenten får ett inbyggt `hand_off`-verktyg med dessa agenter och anledningar. Precis
som med övergångar är varje `when` en intern routningsanteckning som aldrig läses upp.

När agenten lämnar över säger den en kort rad som berättar för uppringaren vart de
kopplas, till exempel "Absolut, jag kopplar dig till vårt faktureringsteam", med sin egen
röst. Sedan tar målagentens prompt, steg, verktyg och röst över och samtalet fortsätter
med samma transkript. Den nya agenten presenterar sig kort och besvarar uppringarens
senaste begäran; den meddelar inte att ett samtal har överlämnats. Målagentens
kunskapsbas är tillgänglig från och med då.

Första gången ett samtal når en agent startar det i agentens
`start_step`: stegets `on_enter_tool` körs och dess `say` läses upp. När samtalet
lämnas tillbaka till en agent som det redan har besökt återupptar agenten steget
den var på, utan att köra `on_enter_tool`, upprepa sitt `say` eller presentera sig
igen. Insamlade värden delas av alla agenter i samtalet.

- Ett mål måste vara en agent i samma organisation, och en agent kan inte lämna
  över till sig själv.
- Allt på samtalsnivå stannar hos agenten som svarade: produkt,
  språk, vem som talar först, röstbrevlåda, samtyckesmeddelande och alla andra
  samtalsinställningar.
- Mål kan lämna över vidare och tillbaka. Ett samtal kan nå upp till 8 agenter.
- Ett testsamtal kör utkastet för agenten du testar. Agenterna som den lämnar över till
  kör sina driftsatta versioner.
- Om två agenter har ett verktyg med samma namn och olika definitioner behålls bara
  ett för samtalet, och den svarande agentens version har alltid företräde. Byggaren
  varnar dig när du sparar.
- En agent kan ha överlämningar utan steg. Hela dess prompt används i befintligt skick.

`go_to_step` och `hand_off` är reserverade för agenter med steg eller överlämningar, så
dina egna verktyg kan inte använda dessa namn.

## Var du ser det i ett samtal

Öppna samtalet i **Samtalshistorik**. En tidslinje över steg bredvid transkriptet visar
varje steg som samtalet gick in i och varför, och de insamlade värdena listas tillsammans
med den.

[Anropsobjektet](/api-reference/calls#retrieve-a-call) och webhooken för avslutat samtal
([`telephony.complete` / `web.complete`](/sv/webhooks/call-complete)) innehåller
samma data som `steps_trace` och `collected_values`. Båda saknas i samtal
utan steg.

```json
"steps_trace": [
  {"t_ms": 0, "agent": "a412", "step": "greet", "via": "start"},
  {"t_ms": 51230, "agent": "a412", "step": "verify", "via": "model"},
  {"t_ms": 98410, "agent": "a412", "step": "minor", "via": "condition"}
],
"collected_values": {"full_name": "Dana Reyes", "dob": "2010-04-02", "age": 15}
```

`agent` är `a` följt av agent-id:t. `via` anger vad som flyttade samtalet:

| `via` | Betydelse |
| --- | --- |
| `start` | Samtalet började i detta steg. |
| `model` | Modellen valde steget via `go_to_step`, en `when` eller en `global_when`. |
| `condition` | En `condition`- eller `always`-övergång matchade. |
| `on_enter` | En övergång matchade resultatet från ett webhook-steg. |
| `handoff` | En annan agent tog över. |

## Var steg körs

Steg körs inbyggt på **Spark**, **Bolt** och alla **Storm**-produkter, för
inkommande, utgående och kampanjsamtal, testsamtal samt webb- och widgetsamtal.

Överallt annars fungerar agenten fortfarande, men utan strukturen: den kör en
sammanplattad prompt som slår ihop de gemensamma instruktionerna och varje steg, i ordning.
Det omfattar:

- de experimentella Bolt-produkterna;
- [Realtime](/sv/guides/use-with-openai-realtime)-sessioner, inklusive sessioner
  för en sparad agent;
- infogade konfigurationer som returneras av en webhook för
  [dynamisk samtalskonfiguration](/sv/guides/dynamic-call-config). En webhook som returnerar ett
  `agent_id` använder den agentens steg.

## Gränser

| Gräns | Värde |
| --- | --- |
| Steg per agent | 100 |
| Insamlade värden per steg | 20 |
| Överlämningsmål per agent | 8 |
| Agenter som kan nås i ett samtal | 8 |
| Storlek på `steps`-JSON | 200 KB |
| Stegets `instructions` | 20 000 tecken |
| `say`-rad | 1 000 tecken |
| Lagrad `on_enter_tool`-resultat | 4 KB |

En sparning som bryter mot en regel returnerar `400` med sökvägen till det
felaktiga fältet, till exempel `steps.steps[2].transitions[0].to`. Verktygsnamn i `tools` och
`on_enter_tool` måste vara verktyg som är kopplade till agenten.

Språk per steg, skriptade steg som hoppar över modellen och insamlade värden
i say-rader stöds inte.

## Importerade agenter

[Import](/sv/guides/import-agents) från Retell, Bland, Vapi eller ElevenLabs
för över agenter med flera promptar, flöden, sökvägar och arbetsflöden som steg,
och squads samt agentöverföringar som överlämningar mellan de importerade agenterna. Granskningssidan visar båda innan du importerar.

## Exempel: tandvårdsregistrering

Tre steg i ordning: hälsa, samla in patientens uppgifter, boka.

```json
{
  "prompt": "You are Ava, the front desk assistant at Acme Dental. Be warm and brief. Ask one question at a time.",
  "steps": {
    "start_step": "greet",
    "steps": [
      {
        "id": "greet",
        "name": "Greeting",
        "instructions": "Greet the caller and ask how you can help.",
        "say": "Thanks for calling Acme Dental, this is Ava. How can I help you today?",
        "tools": null,
        "collect": [],
        "transitions": [
          {"to": "details", "when": "The caller wants to book an appointment"}
        ]
      },
      {
        "id": "details",
        "name": "Patient details",
        "instructions": "Ask for the caller's full name, date of birth and the reason for the visit. Read the date of birth back and ask the caller to confirm it.",
        "tools": null,
        "collect": [
          {"name": "full_name", "type": "string", "description": "Caller's full name", "required": true},
          {"name": "dob", "type": "date", "description": "Date of birth", "required": true},
          {"name": "reason", "type": "string", "description": "Reason for the visit", "required": true},
          {"name": "new_patient", "type": "boolean", "description": "First visit to the practice", "required": false}
        ],
        "transitions": [
          {"to": "book", "when": "The caller has confirmed their details"}
        ]
      },
      {
        "id": "book",
        "name": "Book",
        "instructions": "Offer the two earliest open slots from book_slot and book the one the caller picks. Confirm the date and time, then say goodbye and end the call.",
        "tools": ["book_slot"],
        "collect": [],
        "transitions": []
      }
    ]
  }
}
```

Förbered den med `PATCH /v1/agents/{agent_id}`, testa den med **Prata** och driftsätt sedan.
Steget `details` kan inte lämna över till bokning förrän namn, födelsedatum
och anledning har samlats in. `new_patient` är valfritt.

## Exempel: en gren med åldersgräns

Modellen kan prata med vem som helst, men kod avgör vem som bokas. Samla in
åldern och dirigera sedan utifrån den innan modellens eget val övervägs.

```json
{
  "id": "verify",
  "name": "Verify age",
  "instructions": "Ask for the caller's age.",
  "tools": null,
  "collect": [
    {"name": "age", "type": "number", "description": "Caller's age in years", "required": true}
  ],
  "transitions": [
    {"to": "guardian", "condition": {"value": "age", "op": "lt", "target": 18}},
    {"to": "book", "when": "The caller has given their age"}
  ]
}
```

En uppringare som säger femton går till `guardian`, oavsett vad modellen beslutar.
Alla andra går till `book`. Båda är vanliga steg på andra ställen i grafen.

## Exempel: webhooksteg för kontosökning

Uppringaren anger ett kontonummer, sökningen körs när nästa steg öppnas
och resultatet väljer vägen. Stegen `not_found`, `collections` och `support`
utelämnas för korthetens skull.

```json
[
  {
    "id": "identify",
    "name": "Identify",
    "instructions": "Ask for the caller's account number and read it back digit by digit.",
    "tools": null,
    "collect": [
      {"name": "account_number", "type": "string", "description": "Account number", "required": true}
    ],
    "transitions": [
      {"to": "lookup", "when": "The caller has confirmed their account number"}
    ]
  },
  {
    "id": "lookup",
    "name": "Look up account",
    "instructions": "Tell the caller what you found on their account and ask how you can help.",
    "tools": ["lookup_account"],
    "collect": [],
    "on_enter_tool": "lookup_account",
    "transitions": [
      {"to": "not_found", "condition": {"value": "lookup_account_result.response.found", "op": "eq", "target": false}},
      {"to": "collections", "condition": {"value": "lookup_account_result.response.account_status", "op": "in", "target": ["past_due", "suspended"]}},
      {"to": "support", "when": "The caller needs help with an active account"}
    ]
  }
]
```

`lookup_account` tar emot `account_number` eftersom dess parameter har det
namnet. Om svarstexten innehåller `"found": false` går samtalet till
`not_found`. Om dess `account_status` är `past_due` eller `suspended` går det till
`collections`. Ett aktivt konto stannar i `lookup`, där modellen hjälper till och
går vidare till `support`. Om du vill skicka en misslyckad sökning till ett eget steg lägger du till
villkor för statusen först: ett felsvar lagrar sin statuskod, så
`{"value": "lookup_account_result.status", "op": "gte", "target": 400}`
fångar det, och en timeout eller inget svar lagrar `"error"`, så
`{"value": "lookup_account_result.status", "op": "eq", "target": "error"}`
fångar det.

## Exempel: reception till fakturering

Två agenter. Receptionen (agent `412`) svarar på alla samtal och lämnar över frågor
om fakturering till en faktureringsagent (agent `413`) med egen prompt, egna verktyg och röst.

I receptionen:

```json
{
  "handoffs": [
    {"agent_id": 413, "when": "The caller asks about a bill, a payment or a refund"}
  ]
}
```

På faktureringsagenten, så att den kan lämna tillbaka uppringaren:

```json
{
  "handoffs": [
    {"agent_id": 412, "when": "The billing question is resolved and the caller needs something else"}
  ]
}
```

Receptionen säger en kort rad, till exempel "Jag kopplar dig till vårt
faktureringsteam", och faktureringsagenten presenterar sig och fortsätter samtalet
där receptionen slutade. När faktureringen lämnar tillbaka återupptar
receptionen där den var, utan att hälsa på uppringaren igen. Samtalets produkt,
språk, samtyckesmeddelande och andra samtalsinställningar stannar hos
receptionen, eftersom den svarade.

Om faktureringen bara behöver egna instruktioner och inte en egen agent använder du i stället ett
globalt steg i receptionen. När frågan har besvarats återgår samtalet till det steg
som uppringaren befann sig i:

```json
{
  "id": "billing",
  "name": "Billing questions",
  "instructions": "Answer questions about bills and payments. Offer to send a payment link by email.",
  "tools": null,
  "collect": [],
  "transitions": [
    {"to": "__previous__", "when": "The billing question is answered"}
  ],
  "global_when": "The caller asks about a bill or payment at any point"
}
```

## Nästa steg

<CardGroup cols={2}>
  <Card title="Guide för promptning" icon="pen" href="/sv/guides/prompting">
    Skriv gemensamma instruktioner och steginstruktioner som fungerar i telefon.
  </Card>
  <Card title="Bygg en verktygsintegration" icon="code" href="/sv/guides/build-tool-integration">
    Skapa de verktyg som dina steg och webhook-steg anropar.
  </Card>
  <Card title="Testa dina agenter" icon="flask" href="/sv/guides/test-agents">
    Kör samma scenarier mot varje gren innan du distribuerar.
  </Card>
  <Card title="Agents API" icon="robot" href="/api-reference/agents">
    Alla agentfält, utkast och distributioner.
  </Card>
</CardGroup>
