Workflowi jako kod
Twórz, edytuj i wersjonuj workflowi agentów za pomocą SDK Python i JavaScript
Omówienie
Workflow jest przechowywany jako graf węzłów i krawędzi. Ręczne tworzenie takiego grafu oznacza, że musisz sam dbać o spójność identyfikatorów krawędzi, list edge_order i obiektów warunków. Konstruktor Workflow w SDK Python i JavaScript pozwala opisać ten sam graf za pomocą łańcuchowych wywołań metod. Następnie tworzy wartość workflow, którą akceptują już agents.create() i agents.update().
Użyj go, aby:
- Tworzyć workflow w kodzie i sprawdzać je jak każdą inną zmianę w kodzie.
- Wczytać workflow agenta, zmienić jeden węzeł i wysłać go z powrotem bez naruszania reszty grafu.
- Przechowywać workflowi jako JSON w kontroli wersji i sprawdzać je w CI.
Konstruktor działa wyłącznie w SDK. Nie wywołuje nowych endpointów API, a wszystko, co utworzy, można otworzyć i edytować w edytorze wizualnym w dashboardzie.
Wymagania
- Python: pakiet
elevenlabs. Konstruktor importujesz zelevenlabs.agent_workflows. - JavaScript: pakiet
@elevenlabs/elevenlabs-js. Konstruktor jest eksportowany z głównego modułu pakietu.
Tworzenie workflow
Obiekt Workflow reprezentuje węzeł początkowy. Każdy czasownik dodaje węzeł i go zwraca, więc możesz od niego połączyć kolejne kroki:
Metody routingu określają, która krawędź prowadzi do następnego węzła:
Czasowniki wywołane bezpośrednio na workflow tworzą gałęzie z węzła początkowego przez bezwarunkową krawędź. Ten przykład kieruje dzwoniących do wyszukiwania zamówienia, ponawia identyfikację, jeśli wyszukiwanie się nie uda, oraz przekazuje klientów VIP lub zdenerwowanych:
build() sprawdza cały graf i zwraca model żądania. Dodatkowo:
- Nadaje węzłowi początkowemu wymagany przez API identyfikator
start_node. - Generuje identyfikatory krawędzi w formacie
source__target. - Uzupełnia
edge_orderkażdego węzła w kolejności dodawania krawędzi. - Pozycjonuje każdy węzeł bez pozycji, aby graf był ułożony od lewej do prawej w edytorze wizualnym.
Zapisz workflow jako jeden łańcuch
up() zwraca węzeł, z którego połączono bieżący, więc możesz opisać cały workflow jednym wyrażeniem zamiast przechowywać każdy węzeł w zmiennej. W pojedynczym łańcuchu użyj go_to() / goTo() z ID węzła, ponieważ nie masz zmiennej do przekazania:
Dla uchwytu węzła z wf.node(id) metoda up() zwraca węzeł, z którego prowadzi pierwsza krawędź do tego węzła. Dla węzła początkowego zwraca węzeł początkowy.
Opcje węzłów
Opcjonalne ustawienia przekazujesz jako argumenty nazwane w Pythonie i w końcowym obiekcie opcji w JavaScript. Ich nazwy odpowiadają polom węzła w API:
Każdy czasownik przyjmuje też position, jeśli chcesz samodzielnie ustawić pozycję węzła. Workflow(prevent_subagent_loops=True) w Pythonie lub new Workflow({ preventSubagentLoops: true }) w JavaScript zapobiega ponownemu wejściu rozmowy do odwiedzonego już podagenta.
Cele przekazywania
Warunki
when() przyjmuje zwykły ciąg znaków, Condition lub Expr:
- Ciąg znaków to warunek LLM: LLM decyduje, czy jest spełniony.
Condition.llm(text, label=...)działa tak samo, z etykietą wyświetlaną na krawędzi w edytorze wizualnym. UżyjCondition.expr(expr, label=...), aby oznaczyć wyrażenie etykietą.Exprjest obliczany na podstawie zmiennych dynamicznych, bez wywoływania LLM.
Twórz wyrażenia za pomocą Expr.variable(name) i Expr.literal(value). Porównuj je z eq, neq, gt, gte, lt i lte, a działania arytmetyczne wykonuj przez add, sub, mul i div. Łącz je przez all_of / allOf, any_of / anyOf i if_else / ifElse. Zwykłe wartości są automatycznie opakowywane w Expr.literal(). Expr.llm(description) prosi LLM o wyodrębnienie wartości z rozmowy; przekaż type i enum, aby otrzymać ciąg znaków, liczbę lub jedną z ustalonych wartości zamiast wartości logicznej.
Pętle i krawędzie wsteczne
API pozwala na jedną krawędź między dowolnymi dwoma węzłami, w każdym kierunku. Aby rozmowa mogła wrócić tą samą drogą, nadaj krawędzi warunek wsteczny za pomocą back:
go_to() / goTo() obsługuje typowy przypadek automatycznie. Gdy docelowy węzeł ma już krawędź prowadzącą tutaj, nowa krawędź staje się warunkiem wstecznym tamtej krawędzi. W pierwszym przykładzie failed.go_to(identify) jest wysyłane jako warunek wsteczny krawędzi identify → lookup_order. Każda inna druga krawędź między tymi samymi dwoma węzłami oraz każda krawędź z węzła do niego samego nie przejdzie walidacji.
Edycja istniejącego agenta
Workflow.from_agent() / Workflow.fromAgent() wczytuje workflow agenta zwróconego przez agents.get(). Identyfikatory węzłów i krawędzi, pozycje w edytorze oraz kolejność krawędzi zostają zachowane, więc wysłanie go z powrotem zmienia tylko to, co zmienisz.
insert_between() / insertBetween() przekazuje twojej funkcji gałąź zawierającą warunek zastępowanej krawędzi. Funkcja zwraca ostatni dodany węzeł, który zostaje następnie połączony z pierwotnym celem. Metoda zwraca ten węzeł albo None / undefined, jeśli między tymi dwoma węzłami nie ma krawędzi.
Przechowywanie workflowi w kontroli wersji
to_json_string() / toJSONString() zapisuje workflow w formacie przesyłanym przez API: klucze snake_case, posortowane na każdym poziomie, z wcięciem 2 spacji. To ten sam format, którego używają REST API i CLI, a oba SDK zapisują dla tego samego workflow pliki identyczne bajt po bajcie, więc różnice pozostają niewielkie. Workflow.from_json() / Workflow.fromJSON() odczytuje go z powrotem i przyjmuje też pełną konfigurację agenta z kluczem workflow, na przykład plik z katalogu agent_configs/ CLI.
Typowa konfiguracja:
Utwórz plik
Wczytaj agenta za pomocą from_agent() / fromAgent() i zapisz go albo pobierz przez elevenlabs agents pull.
Edytuj
Zmień JSON bezpośrednio albo wczytaj go przez from_json() / fromJSON() i edytuj konstruktorem
w skrypcie.
Wizualizacja workflow
CLI rysuje plik workflow jako schemat blokowy, dzięki czemu możesz sprawdzić, co utworzył kod, bez otwierania dashboardu. Przyjmuje sam plik workflow zapisany przez to_json_string() / toJSONString() lub konfigurację agenta z kluczem workflow:
Domyślnie rysuje w terminalu pola i strzałki, a każdy warunek krawędzi numeruje na krawędzi i opisuje w legendzie poniżej. Użyj --format mermaid, aby zamiast tego wyświetlić kod źródłowy Mermaid, lub --format mermaid-md, aby umieścić go w ogrodzonym bloku kodu renderowanym przez GitHub, na przykład w komentarzu do pull requesta:
Polecenie odczytuje tylko pliki lokalne, więc nie potrzebuje klucza API i może działać w CI.
Walidacja
Wywołania łańcuchowe same w sobie nigdy nie kończą się błędem. build(), to_json() / toJSON() i to_json_string() / toJSONString() sprawdzają cały graf i zgłaszają lub wyrzucają pojedynczy WorkflowValidationError, którego lista issues zawiera każdy problem wraz z jego code, message oraz dotyczącym go node_id / nodeId.
Błędy obejmują:
- Dwie krawędzie między tą samą parą węzłów lub krawędź z węzła do niego samego.
- Krawędź do węzła początkowego lub z węzła końcowego.
- Krawędź z węzła narzędzia, która nie jest krawędzią sukcesu ani porażki, albo krawędź sukcesu lub porażki z węzła innego typu.
- Dwa węzły z tym samym ID lub krawędź do nieistniejącego węzła.
Węzły, do których nie można dotrzeć z węzła początkowego, są zgłaszane jako ostrzeżenia przez on_warning / onWarning i nie zatrzymują tworzenia.
Typy węzłów nowsze niż twoje SDK
Workflow wczytany z API lub z pliku może zawierać typy węzłów, których twoja wersja SDK jeszcze nie zna. Przechodzą bez zmian przez from_json() / fromJSON() i to_json_string() / toJSONString(), a build() zgłasza każdy z nich jako ostrzeżenie. Typowany model żądania nie może ich obsłużyć, więc zaktualizuj SDK albo wyślij format przesyłany przez sieć bezpośrednio: