hachiflow.com

Ten wpis dotyczy Buzz, naszego wcześniejszego produktu. Dziś tworzymy Waggle.

Dogfooding

Agent jest warstwą renderowania

Daliśmy naszemu agentowi marketingowemu skrzynkę e-mail. Klient pisze do nas, Gary V czyta wiadomość w kanale naszego workspace'u hostowanego na hachiflow, szkicuje odpowiedź i wysyła ją, gdy założyciel powie: go. E-mail do AgentMail, do webhooka workflow, do agenta z zespołu: wszystko na wydanym oprogramowaniu, zero własnej infrastruktury. O ile wiemy, nikt dotąd nie opublikował dokładnie takiego okablowania.

Jeden URL, jeden nagłówek, jeden krok YAML

Części leżały już na półce. AgentMail to skrzynka API-first stworzona dla agentów: tworzysz skrzynkę przez API, ona przyjmuje pocztę i w chwili nadejścia wiadomości wysyła webhook na wybrany przez Ciebie URL. Buzz, open source'owy workspace opublikowany przez Block (hachiflow jest niezależne i niepowiązane z Block), ma silnik workflow wbudowany w sam przekaźnik. Każdy workspace na hachiflow.chat ma go w standardzie, więc workflow wyzwalane webhookiem po prostu działają od pierwszego dnia, bez własnego serwera do utrzymania.

Workflow z wyzwalaczem webhook dostaje endpoint w rodzaju POST https://yourteam.hachiflow.chat/hooks/9f4c21e7-6b3d-4a8e-b02f-c75d10a94e63, uwierzytelniany nagłówkiem X-Webhook-Secret. Skieruj webhook AgentMail na ten URL, wstaw sekret do nagłówka, a przychodzące e-maile wylądują w Twoim kanale.

To cała integracja: jeden URL, jeden nagłówek, jeden krok YAML. Zrzut ekranu poniżej to cała strona Buzz, a terminal pod nim to cały kontrakt, z celowo fałszywymi przykładowymi wartościami.

Edytor workflow w Buzz: workflow customer-marketing-emails na kanale marketing, wyzwalacz webhook, jeden krok Send Message z jednolinijkowym dzwonkiem wzmiankującym Gary'ego V i przełącznik formularz/YAML w rogu.
Cała integracja po stronie Buzz: wyzwalacz webhook i 1 krok Send Message. Ta jedna linijka tekstu to dzwonek.
cały kontrakt
# symulacja dostarczenia z AgentMail: ten sam URL, ten sam nagłówek $ curl -X POST \ -H 'X-Webhook-Secret: 7d81f3a2-4c96-4b0e-a2d5-e6f4903b17c8' \ -H 'Content-Type: application/json' \ --data '{"event":"message.received"}' \ https://yourteam.hachiflow.chat/hooks/9f4c21e7-6b3d-4a8e-b02f-c75d10a94e63 # dzwonek ląduje w kanale, a agent idzie po prawdziwą pocztę

Obie wartości są celowo fałszywymi przykładami: prawdziwy UUID hooka i sekret powstają przy tworzeniu workflow, a sekret trzyma się wyłącznie w konfiguracji webhooka AgentMail.

Podejście 1: ściana JSON-a

Nasz pierwszy workflow zrobił rzecz oczywistą: wstawił payload prosto do kanału przez szablon {{trigger.message}}. Wyszła z tego ściana surowego JSON-a. Nagłówki, wyniki SPF, metadane załączników, cała koperta jako jeden akapit. Zachowała się na zrzucie ekranu niżej, tuż nad swoim następcą.

Ograniczenie jest konkretne i żeby je potwierdzić, przeczytaliśmy kod w Ruście. Szablony workflow w Buzz wyciągają dziś tylko klucze najwyższego poziomu z treści webhooka. Zagnieżdżony obiekt renderuje się jako jeden zserializowany blob: nie ma {{trigger.message.from}}, a jedyne filtry szablonów to truncate i npub. Ładne wyrenderowanie zagnieżdżonego payloadu webhooka w wiadomości workflow nie jest obecnie możliwe.

To nie jest narzekanie. Silnik jest młody i możliwości szablonów będą rosły. Ale dziś uczciwa rada brzmi: nie planuj formatowania payloadu webhooka w workflow, zaplanuj obejście.

Nie renderuj w workflow. Nie renderuj wcale.

Wyjście patrzyło na nas z każdej innej wiadomości w kanale. Wiadomości agentów w Buzz wyglądają świetnie, bo klient renderuje ich treść jako markdown w wersji GitHub. Workflow nie potrafił sformatować poczty, ale kolega z zespołu, do którego ją dostarczał, formatuje wszystko, co mówi. Odwróciliśmy więc architekturę i całkowicie przestaliśmy renderować w workflow.

Wiadomość workflow to teraz jednolinijkowy dzwonek, który @wzmiankuje agenta. Narzędzia AgentMail trzyma sam Gary V: ich hostowany serwer MCP, ograniczony do tej jednej skrzynki. Gdy dzwonek dzwoni, Gary pobiera nieprzeczytaną pocztę, publikuje w kanale czytelną kartę markdown i szkic odpowiedzi, wysyła odpowiedź przez API AgentMail w wątku oryginalnej wiadomości i oznacza wiadomość etykietą jako obsłużoną, żeby nic nie zostało przerobione dwa razy.

Agent jest warstwą renderowania. Workflow jest budzikiem. A zgoda nie ruszyła się z miejsca: Gary szkicuje w kanale, a założyciel mówi go, zanim cokolwiek wyjdzie z firmy.

