Kuvailen Power Platfomia usein valtavaksi LEGO rakennussarjaksi. Rakennuspalikoita on Copilot Studion kehittyessä tullut vain valtavasti lisää. Niin paljon, että heikompaa alkaa huimaamaan.
Tällä kertaa tutustuaan Copilot Studion eri kyvykkyyksiin, eli niihin LEGO-palikoihin. Näitä palikoita käyttämällä voi nimittäin toteuttaa hämmentävän monella eri tavalla (suurinpiirtein) saman asian.
Esimerkki – Agentti joka tietää autoista
Rakennetaan yksinkertainen agentti, jolta voi kysellä perustietoja autoista ja niiden omistajista. Tiedot sijaitsevat Dataversessä kahdessa taulussa
- Autojen omistajat (Contact), Dataversen vakiotaulu
- Autot (Car)

Autoja tietokannassa on hieman yli 5000 kappaletta. Osasta on kerrottu merkki, mutta suuresta osasta ei. Jokaisen auton tiedoissa on auton omistaja (lookup contact-tauluun), sekä autolla ajetut kilometrit (mileages).

Haluamme rakentaa agentin, joka osa vastata peruskysymyksiin tallentamistamme autoista. Tyyliin
- Montako autoa on?
- Montako Toyotaa on?
- Montako autoa Timo Pertilä omistaa?
Mitä eri toteutusvaihtoehtoja meillä on rakentaa agentti, joka hyödyntää Dataversessä makaavia tietoja?
Vaihtoehto 1 – Tietämyslähde (knowledge)
Aloitetaan sillä ilmeisimmällä. Lisätään agentille Dataverse tietämyslähteeksi (knowledge).

Poimitaan mukaan tarvittavat taulut. Tällä kertaa autot-taulu (car) riittää.

Valmista! Testataan agenttia muutamalla simppelillä kysymyksellä. Autojen kokonaislukumäärä tulee kuin apteekin hyllyltä.

Hieman yllättäen agentti kykenee vastaamaan myös kysymykseen autojen omistajista. Vaikka emme lisänneet tietämyslähteeksi kontakti-taulua, jossa omistajien tiedot (kuten etu- ja sukunimi) ovat.

Agentti vastaa nätisti erilaisiin kysymyksiin.

Tosin se ei osaa päätellä miten monta eri automerkkiä tietokannassa on. Tämä voi tosin johtua siitä että olen tallentanut automerkin laiskasti nimisarakkeeseen.

Jatketaan matkaa.
Vaihtoehto 2 – Tietämyslähteen käyttö aiheessa (topic)
Luodaan agentin käyttöön aihe (topic). Kuvataan ensin agentille milloin tätä aihetta käytetään (1, aina kun käyttäjä kysyy autoista tai niiden omistajista). Lisätään seuraavaksi toiminnoksi generatiivinen vastaus ja määritellään sen käyttämäksi tietolähteeksi (Data source) aiemmin lisäämämme tietämyslähde (2). Kysymykseksi (input) annetaan käyttäjän syöttämä kysymys (muuttuja Activity.Text, 3)

Nyt kun kysymme agentilta autoista, käyttää se tätä aihetta vastatakseen. Vastauskin on oikein.

Agentti toimii edelleen myös autojen omistajista kysyttäessä.

Miksi haluaisimme hyödyntää tietämyslähdettä aiheen sisällä? Aiheen käyttö tuo meille huomattavan määrän kontrollia. Voimme lisätä kysymykseen omia parametreja käyttäjän kysymyksen lisäksi. Voimme tehdä kyselyitä useaan paikkaan ja muodostaa vastauksen saamiemme vastausten perusteella. Aiheen käyttö avaa vaikka mitä mahdollisuuksia.
Mikäli käytämme pelkkää tietolähdettä, meillä on hyvin vähän kontrollia.
Vaihtoehto 3 – Yhdistin (connector)
Kokeillaan seuraavaksi agenttia, jolle lisätään työkaluksi (tool) Dataversen yhdistin.

Siirrytään konfiguroimaan yhdistintä (Add and configure).

Kirjoitetaan yhdistimelle parempi kuvaus, jotta agentti osaa käyttää sitä.

Määritellään yhdistimen hakevan tiedot autot-taulusta (sen voi myös antaa itse päättää mistä taulusta tiedot milloinkin haetaan). Lopuksi yhdistin muodostaa vastauksen itse (Write the response with generative AI).

Agenttia testattaessa tulee vastaan heti ongelma. Dataversen palauttama vastaus on niin suuri, ettei agenttimme kykene käsittelemään sitä. Autoja oli hieman yli 5000.

Dataversen List rows -toiminto ei sovellu käytettävksi mikäli rivejä on paljon. Pienillä rivimäärillä sitä voi hyödyntää. Alla sen avulla haetaan mini CRM:stäni t-kirjaimella alkavia asiakkaita.

Yhdistin sopii paremmin esimerkiksi päätöstä tukevien rajattujen tietojen hakemiseen (uudelle työntekijälle tarjolla olevat konemallit), kuin esimerkin tapaisen laajan aineiston vapaaseen kyselyyn.
Vaihtoehto 4 – Agent flow
Entä jos lisäisimme agenttimme käyttöön flow’n, joka hakee Dataversestä kaikki autot tietoineen?
Luodaan flow.

