Johdanto
Tällä hetkellä lähes kaikissa tekoälyprojekteissa törmää kirjainyhdistelmään RAG. Kun tekoälyyn vähemmän tutustunut henkilö käy googlettamassa ’mikä ihmeen RAG?’, hän saa vastaukseksi ’Retrieval Augmented Generation’. Seuraavaksi hän klikkaa jotain linkkiä, joka selittäisi asiaa paremmin ja sieltä saattaa tulla seuraavanlainen vastaus (tämä Amazonin sivuilta):
”Retrieval-Augmented Generation (RAG) is the process of optimizing the output of a large language model, so it references an authoritative knowledge base outside of its training data sources before generating a response. Large Language Models (LLMs) are trained on vast volumes of data and use billions of parameters to generate original output for tasks like answering questions, translating languages, and completing sentences. RAG extends the already powerful capabilities of LLMs to specific domains or an organization’s internal knowledge base, all without the need to retrain the model. It is a cost-effective approach to improving LLM output so it remains relevant, accurate, and useful in various contexts.” (lähde)
Tässä vaiheessa moni nostaa kädet pystyyn, pistää läppärin kiinni ja lähtee bisselle. RAG kuulostaa joltain rakettitieteeltä, antaa olla. Varmaan myös todella kallista, koska pitäisi varmaan palkata joku seniori data scientist. Sitten jos scientist sattuisi kuolemaan, kukaan normaali ihminen ei ymmärtäisi mitä hän on rakennellut ja yritykselle on jäänyt käteen musta laatikko koodia, jota kukaan ei ymmärrä.
Vaikka RAG-projekteissa voidaan tehdä todella monimutkaisiakin juttuja, niin pohjimmiltaan se on vain yksi tapa tehdä tiedosto-, rajapinta- ja tietokantahakuja.
Netti on täynnä juttuja RAG-projektien tekemisestä yleisellä tasolla, tämä kirjoituksen tarkoituksena on avata RAG-projektien toteutusta, kun pohjadatana on suomenkielinen materiaali. Pienen maan kieli vaatii RAG-projekteissa aina vähän erikoishuomiota, asiasta harvemmin muistetaan netin RAG-tutoriaaleissa mainita.
Käydään siis läpi RAG:illa höystettyä hakemista suomenkielinen materiaali huomioiden, kuvitteellisessa chatbot-projektissa jossa on seuraavat vaiheet:
- Tiedon esikäsittely (Pre-Retrieval)
- Tiedon hakeminen (Retrieval)
- Haetun tiedon jälkikäsittely (Post-Retrieval)
- Haetun tiedon käyttö chatbotissa (Generation)
Tässä osassa käydään läpi tiedon esikäsittelyyn liittyviä vaiheita, seuraavassa osassa jatketaan tiedon tallentamiseen ja hakemiseen liittyvillä asioita.

