Arendus 6 min lugemist

Kümme päringut, üks vaba aeg kell 9:00: kuidas meie AI-assistent hoiab pakutud aega kinni

Kui mitmele päringule pakutakse korraga sama varaseimat vaba aega, saab selle esimesena nõustuja ja kõigile teistele tuleb uus aeg pakkuda. Seepärast hoiab assistent nüüd iga pakutud aega kinni.

Viktoras Lava CTO · Faktid on rakenduses üle kontrollitud 5. nov 2026
Jaga
Kümme päringut saabub korraga. Esimene broneerib aja 09:00 ja ülejäänud üheksale hoitakse kinni igaühele oma aeg. Kui kõned on 30-minutilised ja puhveraeg on 10 minutit, jäävad ajad üksteisest tunni kaugusele.
Sellel lehel
  1. Miks ilmsed lahendused ei tööta
  2. Kinnihoidmine, mitte broneering
  3. Kuidas vältida topeltbroneeringuid: süsteemi ülesehitus
  4. Mida sa Send4-s näed
  5. Mida kinnihoidmine ei tee
  6. Küsimused

Kõik sai alguse ühest väikesest juhtumist. Kliendile pakuti aega 9:15, ta nõustus ja sai vastuseks, et aeg on läinud: teine klient oli samale ajale neli minutit varem jah öelnud. Keegi polnud midagi valesti teinud. Meie tehisintellektil (AI) põhinev assistent oli pakkunud mõlemale varaseimat vaba aega ja selle sai endale ainult üks neist.

Nii juhtus iga kord, kui päringud saabusid tihedalt üksteise järel. SMS-kampaania vanale päringute nimekirjale alustab minutis vestlust kõige rohkem 10 inimesega (kampaaniad on Business-paketis), nii et vastused tulevad tagasi hulgakaupa. Sama juhtub vormidega, mis täituvad pärast reklaami käivitumist või kiirel esmaspäeva hommikul. Igas vestluses, mis jõudis broneerimise sammuni, sai assistent samad lähteandmed: tööruumi varaseimad vabad ajad, kus hõivatuks loeti ainult broneeritud kohtumised. Nii pakutigi kõigile aega 9:00. Esimene „jah“ broneeris selle, kõik teised said vastuseks „vabandust, see aeg on juba võetud, kas mõni teine aeg sobiks?“ ja just sellel lisaringil kaob osa kliente ära. See on topeltbroneering, mida ükski kalender ei näita, sest kalender näeb ainult seda üht kohtumist, mis broneeriti.

Seepärast hoiab Send4 assistent nüüd pakutud aega kinni, vaikimisi kaks tundi, ja järgmisele kliendile pakutakse järgmist vaba aega. Mängi allolev päringute tulv läbi kõigepealt ilma kinnihoidmiseta ja siis koos sellega.

Joonis 1Päringute tulvLihtsustatud mudel
10 kliendil 10-st õnnestus broneerida esimesel katsel 0 kliendile tuli pakkuda uut aega Valmis
  • AnuBroneeritud E 09:00
  • ErikBroneeritud E 10:00
  • HelenBroneeritud E 11:00
  • IndrekBroneeritud E 12:00
  • KadriBroneeritud E 13:00
  • KristjanBroneeritud E 14:00
  • LiisBroneeritud E 15:00
  • MargusBroneeritud E 16:00
  • MariBroneeritud T 09:00
  • MarkoBroneeritud T 10:00

Kinnihoidmisega said 10 klienti 10 eri aega ja kellelegi ei tulnud uut aega pakkuda.

Joonis 1. Assistendini jõuab tulvana 10 päringut, 10 päringut minutis. Igale kliendile pakutakse varaseimat vaba aega ja ta nõustub paar minutit hiljem. Mudelis kestab kohtumine 30 minutit, puhveraeg on 10 minutit ja ajad algavad täis- ja pooltundidel.

Miks ilmsed lahendused ei tööta

Esimesena tulevad pähe kolm lahendust ja ükski neist ei tööta. Kahe aja pakkumine ühe asemel ei aita, sest ka teist aega ei hoita kinni ja seda võidakse samamoodi pakkuda mitmele kliendile. Seepärast läksime vastupidist teed: assistent pakub ühte aega ja küsib, kas see sobib. Ei aita ka see, kui lasta AI-l meeles pidada, mida ta pakkus. Pakutud aeg oli olemas ainult tekstina sõnumis, nii et miski ei saanud seda reserveerida. Ja kui aeg pakkumise hetkel ära broneerida, täitub kalender kohtumistega, millega keegi pole nõustunud.

Kinnihoidmine, mitte broneering