Flow listaa kaikki autot (List rows). Poimitaan tulosjoukosta mukaan ainoastaan kiinnostavat sarakkeet (Select) ja ne palautetaan agentille. Jos lopputulos olisi tällä kertaa agentille sopivan kokoinen.

Annetaan flow’lle agenttia varten parempi kuvaus.

Flow’n suorituksen jälkeen muodostetaan vastaus generatiivisella tekoälyllä.

Törmäämme samaan ongelmaan kuin yhdistimen kanssa. Agentti ei pysty käsittelemään saamaansa pitkää vastausta.

Kokeilin rajoittaa flow’n palauttamien rivien lukumäärää. Agentti kykenee käsittelemään 1000 riviä. 1500 on jo liikaa.
Tämän lopputuloksen toki arvasimmekin. Kyseessä on pohjimmiltaan sama toimenpide kuin yhdistintä käytettäessä.
Yhdistintä ja flow’ta voi käyttää myös aiheen sisällä, mutta se ei ratkaise tätä rivilukumäärään liittyvää ongelmaa, joten jatketaan matkaa.
Vaihtoehto 5 – Oma kehoite (custom prompt)
Entä jos kyselisimme tietoja autoista hyödyntäen omaa kehoitetta?
Luodaan sellainen.

Kehoite saa parametrinaan käyttäjän kysymyksen ja se pyrkii selvittämään vastauksen perustuen autot-taulun, sekä siihen liittyvän yhteystieto-taulun, sisältöön.

Kokeillaan. Vastaus tulee, mutta prompt on käyttänyt vastauksessaan ainoastaan 30 riviä Dataversestä.

Syykin on ilmeinen. Kehotteessa on asetus, joka määrittelee montako riviä Dataversestä haetaan. Oletuksena arvo on 30 (maksimi on 1000).

Tämäkin on ymmärrettävää. Kielimallille syötetyn tekstin pituus on suoraan verrainnollinen sen generoimiin kustannuksiin. Omaa kehoitetta ei ole muutoinkaan mitään järkeä käyttää tämän tyyppiseen hakuun.
Omia kehoitteita voi käyttää agentissa myös aiheiden (topics) sisällä, flow’n sisällä tai esimerkiksi aiheesta käynnistettävän flow’n sisällä.
Vaihtoehto 6 – Dataverse MCP palvelin
Entä jos lisäisimme agenttimme käyttöön Dataverse MCP palvelimen. Viimeaikaisen hehkutuksen perusteella se tulee ratkaisemaan kaikki ongelmamme.

Helppoa kuin heinänteko.

MCP palvelimen työkalu (tools) osiosta näkee mitä kaikkea se osaa.

Testataan. Ja sieltä se oikea vastaus tulee. On mielenkiintoista nähdä millainen SQL-kysely kysymyksestä lopulta muodostuu.

Autojen omistajatiedotkin löytyy.

Kolmannen kysymyksen kohdalla törmäämme seinään. Oikea SQL-kysely syntyy, mutta Copilot Studio ilmoittaa että olen käyttänyt generatiivista orkestrointia riittävästi tällä erää.

Muutaman minuutin odottelun jälkeen voin jatkaa agenttini tenttaamista. Käytännössä törmäsin näihin rajoihin. Tarkemmin ottaen kehitysympäristöni 10 pyyntöön per minuutti rajoitukseen.

MCP palvelimen avulla agenttimme muodostaa käytännössä SQL-kyselyjä Dataverseen. Kyselyt kattavat koko taulun, mutta MCP-palvelin palauttaa tulosjoukkona aina maksimissaan 20 riviä.
Pyydetään agenttia listaamaan kaikki autot. Lopputuloksena on 20 riviä 5006:sta.

Yhteenveto
Kuten näimme, Copilot Studiosta pääsee lukemaan Dataversen tietoja usealla eri tavalla. Niiden toiminnassa on kuitenkin merkittäviä eroja. Tietämyslähde hyödyntää Dataversen hakua. Muut menetelmät hakevat Dataversen taulusta/tauluista suoraan tietueita. Tämä tuo välittömästi mukanaan rajoitteita, sillä emme halua (=alusta ei halua) palauttaa kielimallin pureksittavaksi tuhansia rivejä raakadataa, sillä niiden käsittely maksaa. Näin törmäämme nopeasti 1000 rivin rajoitukseen.
Dataverse MCP palvelimen käyttö poikkeaa tästä. Agentti tekee sitä hyödyntäen SQL-kyselyjä Dataverseen. Se saattaa tehdä useita yrityksiä kunnes onnistuu. Agentti voi esimerkiksi kysyä ensin taulun sarakkeiden nimet ja tämän pohjalta päätellä millainen kysely tällä kertaa tulee tehdä.
MCP palvelinta käytettäessä kyselyt kattavat kaikki tietueet, mutta paluuarvona saa aina maksimissaan 30 riviä.
Epäselvintä MCP palvelimien hyödyntämisessä on kustannukset. Mutta eiköhän sekin tästä pian selviä.