← Blog

Chat agents

Slack onboarding-agent: Rotterdamse HR-tech case study

Het onboarding-team was gegroeid naar zes. Elke maandag stapelden de tickets zich op. Toen koppelden we een Slack chat-agent aan Notion en bouwden de flow opnieuw.

Jacob Molkenboer· Oprichter · A Brand New Company· 5 jun 2026· 9 min
Antiek houten hotelbelbord met zes genummerde tabjes, één groen omgeklapt, op ivoren bureau naast gevouwen kaart.

Een maandag in februari. Het hoofd operations bij een Rotterdamse HR-tech SaaS opende haar Slack en zag het kanaal #new-clients vollopen voordat ze haar koffie op had. Zevenenveertig kickoff-aanvragen over het weekend. Zes teamleden die haar al pingden voor de volgorde. Ze klapte de laptop dicht, liep naar buiten en belde ons.

Dit is de case study van wat we daarna bouwden, en wat als eerste stuk ging.

De flow die ze in de lucht probeerde te houden

Het product is een payroll- en HR-platform voor Europees mkb. Self-serve voor de kleine accounts, white-glove voor de grote, en daartussen een dikke middenmoot van bedrijven met 5 tot 50 medewerkers. Die hadden begeleiding nodig, maar geen vaste CSM. Die middenmoot dreef het onboarding-team van zes.

Hun flow telde acht stappen. Intake uit het sales hand-off document. Kickoff-call. CSV-template naar de admin van de klant. Validatie van het teruggestuurde CSV (een bewegend doel, want klanten zijn creatief). Import. SSO instellen. Trainingssessie voor managers. Check-in na 30 dagen. Elke stap zat in een ander tool. Sales gebruikte HubSpot, ops zat in Notion, support gebruikte Intercom, en engineering had een kleine admin-CLI gebouwd die maar twee mensen in het team konden draaien.

De rekensom was hard. Tachtig tot honderdtwintig nieuwe klantbedrijven per maand. Zes fulltime onboarders met gemiddeld vijftien kickoffs elk, en een wachtrij die altijd sneller groeide dan kromp. De bottleneck was geen kunde. Het was dat dezelfde vijf vragen elke dag in vijf verschillende inboxen binnenkwamen.

Waarom we geen portal hebben gebouwd

De eerste reflex vanuit engineering was een self-serve onboarding-portal. Een wizard. Een voortgangsbalk. De ops-lead ging er hard tegenin. "Onze klanten hebben al zes tabbladen openstaan. Ze willen geen zevende."

Ze had gelijk. De klanten waren ops-leads bij restaurantketens, tandartspraktijken, kleine bouwbedrijven. Hun dag bestond al uit een stapel halfafgemaakte tabbladen. Wat ze de hele dag wel openhadden, was hun mail en hun telefoon. En steeds vaker Slack. Ongeveer de helft van het klantenbestand werkte intern al met Slack.

De opdracht werd dus: ontmoet de klant waar die al zit, en haal de stappen weg waar een mens voor de honderdste keer hetzelfde antwoord intypt.

De architectuur

We hebben twee dingen live gezet. Een Slack chat-agent die in een Slack Connect-kanaal met elke klant zit, en een Notion-database die de enige bron van waarheid werd voor elk record over die onboarding.

De onderdelen:

  • Slack Bolt (TypeScript) als oppervlak.
  • De Anthropic API erachter, met een tool-use loop gekoppeld aan zeven interne tools.
  • Notion als enige duurzame state. De agent schrijft daar, ops leest daaruit, de rest van het bedrijf abonneert zich via Notion's eigen automatiseringen.
  • Postgres voor kortlevende state (lopende CSV-validaties, rate limits, audit log) op Fly.io.
  • Een Intercom-tool die de agent aanroept als er een mens moet bijspringen.

De kernkeuze in het ontwerp was: geef de LLM tools, geen vrijheid. De agent kon geen vrije antwoorden schrijven over prijzen of compliance. Hij kon get_onboarding_step, validate_csv, schedule_kickoff, create_notion_record, fetch_doc (de RAG-call), escalate_to_human en summarize_thread aanroepen. Alles buiten die zeven werkwoorden viel buiten scope.

Hier is het relevante stukje van de tool-definitie, licht geredigeerd:

const tools = [
  {
    name: "validate_csv",
    description:
      "Validate an uploaded employee CSV against the platform schema. " +
      "Returns row-level errors with line numbers and a fix suggestion per error.",
    input_schema: {
      type: "object",
      properties: {
        file_url: { type: "string", description: "Slack file URL." },
        client_id: { type: "string" }
      },
      required: ["file_url", "client_id"]
    }
  },
  {
    name: "escalate_to_human",
    description:
      "Hand the conversation to the on-call onboarder. Use when (a) the " +
      "customer asks something not covered by docs, (b) sentiment turns " +
      "negative, or (c) the same question has been asked twice without " +
      "progress.",
    input_schema: {
      type: "object",
      properties: {
        reason: { type: "string" },
        urgency: { type: "string", enum: ["low", "medium", "high"] }
      },
      required: ["reason", "urgency"]
    }
  }
]