Kalendrikeeles on see eelbroneering: aeg hoitakse kinni, kuni klient otsustab, aga midagi pole veel broneeritud. Send4-s on kinnihoidmine eraldi kirje, mitte üks kohtumise liik, sest muidu peaks kõik, mis kohtumisi loeb, alates kalendrist kuni ekspordi ja webhookideni, õppima seda vahele jätma.

Kinnihoidmine kestab vaikimisi kaks tundi. Pikkuse määrad igal broneerimise sammul eraldi: 0 lülitab kinnihoidmise välja ja suurim väärtus on 24 tundi. Varem lõpeb see siis, kui kohtumise alguseni jääb minimaalsest etteteatamisajast vähem aega. Näiteks kui broneerida tuleb vähemalt tund ette ja kella 10:00 aeg võeti kinni kell 08:55, lõpeb kinnihoidmine kell 09:00, sest pärast seda poleks seda aega niikuinii saanud broneerida. Uued sõnumid kinnihoidmist ei pikenda, nii et jutukas klient ei saa aega lõputult endale hoida. Kinnihoidmine kehtib kogu tööruumis, mitte iga müügiesindaja kohta eraldi.

Kinnihoidmine ei ole siduv, sest me ei taha jätta broneerimiseks valmis klienti ilma ajata selle kliendi pärast, kes võib-olla broneerib. Kuni leidub vaba aeg, mida keegi kinni ei hoia, jätab assistent teiste klientide jaoks kinni hoitud ajad vahele. Klient, kes küsib just seda aega, saab selle siiski broneerida ja aja saab see, kes esimesena kinnitab. Kui teine klient järgmine kord kirjutab, ütleb assistent talle, et aeg on juba võetud, ja pakub uut. Kui kõik vabad ajad on juba kinni hoitud, pakub assistent ikkagi varaseimat neist, ilma uut kinnihoidmist loomata. Parem pakkuda aega, mida tahab ka keegi teine, kui mitte pakkuda midagi.

Kuidas vältida topeltbroneeringuid: süsteemi ülesehitus

Reeglit on lihtne sõnastada: ära paku aega, mille üle keegi teine parasjagu otsustab. Esimene otsus oli, et AI-mudel aegu ei vali. Aja valib süsteem ja assistendile öeldakse, et ta pakuks täpselt seda aega. Kui klient tahab mõnda teist aega, peab assistent tegema tööriistakutse (tool call), mis tõstab kinnihoidmise ümber. Nii on iga aeg, mida assistent pakub, süsteemis kirjena olemas, ja viimane sõna jääb broneerimistööriistale. Edasine on mõeldud arendajatele ja kõigile, kes ehitavad broneerimissüsteemi. Plaani kirjutasime 25. septembril ja ehitasime valmis kaks päeva hiljem. Kaks plaani ülevaatust lisasid suurema osa allpool kirjeldatud piirjuhtumitest (edge cases).

Puhveraeg kohtumiste vahel

Kui kohtumine kestab 30 minutit ja puhveraeg on 10 minutit, saab teine klient aja 10:00, mitte 09:30. Kui mõlemad nõustuksid, jääks 09:30 esimese kohtumise puhveraja sisse ja broneering lükataks tagasi. Seega peab esimese kohtumise lõpu ja järgmise alguse vahe olema vähemalt sama pikk kui pikem kahest puhverajast:

kohtumiste vahe ≥ max(puhveraeg A, puhveraeg B)

Suurem neist kahest seepärast, et kahel broneerimise sammul võib puhveraeg olla erinev. Lohista allpool kohtumiste pikkusi ja puhveraegu ning vaata, kust saab järgmine kohtumine alata.

Joonis 2Puhveraja joonlaudLihtsustatud mudel
kohtumiste vahe ≥ max(puhveraeg A, puhveraeg B) 30 min ≥ max(10, 10) = 10 min

Järgmisele kliendile pakutakse aega 10:00. Esimese kliendi kohtumise lõpu ja järgmise alguse vahe on 30 minutit ja pikem kahest puhverajast on 10 minutit. Kohtumine kell 09:30 jätaks vaheks ainult 0 minutit, vähem kui 10, nii et broneering lükataks tagasi.

Joonis 2. Ühel broneerimise sammul hoitakse esimese kliendi jaoks kinni aeg 09:00. Vaata, millal saab alata järgmise kliendi kohtumine, kui tema sammul on oma kohtumise pikkus ja puhveraeg. Mudel pakub aegu täis- ja pooltundidel.

Samamoodi loeb kohtumise pikkus. Broneerimise samm võib pakkuda eri pikkusega teenuseid. Kuni klient pole teenust valinud, hoitakse kalendris kinni pikima teenuse jaoks vajalik ajavahemik. Nii lükkavad 30- ja 90-minutiline teenus järgmise kliendi kella 11:00 peale. Pärast valikut kohandatakse ajavahemikku valitud teenuse kestuse järgi. Aja valimisel kontrollib süsteem kattumist nii kohtumiste kui ka teiste klientide kinnihoidmistega ja hoiab kinni esimese aja, mis kontrolli läbib:

Pseudokood
# Vali kliendile pakkumiseks üks aeg ja hoia see kinni.
function offerTime(lead):
    for time in openTimes(after: now + minimumNotice):
        if clashes(time, meetings): continue
        if clashes(time, holdsOfOtherLeads): continue
        hold(time, lead, until: earliest(now + holdLength, time − minimumNotice))
        return time
    # Kõik vabad ajad on kinni hoitud: paku ikkagi varaseimat, ilma kinnihoidmiseta.
    return firstOpen(openTimes, ignoring: holds)

# Kaks kohtumist kattuvad, kui ühe lõpu ja teise alguse vahe on liiga väike.
function clashes(a, b):
    return gap(a, b) < max(a.buffer, b.buffer)
Kuidas assistent valib pakutava aja. Lihtsustatud, nimed on muudetud.

Millal kinnihoidmine enam ei loe

Kinnihoidmine loeb ainult seni, kuni selle vestlus on broneerimise sammul. Kui vestlus lõpeb või liigub järgmisele sammule, ei blokeeri see aega enam. Nii lõpeb kinnihoidmine ükskõik mis teed pidi vestlus sammult lahkub, ja ühegi väljapääsu jaoks ei pea eraldi koristust kirjutama. Kui keegi sinu meeskonnast on vestluse üle võtnud, võib selle kinni hoitud aega pakkuda ka teistele klientidele ning aeg, mille klient tagasi lükkab, läheb samal hetkel uuesti pakkumisse.

Enne kui assistent kinni hoitud aega uuesti pakub, kontrollib ta seda samade reeglite järgi nagu broneeringut. Tööaeg võib muutuda, juurde võidakse lisada blokeeritud päev või keegi võib kohtumise käsitsi broneerida. Aeg, mis enam ei sobi, vabastatakse ja kliendile pakutakse teist. Hilise jaatusega on lugu vastupidine. Kui klient ütleb jah kolm tundi hiljem ja aeg on endiselt vaba, saab ta sama aja. Assistent ei vaheta seda uue vastu, sest klient nõustus konkreetse ajaga, mitte sellega, mis parasjagu vaba on.

Testid jäävad sellest kõigest välja. Testvestlus stsenaariumide koostajas ei võta kunagi päris kliendi aega ja testbroneering ei võta kunagi päris kliendile kinni hoitud aega.

Race condition meie broneerimissüsteemis

Selle leidsime töö käigus ja see on topeltbroneeringu õpikunäide: kaks samal hetkel tehtud broneeringut samale tühjale ajale võisid mõlemad õnnestuda. Enne broneerimist tehtud kontroll lukustas selles ajavahemikus juba olevad kohtumised, aga tühjas ajavahemikus neid pole, nii et polnud midagi lukustada. Mõlemad broneeringud kontrollisid, kumbki ei leidnud midagi ja mõlemad salvestasid kohtumise. Meie AI-tööde järjekorda töötlesid kaks taustaprotsessi (workers), nii et kaks jaatust võidigi töödelda täpselt samal hetkel, ja kohtumiste tabelis polnud piirangut, mis selle kinni püüaks.

Parandasime selle kinnihoidmist ehitades. Aja valimine ja broneerimine võtavad nüüd sama luku (lock), ühe konto kohta, nii et teine broneering ootab, näeb esimest ja kliendile pakutakse teist aega. Kui lukku ei õnnestu saada, läheb broneering läbi nagu varem, sest kliendi „jah“ ei tohi kunagi ebaõnnestuda meie vahemälu (cache) pärast. Käi see allpool samm-sammult läbi, kõigepealt ilma lukuta, siis lukuga.

Joonis 3Kaks jaatust samal hetkelLihtsustatud mudel
Anu broneering Valmis
Eriku broneering Tagasi lükatud. Assistent pakub aega 10:00
Kohtumised kell 09:00
  • 09:00 Anu
Lukk: vaba

Samm 7 / 7

Lukuga pidi Eriku broneering ootama. Siis leidis see eest Anu kohtumise ja lükati tagasi. Assistent pakkus Erikule järgmist vaba aega, 10:00.

Joonis 3. Anu ja Erik nõustuvad samal hetkel sama tühja ajaga 09:00. Kinnihoidmine ei ole siduv, nii et klient, kes küsib just kinni hoitud aega, saab selle samuti broneerida. Käi see samm-sammult läbi, kõigepealt ilma lukuta, siis lukuga.

Mida sa Send4-s näed

Kinni hoitud ajad on Send4 kalendris viirutatud plokid tekstiga „Offered to …“, juba broneeritud kõnede kõrval. Need ei ole kohtumised ja neid ei arvestata kohtumistena. Ploki valimisel avaneb selle vestlus.

Joonis 4. Send4 kalender, kus kaks aega on kinni hoitud klientidele, kes pole veel vastanud. Demotööruum.

Kui kaua aega kinni hoitakse, määrad igal broneerimise sammul eraldi. Juhised on abikeskuses: kuidas pakutud aegu kinni hoitakse.

Mida kinnihoidmine ei tee

Kinnihoidmine ei ole siduv, nii et kaks klienti võivad ikkagi sama aja peale sattuda, kui üks neist küsib aega, mida teisele kinni hoitakse. See ei ole garantii. Samuti teab kinnihoidmine ainult Send4 kalendrit. Kas assistent kontrollib enne aja pakkumist müügiesindaja enda kalendrit?

Veel mitte. Broneeringud lähevad Send4 kalendrisse.

Iga müügiesindaja jaoks eraldi vabu aegu ka ei määrata: iga broneerimise samm pakub aegu, mis on vabad ühes ja samas Send4 kalendris. Suur päringute tulv võib aga terve hommiku kinnihoidmisi täis teha, nii et hilisematele klientidele pakutakse pärastlõunat või järgmist päeva. Kui nii juhtub, lühenda selle broneerimise sammu kinnihoidmise aega.

Kui broneerid klientidega kõnesid, siis just nii töötab Send4 müügikohtumiste broneerimine: assistent esitab sinu küsimused, hoiab aega kinni ja broneerib kõne samas vestluses.

Küsimused

Mis on topeltbroneering?

Kaks kohtumist samal ajal või kaks inimest, kellele mõlemale on öeldud, et sama aeg on nende oma. Kui AI-assistent vastab korraga paljudele päringutele, esineb sagedamini teine olukord, sest kõigile pakutakse varaseimat vaba aega.

Kuidas vältida topeltbroneeringuid?

Hoia aega pakkumise ajal kinni, jäta kohtumiste vahele puhveraeg ja kontrolli aega uuesti, kui inimene nõustub. Send4 AI-assistent hoiab iga pakutud aega vaikimisi kaks tundi kinni, nii et järgmisele kliendile pakutakse järgmist vaba aega.

Mida tähendab aja kinnihoidmine?

Aeg hoitakse kellegi jaoks kinni, kuni ta otsustab, aga seda ei broneerita. Send4 kinnihoidmine ei ole siduv. Kuni leidub vaba aeg, mida keegi kinni ei hoia, jätab assistent teiste klientide jaoks kinni hoitud ajad vahele. Kui kõik vabad ajad on kinni hoitud, pakub ta varaseimat neist, ilma uut kinnihoidmist loomata. Klient, kes küsib just kinni hoitud aega, saab selle ikkagi broneerida ja aja saab see, kes esimesena kinnitab.

Milleks on vaja puhveraega kohtumiste vahel?

Et pärast ühte kohtumist jääks aega enne järgmise algust. Send4-s on puhveraeg vaikimisi 10 minutit. Kahe kinni hoitud aja puhul peab esimese kohtumise lõpu ja järgmise alguse vahe olema vähemalt sama pikk kui pikem kahest puhverajast.

Kas AI saab kohtumisi broneerida?

Jah. Send4 AI-assistent broneerib kõnesid SMS-i teel, Business-paketis ka e-kirja teel, Send4 kalendrisse ja hoiab iga pakutud aega kinni, kuni klient otsustab.

Mille poolest erineb AI-assistent online broneerimissüsteemist?

Veebipõhises broneerimissüsteemis valib klient ise kalendrist vaba aja. Send4 AI-assistent vastab päringule SMS-iga, Business-paketis ka e-kirjaga, esitab sinu küsimused ja pakub ühe aja. Seda aega hoitakse kinni, kuni klient otsustab, ja broneeritud kõne läheb Send4 kalendrisse.

Kas Send4 töötab Google Meeti või Microsoft Teamsiga?

Veel mitte. Kõne broneeritakse Send4-s ja lingi saadad sina.

Kas see kontrollib enne aja pakkumist minu enda kalendrit?

Veel mitte. Broneeringud lähevad Send4 kalendrisse.

Kas kinni hoitud ajad lisatakse minu kalendrisse?

Ei. Kinnihoidmine on ainult Send4-s. Send4 kalendris on see viirutatud plokk ja see ei ole kohtumine.

Viktoras Lava

CTO

Viktoras ehitab Send4 toodet. Pakutud aegade kinnihoidmise tegi ta valmis 2026. aasta septembris.

Kus see Send4-s on Broneeri müügikohtumisi Hinda päringute sobivust SMS-i või e-kirja teel, jaga need müügiesindajate vahel ja lepi kokku kõneajad.

Iga päring saab vastuse.
Sina saad broneeringu.

14-päevane prooviperiood sinu enda Twilio või Vonage'i numbriga.