§lectorium

Lectoriumi API

Praegune staatus

Lectorium on ehitatud API-na - veebiliides on selle peal olev kiht, mitte vastupidi. See tähendab, et sama päringuliides, mida kasutab app.lectorium.ee, on põhimõtteliselt liidestatav ka mujale: personalitarkvarasse, kliendiportaali, sisemisse teenusesse.

Seis osade kaupa:

Päringuliides (otsing ja vastus)
töötab
Stabiilne avalik aadress
töötab
HTTPS
töötab
API võtmed
töötab
Võtme väljastamine iseteeninduses
planeeritud
Kvoodid võtme kohta
planeeritud
Kasutustingimused
planeeritud

Aadress on https://api.lectorium.ee ja iga päring vajab API-võtit. See pool on valmis ja töötab. Puudu on veel iseteenindus: võtit ei saa ise genereerida, selleks tuleb ühendust võtta. Kõik, mis on märgitud planeeritud, ei ole veel olemas ja võib muutuda.

Otspunktid töötab

Kolm otspunkti. Kõik võtavad ja tagastavad JSON-i.

  • GET/healthindeksi seis ja lävend - võtit ei vaja
  • GET/mekontrolli, kas võti töötab
  • POST/searchleitud sätted, ilma vastust koostamata
  • POST/answertsiteeritud vastus koos allikatega

Autentimine

Võti käib päises. Muud viisi ei ole - /health on ainus otspunkt, mis võtit ei vaja.

Authorization: Bearer lec_sk_…

Võtit ei tohi panna URL-i (?api_key=…). Selline päring lükatakse tagasi veaga 400: URL-id satuvad serverilogidesse, brauseri ajalukku ja Referer-päisesse.

Kas võti töötab, saab kontrollida ilma päringut kulutamata:

curl https://api.lectorium.ee/me \
  -H 'Authorization: Bearer lec_sk_…'

{
  "kind": "key",
  "id": "minu-teenus",
  "label": "Minu süsteem"
}

Päring

curl -X POST https://api.lectorium.ee/answer \
  -H 'Authorization: Bearer lec_sk_…' \
  -H 'content-type: application/json' \
  -d '{"question": "Kui pikk on põhipuhkus?", "top_k": 2}'

question on kohustuslik, top_k vabatahtlik (vaikimisi 5). Vabatahtlik on ka asked - vt täpsustust allpool.

Vastus

See on tegelik vastus, mitte näidis - lühendatud ühe allikani:

{
  "question": "Kui pikk on põhipuhkus?",
  "answer": "§ 55 (Töölepingu seadus): Eeldatakse, et töötaja
              iga-aastane puhkus on 28 kalendripäeva (põhipuhkus), kui
              töötaja ja tööandja ei ole leppinud kokku pikemas
              põhipuhkuses või kui seadus ei sätesta teisiti.",
  "sources": [
    {
      "act": "Töölepingu seadus",
      "act_id": "TLS",
      "section": "§ 55",
      "effective_date": "2026-07-12",
      "url": "https://www.riigiteataja.ee/akt/103072026034?leiaKehtiv#para55",
      "excerpt": "§ 55 Põhipuhkus Eeldatakse, et töötaja iga-aastane…",
      "score": 0.8855
    }
  ],
  "confidence": 0.8855,
  "disclaimer": "See vastus on koostatud automaatselt Riigi Teataja
                 tekstide põhjal ega ole õigusnõustamine. Kontrolli alati
                 viidatud sätete kehtivat redaktsiooni.",
  "answered": true
}

Kui vastust ei tule

Kui ükski säte ei ületa asjakohasuse lävendit, tuleb ikkagi HTTP 200 - aga answer on null ja answered on false:

{
  "question": "mis kell on?",
  "answer": null,
  "sources": [],
  "confidence": 0.0,
  "answered": false,
  "note": "asjakohast sätet ei leitud"
}

See ei ole viga, vaid süsteemi kavatsetud käitumine. Vt miks vastus on tsitaat.

Märkus ka õnnestunud vastuse juures

Väli note ei esine ainult vaikimise korral. Kui tsiteeritud säte pärineb seadusest, mis üksi kogu reeglit ei sisalda, tuleb märkus koos vastusega - praegu puudutab see isikuandmete kaitse seadust, mis üksnes täpsustab EL üldmäärust (GDPR). Liidestajana kuva note alati, kui see on olemas, ka siis kui answered on true.

Täpsustus: kui küsimus on kahe seaduse vahel

Kui kaks seadust jäävad lävendist üles peaaegu võrdse skooriga ja selle paari kohta on käsitsi kirjutatud juhtum, lisandub vastusele vabatahtlik väli clarify. Vastus ise on täiesti tavaline - tsitaat, allikad ja answered: true on kõik olemas. Täpsustus on pakkumine, mitte tõrge: kui sa selle vahele jätad, ei muutu midagi.

{
  "answer": "§ 15 (Töölepingu seadus): …",
  "answered": true,
  "sources": [ … ],
  "clarify": {
    "case": "too-ohutus",
    "question": "Kas küsimus puudutab töösuhet või töökeskkonda?",
    "options": [
      { "label": "Töösuhe ja tingimused", "payload": "tööandja kohustused töölepingu täitmisel" },
      { "label": "Töökeskkonna ohutus",   "payload": "töökeskkonna riskianalüüs ja tööohutuse nõuded" }
    ]
  }
}

Kuva kasutajale question ja label-id. payload ei ole kasutajale mõeldud tekst - see on otsingusõnastus. Kui kasutaja valib variandi, saada uus päring, kus question on algne küsimus + tühik + payload ja asked sisaldab selle juhtumi case-väärtust:

-d '{"question": "Millised on tööandja kohustused töötaja ees? töökeskkonna riskianalüüs ja tööohutuse nõuded",
     "asked": ["too-ohutus"]}'

Seansi hoiab liidestaja, mitte server: asked on ainus koht, kus see olek elab. Sama juhtumit teist korda ei pakuta ja kokku ei tule täpsustust rohkem kui kaks korda vestluse jooksul. Täpsustuse tekstid on eelnevalt käsitsi kirja pandud - keelemudel neid ei genereeri - ja neid tuleb aja jooksul juurde.

Veakoodid

Vead tulevad kujul {"message": "…"}.

400 Võti oli URL-is
kasuta päist
400 question puudub
väli on kohustuslik
401 Võti puudub või on tundmatu
+ WWW-Authenticate
403 Võti on tühistatud
küsi uus
429 Liiga palju päringuid
+ Retry-After
500 Otsing ebaõnnestus
serveripoolne viga

Puuduv või vale võti annab alati sama teate - see ei ütle, kas võti oli olemas, vigane või tundmatu. Erinevus aitaks ainult ründajat.

Vastuse struktuur

  • answerstring | null Tsiteeritud sätte tekst kujul „§ N (seadus): …“. null, kui midagi asjakohast ei leitud. Tekst on võetud seadusest, mitte mudeli poolt sõnastatud.
  • answeredbool Kas vastus leiti. Kontrolli seda enne answer kuvamist.
  • sources[]array Leitud sätted. Kui answer ei ole null, ei ole see loend kunagi tühi.
  • sources[].actstring Seaduse nimi, nt „Töölepingu seadus“.
  • sources[].act_idstring Lühend, nt TLS, VÕS, PärS.
  • sources[].sectionstring Paragrahv, nt § 55.
  • sources[].effective_datestring Viidatud redaktsiooni jõustumiskuupäev. Kasulik, kui tahad kuvada, et säte on hiljuti muutunud.
  • sources[].urlstring Otselink kehtivale tekstile Riigi Teatajas. Ehitatud indekseerimise ajal, mitte hiljem kokku pandud.
  • sources[].excerptstring Sätte tekst, muutmata.
  • sources[].scorefloat Koosinussarnasus küsimusega. Mida kõrgem, seda kindlam vaste.
  • confidencefloat Parima vaste skoor.
  • disclaimerstring Kohustuslik hoiatustekst. Vt allpool.
  • clarifyobject | puudub Täpsustav küsimus koos valikutega, kui otsing jäi kahe seaduse vahel kahevahel. Vastust see ei asenda. Väljad: case, question, options[].label, options[].payload. Vt täpsustust.
  • notestring Hoiatus või selgitus. Puudumise korral selgitab, miks vastust ei tulnud; vastuse korral hoiatab, kui tsiteeritud säte ei ole kogu reegel (nt isikuandmete kaitse seadus täpsustab GDPR-i). Kuva see alati vastuse juures.

Reeglid liidestajale