De escalate_to_human-tool was de belangrijkste. Niet de slimste in de stack. De belangrijkste. Want de vraag die elke ops-lead bij de klant ons bleef stellen, was: "Hoe vertrouw ik dat dit ding niet liegt tegen mijn klant?" Het antwoord was: vertel hem, in de system prompt en in de tool-beschrijving, om vroeg en vaak te escaleren.

Notion als enige plek waar waarheid leeft

De helft van het werk aan zo'n project is niet de agent. Het is besluiten waar state woont. We kozen Notion om drie redenen. Ops kende het al. Het bedrijf betaalde er al voor. En de REST API van Notion is simpel genoeg dat we geen ORM nodig hadden.

Elke nieuwe klant werd een rij in één Notion-database genaamd Onboarding. Status-veld, owner-veld, kickoff-datum, boolean CSV-gevalideerd, boolean SSO-ingericht, boolean training-gedaan, datum check-in na 30 dagen. De agent schreef in die rij. Het ops-team las uit die rij tijdens de ochtendstandup. Sales keek naar dezelfde view, gefilterd op "kickoff deze week". Engineering keek naar de view gefilterd op "geblokkeerd bij ons".

We verboden een tweede bron van waarheid. Geen spreadsheets. Geen Linear-tickets die Notion-rijen dupliceerden. Geen "dit hou ik wel even in mijn hoofd bij". Als iets op twee plekken leefde, leefde het op nul plekken.

Let op

Als je chat-agent en je ops-team het oneens zijn over de state van een klant, verliest je agent. Elke keer. De oplossing is geen betere prompts. De oplossing is één database waar beide kanten in schrijven.

De agent-loop

De Slack-agent draait een vrij standaard tool-use loop. Nieuw bericht komt binnen. We bouwen een context window uit de laatste twintig berichten in de thread, de Notion-rij van de klant, en de relevante chunks uit de docs-RAG. Het model kiest een tool. Wij draaien hem. We geven het resultaat terug. Herhalen tot het model tekst uitspuugt, of tot er vijf tool-calls voorbij zijn, waarna we een wrap-up forceren.

Twee niet-vanzelfsprekende keuzes maakten het werkend.

Ten eerste: elk model-antwoord dat tekst richting de klant bevatte, ging door een tweede, goedkoper model heen als sanity check. Die check beantwoordde drie vragen. Spreekt dit de docs tegen die we in de context meestuurden. Doet dit een belofte waar de agent geen toestemming voor heeft. Staat dit in de taal van de klant. Als één check faalde, stuurden we het door naar een mens en verstuurden we de draft niet. Kostte ongeveer een tiende cent per bericht. Ving ruwweg één slecht antwoord per honderd.

Ten tweede: de agent nam nooit een besluit dat het ops-team niet als categorie had goedgekeurd. Nieuw type vraag. Escaleren. Klant vraagt om geld terug. Escaleren. CSV-validatie geslaagd, maar de klant zegt "wacht, ik denk dat ik het verkeerde bestand stuurde". Escaleren. De taak van de agent was de negentig procent van berichten afhandelen die dezelfde vijf vragen waren, niet slim doen over de long tail.

Wat als eerste stuk ging

Twee dingen gingen stuk in de eerste maand, geen van beide was het model.

De eerste was Slack Connect zelf. Ongeveer één op de acht Slack-workspaces van klanten had Connect uitstaan op org-niveau, en hun IT-team zover krijgen om dat aan te zetten kostte vier dagen extra waar we niet op gerekend hadden. We hebben het opgelost door een e-mail-fallback live te zetten op dezelfde agent-backend, zodat een klant die Connect niet aan kreeg, alsnog de chat-ervaring kreeg via threaded e-mailantwoorden. Ongeveer vijftien procent van de klanten kwam op het e-mailpad uit.

De tweede was de rate limit van de Notion API. Notion houdt je op ongeveer drie requests per seconde per integratie. Met de agent die bij elke state-wijziging naar de database schreef, plus ops die dashboards las, raakten we de cap tijdens ochtendstandups en begon de agent stilletjes writes te laten vallen. De fix was een kleine write-coalescing queue in Postgres die Notion-writes batchte naar één update per rij per tien seconden. Saai infrastructuurwerk, maar het was het verschil tussen een agent die het team vertrouwde en een die ze niet vertrouwden.

