Workflows als code
Bouw, bewerk en versiebeheer agentworkflows met de Python- en JavaScript-SDK’s
Overzicht
Een workflow wordt opgeslagen als een graaf van nodes en edges. Als je die graaf met de hand schrijft, moet je zelf zorgen dat edge-ID’s, lijsten met edge_order en voorwaardeobjecten consistent blijven. Met de Workflow-builder in de Python- en JavaScript-SDK’s kun je dezelfde graaf beschrijven met gekoppelde methodeaanroepen. Vervolgens produceert deze de waarde workflow die agents.create() en agents.update() al accepteren.
Gebruik dit om:
- Een workflow in code te bouwen en deze te beoordelen zoals elke andere codewijziging.
- De workflow van een agent te laden, één node te wijzigen en deze terug te sturen zonder de rest van de graaf te verstoren.
- Workflows als JSON op te slaan in versiebeheer en ze te valideren in CI.
De builder wordt volledig in de SDK uitgevoerd. Hij roept geen nieuwe API-endpoints aan en alles wat hij bouwt kan worden geopend en bewerkt in de visuele editor van het dashboard.
Vereisten
- Python: het pakket
elevenlabs. De builder wordt geïmporteerd vanuitelevenlabs.agent_workflows. - JavaScript: het pakket
@elevenlabs/elevenlabs-js. De builder wordt geëxporteerd vanuit de hoofdmap van het pakket.
Een workflow bouwen
Het object Workflow staat voor de startnode. Elk werkwoord voegt een node toe en retourneert deze, zodat je vanaf daar de volgende stap kunt koppelen:
De routeringsmethoden bepalen welke edge naar de volgende node leidt:
Werkwoorden die rechtstreeks op de workflow worden aangeroepen, vertakken vanaf de startnode met een onvoorwaardelijke edge. Dit voorbeeld routeert bellers naar het opzoeken van een bestelling, probeert identificatie opnieuw als het opzoeken mislukt en transfereert VIP-bellers of gefrustreerde bellers:
build() valideert de hele graaf en retourneert het requestmodel. Het doet ook het volgende:
- Geeft de startnode de ID
start_node, die de API vereist. - Genereert edge-ID’s in de vorm
source__target. - Vult de
edge_ordervan elke node in de volgorde waarin je de edges hebt toegevoegd. - Positioneert elke node zonder positie, zodat de graaf van links naar rechts wordt weergegeven in de visuele editor.
Een workflow als één keten schrijven
up() retourneert de node waarvan de huidige node is gekoppeld, zodat je een hele workflow in één expressie kunt beschrijven in plaats van elke node in een variabele te bewaren. Gebruik binnen één keten go_to() / goTo() met een node-ID, omdat er geen variabele is om door te geven:
Voor een node-handle van wf.node(id) retourneert up() de node waar de eerste inkomende edge vandaan komt. Voor de startnode retourneert deze de startnode.
Nodeopties
Optionele instellingen geef je in Python door als keyword-argumenten en in JavaScript in een afsluitend options-object. De namen komen overeen met de velden van de node in de API:
Elk werkwoord accepteert ook position als je de node zelf wilt plaatsen. Workflow(prevent_subagent_loops=True) in Python, of new Workflow({ preventSubagentLoops: true }) in JavaScript, voorkomt dat het gesprek opnieuw een subagent binnenkomt die het al heeft bezocht.
Transferbestemmingen
Voorwaarden
when() accepteert een gewone string, een Condition of een Expr:
- Een string is een LLM-voorwaarde: de LLM bepaalt of deze geldt.
Condition.llm(text, label=...)is hetzelfde, met een label dat op de edge in de visuele editor wordt weergegeven. GebruikCondition.expr(expr, label=...)om een expressie van een label te voorzien.- Een
Exprwordt geëvalueerd aan de hand van dynamische variabelen, zonder de LLM aan te roepen.
Bouw expressies op uit Expr.variable(name) en Expr.literal(value). Vergelijk ze met eq, neq, gt, gte, lt en lte, en voer rekenkundige bewerkingen uit met add, sub, mul en div. Combineer ze met all_of / allOf, any_of / anyOf en if_else / ifElse. Gewone waarden worden automatisch verpakt in Expr.literal(). Expr.llm(description) vraagt de LLM een waarde uit het gesprek te halen; geef type en enum door om een string, een getal of een van een vaste reeks waarden te krijgen in plaats van een boolean.
Loops en achterwaartse edges
De API staat één edge tussen twee willekeurige nodes toe, in beide richtingen. Om het gesprek langs dezelfde weg terug te laten gaan, geef je de edge met back een achterwaartse voorwaarde:
go_to() / goTo() handelt het veelvoorkomende geval voor je af. Wanneer de doelnode al een edge heeft die hierheen leidt, wordt de nieuwe edge de achterwaartse voorwaarde van die edge. In het eerste voorbeeld wordt failed.go_to(identify) verzonden als de achterwaartse voorwaarde van de edge identify → lookup_order. Elke andere tweede edge tussen dezelfde twee nodes, en elke edge van een node naar zichzelf, faalt bij validatie.
Een bestaande agent bewerken
Workflow.from_agent() / Workflow.fromAgent() laadt de workflow van een agent die is geretourneerd door agents.get(). Node-ID’s, edge-ID’s, editorposities en edgevolgorde blijven behouden, dus door deze terug te sturen wijzig je alleen wat je hebt gewijzigd.
insert_between() / insertBetween() geeft aan je functie een vertakking door die de voorwaarde van de vervangen edge bevat. De functie retourneert de laatste node die deze heeft toegevoegd, die vervolgens met het oorspronkelijke doel wordt verbonden. De methode retourneert die node, of None / undefined als er geen edge tussen de twee nodes is.
Workflows opslaan in versiebeheer
to_json_string() / toJSONString() schrijft de workflow in het wire format van de API: snake_case-sleutels, op elk niveau gesorteerd, met inspringing van 2 spaties. Het heeft dezelfde vorm als de REST API en de CLI gebruiken, en beide SDK’s schrijven voor dezelfde workflow byte voor byte identieke bestanden, zodat verschillen klein blijven. Workflow.from_json() / Workflow.fromJSON() leest het weer in en accepteert ook een volledige agentconfiguratie met een sleutel workflow, zoals een bestand in de map agent_configs/ van de CLI.
Een gebruikelijke opzet:
Het bestand voorbereiden
Laad de agent met from_agent() / fromAgent() en schrijf deze weg, of haal deze op met elevenlabs agents pull.
Bewerken
Wijzig de JSON rechtstreeks, of laad deze met from_json() / fromJSON() en bewerk deze met de
builder in een script.
Een workflow visualiseren
De CLI tekent een workflowbestand als stroomdiagram, zodat je kunt controleren wat je code heeft gebouwd zonder het dashboard te openen. De CLI accepteert een los workflowbestand dat is geschreven door to_json_string() / toJSONString(), of een agentconfiguratie met een sleutel workflow:
Standaard tekent de CLI vakken en pijlen in de terminal, waarbij elke edgevoorwaarde op de edge wordt genummerd en in een legenda eronder wordt uitgeschreven. Gebruik --format mermaid om in plaats daarvan Mermaid-broncode af te drukken, of --format mermaid-md om deze in een fenced code block te plaatsen dat GitHub rendert, bijvoorbeeld in een opmerking bij een pull request:
De opdracht leest alleen lokale bestanden, heeft dus geen API-sleutel nodig en kan in CI worden uitgevoerd.
Validatie
Gekoppelde aanroepen falen nooit op zichzelf. build(), to_json() / toJSON() en to_json_string() / toJSONString() controleren de hele graaf en veroorzaken of gooien één WorkflowValidationError waarvan de lijst issues elk probleem vermeldt, elk met een code, een message en de relevante node_id / nodeId.
Fouten zijn onder meer:
- Twee edges tussen hetzelfde paar nodes, of een edge van een node naar zichzelf.
- Een edge naar de startnode, of vanuit een eindnode.
- Een edge vanuit een toolnode die geen succes- of foutedge is, of een succes- of foutedge vanuit een ander type node.
- Twee nodes met dezelfde ID, of een edge naar een node die niet bestaat.
Nodes die niet bereikbaar zijn vanaf de startnode worden als waarschuwingen gemeld via on_warning / onWarning en stoppen de build niet.
Nodetypen nieuwer dan je SDK
Een workflow die vanuit de API of uit een bestand wordt geladen, kan nodetypen bevatten die je SDK-versie nog niet kent. Deze gaan ongewijzigd heen en weer via from_json() / fromJSON() en to_json_string() / toJSONString(), en build() meldt elk type als waarschuwing. Het getypeerde requestmodel kan ze niet meenemen, dus upgrade de SDK of verzend het wire format rechtstreeks: