
Ouron some- ja blogipostauksissa esiintyy aiheena usein ”Kullanhuuhdonta”. Se on ourolaisten sisäinen koulutuspäivä ja tärkeä osa yrityskulttuuriamme. Kullanhuuhdontapäivinä kokoonnumme mielenkiintoisiin paikkoihin opettamaan toisillemme uusia aiheita ja taitoja. Silloin tällöin saamme myös kouluttajan Ouron ulkopuolelta iloksemme. Kullanhuuhdonnan aiheet vaihtelevat tekoälyn etiikasta ohjelmistokielien syntakseihin ja muistinhallintamalleihin.
Elokuussa tapasimme Lonnassa, joka on yksi Helsingin edustan lähisaarista. Ohjelmassa meillä oli Large language model (LLM) ja Retrieval Augmented Generation (RAG). RAG on tekniikka, jossa generatiivisen tekoälyn tuotoksia rikastetaan eri lähteistä, esimerkiksi yrityksen omista tietokannoista haetuilla tiedoilla.
Pääpaino päivässä oli tutustua RAG:in perusteisiin käytännön tasolla. Onneksi Pythonilla on mieletön repertuaari kirjastoja saatavilla, sillä ne auttavat pääsemään nopeasti tekemisen makuun myös ilman syvällistä teorian osaamista. Tämä muuten on yksi Kullanhuuhdonnan perusideoista, esitellä ideoita ja työkaluja kollegoille sekä jakaa omaa osaamistaan. Jos jollakulla tiimissä on halua syventää osaamistaan kyseisestä aiheesta, Ourolta tulee tähän täysi tuki.
RAG-päivämme jakautui neljään vaiheeseen:
Ensin päätimme datan, jota kukin meistä käytti lähdemateriaalina. Sen jälkeen keräsimme dokumentit ja prosessoimme ne käyttämällä Langchain Community -kirjastoja, erityisesti DirectoryLoaderia. Tämä salli meidän yhdistää kaikki tiedostot yhdeksi suureksi tietorakenteeksi, joka oli sitten valmis seuraavaan vaiheeseen.
Seuraavaksi oli aika käsitellä suurta tietorakennetta. Näin iso datamöhkäle ei ole käyttökelpoinen, joten se täytyi jakaa pienempiin, helpommin käsiteltäviin paloihin. Langchain-kirjastossa on työkalu nimeltään text_splitter, joka tarjoaa RecursiveCharacterTextSplitter-ominaisuuden datan jakamiseksi automaattisesti pienempiin paloihin, ennalta määritellyn koon ja päällekkäisyyden avulla. Nämä ominaisuudet olivat välttämättömiä tavoitteellemme syöttää dataa LLM:lle myöhemmin.
Kolmas ja viimeinen vaihe datan valmisteluun on prosessoida se vektoritietokantaan ja tallettaa myöhempää käyttöä varten. Jälleen Langchain Community -kirjastot tulivat pelastamaan meidät. Moduuli nimeltään Chroma pystyy ottamaan kaikki aiemmin valmistellut palat ja suorittamaan OpenAIEmbeddings()-taikuutta. Tämä taika liittyy olennaisesti merkkijonojen sukulaisuuteen, johon LLM:t perustuvat.
Kaikkien valmistelutöiden jälkeen oli kahvitauon aika. Tauon jälkeen paneuduimme pääaiheeseemme eli RAG:iin käyttämällä erityisdataa kyselyiden muodostamiseksi. Tämä osoittautui vähemmän taianomaiseksi kuin mitä olimme kuvitelleet. Simppelisti ilmaistuna kysyimme käyttäjältä kysymyksen ja annoimme sen Chroma-tietokannalle, josta saimme takaisin relevantit tiedonpalaset. Sitten teimme promptin eli kehotteen OpenAI:lle, joka oli kutakuinkin seuraava:
”””
Vastaa kysymykseen käyttäen vain seuraavassa annettua kontekstia:
– ensimmäinen datan palanen, joka liittyy kysymykseen
– toinen datan palanen, joka liittyy kysymykseen
– kolmas datan palanen, joka liittyy kysymykseen
—
Vastaa kysymyksen käyttäen edellä annettua kontekstia: “Tässä kysymys, joka liittyy käytettyyn tietoaineistoon”
”””
Ja tässä kaikki! Avain RAG:n toteutukseen on luoda tarpeeksi sopivan kokoisia osia käytetystä datasta ja luoda kysymys LLM chatille käyttäen vain relevantteja osia. Chat käyttää omaa kielen jäsentämistaikuuttaan prosessoidakseen promptia. Tuloksena on sitten toivottavasti järkeä vastaus. Periaatteessa kaikki nämä työvaiheet voidaan toki tehdä käsityönä millä tahansa LLM:llä jossa on chat-toiminto. Mutta, kuten yllä todettu, suurin tehtävä on relevantin tiedon valmistelu ja sen tallentaminen tulevaa varten. Loppu on yllättävän helppoa, kiitos LLM:n kyvylle jäsentää ja muotoilla tekstiä.
Kirjoittajat: Ouron Senior Developer Matti Kärki ja HR & SoMe Specialist Mari Tarkiainen