Lectorium tagastab õigusinfot. Kui sa ehitad selle peale oma liidese, lähevad mõned süsteemi garantiid sinu kätte - ja kui sa need eemaldad, lagunevad need ära. Neid palume järgida:

  • Kuva alati viide. Vastus ilma allikata ei ole Lectoriumi vastus. Kui su liides näitab answer välja, aga peidab sources, oled võtnud ära ainsa asja, mis teeb vastuse kontrollitavaks.
  • Kanna hoiatus edasi. disclaimer tuleb kasutajale näidata. Eestis on reguleeritud, kes tohib õigusabi anda - see tekst ei ole vormistuslik detail.
  • Käsitle answered: false korrektselt. Kui vastust ei leitud, ütle seda kasutajale. Ära asenda seda oma süsteemi oletusega ega saada küsimust vaikselt mujale.
  • Ära sõnasta vastust ümber. Kogu mõte on selles, et tekst on seadusest võetud sõna-sõnalt. Kokkuvõtte tegemine viib tagasi sinna, kust me alustasime.
  • Ära esitle seda õigusnõustamisena. Ka mitte kaudselt - ei tootenimes, ei kasutajaliidese sõnastuses.
Miks nii range

Need ei ole juriidiline pisikiri, vaid sama kolm reeglit, mis on Lectoriumi koodis jõustatud. Meie ei saa neid sinu liideses jõustada - saame ainult paluda. Kui liidestus neid ei järgi, ei ole tulemus enam see süsteem, mille täpsust me mõõtsime.

API võtmed töötab

Võtmed on kasutusel alates 30. juulist 2026. Enne seda oli API autentimiseta - kes aadressi teadis, sai päringuid teha. Nüüd ei teenindata ühtegi päringut ilma võtmeta, välja arvatud /health.

  • Võti päises. Authorization: Bearer lec_sk_… - võti algab alati lec_sk_-ga, nii on ta logist või koodist ära tuntav.
  • Võti organisatsiooni kohta, mitte kasutaja kohta - liidestus käib süsteemide, mitte inimeste vahel.
  • Serveris hoitakse ainult räsi. Võtit ennast me ei salvesta, seega kaotatud võtit ei saa keegi - ka meie mitte - taastada. Selle asemel väljastame uue ja tühistame vana.
  • Mitu võtit korraga on lubatud, nii et vahetamine ei nõua seisakut: võta uus, vii liidestus üle, tühista vana.
  • Tühistamine kehtib kohe - vana võti hakkab andma veakoodi 403 ilma teenuse taaskäivitamist.

Millist küsimust keegi küsis, ei ole meil vaja säilitada, ja plaan on seda ka mitte teha. Kui see peaks muutuma, kirjutame selle siia lehele enne, mitte pärast.

Hind ja piirangud

Kavatsus on hoida liidestamine tasuta. Lectorium tugineb avalikule andmele - Riigi Teataja tekstid on riigi poolt tasuta avaldatud - ja teenuse jooksutamine ei ole kallis: kogu asi on üks Go teenus ühel serveril, ilma välise mudeli-API-ta.

Aus täpsustus: „tasuta“ tähendab praegu kavatsust, mitte lubadust igaveseks. Realistlikud piirid, mis võivad tekkida:

  • Päringute arv. Kui üks liidestus hakkab masinatäiega päringuid saatma, tuleb piirang - muidu kannatavad kõik teised.
  • Kättesaadavus ei ole lubatud. See on üks server. SLA-d ega tööajagarantiid ei ole. Ära ehita sellest sõltuvat kriitilist protsessi.
  • Vastuse kuju võib muutuda. Väljasid võib juurde tulla. Enne olemasolevate eemaldamist või ümbernimetamist anname teada.

Kuidas ligi saada

Võtmed on olemas, aga iseteenindust ei ole: vormi, mida täita, ega automaatset registreerimist veel ei ole. Võtme saamiseks tuleb ühendust võtta ja öelda, mida sa ehitada tahad - see mõjutab ka seda, mis järjekorras me ülejäänud ligipääsu poole ehitame.

Kontakt käib Crowned Phoenixi kaudu.

Seniks saab süsteemi hinnata ilma ühegi kokkuleppeta: proovi rakendust ja loe tehnilist ülevaadet, kus on kirjas ka mõõdetud täpsus ja teadaolevad puudused. Kui midagi neist on sinu kasutusjuhtumi jaoks välistav, on parem see enne teada saada.