Roskaa sisään, roskaa ulos
’Garbage in, garbage out’. Tuo on tärkeimpiä lauseita pitää mielessä tiedon esikäsittelyssä. Jos pohjadata on roskaa, siitä haetut tulokset ovat noin aina roskaa. Tässä yhteydessä roskalla tarkoitetaan dataa, jota ei ole millään tavalla esikäsitelty sellaiseen muotoon, että siitä olisi helpompi hakea tarvittuja tiedon osia.
Useat tahot myyvät RAG-ratkaisujaan myyntipuheilla, että voit heittää heidän palveluunsa vaikka tuhat PDF-tiedostoa pohjaksi chatbotille ja sen jälkeen botti on valmis ja voi jutella kaikesta mitä PDF-tiedostoissa oli mainittuna. Kokeilijat tietävät, että varsinkin jos pohjana oli suomenkielinen materiaali, niin harva noista palveluista tuottaa muuta kuin ns. euron-botin, joka enimmäkseen vastaa melko oikein esitettyihin kysymyksiin mutta vastaa kuitenkin niin usein täysin väärin, että lopulta elämä ilman sitä on helpompaa.
Miksi nuo palvelut usein tuottavat lähes hyödyttömän chatbotin? Jos kurkistetaan pellin alle, niin halvimmat niistä eivät tee PDF-tiedostoille mitään muuta, kuin imuttavat niistä tekstit ulos (usein varmistamatta millään tavalla tuliko teksti ulos mitenkään ehjänä, monesti se on hajoillut tavoilla x, y ja z) ja sen jälkeen joko pistävät tekstin haettavaksi johonkin perus tietokantaan (esim. MySQL), tai sitten he jakavat sen esim. 1000 merkin osiin ja tallentavat vektoritietokantaan. Jos edellä mainitulla tavalla tallennetun datan pohjalla oli esimerkiksi CV-tiedostoja, on suuri todennäköisyys, että monissa niissä muun muassa nimet ja tittelit ovat tallentuneet kantaan ylimääräisillä välilyönneillä muotoihin kuten ’b a c k e n d d e v e l o p e r’ tai ’tie to kan ta asian tunti-ja’ eivätkä haut osaa käyttää niitä.
Pienellä vaivalla iso hyöty
Jos omista PDF tiedostoistaan haluaa saada hakukelpoisia, kannattaa a) kilpailuttaa useita PDF-parsijoita keskenään ja b) kierrättää saadut tulokset jonkun ison kielimallin kautta.
Parsijoiden tulosten kilpailutuksen voi tehdä ilman tekoälyä. Prosessi toimii siten, että ensin valitaan esimerkiksi viisi eri parsijaa, pyöräytetään PDF-tiedostot niiden kautta ja sen jälkeen vertaillaan tuloksia per PDF ihan perus koodin avulla. Onko jossain tuloksissa enemmän irtokirjaimia kuin muissa? Onko jossain tuloksissa enemmän väliviivoja kuin muissa? Onko jossain tuloksissa enemmän rikkinäisiä kirjaimia kuin muissa? Se tulos, jossa on vähiten häikää otetaan jatkoon. Tämä vaihe pitää tehdä per PDF, koska yksi parsija voi toimia yhteen PDF:ään parhaiten ja toinen parsija seuraavaan. En ole vielä koskaan törmännyt tilanteeseen, jossa yksi parsija olisi paras kaikille PDF-tiedostoille, jos niitä on vähänkin enemmän ja useasta eri lähteestä.
Seuraavassa vaiheessa jollekin isolle kielimallille (esim. chatGPT-4, Claude 3 Opus, Gemini 1.5) kirjoitetaan prompti, jossa sille kerrotaan PDF:ien sisällön tyyppi (esimerkiksi, että kyseessä on curriculum vitae-tieto), sisällön kieli ja pyydetään sitä korjaamaan ilmiselvät välistysvirheet ja muut tekstihäikät ja palauttamaan teksti niiden osalta korjattuna, muuten ilman muutoksia. Promptiin kannattaa lisätä esimerkkejä virheistä ja miltä korjattu teksti näyttäisi. Näin kielimalli saa itselleen kättä pidempää siitä miten sen tulisi toimia.
Noilla muutamalla yksinkertaisella tempulla saa suurimman osan PDF-parsijoiden virheistä korjattua. Tarvittu taitotaso koodaajana: ei juuri mikään. Jos ei osaa kirjoittaa prompteja, voi pyytää vaikka chatGPT:ltä pohjaksi malliesimerkin. Tässä yksi sellainen:
”Given the following text extracted from a CV file, please correct any spelling, spacing, and formatting errors. Ensure the text adheres to standard Finnish language rules and is clear and professional. The goal is to optimize the text’s accuracy and searchability in a database. Please provide the revised version of the text: [Insert the extracted text here]”
Lisädatan generointi
Kun PDF:ien teksti on saatu ehjänä ulos, monet netin RAG-tutoriaalit ohjaavat seuraavaksi ottamaan käyttöön esim. LangChainin tai LlamaIndexin koodikirjastoja, jotta tekstistä saataisiin generoitua ulos lisädataa hakuja varten. Generoitu lisädata on tekoälyjen tekemää dataa, joka voi olla yhteenvetoja annetusta datasta, sanojen synonyymejä, tärkeimpiä avainsanoja ja vaikka mitä muuta. Tämä lisädata auttaa hakemisessa, kun yritetään löytää oleellisin tieto jota palauttaa isoista tietomassoista. Kun pohjalla on materiaalia suomen kielellä, suosittelisin välttämään generoinnin tekemistä valmiilla koodikirjastoilla. Syy on se, että generointi tapahtuu yleensä kielimallia ohjeistamalla ja jos käyttää valmista kirjastoa, tuo ohje on todennäköisesti jossain piilossa eikä se lainkaan ota huomioon mikä oli pohjamateriaalin tyyppi ja kieli. Saatat olettaa, että se genroi suomenkielisestä tekstistä suomenkielistä dataa mutta todellisuudessa generoitu materiaali onkin englanniksi. Vaikka kielimallin ohje löytyisi kaivamalla ja teet siihen tarvittavia muutoksia muun muassa kielen korjaamiseksi, todennäköisesti unohdat lukita kirjaston päivityksen ja kaikki lisäohjeesi katoavat seuraavan kerran kuin kirjastot päivittyvät. Joten kaikista fiksuinta ja turvallisinta on tehdä nuo generointiohjeet (eli prompit) ihan itse. Ei ole iso vaiva. Alla esimerkki-prompti synonyymien generoimiselle (lyhyemmälläkin promptilla saa jo ihan hyviä tuloksia).

Kun tekee yhden promptin kunnolla tätä vaihetta varten, sen voi sitten antaa chatGPT:lle ja pyytää sitä tekemään sen pohjalta loput tarvittavat. Itse tuotan yleensä generoituna datana muun muassa seuraavia asioita:
- Tärkeimmät avainsanat
- Synonyymit
- Yhteenvedot
- Listan nimistä, osoitteista, päivämääristä joita tekstissä esiintyy
- Esimerkkikysymyksiä joihin kyseinen teksti oisaisi vastata
- Variaatioita tekstistä, jossa asiat on esitetty vähän eri muodossa
Yhden sivun CV-tiedostosta voi saada generoitua kymmenen sivua lisädataa, joka helpottaa chatbotin taustalla olevia hakukoodeja huomattavasti, kun ne yrittävät hakea chatbotille parhaat mahdolliset sisällöt vastauksien luomiseksi.
Tämän kirjoituksen tärkein viesti on se, että kun teet tekoälyprojektia johon liittyy datan hakeminen, älä luota mainoslauseisiin joissa sanotaan, että sinun ei tarvitse kuin heittää PDF-tiedostosi sisään jonnekin palveluun ja sen jälkeen hakeminen sujuu vaivatta. Sellainen lopputulos on äärimmäisen harvinainen, jopa isojen firmojen palveluissa. Varaudu tekemään työtä datasi laadun eteen, se työ on aina vaivansa väärti.
Kiitos lukemisesta, seuraavassa osassa käydään läpi tietojen tallentamista ja tallennetusta tiedosta hakemista.
Mikäli aihe kiinnostaa, pistä Linkkariprofiilini tästä seurantaan. Pistän sinne tietoa, kun saan uusia osia kirjoitettua.
Tommi Bäckgren | 4.5.2024
Kirjoittaja on sarjayrittäjä, joka tykkää myynnin ohessa istua yöt testailemassa uusimpien teknologisten innovaatioiden soveltuvuutta käytännön ratkaisuihin.