e-mail klienta skądkolwiek skrzynka AgentMail API-first · webhooki workflow na twoim przekaźniku wyzwalacz webhook POST /hooks/… · X-Webhook-Secret jednolinijkowy dzwonek #marketing Gary V agent · trzyma narzędzia skrzynki @wzmianka budzi karta markdown + szkic MCP: pobierz · odpowiedz · etykieta założyciel: go
Kształt, który działa: workflow tylko dzwoni, a agent czyta, renderuje i odpowiada. Zgoda zostaje w kanale.
Kanał marketing w Buzz. Wyżej starsza wiadomość renderująca payload webhooka jako ścianę surowego JSON-a, niżej jednolinijkowy dzwonek, który ją zastąpił, a w panelu wątku po prawej czytelne podsumowanie agenta i wysłana odpowiedź.
Przed i po w jednym kadrze: u góry blob surowego JSON-a z podejścia 1, niżej jednolinijkowy dzwonek, który go zastąpił, po prawej czytelne podsumowanie Gary'ego i odpowiedź w wątku.

Wzmianka, która nikogo nie budzi

Pułapka 1 kosztowała nas 3 rundy testów. Wzmianki w wiadomościach workflow są rozwiązywane po stronie serwera: przekaźnik dopasowuje @Name z tekstu kroku do członków kanału po nazwie wyświetlanej. Jeśli 2 członków ma tę samą nazwę wyświetlaną, przekaźnik celowo nie budzi nikogo. Żadnego błędu, żadnego częściowego dopasowania, żadnego logu, który mógłbyś zobaczyć. Cisza.

Mieliśmy nieaktualny duplikat: wcześniejszy, martwy „Gary V” wciąż był członkiem kanału obok żywego, więc każdy dzwonek dzwonił dla nikogo. Jako zasada chroniąca przed błędnym kierowaniem to rozsądne, nie chcesz, żeby workflow zgadywał, którego z 2 członków o tej samej nazwie obudzić. Jako doświadczenie debugowania to brutalne, bo nic i nigdzie nie mówi Ci, że to się stało. Wyrzuciliśmy nieaktualnego członka i dzwonek zadzwonił.

Podpis autora jest kosmetyczny

Pułapka 2 jest subtelniejsza. Wiadomość workflow wygląda, jakby pochodziła od Ciebie. Tak nie jest. Przypisanie autorstwa renderuje klient; kryptograficznie wiadomość jest podpisana własnym kluczem przekaźnika.

Bramka odpowiadania Gary'ego była ustawiona na tylko właściciela, a bramka sprawdza podpis, nie widocznego autora. Gary zobaczył więc, jak przychodzi dzwonek, stwierdził, że nie jest podpisany przez jego właściciela, i słusznie go zignorował. Bramka ma rację, podpis autora jest kosmetyczny, a poprawka polega na dodaniu klucza przekaźnika do listy dozwolonych agenta, tak żeby wiadomości workflow podpisane przez przekaźnik liczyły się jako pobudka.

Znaleźliśmy to, czytając źródła buzz-acp, a upstream mocował się z tym samym problemem: poprawka trafiła do kodu i została wycofana. Jeśli więc Twój agent zostaje oznaczony i nigdy się nie budzi, a w kanale jest dokładnie 1 taki agent, to właśnie dlatego.

Jeszcze jedno na drogę

Drobiazg z edytora YAML dla workflow. Wartość tekstowa zaczynająca się od @ musi być w cudzysłowie, bo gołe @ nie może rozpoczynać skalara YAML. I wklejaj ostrożnie: raz udało nam się dokleić cały drugi dokument YAML do pola tekstu wiadomości, a edytor przyjął to bez mrugnięcia. Widok formularza i widok YAML to 2 drzwi do tego samego kroku; formularz gryzie rzadziej.

Naprawianie narzędzi, które trzymasz w ręku

Każda runda testów to był prawdziwy e-mail z naszej własnej domeny, wysłany przez higgs, nasze CLI do Proton Mail, które steruje Proton Mail Bridge przez IMAP i SMTP. Żadnych mocków: każdy test przeszedł przez prawdziwy internet, wylądował w prawdziwej skrzynce i zadzwonił prawdziwym dzwonkiem, i właśnie dlatego złapaliśmy pułapki, których żaden fixture by nie ujawnił.

Dogfooding działał w obie strony. W trakcie debugowania odkryliśmy, że higgs send nie potrafi od razu rozmawiać z Bridge, więc to naprawiliśmy i jeszcze tej samej nocy wydaliśmy higgs v1.3.0. Tak wygląda prawdziwa praca przy łączeniu agentów: przez połowę czasu naprawiasz narzędzia, które trzymasz w ręku.

Klasa alfa, i już wydane

Każdy workspace hachiflow uruchamia dziś wszystko powyższe: stałe $50 miesięcznie, bez limitu ludzi i agentów, Twoje własne klucze LLM, dedykowany serwer. Nic tutaj nie wymagało własnej infrastruktury. AgentMail to produkt, na który możesz się zapisać, silnik workflow jest dostarczany z każdym workspace'em, a agent jest członkiem Twojego zespołu jak każdy inny.

Buzz jest młody, a to okablowanie klasy alfa z ostrymi krawędziami, i właśnie dlatego publikujemy pułapki zamiast listy samych sukcesów. Jeśli chcesz skrzynkę, za którą stoi kolega z zespołu, zacznij od hachiflow.com.

← Wszystkie notatki