Bouw je iets dat op volume met de Notion API praat, lees dan de rate-limit-pagina voordat je een regel code schrijft. Ze zijn er eerlijk over. De meeste projecten komen er pas op de harde manier achter.

De cijfers na drie maanden

We zijn geen fan van vanity metrics, maar dit zijn de drie die de ops-lead elke maandag bekijkt.

De mediane tijd van "kickoff geboekt" tot "eerste payroll-run gelukt" was veertien dagen toen we begonnen. Drie maanden later staat dat op vier dagen. De winst kwam vooral uit het wegsnijden van dode tijd tussen menselijke stappen, niet uit slimheid van de agent. De agent wacht niet tot iemand terug is van de lunch.

Het onboarding-team ging van zes fulltime onboarders naar twee. Niet door ontslag. De andere vier verhuisden naar een nieuwe functie waar het bedrijf al een jaar mensen voor wilde: een implementatieteam met meer touch voor klanten boven de 50 medewerkers. Zelfde bezetting, meer omzet per persoon, minder maandagwachtrij.

En de agent handelt, afhankelijk van de week, tussen de vijfenzeventig en vijfentachtig procent van de inkomende berichten op het onboarding-kanaal af zonder dat er een mens reageert. Het stuk dat overblijft is precies het werk dat het menselijke team wil doen.

Wat we anders zouden doen

Drie dingen, eerlijk gezegd.

We zouden de e-mail-fallback in week één bouwen, niet week drie. De klanten die Slack Connect niet aan kregen, waren onze traagste accounts. En juist zij hadden de agent het hardst nodig.

We zouden elke tool-call vanaf dag één als structured event loggen. We voegden dat pas in maand twee toe en het veranderde het soort vragen dat we aan de data konden stellen ("hoe vaak faalt de validate_csv-tool op veld X" in plaats van "heeft de agent deze week gewerkt").

En we zouden eerder en harder terugduwen op het idee om een negende tool toe te voegen. Elke tool die je toevoegt is een nieuwe beslissingsgrens die het model kan vervagen. De zeven die we live zetten waren genoeg. De achtste die we voorstelden en daarna schrapten was een "stuur een betalingsherinnering"-tool die niets te zoeken had in een onboarding-agent.

Het kleinste wat je vandaag kunt doen

Run je een ops-team dat verspreid zit over Slack, mail en een kennisbank, dan is dit de audit van vijf minuten. Open de inbox met klantthreads van vorige week. Schrijf voor elke thread één van drie letters in de marge. R voor "een antwoord dat in onze docs stond". S voor "een antwoord waar een mens voor nodig was en niet te automatiseren viel". B voor "saai repeterend werk dat de mens deed omdat niemand de tool had aangelegd".

Tel de R'en en de B's. Dat is het stuk dat een agent zoals die wij bouwden van het bordje van je team kan halen.

Toen we deze chat-agent bouwden, liepen we er steeds tegenaan dat de accuratesse van de agent er minder toe deed dan de escalatieregels. We losten het op door het escalatiebeleid in dezelfde Notion-database te schrijven die het ops-team al vertrouwde. Zo benaderen we AI-agents bij ABN: begin bij escalatie, werk terug naar de prompt.

Kern

De accuratesse van je chat-agent doet er minder toe dan de escalatieregels. Schrijf het escalatiebeleid op een plek waar het ops-team het kan aanpassen zonder deploy.

FAQ

Waarom Slack in plaats van een eigen onboarding-portal?

De klanten hadden Slack al openstaan. Een zevende tabblad had de completion verlaagd. De klant ontmoeten waar die al werkt is beter dan een nieuwe omgeving bouwen die ze nog moeten leren.

Waarom Notion als bron van waarheid en geen database van engineering?

Ops vertrouwde Notion al en las het elke ochtend. De tool kiezen die de mensen gebruiken is beter dan de technisch netste tool kiezen. De agent schrijft in dezelfde rij waar ops uit leest.

Hoe voorkom je dat een LLM-gedreven agent beloftes doet die hij niet mag doen?

Beperk hem met tools, niet met tekst. Zeven strak afgebakende tools, een tweede, goedkoper model als sanity check, en een escalatiebeleid dat het ops-team kan aanpassen zonder redeploy.

Wat is de meest voorkomende fout bij het koppelen van een agent aan Notion op volume?

De rate limit negeren. Ongeveer drie requests per seconde per integratie is zo geraakt. Gebruik een write-coalescing queue in Postgres en batch updates naar één per rij per tien seconden.

Zijn de zes onboarders hun baan kwijtgeraakt?

Nee. Twee bleven bij onboarding. De andere vier gingen naar een implementatieteam met meer touch voor klanten boven de 50 medewerkers, een functie waar het bedrijf al een jaar mensen voor wilde.

chat agentsai agentsprocess automationcase studyintegrationsworkflow

Iets bouwen?

Start een project